Wed Jan 27 02:12:16 2021 UTC ()
Use DEVICE_COMPAT_EOL.


(thorpej)
diff -r1.8 -r1.9 src/sys/arch/arm/ti/ti_gpio.c
diff -r1.8 -r1.9 src/sys/arch/arm/ti/ti_sdhc.c
diff -r1.11 -r1.12 src/sys/arch/arm/ti/ti_iic.c
diff -r1.6 -r1.7 src/sys/arch/arm/ti/ti_omapintc.c
diff -r1.7 -r1.8 src/sys/arch/arm/ti/ti_omaptimer.c

cvs diff -r1.8 -r1.9 src/sys/arch/arm/ti/ti_gpio.c (switch to unified diff)

--- src/sys/arch/arm/ti/ti_gpio.c 2021/01/25 14:20:39 1.8
+++ src/sys/arch/arm/ti/ti_gpio.c 2021/01/27 02:12:16 1.9
@@ -1,540 +1,540 @@ @@ -1,540 +1,540 @@
1/* $NetBSD: ti_gpio.c,v 1.8 2021/01/25 14:20:39 thorpej Exp $ */ 1/* $NetBSD: ti_gpio.c,v 1.9 2021/01/27 02:12:16 thorpej Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2019 Jared McNeill <jmcneill@invisible.ca> 4 * Copyright (c) 2019 Jared McNeill <jmcneill@invisible.ca>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE. 26 * SUCH DAMAGE.
27 */ 27 */
28 28
29#include <sys/cdefs.h> 29#include <sys/cdefs.h>
30__KERNEL_RCSID(0, "$NetBSD: ti_gpio.c,v 1.8 2021/01/25 14:20:39 thorpej Exp $"); 30__KERNEL_RCSID(0, "$NetBSD: ti_gpio.c,v 1.9 2021/01/27 02:12:16 thorpej Exp $");
31 31
32#include <sys/param.h> 32#include <sys/param.h>
33#include <sys/bus.h> 33#include <sys/bus.h>
34#include <sys/device.h> 34#include <sys/device.h>
35#include <sys/intr.h> 35#include <sys/intr.h>
36#include <sys/systm.h> 36#include <sys/systm.h>
37#include <sys/mutex.h> 37#include <sys/mutex.h>
38#include <sys/kmem.h> 38#include <sys/kmem.h>
39#include <sys/gpio.h> 39#include <sys/gpio.h>
40#include <sys/bitops.h> 40#include <sys/bitops.h>
41 41
42#include <dev/fdt/fdtvar.h> 42#include <dev/fdt/fdtvar.h>
43#include <dev/gpio/gpiovar.h> 43#include <dev/gpio/gpiovar.h>
44 44
45#include <arm/ti/ti_prcm.h> 45#include <arm/ti/ti_prcm.h>
46 46
47#define TI_GPIO_NPINS 32 47#define TI_GPIO_NPINS 32
48 48
49enum ti_gpio_type { 49enum ti_gpio_type {
50 TI_GPIO_OMAP3, 50 TI_GPIO_OMAP3,
51 TI_GPIO_OMAP4, 51 TI_GPIO_OMAP4,
52 TI_NGPIO 52 TI_NGPIO
53}; 53};
54 54
55enum { 55enum {
56 GPIO_IRQSTATUS1, 56 GPIO_IRQSTATUS1,
57 GPIO_IRQENABLE1, /* OMAP3 */ 57 GPIO_IRQENABLE1, /* OMAP3 */
58 GPIO_IRQENABLE1_SET, /* OMAP4 */ 58 GPIO_IRQENABLE1_SET, /* OMAP4 */
59 GPIO_IRQENABLE1_CLR, /* OMAP4 */ 59 GPIO_IRQENABLE1_CLR, /* OMAP4 */
60 GPIO_OE, 60 GPIO_OE,
61 GPIO_DATAIN, 61 GPIO_DATAIN,
62 GPIO_DATAOUT, 62 GPIO_DATAOUT,
63 GPIO_LEVELDETECT0, 63 GPIO_LEVELDETECT0,
64 GPIO_LEVELDETECT1, 64 GPIO_LEVELDETECT1,
65 GPIO_RISINGDETECT, 65 GPIO_RISINGDETECT,
66 GPIO_FALLINGDETECT, 66 GPIO_FALLINGDETECT,
67 GPIO_CLEARDATAOUT, 67 GPIO_CLEARDATAOUT,
68 GPIO_SETDATAOUT, 68 GPIO_SETDATAOUT,
69 GPIO_NREG 69 GPIO_NREG
70}; 70};
71 71
72static const u_int ti_gpio_regmap[TI_NGPIO][GPIO_NREG] = { 72static const u_int ti_gpio_regmap[TI_NGPIO][GPIO_NREG] = {
73 [TI_GPIO_OMAP3] = { 73 [TI_GPIO_OMAP3] = {
74 [GPIO_IRQSTATUS1] = 0x18, 74 [GPIO_IRQSTATUS1] = 0x18,
75 [GPIO_IRQENABLE1] = 0x1c, 75 [GPIO_IRQENABLE1] = 0x1c,
76 [GPIO_OE] = 0x34, 76 [GPIO_OE] = 0x34,
77 [GPIO_DATAIN] = 0x38, 77 [GPIO_DATAIN] = 0x38,
78 [GPIO_DATAOUT] = 0x3c, 78 [GPIO_DATAOUT] = 0x3c,
79 [GPIO_LEVELDETECT0] = 0x40, 79 [GPIO_LEVELDETECT0] = 0x40,
80 [GPIO_LEVELDETECT1] = 0x44, 80 [GPIO_LEVELDETECT1] = 0x44,
81 [GPIO_RISINGDETECT] = 0x48, 81 [GPIO_RISINGDETECT] = 0x48,
82 [GPIO_FALLINGDETECT] = 0x4c, 82 [GPIO_FALLINGDETECT] = 0x4c,
83 [GPIO_CLEARDATAOUT] = 0x90, 83 [GPIO_CLEARDATAOUT] = 0x90,
84 [GPIO_SETDATAOUT] = 0x94, 84 [GPIO_SETDATAOUT] = 0x94,
85 }, 85 },
86 [TI_GPIO_OMAP4] = { 86 [TI_GPIO_OMAP4] = {
87 [GPIO_IRQSTATUS1] = 0x2c, 87 [GPIO_IRQSTATUS1] = 0x2c,
88 [GPIO_IRQENABLE1_SET] = 0x34, 88 [GPIO_IRQENABLE1_SET] = 0x34,
89 [GPIO_IRQENABLE1_CLR] = 0x38, 89 [GPIO_IRQENABLE1_CLR] = 0x38,
90 [GPIO_OE] = 0x134, 90 [GPIO_OE] = 0x134,
91 [GPIO_DATAIN] = 0x138, 91 [GPIO_DATAIN] = 0x138,
92 [GPIO_DATAOUT] = 0x13c, 92 [GPIO_DATAOUT] = 0x13c,
93 [GPIO_LEVELDETECT0] = 0x140, 93 [GPIO_LEVELDETECT0] = 0x140,
94 [GPIO_LEVELDETECT1] = 0x144, 94 [GPIO_LEVELDETECT1] = 0x144,
95 [GPIO_RISINGDETECT] = 0x148, 95 [GPIO_RISINGDETECT] = 0x148,
96 [GPIO_FALLINGDETECT] = 0x14c, 96 [GPIO_FALLINGDETECT] = 0x14c,
97 [GPIO_CLEARDATAOUT] = 0x190, 97 [GPIO_CLEARDATAOUT] = 0x190,
98 [GPIO_SETDATAOUT] = 0x194, 98 [GPIO_SETDATAOUT] = 0x194,
99 }, 99 },
100}; 100};
101 101
102static const struct device_compatible_entry compat_data[] = { 102static const struct device_compatible_entry compat_data[] = {
103 { .compat = "ti,omap3-gpio", .value = TI_GPIO_OMAP3 }, 103 { .compat = "ti,omap3-gpio", .value = TI_GPIO_OMAP3 },
104 { .compat = "ti,omap4-gpio", .value = TI_GPIO_OMAP4 }, 104 { .compat = "ti,omap4-gpio", .value = TI_GPIO_OMAP4 },
105 { } 105 DEVICE_COMPAT_EOL
106}; 106};
107 107
108struct ti_gpio_intr { 108struct ti_gpio_intr {
109 u_int intr_pin; 109 u_int intr_pin;
110 int (*intr_func)(void *); 110 int (*intr_func)(void *);
111 void *intr_arg; 111 void *intr_arg;
112 bool intr_mpsafe; 112 bool intr_mpsafe;
113}; 113};
114 114
115struct ti_gpio_softc { 115struct ti_gpio_softc {
116 device_t sc_dev; 116 device_t sc_dev;
117 bus_space_tag_t sc_bst; 117 bus_space_tag_t sc_bst;
118 bus_space_handle_t sc_bsh; 118 bus_space_handle_t sc_bsh;
119 kmutex_t sc_lock; 119 kmutex_t sc_lock;
120 enum ti_gpio_type sc_type; 120 enum ti_gpio_type sc_type;
121 const char *sc_modname; 121 const char *sc_modname;
122 void *sc_ih; 122 void *sc_ih;
123 123
124 struct gpio_chipset_tag sc_gp; 124 struct gpio_chipset_tag sc_gp;
125 gpio_pin_t sc_pins[TI_GPIO_NPINS]; 125 gpio_pin_t sc_pins[TI_GPIO_NPINS];
126 bool sc_pinout[TI_GPIO_NPINS]; 126 bool sc_pinout[TI_GPIO_NPINS];
127 struct ti_gpio_intr sc_intr[TI_GPIO_NPINS]; 127 struct ti_gpio_intr sc_intr[TI_GPIO_NPINS];
128 device_t sc_gpiodev; 128 device_t sc_gpiodev;
129}; 129};
130 130
131struct ti_gpio_pin { 131struct ti_gpio_pin {
132 struct ti_gpio_softc *pin_sc; 132 struct ti_gpio_softc *pin_sc;
133 u_int pin_nr; 133 u_int pin_nr;
134 int pin_flags; 134 int pin_flags;
135 bool pin_actlo; 135 bool pin_actlo;
136}; 136};
137 137
138#define RD4(sc, reg) \ 138#define RD4(sc, reg) \
139 bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, ti_gpio_regmap[(sc)->sc_type][(reg)]) 139 bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, ti_gpio_regmap[(sc)->sc_type][(reg)])
140#define WR4(sc, reg, val) \ 140#define WR4(sc, reg, val) \
141 bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, ti_gpio_regmap[(sc)->sc_type][(reg)], (val)) 141 bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, ti_gpio_regmap[(sc)->sc_type][(reg)], (val))
142 142
143static int ti_gpio_match(device_t, cfdata_t, void *); 143static int ti_gpio_match(device_t, cfdata_t, void *);
144static void ti_gpio_attach(device_t, device_t, void *); 144static void ti_gpio_attach(device_t, device_t, void *);
145 145
146CFATTACH_DECL_NEW(ti_gpio, sizeof(struct ti_gpio_softc), 146CFATTACH_DECL_NEW(ti_gpio, sizeof(struct ti_gpio_softc),
147 ti_gpio_match, ti_gpio_attach, NULL, NULL); 147 ti_gpio_match, ti_gpio_attach, NULL, NULL);
148 148
149static int 149static int
150ti_gpio_ctl(struct ti_gpio_softc *sc, u_int pin, int flags) 150ti_gpio_ctl(struct ti_gpio_softc *sc, u_int pin, int flags)
151{ 151{
152 uint32_t oe; 152 uint32_t oe;
153 153
154 KASSERT(mutex_owned(&sc->sc_lock)); 154 KASSERT(mutex_owned(&sc->sc_lock));
155 155
156 oe = RD4(sc, GPIO_OE); 156 oe = RD4(sc, GPIO_OE);
157 if (flags & GPIO_PIN_INPUT) 157 if (flags & GPIO_PIN_INPUT)
158 oe |= __BIT(pin); 158 oe |= __BIT(pin);
159 else if (flags & GPIO_PIN_OUTPUT) 159 else if (flags & GPIO_PIN_OUTPUT)
160 oe &= ~__BIT(pin); 160 oe &= ~__BIT(pin);
161 WR4(sc, GPIO_OE, oe); 161 WR4(sc, GPIO_OE, oe);
162 162
163 sc->sc_pinout[pin] = (flags & GPIO_PIN_OUTPUT) != 0; 163 sc->sc_pinout[pin] = (flags & GPIO_PIN_OUTPUT) != 0;
164 164
165 return 0; 165 return 0;
166} 166}
167 167
168static void * 168static void *
169ti_gpio_acquire(device_t dev, const void *data, size_t len, int flags) 169ti_gpio_acquire(device_t dev, const void *data, size_t len, int flags)
170{ 170{
171 struct ti_gpio_softc * const sc = device_private(dev); 171 struct ti_gpio_softc * const sc = device_private(dev);
172 struct ti_gpio_pin *gpin; 172 struct ti_gpio_pin *gpin;
173 const u_int *gpio = data; 173 const u_int *gpio = data;
174 int error; 174 int error;
175 175
176 if (len != 12) 176 if (len != 12)
177 return NULL; 177 return NULL;
178 178
179 const uint8_t pin = be32toh(gpio[1]) & 0xff; 179 const uint8_t pin = be32toh(gpio[1]) & 0xff;
180 const bool actlo = be32toh(gpio[2]) & 1; 180 const bool actlo = be32toh(gpio[2]) & 1;
181 181
182 if (pin >= __arraycount(sc->sc_pins)) 182 if (pin >= __arraycount(sc->sc_pins))
183 return NULL; 183 return NULL;
184 184
185 mutex_enter(&sc->sc_lock); 185 mutex_enter(&sc->sc_lock);
186 error = ti_gpio_ctl(sc, pin, flags); 186 error = ti_gpio_ctl(sc, pin, flags);
187 mutex_exit(&sc->sc_lock); 187 mutex_exit(&sc->sc_lock);
188 188
189 if (error != 0) 189 if (error != 0)
190 return NULL; 190 return NULL;
191 191
192 gpin = kmem_zalloc(sizeof(*gpin), KM_SLEEP); 192 gpin = kmem_zalloc(sizeof(*gpin), KM_SLEEP);
193 gpin->pin_sc = sc; 193 gpin->pin_sc = sc;
194 gpin->pin_nr = pin; 194 gpin->pin_nr = pin;
195 gpin->pin_flags = flags; 195 gpin->pin_flags = flags;
196 gpin->pin_actlo = actlo; 196 gpin->pin_actlo = actlo;
197 197
198 return gpin; 198 return gpin;
199} 199}
200 200
201static void 201static void
202ti_gpio_release(device_t dev, void *priv) 202ti_gpio_release(device_t dev, void *priv)
203{ 203{
204 struct ti_gpio_softc * const sc = device_private(dev); 204 struct ti_gpio_softc * const sc = device_private(dev);
205 struct ti_gpio_pin *pin = priv; 205 struct ti_gpio_pin *pin = priv;
206 206
207 mutex_enter(&sc->sc_lock); 207 mutex_enter(&sc->sc_lock);
208 ti_gpio_ctl(pin->pin_sc, pin->pin_nr, GPIO_PIN_INPUT); 208 ti_gpio_ctl(pin->pin_sc, pin->pin_nr, GPIO_PIN_INPUT);
209 mutex_exit(&sc->sc_lock); 209 mutex_exit(&sc->sc_lock);
210 210
211 kmem_free(pin, sizeof(*pin)); 211 kmem_free(pin, sizeof(*pin));
212} 212}
213 213
214static int 214static int
215ti_gpio_read(device_t dev, void *priv, bool raw) 215ti_gpio_read(device_t dev, void *priv, bool raw)
216{ 216{
217 struct ti_gpio_softc * const sc = device_private(dev); 217 struct ti_gpio_softc * const sc = device_private(dev);
218 struct ti_gpio_pin *pin = priv; 218 struct ti_gpio_pin *pin = priv;
219 uint32_t data; 219 uint32_t data;
220 int val; 220 int val;
221 221
222 KASSERT(sc == pin->pin_sc); 222 KASSERT(sc == pin->pin_sc);
223 223
224 const uint32_t data_mask = __BIT(pin->pin_nr); 224 const uint32_t data_mask = __BIT(pin->pin_nr);
225 225
226 /* No lock required for reads */ 226 /* No lock required for reads */
227 if (sc->sc_pinout[pin->pin_nr]) 227 if (sc->sc_pinout[pin->pin_nr])
228 data = RD4(sc, GPIO_DATAOUT); 228 data = RD4(sc, GPIO_DATAOUT);
229 else 229 else
230 data = RD4(sc, GPIO_DATAIN); 230 data = RD4(sc, GPIO_DATAIN);
231 val = __SHIFTOUT(data, data_mask); 231 val = __SHIFTOUT(data, data_mask);
232 if (!raw && pin->pin_actlo) 232 if (!raw && pin->pin_actlo)
233 val = !val; 233 val = !val;
234 234
235 return val; 235 return val;
236} 236}
237 237
238static void 238static void
239ti_gpio_write(device_t dev, void *priv, int val, bool raw) 239ti_gpio_write(device_t dev, void *priv, int val, bool raw)
240{ 240{
241 struct ti_gpio_softc * const sc = device_private(dev); 241 struct ti_gpio_softc * const sc = device_private(dev);
242 struct ti_gpio_pin *pin = priv; 242 struct ti_gpio_pin *pin = priv;
243 243
244 KASSERT(sc == pin->pin_sc); 244 KASSERT(sc == pin->pin_sc);
245 245
246 const uint32_t data_mask = __BIT(pin->pin_nr); 246 const uint32_t data_mask = __BIT(pin->pin_nr);
247 247
248 if (!raw && pin->pin_actlo) 248 if (!raw && pin->pin_actlo)
249 val = !val; 249 val = !val;
250 250
251 const u_int data_reg = val ? GPIO_SETDATAOUT : GPIO_CLEARDATAOUT; 251 const u_int data_reg = val ? GPIO_SETDATAOUT : GPIO_CLEARDATAOUT;
252 252
253 WR4(sc, data_reg, data_mask); 253 WR4(sc, data_reg, data_mask);
254} 254}
255 255
256static struct fdtbus_gpio_controller_func ti_gpio_funcs = { 256static struct fdtbus_gpio_controller_func ti_gpio_funcs = {
257 .acquire = ti_gpio_acquire, 257 .acquire = ti_gpio_acquire,
258 .release = ti_gpio_release, 258 .release = ti_gpio_release,
259 .read = ti_gpio_read, 259 .read = ti_gpio_read,
260 .write = ti_gpio_write, 260 .write = ti_gpio_write,
261}; 261};
262 262
263static void 263static void
264ti_gpio_intr_disestablish(device_t dev, void *ih) 264ti_gpio_intr_disestablish(device_t dev, void *ih)
265{ 265{
266 struct ti_gpio_softc * const sc = device_private(dev); 266 struct ti_gpio_softc * const sc = device_private(dev);
267 struct ti_gpio_intr *intr = ih; 267 struct ti_gpio_intr *intr = ih;
268 const u_int pin = intr->intr_pin; 268 const u_int pin = intr->intr_pin;
269 const uint32_t pin_mask = __BIT(pin); 269 const uint32_t pin_mask = __BIT(pin);
270 uint32_t val; 270 uint32_t val;
271 271
272 /* Disable interrupts */ 272 /* Disable interrupts */
273 if (sc->sc_type == TI_GPIO_OMAP3) { 273 if (sc->sc_type == TI_GPIO_OMAP3) {
274 val = RD4(sc, GPIO_IRQENABLE1); 274 val = RD4(sc, GPIO_IRQENABLE1);
275 WR4(sc, GPIO_IRQENABLE1, val & ~pin_mask); 275 WR4(sc, GPIO_IRQENABLE1, val & ~pin_mask);
276 } else { 276 } else {
277 WR4(sc, GPIO_IRQENABLE1_CLR, pin_mask); 277 WR4(sc, GPIO_IRQENABLE1_CLR, pin_mask);
278 } 278 }
279 279
280 intr->intr_func = NULL; 280 intr->intr_func = NULL;
281 intr->intr_arg = NULL; 281 intr->intr_arg = NULL;
282} 282}
283 283
284static void * 284static void *
285ti_gpio_intr_establish(device_t dev, u_int *specifier, int ipl, int flags, 285ti_gpio_intr_establish(device_t dev, u_int *specifier, int ipl, int flags,
286 int (*func)(void *), void *arg, const char *xname) 286 int (*func)(void *), void *arg, const char *xname)
287{ 287{
288 struct ti_gpio_softc * const sc = device_private(dev); 288 struct ti_gpio_softc * const sc = device_private(dev);
289 uint32_t val; 289 uint32_t val;
290 290
291 /* 1st cell is the pin */ 291 /* 1st cell is the pin */
292 /* 2nd cell is flags */ 292 /* 2nd cell is flags */
293 const u_int pin = be32toh(specifier[0]); 293 const u_int pin = be32toh(specifier[0]);
294 const u_int type = be32toh(specifier[2]) & 0xf; 294 const u_int type = be32toh(specifier[2]) & 0xf;
295 295
296 if (ipl != IPL_VM || pin >= __arraycount(sc->sc_pins)) 296 if (ipl != IPL_VM || pin >= __arraycount(sc->sc_pins))
297 return NULL; 297 return NULL;
298 298
299 /* 299 /*
300 * Enabling both high and low level triggers will cause the GPIO 300 * Enabling both high and low level triggers will cause the GPIO
301 * controller to always assert the interrupt. 301 * controller to always assert the interrupt.
302 */ 302 */
303 if ((type & (FDT_INTR_TYPE_LOW_LEVEL|FDT_INTR_TYPE_HIGH_LEVEL)) == 303 if ((type & (FDT_INTR_TYPE_LOW_LEVEL|FDT_INTR_TYPE_HIGH_LEVEL)) ==
304 (FDT_INTR_TYPE_LOW_LEVEL|FDT_INTR_TYPE_HIGH_LEVEL)) 304 (FDT_INTR_TYPE_LOW_LEVEL|FDT_INTR_TYPE_HIGH_LEVEL))
305 return NULL; 305 return NULL;
306 306
307 if (sc->sc_intr[pin].intr_func != NULL) 307 if (sc->sc_intr[pin].intr_func != NULL)
308 return NULL; 308 return NULL;
309 309
310 /* Set pin as input */ 310 /* Set pin as input */
311 if (ti_gpio_ctl(sc, pin, GPIO_PIN_INPUT) != 0) 311 if (ti_gpio_ctl(sc, pin, GPIO_PIN_INPUT) != 0)
312 return NULL; 312 return NULL;
313 313
314 sc->sc_intr[pin].intr_pin = pin; 314 sc->sc_intr[pin].intr_pin = pin;
315 sc->sc_intr[pin].intr_func = func; 315 sc->sc_intr[pin].intr_func = func;
316 sc->sc_intr[pin].intr_arg = arg; 316 sc->sc_intr[pin].intr_arg = arg;
317 sc->sc_intr[pin].intr_mpsafe = (flags & FDT_INTR_MPSAFE) != 0; 317 sc->sc_intr[pin].intr_mpsafe = (flags & FDT_INTR_MPSAFE) != 0;
318 318
319 const uint32_t pin_mask = __BIT(pin); 319 const uint32_t pin_mask = __BIT(pin);
320 320
321 /* Configure triggers */ 321 /* Configure triggers */
322 val = RD4(sc, GPIO_LEVELDETECT0); 322 val = RD4(sc, GPIO_LEVELDETECT0);
323 if ((type & FDT_INTR_TYPE_LOW_LEVEL) != 0) 323 if ((type & FDT_INTR_TYPE_LOW_LEVEL) != 0)
324 val |= pin_mask; 324 val |= pin_mask;
325 else 325 else
326 val &= ~pin_mask; 326 val &= ~pin_mask;
327 WR4(sc, GPIO_LEVELDETECT0, val); 327 WR4(sc, GPIO_LEVELDETECT0, val);
328 328
329 val = RD4(sc, GPIO_LEVELDETECT1); 329 val = RD4(sc, GPIO_LEVELDETECT1);
330 if ((type & FDT_INTR_TYPE_HIGH_LEVEL) != 0) 330 if ((type & FDT_INTR_TYPE_HIGH_LEVEL) != 0)
331 val |= pin_mask; 331 val |= pin_mask;
332 else 332 else
333 val &= ~pin_mask; 333 val &= ~pin_mask;
334 WR4(sc, GPIO_LEVELDETECT1, val); 334 WR4(sc, GPIO_LEVELDETECT1, val);
335 335
336 val = RD4(sc, GPIO_RISINGDETECT); 336 val = RD4(sc, GPIO_RISINGDETECT);
337 if ((type & FDT_INTR_TYPE_POS_EDGE) != 0) 337 if ((type & FDT_INTR_TYPE_POS_EDGE) != 0)
338 val |= pin_mask; 338 val |= pin_mask;
339 else 339 else
340 val &= ~pin_mask; 340 val &= ~pin_mask;
341 WR4(sc, GPIO_RISINGDETECT, val); 341 WR4(sc, GPIO_RISINGDETECT, val);
342 342
343 val = RD4(sc, GPIO_FALLINGDETECT); 343 val = RD4(sc, GPIO_FALLINGDETECT);
344 if ((type & FDT_INTR_TYPE_NEG_EDGE) != 0) 344 if ((type & FDT_INTR_TYPE_NEG_EDGE) != 0)
345 val |= pin_mask; 345 val |= pin_mask;
346 else 346 else
347 val &= ~pin_mask; 347 val &= ~pin_mask;
348 WR4(sc, GPIO_FALLINGDETECT, val); 348 WR4(sc, GPIO_FALLINGDETECT, val);
349 349
350 /* Enable interrupts */ 350 /* Enable interrupts */
351 if (sc->sc_type == TI_GPIO_OMAP3) { 351 if (sc->sc_type == TI_GPIO_OMAP3) {
352 val = RD4(sc, GPIO_IRQENABLE1); 352 val = RD4(sc, GPIO_IRQENABLE1);
353 WR4(sc, GPIO_IRQENABLE1, val | pin_mask); 353 WR4(sc, GPIO_IRQENABLE1, val | pin_mask);
354 } else { 354 } else {
355 WR4(sc, GPIO_IRQENABLE1_SET, pin_mask); 355 WR4(sc, GPIO_IRQENABLE1_SET, pin_mask);
356 } 356 }
357 357
358 return &sc->sc_intr[pin]; 358 return &sc->sc_intr[pin];
359} 359}
360 360
361static bool 361static bool
362ti_gpio_intrstr(device_t dev, u_int *specifier, char *buf, size_t buflen) 362ti_gpio_intrstr(device_t dev, u_int *specifier, char *buf, size_t buflen)
363{ 363{
364 struct ti_gpio_softc * const sc = device_private(dev); 364 struct ti_gpio_softc * const sc = device_private(dev);
365 365
366 /* 1st cell is the pin */ 366 /* 1st cell is the pin */
367 /* 2nd cell is flags */ 367 /* 2nd cell is flags */
368 const u_int pin = be32toh(specifier[0]); 368 const u_int pin = be32toh(specifier[0]);
369 369
370 if (pin >= __arraycount(sc->sc_pins)) 370 if (pin >= __arraycount(sc->sc_pins))
371 return false; 371 return false;
372 372
373 snprintf(buf, buflen, "%s pin %d", sc->sc_modname, pin); 373 snprintf(buf, buflen, "%s pin %d", sc->sc_modname, pin);
374 return true; 374 return true;
375} 375}
376 376
377static struct fdtbus_interrupt_controller_func ti_gpio_intrfuncs = { 377static struct fdtbus_interrupt_controller_func ti_gpio_intrfuncs = {
378 .establish = ti_gpio_intr_establish, 378 .establish = ti_gpio_intr_establish,
379 .disestablish = ti_gpio_intr_disestablish, 379 .disestablish = ti_gpio_intr_disestablish,
380 .intrstr = ti_gpio_intrstr, 380 .intrstr = ti_gpio_intrstr,
381}; 381};
382 382
383static int 383static int
384ti_gpio_pin_read(void *priv, int pin) 384ti_gpio_pin_read(void *priv, int pin)
385{ 385{
386 struct ti_gpio_softc * const sc = priv; 386 struct ti_gpio_softc * const sc = priv;
387 uint32_t data; 387 uint32_t data;
388 int val; 388 int val;
389 389
390 KASSERT(pin < __arraycount(sc->sc_pins)); 390 KASSERT(pin < __arraycount(sc->sc_pins));
391 391
392 const uint32_t data_mask = __BIT(pin); 392 const uint32_t data_mask = __BIT(pin);
393 393
394 data = RD4(sc, GPIO_DATAIN); 394 data = RD4(sc, GPIO_DATAIN);
395 val = __SHIFTOUT(data, data_mask); 395 val = __SHIFTOUT(data, data_mask);
396 396
397 return val; 397 return val;
398} 398}
399 399
400static void 400static void
401ti_gpio_pin_write(void *priv, int pin, int val) 401ti_gpio_pin_write(void *priv, int pin, int val)
402{ 402{
403 struct ti_gpio_softc * const sc = priv; 403 struct ti_gpio_softc * const sc = priv;
404 404
405 KASSERT(pin < __arraycount(sc->sc_pins)); 405 KASSERT(pin < __arraycount(sc->sc_pins));
406 406
407 const u_int data_reg = val ? GPIO_SETDATAOUT : GPIO_CLEARDATAOUT; 407 const u_int data_reg = val ? GPIO_SETDATAOUT : GPIO_CLEARDATAOUT;
408 const uint32_t data_mask = __BIT(pin); 408 const uint32_t data_mask = __BIT(pin);
409 409
410 WR4(sc, data_reg, data_mask); 410 WR4(sc, data_reg, data_mask);
411} 411}
412 412
413static void 413static void
414ti_gpio_pin_ctl(void *priv, int pin, int flags) 414ti_gpio_pin_ctl(void *priv, int pin, int flags)
415{ 415{
416 struct ti_gpio_softc * const sc = priv; 416 struct ti_gpio_softc * const sc = priv;
417 417
418 KASSERT(pin < __arraycount(sc->sc_pins)); 418 KASSERT(pin < __arraycount(sc->sc_pins));
419 419
420 mutex_enter(&sc->sc_lock); 420 mutex_enter(&sc->sc_lock);
421 ti_gpio_ctl(sc, pin, flags); 421 ti_gpio_ctl(sc, pin, flags);
422 mutex_exit(&sc->sc_lock); 422 mutex_exit(&sc->sc_lock);
423} 423}
424 424
425static void 425static void
426ti_gpio_attach_ports(struct ti_gpio_softc *sc) 426ti_gpio_attach_ports(struct ti_gpio_softc *sc)
427{ 427{
428 struct gpio_chipset_tag *gp = &sc->sc_gp; 428 struct gpio_chipset_tag *gp = &sc->sc_gp;
429 struct gpiobus_attach_args gba; 429 struct gpiobus_attach_args gba;
430 u_int pin; 430 u_int pin;
431 431
432 gp->gp_cookie = sc; 432 gp->gp_cookie = sc;
433 gp->gp_pin_read = ti_gpio_pin_read; 433 gp->gp_pin_read = ti_gpio_pin_read;
434 gp->gp_pin_write = ti_gpio_pin_write; 434 gp->gp_pin_write = ti_gpio_pin_write;
435 gp->gp_pin_ctl = ti_gpio_pin_ctl; 435 gp->gp_pin_ctl = ti_gpio_pin_ctl;
436 436
437 for (pin = 0; pin < __arraycount(sc->sc_pins); pin++) { 437 for (pin = 0; pin < __arraycount(sc->sc_pins); pin++) {
438 sc->sc_pins[pin].pin_num = pin; 438 sc->sc_pins[pin].pin_num = pin;
439 sc->sc_pins[pin].pin_caps = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT; 439 sc->sc_pins[pin].pin_caps = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT;
440 sc->sc_pins[pin].pin_state = ti_gpio_pin_read(sc, pin); 440 sc->sc_pins[pin].pin_state = ti_gpio_pin_read(sc, pin);
441 } 441 }
442 442
443 memset(&gba, 0, sizeof(gba)); 443 memset(&gba, 0, sizeof(gba));
444 gba.gba_gc = gp; 444 gba.gba_gc = gp;
445 gba.gba_pins = sc->sc_pins; 445 gba.gba_pins = sc->sc_pins;
446 gba.gba_npins = __arraycount(sc->sc_pins); 446 gba.gba_npins = __arraycount(sc->sc_pins);
447 sc->sc_gpiodev = config_found_ia(sc->sc_dev, "gpiobus", &gba, NULL); 447 sc->sc_gpiodev = config_found_ia(sc->sc_dev, "gpiobus", &gba, NULL);
448} 448}
449 449
450static int 450static int
451ti_gpio_intr(void *priv) 451ti_gpio_intr(void *priv)
452{ 452{
453 struct ti_gpio_softc * const sc = priv; 453 struct ti_gpio_softc * const sc = priv;
454 uint32_t status; 454 uint32_t status;
455 u_int bit; 455 u_int bit;
456 int rv = 0; 456 int rv = 0;
457 457
458 status = RD4(sc, GPIO_IRQSTATUS1); 458 status = RD4(sc, GPIO_IRQSTATUS1);
459 WR4(sc, GPIO_IRQSTATUS1, status); 459 WR4(sc, GPIO_IRQSTATUS1, status);
460 460
461 while ((bit = ffs32(status)) != 0) { 461 while ((bit = ffs32(status)) != 0) {
462 const u_int pin = bit - 1; 462 const u_int pin = bit - 1;
463 const uint32_t pin_mask = __BIT(pin); 463 const uint32_t pin_mask = __BIT(pin);
464 struct ti_gpio_intr *intr = &sc->sc_intr[pin]; 464 struct ti_gpio_intr *intr = &sc->sc_intr[pin];
465 status &= ~pin_mask; 465 status &= ~pin_mask;
466 if (intr->intr_func == NULL) 466 if (intr->intr_func == NULL)
467 continue; 467 continue;
468 if (!intr->intr_mpsafe) 468 if (!intr->intr_mpsafe)
469 KERNEL_LOCK(1, curlwp); 469 KERNEL_LOCK(1, curlwp);
470 rv |= intr->intr_func(intr->intr_arg); 470 rv |= intr->intr_func(intr->intr_arg);
471 if (!intr->intr_mpsafe) 471 if (!intr->intr_mpsafe)
472 KERNEL_UNLOCK_ONE(curlwp); 472 KERNEL_UNLOCK_ONE(curlwp);
473 } 473 }
474 474
475 return rv; 475 return rv;
476} 476}
477 477
478static int 478static int
479ti_gpio_match(device_t parent, cfdata_t cf, void *aux) 479ti_gpio_match(device_t parent, cfdata_t cf, void *aux)
480{ 480{
481 struct fdt_attach_args * const faa = aux; 481 struct fdt_attach_args * const faa = aux;
482 482
483 return of_match_compat_data(faa->faa_phandle, compat_data); 483 return of_match_compat_data(faa->faa_phandle, compat_data);
484} 484}
485 485
486static void 486static void
487ti_gpio_attach(device_t parent, device_t self, void *aux) 487ti_gpio_attach(device_t parent, device_t self, void *aux)
488{ 488{
489 struct ti_gpio_softc * const sc = device_private(self); 489 struct ti_gpio_softc * const sc = device_private(self);
490 struct fdt_attach_args * const faa = aux; 490 struct fdt_attach_args * const faa = aux;
491 const int phandle = faa->faa_phandle; 491 const int phandle = faa->faa_phandle;
492 char intrstr[128]; 492 char intrstr[128];
493 bus_addr_t addr; 493 bus_addr_t addr;
494 bus_size_t size; 494 bus_size_t size;
495 495
496 if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { 496 if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
497 aprint_error(": couldn't get registers\n"); 497 aprint_error(": couldn't get registers\n");
498 return; 498 return;
499 } 499 }
500 if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) { 500 if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) {
501 aprint_error(": couldn't decode interrupt\n"); 501 aprint_error(": couldn't decode interrupt\n");
502 return; 502 return;
503 } 503 }
504 if (ti_prcm_enable_hwmod(phandle, 0) != 0) { 504 if (ti_prcm_enable_hwmod(phandle, 0) != 0) {
505 aprint_error(": couldn't enable module\n"); 505 aprint_error(": couldn't enable module\n");
506 return; 506 return;
507 } 507 }
508 508
509 sc->sc_dev = self; 509 sc->sc_dev = self;
510 sc->sc_bst = faa->faa_bst; 510 sc->sc_bst = faa->faa_bst;
511 if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) { 511 if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) {
512 aprint_error(": couldn't map registers\n"); 512 aprint_error(": couldn't map registers\n");
513 return; 513 return;
514 } 514 }
515 sc->sc_type = of_search_compatible(phandle, compat_data)->value; 515 sc->sc_type = of_search_compatible(phandle, compat_data)->value;
516 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM); 516 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM);
517 517
518 sc->sc_modname = fdtbus_get_string(phandle, "ti,hwmods"); 518 sc->sc_modname = fdtbus_get_string(phandle, "ti,hwmods");
519 if (sc->sc_modname == NULL) 519 if (sc->sc_modname == NULL)
520 sc->sc_modname = fdtbus_get_string(OF_parent(phandle), "ti,hwmods"); 520 sc->sc_modname = fdtbus_get_string(OF_parent(phandle), "ti,hwmods");
521 if (sc->sc_modname == NULL) 521 if (sc->sc_modname == NULL)
522 sc->sc_modname = kmem_asprintf("gpio@%" PRIxBUSADDR, addr); 522 sc->sc_modname = kmem_asprintf("gpio@%" PRIxBUSADDR, addr);
523 523
524 aprint_naive("\n"); 524 aprint_naive("\n");
525 aprint_normal(": GPIO (%s)\n", sc->sc_modname); 525 aprint_normal(": GPIO (%s)\n", sc->sc_modname);
526 526
527 fdtbus_register_gpio_controller(self, phandle, &ti_gpio_funcs); 527 fdtbus_register_gpio_controller(self, phandle, &ti_gpio_funcs);
528 528
529 ti_gpio_attach_ports(sc); 529 ti_gpio_attach_ports(sc);
530 530
531 sc->sc_ih = fdtbus_intr_establish_xname(phandle, 0, IPL_VM, 531 sc->sc_ih = fdtbus_intr_establish_xname(phandle, 0, IPL_VM,
532 FDT_INTR_MPSAFE, ti_gpio_intr, sc, device_xname(self)); 532 FDT_INTR_MPSAFE, ti_gpio_intr, sc, device_xname(self));
533 if (sc->sc_ih == NULL) { 533 if (sc->sc_ih == NULL) {
534 aprint_error_dev(self, "failed to establish interrupt on %s\n", 534 aprint_error_dev(self, "failed to establish interrupt on %s\n",
535 intrstr); 535 intrstr);
536 return; 536 return;
537 } 537 }
538 aprint_normal_dev(self, "interrupting on %s\n", intrstr); 538 aprint_normal_dev(self, "interrupting on %s\n", intrstr);
539 fdtbus_register_interrupt_controller(self, phandle, &ti_gpio_intrfuncs); 539 fdtbus_register_interrupt_controller(self, phandle, &ti_gpio_intrfuncs);
540} 540}

cvs diff -r1.8 -r1.9 src/sys/arch/arm/ti/ti_sdhc.c (switch to unified diff)

--- src/sys/arch/arm/ti/ti_sdhc.c 2021/01/25 14:20:39 1.8
+++ src/sys/arch/arm/ti/ti_sdhc.c 2021/01/27 02:12:16 1.9
@@ -1,687 +1,687 @@ @@ -1,687 +1,687 @@
1/* $NetBSD: ti_sdhc.c,v 1.8 2021/01/25 14:20:39 thorpej Exp $ */ 1/* $NetBSD: ti_sdhc.c,v 1.9 2021/01/27 02:12:16 thorpej Exp $ */
2/*- 2/*-
3 * Copyright (c) 2011 The NetBSD Foundation, Inc. 3 * Copyright (c) 2011 The NetBSD Foundation, Inc.
4 * All rights reserved. 4 * All rights reserved.
5 * 5 *
6 * This code is derived from software contributed to The NetBSD Foundation 6 * This code is derived from software contributed to The NetBSD Foundation
7 * by Matt Thomas of 3am Software Foundry. 7 * by Matt Thomas of 3am Software Foundry.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the 15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution. 16 * documentation and/or other materials provided with the distribution.
17 * 17 *
18 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 18 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
19 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 19 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 20 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
22 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE. 28 * POSSIBILITY OF SUCH DAMAGE.
29 */ 29 */
30 30
31#include <sys/cdefs.h> 31#include <sys/cdefs.h>
32__KERNEL_RCSID(0, "$NetBSD: ti_sdhc.c,v 1.8 2021/01/25 14:20:39 thorpej Exp $"); 32__KERNEL_RCSID(0, "$NetBSD: ti_sdhc.c,v 1.9 2021/01/27 02:12:16 thorpej Exp $");
33 33
34#include <sys/param.h> 34#include <sys/param.h>
35#include <sys/systm.h> 35#include <sys/systm.h>
36#include <sys/device.h> 36#include <sys/device.h>
37#include <sys/errno.h> 37#include <sys/errno.h>
38#include <sys/kernel.h> 38#include <sys/kernel.h>
39#include <sys/proc.h> 39#include <sys/proc.h>
40#include <sys/queue.h> 40#include <sys/queue.h>
41#include <sys/mutex.h> 41#include <sys/mutex.h>
42#include <sys/condvar.h> 42#include <sys/condvar.h>
43#include <sys/bus.h> 43#include <sys/bus.h>
44 44
45#include <arm/ti/ti_prcm.h> 45#include <arm/ti/ti_prcm.h>
46#include <arm/ti/ti_edma.h> 46#include <arm/ti/ti_edma.h>
47#include <arm/ti/ti_sdhcreg.h> 47#include <arm/ti/ti_sdhcreg.h>
48 48
49#include <dev/sdmmc/sdhcreg.h> 49#include <dev/sdmmc/sdhcreg.h>
50#include <dev/sdmmc/sdhcvar.h> 50#include <dev/sdmmc/sdhcvar.h>
51#include <dev/sdmmc/sdmmcvar.h> 51#include <dev/sdmmc/sdmmcvar.h>
52 52
53#include <dev/fdt/fdtvar.h> 53#include <dev/fdt/fdtvar.h>
54 54
55#define EDMA_MAX_PARAMS 32 55#define EDMA_MAX_PARAMS 32
56 56
57#ifdef TISDHC_DEBUG 57#ifdef TISDHC_DEBUG
58int tisdhcdebug = 1; 58int tisdhcdebug = 1;
59#define DPRINTF(n,s) do { if ((n) <= tisdhcdebug) device_printf s; } while (0) 59#define DPRINTF(n,s) do { if ((n) <= tisdhcdebug) device_printf s; } while (0)
60#else 60#else
61#define DPRINTF(n,s) do {} while (0) 61#define DPRINTF(n,s) do {} while (0)
62#endif 62#endif
63 63
64 64
65#define CLKD(kz) (sc->sc.sc_clkbase / (kz)) 65#define CLKD(kz) (sc->sc.sc_clkbase / (kz))
66 66
67#define SDHC_READ(sc, reg) \ 67#define SDHC_READ(sc, reg) \
68 bus_space_read_4((sc)->sc_bst, (sc)->sc_sdhc_bsh, (reg)) 68 bus_space_read_4((sc)->sc_bst, (sc)->sc_sdhc_bsh, (reg))
69#define SDHC_WRITE(sc, reg, val) \ 69#define SDHC_WRITE(sc, reg, val) \
70 bus_space_write_4((sc)->sc_bst, (sc)->sc_sdhc_bsh, (reg), (val)) 70 bus_space_write_4((sc)->sc_bst, (sc)->sc_sdhc_bsh, (reg), (val))
71 71
72struct ti_sdhc_config { 72struct ti_sdhc_config {
73 bus_size_t regoff; 73 bus_size_t regoff;
74 uint32_t flags; 74 uint32_t flags;
75}; 75};
76 76
77static const struct ti_sdhc_config omap2_hsmmc_config = { 77static const struct ti_sdhc_config omap2_hsmmc_config = {
78}; 78};
79 79
80static const struct ti_sdhc_config omap3_pre_es3_hsmmc_config = { 80static const struct ti_sdhc_config omap3_pre_es3_hsmmc_config = {
81 .flags = SDHC_FLAG_SINGLE_ONLY 81 .flags = SDHC_FLAG_SINGLE_ONLY
82}; 82};
83 83
84static const struct ti_sdhc_config omap4_hsmmc_config = { 84static const struct ti_sdhc_config omap4_hsmmc_config = {
85 .regoff = 0x100 85 .regoff = 0x100
86}; 86};
87 87
88static const struct device_compatible_entry compat_data[] = { 88static const struct device_compatible_entry compat_data[] = {
89 { .compat = "ti,omap2-hsmmc", 89 { .compat = "ti,omap2-hsmmc",
90 .data = &omap2_hsmmc_config }, 90 .data = &omap2_hsmmc_config },
91 { .compat = "ti,omap3-hsmmc", 91 { .compat = "ti,omap3-hsmmc",
92 .data = &omap2_hsmmc_config }, 92 .data = &omap2_hsmmc_config },
93 { .compat = "ti,omap3-pre-es3-hsmmc", 93 { .compat = "ti,omap3-pre-es3-hsmmc",
94 .data = &omap3_pre_es3_hsmmc_config }, 94 .data = &omap3_pre_es3_hsmmc_config },
95 { .compat = "ti,omap4-hsmmc", 95 { .compat = "ti,omap4-hsmmc",
96 .data = &omap4_hsmmc_config }, 96 .data = &omap4_hsmmc_config },
97 97
98 { } 98 DEVICE_COMPAT_EOL
99}; 99};
100 100
101enum { 101enum {
102 EDMA_CHAN_TX, 102 EDMA_CHAN_TX,
103 EDMA_CHAN_RX, 103 EDMA_CHAN_RX,
104 EDMA_NCHAN 104 EDMA_NCHAN
105}; 105};
106 106
107struct ti_sdhc_softc { 107struct ti_sdhc_softc {
108 struct sdhc_softc sc; 108 struct sdhc_softc sc;
109 int sc_phandle; 109 int sc_phandle;
110 bus_addr_t sc_addr; 110 bus_addr_t sc_addr;
111 bus_space_tag_t sc_bst; 111 bus_space_tag_t sc_bst;
112 bus_space_handle_t sc_bsh; 112 bus_space_handle_t sc_bsh;
113 bus_space_handle_t sc_hl_bsh; 113 bus_space_handle_t sc_hl_bsh;
114 bus_space_handle_t sc_sdhc_bsh; 114 bus_space_handle_t sc_sdhc_bsh;
115 struct sdhc_host *sc_hosts[1]; 115 struct sdhc_host *sc_hosts[1];
116 void *sc_ih; /* interrupt vectoring */ 116 void *sc_ih; /* interrupt vectoring */
117 117
118 int sc_edma_chan[EDMA_NCHAN]; 118 int sc_edma_chan[EDMA_NCHAN];
119 struct edma_channel *sc_edma_tx; 119 struct edma_channel *sc_edma_tx;
120 struct edma_channel *sc_edma_rx; 120 struct edma_channel *sc_edma_rx;
121 uint16_t sc_edma_param_tx[EDMA_MAX_PARAMS]; 121 uint16_t sc_edma_param_tx[EDMA_MAX_PARAMS];
122 uint16_t sc_edma_param_rx[EDMA_MAX_PARAMS]; 122 uint16_t sc_edma_param_rx[EDMA_MAX_PARAMS];
123 kcondvar_t sc_edma_cv; 123 kcondvar_t sc_edma_cv;
124 bus_addr_t sc_edma_fifo; 124 bus_addr_t sc_edma_fifo;
125 bool sc_edma_pending; 125 bool sc_edma_pending;
126 bus_dmamap_t sc_edma_dmamap; 126 bus_dmamap_t sc_edma_dmamap;
127 bus_dma_segment_t sc_edma_segs[1]; 127 bus_dma_segment_t sc_edma_segs[1];
128 void *sc_edma_bbuf; 128 void *sc_edma_bbuf;
129}; 129};
130 130
131static int ti_sdhc_match(device_t, cfdata_t, void *); 131static int ti_sdhc_match(device_t, cfdata_t, void *);
132static void ti_sdhc_attach(device_t, device_t, void *); 132static void ti_sdhc_attach(device_t, device_t, void *);
133 133
134static void ti_sdhc_init(struct ti_sdhc_softc *, const struct ti_sdhc_config *); 134static void ti_sdhc_init(struct ti_sdhc_softc *, const struct ti_sdhc_config *);
135 135
136static int ti_sdhc_bus_width(struct sdhc_softc *, int); 136static int ti_sdhc_bus_width(struct sdhc_softc *, int);
137static int ti_sdhc_rod(struct sdhc_softc *, int); 137static int ti_sdhc_rod(struct sdhc_softc *, int);
138static int ti_sdhc_write_protect(struct sdhc_softc *); 138static int ti_sdhc_write_protect(struct sdhc_softc *);
139static int ti_sdhc_card_detect(struct sdhc_softc *); 139static int ti_sdhc_card_detect(struct sdhc_softc *);
140 140
141static int ti_sdhc_edma_init(struct ti_sdhc_softc *, u_int, u_int); 141static int ti_sdhc_edma_init(struct ti_sdhc_softc *, u_int, u_int);
142static int ti_sdhc_edma_xfer_data(struct sdhc_softc *, struct sdmmc_command *); 142static int ti_sdhc_edma_xfer_data(struct sdhc_softc *, struct sdmmc_command *);
143static void ti_sdhc_edma_done(void *); 143static void ti_sdhc_edma_done(void *);
144static int ti_sdhc_edma_transfer(struct sdhc_softc *, struct sdmmc_command *); 144static int ti_sdhc_edma_transfer(struct sdhc_softc *, struct sdmmc_command *);
145 145
146CFATTACH_DECL_NEW(ti_sdhc, sizeof(struct ti_sdhc_softc), 146CFATTACH_DECL_NEW(ti_sdhc, sizeof(struct ti_sdhc_softc),
147 ti_sdhc_match, ti_sdhc_attach, NULL, NULL); 147 ti_sdhc_match, ti_sdhc_attach, NULL, NULL);
148 148
149static int 149static int
150ti_sdhc_match(device_t parent, cfdata_t cf, void *aux) 150ti_sdhc_match(device_t parent, cfdata_t cf, void *aux)
151{ 151{
152 struct fdt_attach_args * const faa = aux; 152 struct fdt_attach_args * const faa = aux;
153 153
154 return of_match_compat_data(faa->faa_phandle, compat_data); 154 return of_match_compat_data(faa->faa_phandle, compat_data);
155} 155}
156 156
157static void 157static void
158ti_sdhc_attach(device_t parent, device_t self, void *aux) 158ti_sdhc_attach(device_t parent, device_t self, void *aux)
159{ 159{
160 struct ti_sdhc_softc * const sc = device_private(self); 160 struct ti_sdhc_softc * const sc = device_private(self);
161 struct fdt_attach_args * const faa = aux; 161 struct fdt_attach_args * const faa = aux;
162 const int phandle = faa->faa_phandle; 162 const int phandle = faa->faa_phandle;
163 const struct ti_sdhc_config *conf; 163 const struct ti_sdhc_config *conf;
164 bus_addr_t addr; 164 bus_addr_t addr;
165 bus_size_t size; 165 bus_size_t size;
166 u_int bus_width; 166 u_int bus_width;
167 167
168 conf = of_search_compatible(phandle, compat_data)->data; 168 conf = of_search_compatible(phandle, compat_data)->data;
169 169
170 if (ti_prcm_enable_hwmod(phandle, 0) != 0) { 170 if (ti_prcm_enable_hwmod(phandle, 0) != 0) {
171 aprint_error(": couldn't enable module\n"); 171 aprint_error(": couldn't enable module\n");
172 return; 172 return;
173 } 173 }
174 174
175 if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0 || size <= conf->regoff) { 175 if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0 || size <= conf->regoff) {
176 aprint_error(": couldn't get registers\n"); 176 aprint_error(": couldn't get registers\n");
177 return; 177 return;
178 } 178 }
179 addr += conf->regoff; 179 addr += conf->regoff;
180 size -= conf->regoff; 180 size -= conf->regoff;
181 181
182 sc->sc.sc_dmat = faa->faa_dmat; 182 sc->sc.sc_dmat = faa->faa_dmat;
183 sc->sc.sc_dev = self; 183 sc->sc.sc_dev = self;
184 sc->sc_phandle = phandle; 184 sc->sc_phandle = phandle;
185 sc->sc_addr = addr; 185 sc->sc_addr = addr;
186 sc->sc_bst = faa->faa_bst; 186 sc->sc_bst = faa->faa_bst;
187 187
188 /* XXX use fdtbus_dma API */ 188 /* XXX use fdtbus_dma API */
189 int len; 189 int len;
190 const u_int *dmas = fdtbus_get_prop(phandle, "dmas", &len); 190 const u_int *dmas = fdtbus_get_prop(phandle, "dmas", &len);
191 switch (len) { 191 switch (len) {
192 case 24: 192 case 24:
193 sc->sc_edma_chan[EDMA_CHAN_TX] = be32toh(dmas[1]); 193 sc->sc_edma_chan[EDMA_CHAN_TX] = be32toh(dmas[1]);
194 sc->sc_edma_chan[EDMA_CHAN_RX] = be32toh(dmas[4]); 194 sc->sc_edma_chan[EDMA_CHAN_RX] = be32toh(dmas[4]);
195 break; 195 break;
196 case 32: 196 case 32:
197 sc->sc_edma_chan[EDMA_CHAN_TX] = be32toh(dmas[1]); 197 sc->sc_edma_chan[EDMA_CHAN_TX] = be32toh(dmas[1]);
198 sc->sc_edma_chan[EDMA_CHAN_RX] = be32toh(dmas[5]); 198 sc->sc_edma_chan[EDMA_CHAN_RX] = be32toh(dmas[5]);
199 break; 199 break;
200 default: 200 default:
201 sc->sc_edma_chan[EDMA_CHAN_TX] = -1; 201 sc->sc_edma_chan[EDMA_CHAN_TX] = -1;
202 sc->sc_edma_chan[EDMA_CHAN_RX] = -1; 202 sc->sc_edma_chan[EDMA_CHAN_RX] = -1;
203 break; 203 break;
204 } 204 }
205 205
206 if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) { 206 if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) {
207 aprint_error(": couldn't map registers\n"); 207 aprint_error(": couldn't map registers\n");
208 return; 208 return;
209 } 209 }
210 210
211 if (of_getprop_uint32(phandle, "bus-width", &bus_width) != 0) 211 if (of_getprop_uint32(phandle, "bus-width", &bus_width) != 0)
212 bus_width = 4; 212 bus_width = 4;
213 213
214 sc->sc.sc_flags |= conf->flags; 214 sc->sc.sc_flags |= conf->flags;
215 sc->sc.sc_flags |= SDHC_FLAG_32BIT_ACCESS; 215 sc->sc.sc_flags |= SDHC_FLAG_32BIT_ACCESS;
216 sc->sc.sc_flags |= SDHC_FLAG_NO_LED_ON; 216 sc->sc.sc_flags |= SDHC_FLAG_NO_LED_ON;
217 sc->sc.sc_flags |= SDHC_FLAG_RSP136_CRC; 217 sc->sc.sc_flags |= SDHC_FLAG_RSP136_CRC;
218 if (bus_width == 8) 218 if (bus_width == 8)
219 sc->sc.sc_flags |= SDHC_FLAG_8BIT_MODE; 219 sc->sc.sc_flags |= SDHC_FLAG_8BIT_MODE;
220 if (of_hasprop(phandle, "ti,needs-special-reset")) 220 if (of_hasprop(phandle, "ti,needs-special-reset"))
221 sc->sc.sc_flags |= SDHC_FLAG_WAIT_RESET; 221 sc->sc.sc_flags |= SDHC_FLAG_WAIT_RESET;
222 if (!of_hasprop(phandle, "ti,needs-special-hs-handling")) 222 if (!of_hasprop(phandle, "ti,needs-special-hs-handling"))
223 sc->sc.sc_flags |= SDHC_FLAG_NO_HS_BIT; 223 sc->sc.sc_flags |= SDHC_FLAG_NO_HS_BIT;
224 if (of_hasprop(phandle, "ti,dual-volt")) 224 if (of_hasprop(phandle, "ti,dual-volt"))
225 sc->sc.sc_caps = SDHC_VOLTAGE_SUPP_3_0V; 225 sc->sc.sc_caps = SDHC_VOLTAGE_SUPP_3_0V;
226 226
227 sc->sc.sc_host = sc->sc_hosts; 227 sc->sc.sc_host = sc->sc_hosts;
228 sc->sc.sc_clkbase = 96000; /* 96MHZ */ 228 sc->sc.sc_clkbase = 96000; /* 96MHZ */
229 sc->sc.sc_clkmsk = 0x0000ffc0; 229 sc->sc.sc_clkmsk = 0x0000ffc0;
230 sc->sc.sc_vendor_rod = ti_sdhc_rod; 230 sc->sc.sc_vendor_rod = ti_sdhc_rod;
231 sc->sc.sc_vendor_write_protect = ti_sdhc_write_protect; 231 sc->sc.sc_vendor_write_protect = ti_sdhc_write_protect;
232 sc->sc.sc_vendor_card_detect = ti_sdhc_card_detect; 232 sc->sc.sc_vendor_card_detect = ti_sdhc_card_detect;
233 sc->sc.sc_vendor_bus_width = ti_sdhc_bus_width; 233 sc->sc.sc_vendor_bus_width = ti_sdhc_bus_width;
234 234
235 if (bus_space_subregion(sc->sc_bst, sc->sc_bsh, 0x100, 0x100, 235 if (bus_space_subregion(sc->sc_bst, sc->sc_bsh, 0x100, 0x100,
236 &sc->sc_sdhc_bsh) != 0) { 236 &sc->sc_sdhc_bsh) != 0) {
237 aprint_error(": couldn't map subregion\n"); 237 aprint_error(": couldn't map subregion\n");
238 return; 238 return;
239 } 239 }
240 240
241 aprint_naive("\n"); 241 aprint_naive("\n");
242 aprint_normal(": MMCHS\n"); 242 aprint_normal(": MMCHS\n");
243 243
244 ti_sdhc_init(sc, conf); 244 ti_sdhc_init(sc, conf);
245} 245}
246 246
247static void 247static void
248ti_sdhc_init(struct ti_sdhc_softc *sc, const struct ti_sdhc_config *conf) 248ti_sdhc_init(struct ti_sdhc_softc *sc, const struct ti_sdhc_config *conf)
249{ 249{
250 device_t dev = sc->sc.sc_dev; 250 device_t dev = sc->sc.sc_dev;
251 uint32_t clkd, stat; 251 uint32_t clkd, stat;
252 int error, timo, clksft, n; 252 int error, timo, clksft, n;
253 char intrstr[128]; 253 char intrstr[128];
254 254
255 const int tx_chan = sc->sc_edma_chan[EDMA_CHAN_TX]; 255 const int tx_chan = sc->sc_edma_chan[EDMA_CHAN_TX];
256 const int rx_chan = sc->sc_edma_chan[EDMA_CHAN_RX]; 256 const int rx_chan = sc->sc_edma_chan[EDMA_CHAN_RX];
257 257
258 if (tx_chan != -1 && rx_chan != -1) { 258 if (tx_chan != -1 && rx_chan != -1) {
259 aprint_normal_dev(dev, 259 aprint_normal_dev(dev,
260 "EDMA tx channel %d, rx channel %d\n", 260 "EDMA tx channel %d, rx channel %d\n",
261 tx_chan, rx_chan); 261 tx_chan, rx_chan);
262 262
263 if (ti_sdhc_edma_init(sc, tx_chan, rx_chan) != 0) { 263 if (ti_sdhc_edma_init(sc, tx_chan, rx_chan) != 0) {
264 aprint_error_dev(dev, "EDMA disabled\n"); 264 aprint_error_dev(dev, "EDMA disabled\n");
265 goto no_dma; 265 goto no_dma;
266 } 266 }
267 267
268 cv_init(&sc->sc_edma_cv, "sdhcedma"); 268 cv_init(&sc->sc_edma_cv, "sdhcedma");
269 sc->sc_edma_fifo = sc->sc_addr + 0x100 + SDHC_DATA; 269 sc->sc_edma_fifo = sc->sc_addr + 0x100 + SDHC_DATA;
270 sc->sc.sc_flags |= SDHC_FLAG_USE_DMA; 270 sc->sc.sc_flags |= SDHC_FLAG_USE_DMA;
271 sc->sc.sc_flags |= SDHC_FLAG_EXTERNAL_DMA; 271 sc->sc.sc_flags |= SDHC_FLAG_EXTERNAL_DMA;
272 sc->sc.sc_flags |= SDHC_FLAG_EXTDMA_DMAEN; 272 sc->sc.sc_flags |= SDHC_FLAG_EXTDMA_DMAEN;
273 sc->sc.sc_vendor_transfer_data_dma = ti_sdhc_edma_xfer_data; 273 sc->sc.sc_vendor_transfer_data_dma = ti_sdhc_edma_xfer_data;
274 } 274 }
275no_dma: 275no_dma:
276 276
277 /* XXXXXX: Turn-on regulator via I2C. */ 277 /* XXXXXX: Turn-on regulator via I2C. */
278 /* XXXXXX: And enable ICLOCK/FCLOCK. */ 278 /* XXXXXX: And enable ICLOCK/FCLOCK. */
279 279
280 SDHC_WRITE(sc, SDHC_CAPABILITIES, 280 SDHC_WRITE(sc, SDHC_CAPABILITIES,
281 SDHC_READ(sc, SDHC_CAPABILITIES) | SDHC_VOLTAGE_SUPP_1_8V); 281 SDHC_READ(sc, SDHC_CAPABILITIES) | SDHC_VOLTAGE_SUPP_1_8V);
282 if (sc->sc.sc_caps & SDHC_VOLTAGE_SUPP_3_0V) 282 if (sc->sc.sc_caps & SDHC_VOLTAGE_SUPP_3_0V)
283 SDHC_WRITE(sc, SDHC_CAPABILITIES, 283 SDHC_WRITE(sc, SDHC_CAPABILITIES,
284 SDHC_READ(sc, SDHC_CAPABILITIES) | SDHC_VOLTAGE_SUPP_3_0V); 284 SDHC_READ(sc, SDHC_CAPABILITIES) | SDHC_VOLTAGE_SUPP_3_0V);
285 285
286 /* MMCHS Soft reset */ 286 /* MMCHS Soft reset */
287 bus_space_write_4(sc->sc_bst, sc->sc_bsh, MMCHS_SYSCONFIG, 287 bus_space_write_4(sc->sc_bst, sc->sc_bsh, MMCHS_SYSCONFIG,
288 SYSCONFIG_SOFTRESET); 288 SYSCONFIG_SOFTRESET);
289 timo = 3000000; /* XXXX 3 sec. */ 289 timo = 3000000; /* XXXX 3 sec. */
290 while (timo--) { 290 while (timo--) {
291 if (bus_space_read_4(sc->sc_bst, sc->sc_bsh, MMCHS_SYSSTATUS) & 291 if (bus_space_read_4(sc->sc_bst, sc->sc_bsh, MMCHS_SYSSTATUS) &
292 SYSSTATUS_RESETDONE) 292 SYSSTATUS_RESETDONE)
293 break; 293 break;
294 delay(1); 294 delay(1);
295 } 295 }
296 if (timo == 0) 296 if (timo == 0)
297 aprint_error_dev(dev, "Soft reset timeout\n"); 297 aprint_error_dev(dev, "Soft reset timeout\n");
298 bus_space_write_4(sc->sc_bst, sc->sc_bsh, MMCHS_SYSCONFIG, 298 bus_space_write_4(sc->sc_bst, sc->sc_bsh, MMCHS_SYSCONFIG,
299 SYSCONFIG_ENAWAKEUP | 299 SYSCONFIG_ENAWAKEUP |
300#if notyet 300#if notyet
301 SYSCONFIG_AUTOIDLE | 301 SYSCONFIG_AUTOIDLE |
302 SYSCONFIG_SIDLEMODE_AUTO | 302 SYSCONFIG_SIDLEMODE_AUTO |
303#else 303#else
304 SYSCONFIG_SIDLEMODE_IGNORE | 304 SYSCONFIG_SIDLEMODE_IGNORE |
305#endif 305#endif
306 SYSCONFIG_CLOCKACTIVITY_FCLK | 306 SYSCONFIG_CLOCKACTIVITY_FCLK |
307 SYSCONFIG_CLOCKACTIVITY_ICLK); 307 SYSCONFIG_CLOCKACTIVITY_ICLK);
308 308
309 if (!fdtbus_intr_str(sc->sc_phandle, 0, intrstr, sizeof(intrstr))) { 309 if (!fdtbus_intr_str(sc->sc_phandle, 0, intrstr, sizeof(intrstr))) {
310 aprint_error_dev(dev, "couldn't decode interrupt\n"); 310 aprint_error_dev(dev, "couldn't decode interrupt\n");
311 return; 311 return;
312 } 312 }
313 sc->sc_ih = fdtbus_intr_establish_xname(sc->sc_phandle, 0, IPL_VM, 313 sc->sc_ih = fdtbus_intr_establish_xname(sc->sc_phandle, 0, IPL_VM,
314 0, sdhc_intr, &sc->sc, device_xname(dev)); 314 0, sdhc_intr, &sc->sc, device_xname(dev));
315 if (sc->sc_ih == NULL) { 315 if (sc->sc_ih == NULL) {
316 aprint_error_dev(dev, "couldn't establish interrupt\n"); 316 aprint_error_dev(dev, "couldn't establish interrupt\n");
317 return; 317 return;
318 } 318 }
319 aprint_normal_dev(dev, "interrupting on %s\n", intrstr); 319 aprint_normal_dev(dev, "interrupting on %s\n", intrstr);
320 320
321 error = sdhc_host_found(&sc->sc, sc->sc_bst, sc->sc_sdhc_bsh, 0x100); 321 error = sdhc_host_found(&sc->sc, sc->sc_bst, sc->sc_sdhc_bsh, 0x100);
322 if (error != 0) { 322 if (error != 0) {
323 aprint_error_dev(dev, "couldn't initialize host, error=%d\n", 323 aprint_error_dev(dev, "couldn't initialize host, error=%d\n",
324 error); 324 error);
325 fdtbus_intr_disestablish(sc->sc_phandle, sc->sc_ih); 325 fdtbus_intr_disestablish(sc->sc_phandle, sc->sc_ih);
326 return; 326 return;
327 } 327 }
328 328
329 clksft = ffs(sc->sc.sc_clkmsk) - 1; 329 clksft = ffs(sc->sc.sc_clkmsk) - 1;
330 330
331 /* Set SDVS 1.8v and DTW 1bit mode */ 331 /* Set SDVS 1.8v and DTW 1bit mode */
332 SDHC_WRITE(sc, SDHC_HOST_CTL, 332 SDHC_WRITE(sc, SDHC_HOST_CTL,
333 SDHC_VOLTAGE_1_8V << (SDHC_VOLTAGE_SHIFT + 8)); 333 SDHC_VOLTAGE_1_8V << (SDHC_VOLTAGE_SHIFT + 8));
334 SDHC_WRITE(sc, SDHC_CLOCK_CTL, 334 SDHC_WRITE(sc, SDHC_CLOCK_CTL,
335 SDHC_READ(sc, SDHC_CLOCK_CTL) | SDHC_INTCLK_ENABLE | 335 SDHC_READ(sc, SDHC_CLOCK_CTL) | SDHC_INTCLK_ENABLE |
336 SDHC_SDCLK_ENABLE); 336 SDHC_SDCLK_ENABLE);
337 SDHC_WRITE(sc, SDHC_HOST_CTL, 337 SDHC_WRITE(sc, SDHC_HOST_CTL,
338 SDHC_READ(sc, SDHC_HOST_CTL) | SDHC_BUS_POWER << 8); 338 SDHC_READ(sc, SDHC_HOST_CTL) | SDHC_BUS_POWER << 8);
339 SDHC_WRITE(sc, SDHC_CLOCK_CTL, 339 SDHC_WRITE(sc, SDHC_CLOCK_CTL,
340 SDHC_READ(sc, SDHC_CLOCK_CTL) | CLKD(150) << clksft); 340 SDHC_READ(sc, SDHC_CLOCK_CTL) | CLKD(150) << clksft);
341 341
342 /* 342 /*
343 * 22.6.1.3.1.5 MMCHS Controller INIT Procedure Start 343 * 22.6.1.3.1.5 MMCHS Controller INIT Procedure Start
344 * from 'OMAP35x Applications Processor Technical Reference Manual'. 344 * from 'OMAP35x Applications Processor Technical Reference Manual'.
345 * 345 *
346 * During the INIT procedure, the MMCHS controller generates 80 clock 346 * During the INIT procedure, the MMCHS controller generates 80 clock
347 * periods. In order to keep the 1ms gap, the MMCHS controller should 347 * periods. In order to keep the 1ms gap, the MMCHS controller should
348 * be configured to generate a clock whose frequency is smaller or 348 * be configured to generate a clock whose frequency is smaller or
349 * equal to 80 KHz. 349 * equal to 80 KHz.
350 */ 350 */
351 351
352 SDHC_WRITE(sc, SDHC_CLOCK_CTL, 352 SDHC_WRITE(sc, SDHC_CLOCK_CTL,
353 SDHC_READ(sc, SDHC_CLOCK_CTL) & ~SDHC_SDCLK_ENABLE); 353 SDHC_READ(sc, SDHC_CLOCK_CTL) & ~SDHC_SDCLK_ENABLE);
354 SDHC_WRITE(sc, SDHC_CLOCK_CTL, 354 SDHC_WRITE(sc, SDHC_CLOCK_CTL,
355 SDHC_READ(sc, SDHC_CLOCK_CTL) & ~sc->sc.sc_clkmsk); 355 SDHC_READ(sc, SDHC_CLOCK_CTL) & ~sc->sc.sc_clkmsk);
356 clkd = CLKD(80); 356 clkd = CLKD(80);
357 n = 1; 357 n = 1;
358 while (clkd & ~(sc->sc.sc_clkmsk >> clksft)) { 358 while (clkd & ~(sc->sc.sc_clkmsk >> clksft)) {
359 clkd >>= 1; 359 clkd >>= 1;
360 n <<= 1; 360 n <<= 1;
361 } 361 }
362 SDHC_WRITE(sc, SDHC_CLOCK_CTL, 362 SDHC_WRITE(sc, SDHC_CLOCK_CTL,
363 SDHC_READ(sc, SDHC_CLOCK_CTL) | (clkd << clksft)); 363 SDHC_READ(sc, SDHC_CLOCK_CTL) | (clkd << clksft));
364 SDHC_WRITE(sc, SDHC_CLOCK_CTL, 364 SDHC_WRITE(sc, SDHC_CLOCK_CTL,
365 SDHC_READ(sc, SDHC_CLOCK_CTL) | SDHC_SDCLK_ENABLE); 365 SDHC_READ(sc, SDHC_CLOCK_CTL) | SDHC_SDCLK_ENABLE);
366 366
367 bus_space_write_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON, 367 bus_space_write_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON,
368 bus_space_read_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON) | CON_INIT); 368 bus_space_read_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON) | CON_INIT);
369 SDHC_WRITE(sc, SDHC_TRANSFER_MODE, 0x00000000); 369 SDHC_WRITE(sc, SDHC_TRANSFER_MODE, 0x00000000);
370 delay(1000); 370 delay(1000);
371 stat = SDHC_READ(sc, SDHC_NINTR_STATUS); 371 stat = SDHC_READ(sc, SDHC_NINTR_STATUS);
372 SDHC_WRITE(sc, SDHC_NINTR_STATUS, stat | SDHC_COMMAND_COMPLETE); 372 SDHC_WRITE(sc, SDHC_NINTR_STATUS, stat | SDHC_COMMAND_COMPLETE);
373 bus_space_write_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON, 373 bus_space_write_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON,
374 bus_space_read_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON) & ~CON_INIT); 374 bus_space_read_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON) & ~CON_INIT);
375 SDHC_WRITE(sc, SDHC_NINTR_STATUS, 0xffffffff); 375 SDHC_WRITE(sc, SDHC_NINTR_STATUS, 0xffffffff);
376 376
377 SDHC_WRITE(sc, SDHC_CLOCK_CTL, 377 SDHC_WRITE(sc, SDHC_CLOCK_CTL,
378 SDHC_READ(sc, SDHC_CLOCK_CTL) & ~SDHC_SDCLK_ENABLE); 378 SDHC_READ(sc, SDHC_CLOCK_CTL) & ~SDHC_SDCLK_ENABLE);
379 SDHC_WRITE(sc, SDHC_CLOCK_CTL, 379 SDHC_WRITE(sc, SDHC_CLOCK_CTL,
380 SDHC_READ(sc, SDHC_CLOCK_CTL) & ~sc->sc.sc_clkmsk); 380 SDHC_READ(sc, SDHC_CLOCK_CTL) & ~sc->sc.sc_clkmsk);
381 SDHC_WRITE(sc, SDHC_CLOCK_CTL, 381 SDHC_WRITE(sc, SDHC_CLOCK_CTL,
382 SDHC_READ(sc, SDHC_CLOCK_CTL) | CLKD(150) << clksft); 382 SDHC_READ(sc, SDHC_CLOCK_CTL) | CLKD(150) << clksft);
383 timo = 3000000; /* XXXX 3 sec. */ 383 timo = 3000000; /* XXXX 3 sec. */
384 while (--timo) { 384 while (--timo) {
385 if (SDHC_READ(sc, SDHC_CLOCK_CTL) & SDHC_INTCLK_STABLE) 385 if (SDHC_READ(sc, SDHC_CLOCK_CTL) & SDHC_INTCLK_STABLE)
386 break; 386 break;
387 delay(1); 387 delay(1);
388 } 388 }
389 if (timo == 0) 389 if (timo == 0)
390 aprint_error_dev(dev, "ICS timeout\n"); 390 aprint_error_dev(dev, "ICS timeout\n");
391 SDHC_WRITE(sc, SDHC_CLOCK_CTL, 391 SDHC_WRITE(sc, SDHC_CLOCK_CTL,
392 SDHC_READ(sc, SDHC_CLOCK_CTL) | SDHC_SDCLK_ENABLE); 392 SDHC_READ(sc, SDHC_CLOCK_CTL) | SDHC_SDCLK_ENABLE);
393 393
394 if (sc->sc.sc_flags & SDHC_FLAG_USE_ADMA2) 394 if (sc->sc.sc_flags & SDHC_FLAG_USE_ADMA2)
395 bus_space_write_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON, 395 bus_space_write_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON,
396 bus_space_read_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON) | 396 bus_space_read_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON) |
397 CON_MNS); 397 CON_MNS);
398} 398}
399 399
400static int 400static int
401ti_sdhc_rod(struct sdhc_softc *sc, int on) 401ti_sdhc_rod(struct sdhc_softc *sc, int on)
402{ 402{
403 struct ti_sdhc_softc *hmsc = (struct ti_sdhc_softc *)sc; 403 struct ti_sdhc_softc *hmsc = (struct ti_sdhc_softc *)sc;
404 uint32_t con; 404 uint32_t con;
405 405
406 con = bus_space_read_4(hmsc->sc_bst, hmsc->sc_bsh, MMCHS_CON); 406 con = bus_space_read_4(hmsc->sc_bst, hmsc->sc_bsh, MMCHS_CON);
407 if (on) 407 if (on)
408 con |= CON_OD; 408 con |= CON_OD;
409 else 409 else
410 con &= ~CON_OD; 410 con &= ~CON_OD;
411 bus_space_write_4(hmsc->sc_bst, hmsc->sc_bsh, MMCHS_CON, con); 411 bus_space_write_4(hmsc->sc_bst, hmsc->sc_bsh, MMCHS_CON, con);
412 412
413 return 0; 413 return 0;
414} 414}
415 415
416static int 416static int
417ti_sdhc_write_protect(struct sdhc_softc *sc) 417ti_sdhc_write_protect(struct sdhc_softc *sc)
418{ 418{
419 419
420 /* Maybe board dependent, using GPIO. Get GPIO-pin from prop? */ 420 /* Maybe board dependent, using GPIO. Get GPIO-pin from prop? */
421 return 0; /* XXXXXXX */ 421 return 0; /* XXXXXXX */
422} 422}
423 423
424static int 424static int
425ti_sdhc_card_detect(struct sdhc_softc *sc) 425ti_sdhc_card_detect(struct sdhc_softc *sc)
426{ 426{
427 427
428 /* Maybe board dependent, using GPIO. Get GPIO-pin from prop? */ 428 /* Maybe board dependent, using GPIO. Get GPIO-pin from prop? */
429 return 1; /* XXXXXXXX */ 429 return 1; /* XXXXXXXX */
430} 430}
431 431
432static int 432static int
433ti_sdhc_bus_width(struct sdhc_softc *sc, int width) 433ti_sdhc_bus_width(struct sdhc_softc *sc, int width)
434{ 434{
435 struct ti_sdhc_softc *hmsc = (struct ti_sdhc_softc *)sc; 435 struct ti_sdhc_softc *hmsc = (struct ti_sdhc_softc *)sc;
436 uint32_t con, hctl; 436 uint32_t con, hctl;
437 437
438 con = bus_space_read_4(hmsc->sc_bst, hmsc->sc_bsh, MMCHS_CON); 438 con = bus_space_read_4(hmsc->sc_bst, hmsc->sc_bsh, MMCHS_CON);
439 hctl = SDHC_READ(hmsc, SDHC_HOST_CTL); 439 hctl = SDHC_READ(hmsc, SDHC_HOST_CTL);
440 if (width == 8) { 440 if (width == 8) {
441 con |= CON_DW8; 441 con |= CON_DW8;
442 } else if (width == 4) { 442 } else if (width == 4) {
443 con &= ~CON_DW8; 443 con &= ~CON_DW8;
444 hctl |= SDHC_4BIT_MODE; 444 hctl |= SDHC_4BIT_MODE;
445 } else { 445 } else {
446 con &= ~CON_DW8; 446 con &= ~CON_DW8;
447 hctl &= ~SDHC_4BIT_MODE; 447 hctl &= ~SDHC_4BIT_MODE;
448 } 448 }
449 bus_space_write_4(hmsc->sc_bst, hmsc->sc_bsh, MMCHS_CON, con); 449 bus_space_write_4(hmsc->sc_bst, hmsc->sc_bsh, MMCHS_CON, con);
450 SDHC_WRITE(hmsc, SDHC_HOST_CTL, hctl); 450 SDHC_WRITE(hmsc, SDHC_HOST_CTL, hctl);
451 451
452 return 0; 452 return 0;
453} 453}
454 454
455static int 455static int
456ti_sdhc_edma_init(struct ti_sdhc_softc *sc, u_int tx_chan, u_int rx_chan) 456ti_sdhc_edma_init(struct ti_sdhc_softc *sc, u_int tx_chan, u_int rx_chan)
457{ 457{
458 int i, error, rseg; 458 int i, error, rseg;
459 459
460 /* Request tx and rx DMA channels */ 460 /* Request tx and rx DMA channels */
461 sc->sc_edma_tx = edma_channel_alloc(EDMA_TYPE_DMA, tx_chan, 461 sc->sc_edma_tx = edma_channel_alloc(EDMA_TYPE_DMA, tx_chan,
462 ti_sdhc_edma_done, sc); 462 ti_sdhc_edma_done, sc);
463 KASSERT(sc->sc_edma_tx != NULL); 463 KASSERT(sc->sc_edma_tx != NULL);
464 sc->sc_edma_rx = edma_channel_alloc(EDMA_TYPE_DMA, rx_chan, 464 sc->sc_edma_rx = edma_channel_alloc(EDMA_TYPE_DMA, rx_chan,
465 ti_sdhc_edma_done, sc); 465 ti_sdhc_edma_done, sc);
466 KASSERT(sc->sc_edma_rx != NULL); 466 KASSERT(sc->sc_edma_rx != NULL);
467 467
468 /* Allocate some PaRAM pages */ 468 /* Allocate some PaRAM pages */
469 for (i = 0; i < __arraycount(sc->sc_edma_param_tx); i++) { 469 for (i = 0; i < __arraycount(sc->sc_edma_param_tx); i++) {
470 sc->sc_edma_param_tx[i] = edma_param_alloc(sc->sc_edma_tx); 470 sc->sc_edma_param_tx[i] = edma_param_alloc(sc->sc_edma_tx);
471 KASSERT(sc->sc_edma_param_tx[i] != 0xffff); 471 KASSERT(sc->sc_edma_param_tx[i] != 0xffff);
472 } 472 }
473 for (i = 0; i < __arraycount(sc->sc_edma_param_rx); i++) { 473 for (i = 0; i < __arraycount(sc->sc_edma_param_rx); i++) {
474 sc->sc_edma_param_rx[i] = edma_param_alloc(sc->sc_edma_rx); 474 sc->sc_edma_param_rx[i] = edma_param_alloc(sc->sc_edma_rx);
475 KASSERT(sc->sc_edma_param_rx[i] != 0xffff); 475 KASSERT(sc->sc_edma_param_rx[i] != 0xffff);
476 } 476 }
477 477
478 /* Setup bounce buffer */ 478 /* Setup bounce buffer */
479 error = bus_dmamem_alloc(sc->sc.sc_dmat, MAXPHYS, 32, MAXPHYS, 479 error = bus_dmamem_alloc(sc->sc.sc_dmat, MAXPHYS, 32, MAXPHYS,
480 sc->sc_edma_segs, 1, &rseg, BUS_DMA_WAITOK); 480 sc->sc_edma_segs, 1, &rseg, BUS_DMA_WAITOK);
481 if (error) { 481 if (error) {
482 aprint_error_dev(sc->sc.sc_dev, 482 aprint_error_dev(sc->sc.sc_dev,
483 "couldn't allocate dmamem: %d\n", error); 483 "couldn't allocate dmamem: %d\n", error);
484 return error; 484 return error;
485 } 485 }
486 KASSERT(rseg == 1); 486 KASSERT(rseg == 1);
487 error = bus_dmamem_map(sc->sc.sc_dmat, sc->sc_edma_segs, rseg, MAXPHYS, 487 error = bus_dmamem_map(sc->sc.sc_dmat, sc->sc_edma_segs, rseg, MAXPHYS,
488 &sc->sc_edma_bbuf, BUS_DMA_WAITOK); 488 &sc->sc_edma_bbuf, BUS_DMA_WAITOK);
489 if (error) { 489 if (error) {
490 aprint_error_dev(sc->sc.sc_dev, "couldn't map dmamem: %d\n", 490 aprint_error_dev(sc->sc.sc_dev, "couldn't map dmamem: %d\n",
491 error); 491 error);
492 return error; 492 return error;
493 } 493 }
494 error = bus_dmamap_create(sc->sc.sc_dmat, MAXPHYS, 1, MAXPHYS, 0, 494 error = bus_dmamap_create(sc->sc.sc_dmat, MAXPHYS, 1, MAXPHYS, 0,
495 BUS_DMA_WAITOK, &sc->sc_edma_dmamap); 495 BUS_DMA_WAITOK, &sc->sc_edma_dmamap);
496 if (error) { 496 if (error) {
497 aprint_error_dev(sc->sc.sc_dev, "couldn't create dmamap: %d\n", 497 aprint_error_dev(sc->sc.sc_dev, "couldn't create dmamap: %d\n",
498 error); 498 error);
499 return error; 499 return error;
500 } 500 }
501 error = bus_dmamap_load(sc->sc.sc_dmat, sc->sc_edma_dmamap, 501 error = bus_dmamap_load(sc->sc.sc_dmat, sc->sc_edma_dmamap,
502 sc->sc_edma_bbuf, MAXPHYS, NULL, BUS_DMA_WAITOK); 502 sc->sc_edma_bbuf, MAXPHYS, NULL, BUS_DMA_WAITOK);
503 if (error) { 503 if (error) {
504 device_printf(sc->sc.sc_dev, "couldn't load dmamap: %d\n", 504 device_printf(sc->sc.sc_dev, "couldn't load dmamap: %d\n",
505 error); 505 error);
506 return error; 506 return error;
507 } 507 }
508 508
509 return error; 509 return error;
510} 510}
511 511
512static int 512static int
513ti_sdhc_edma_xfer_data(struct sdhc_softc *sdhc_sc, struct sdmmc_command *cmd) 513ti_sdhc_edma_xfer_data(struct sdhc_softc *sdhc_sc, struct sdmmc_command *cmd)
514{ 514{
515 struct ti_sdhc_softc *sc = device_private(sdhc_sc->sc_dev); 515 struct ti_sdhc_softc *sc = device_private(sdhc_sc->sc_dev);
516 const bus_dmamap_t map = cmd->c_dmamap; 516 const bus_dmamap_t map = cmd->c_dmamap;
517 bool bounce; 517 bool bounce;
518 int error; 518 int error;
519 519
520#if notyet 520#if notyet
521 bounce = false; 521 bounce = false;
522 for (int seg = 0; seg < cmd->c_dmamap->dm_nsegs; seg++) { 522 for (int seg = 0; seg < cmd->c_dmamap->dm_nsegs; seg++) {
523 if ((cmd->c_dmamap->dm_segs[seg].ds_addr & 0x1f) != 0 || 523 if ((cmd->c_dmamap->dm_segs[seg].ds_addr & 0x1f) != 0 ||
524 (cmd->c_dmamap->dm_segs[seg].ds_len & 3) != 0) { 524 (cmd->c_dmamap->dm_segs[seg].ds_len & 3) != 0) {
525 bounce = true; 525 bounce = true;
526 break; 526 break;
527 } 527 }
528 } 528 }
529#else 529#else
530 bounce = true; 530 bounce = true;
531#endif 531#endif
532 532
533 if (bounce) { 533 if (bounce) {
534 if (ISSET(cmd->c_flags, SCF_CMD_READ)) { 534 if (ISSET(cmd->c_flags, SCF_CMD_READ)) {
535 bus_dmamap_sync(sc->sc.sc_dmat, sc->sc_edma_dmamap, 0, 535 bus_dmamap_sync(sc->sc.sc_dmat, sc->sc_edma_dmamap, 0,
536 MAXPHYS, BUS_DMASYNC_PREREAD); 536 MAXPHYS, BUS_DMASYNC_PREREAD);
537 } else { 537 } else {
538 memcpy(sc->sc_edma_bbuf, cmd->c_data, cmd->c_datalen); 538 memcpy(sc->sc_edma_bbuf, cmd->c_data, cmd->c_datalen);
539 bus_dmamap_sync(sc->sc.sc_dmat, sc->sc_edma_dmamap, 0, 539 bus_dmamap_sync(sc->sc.sc_dmat, sc->sc_edma_dmamap, 0,
540 MAXPHYS, BUS_DMASYNC_PREWRITE); 540 MAXPHYS, BUS_DMASYNC_PREWRITE);
541 } 541 }
542 542
543 cmd->c_dmamap = sc->sc_edma_dmamap; 543 cmd->c_dmamap = sc->sc_edma_dmamap;
544 } 544 }
545 545
546 error = ti_sdhc_edma_transfer(sdhc_sc, cmd); 546 error = ti_sdhc_edma_transfer(sdhc_sc, cmd);
547 547
548 if (bounce) { 548 if (bounce) {
549 if (ISSET(cmd->c_flags, SCF_CMD_READ)) { 549 if (ISSET(cmd->c_flags, SCF_CMD_READ)) {
550 bus_dmamap_sync(sc->sc.sc_dmat, sc->sc_edma_dmamap, 0, 550 bus_dmamap_sync(sc->sc.sc_dmat, sc->sc_edma_dmamap, 0,
551 MAXPHYS, BUS_DMASYNC_POSTREAD); 551 MAXPHYS, BUS_DMASYNC_POSTREAD);
552 } else { 552 } else {
553 bus_dmamap_sync(sc->sc.sc_dmat, sc->sc_edma_dmamap, 0, 553 bus_dmamap_sync(sc->sc.sc_dmat, sc->sc_edma_dmamap, 0,
554 MAXPHYS, BUS_DMASYNC_POSTWRITE); 554 MAXPHYS, BUS_DMASYNC_POSTWRITE);
555 } 555 }
556 if (ISSET(cmd->c_flags, SCF_CMD_READ) && error == 0) { 556 if (ISSET(cmd->c_flags, SCF_CMD_READ) && error == 0) {
557 memcpy(cmd->c_data, sc->sc_edma_bbuf, cmd->c_datalen); 557 memcpy(cmd->c_data, sc->sc_edma_bbuf, cmd->c_datalen);
558 } 558 }
559 559
560 cmd->c_dmamap = map; 560 cmd->c_dmamap = map;
561 } 561 }
562 562
563 return error; 563 return error;
564} 564}
565 565
566static int 566static int
567ti_sdhc_edma_transfer(struct sdhc_softc *sdhc_sc, struct sdmmc_command *cmd) 567ti_sdhc_edma_transfer(struct sdhc_softc *sdhc_sc, struct sdmmc_command *cmd)
568{ 568{
569 struct ti_sdhc_softc *sc = device_private(sdhc_sc->sc_dev); 569 struct ti_sdhc_softc *sc = device_private(sdhc_sc->sc_dev);
570 kmutex_t *plock = sdhc_host_lock(sc->sc_hosts[0]); 570 kmutex_t *plock = sdhc_host_lock(sc->sc_hosts[0]);
571 struct edma_channel *edma; 571 struct edma_channel *edma;
572 uint16_t *edma_param; 572 uint16_t *edma_param;
573 struct edma_param ep; 573 struct edma_param ep;
574 size_t seg; 574 size_t seg;
575 int error, resid = cmd->c_datalen; 575 int error, resid = cmd->c_datalen;
576 int blksize = MIN(cmd->c_datalen, cmd->c_blklen); 576 int blksize = MIN(cmd->c_datalen, cmd->c_blklen);
577 577
578 KASSERT(mutex_owned(plock)); 578 KASSERT(mutex_owned(plock));
579 579
580 edma = ISSET(cmd->c_flags, SCF_CMD_READ) ? 580 edma = ISSET(cmd->c_flags, SCF_CMD_READ) ?
581 sc->sc_edma_rx : sc->sc_edma_tx; 581 sc->sc_edma_rx : sc->sc_edma_tx;
582 edma_param = ISSET(cmd->c_flags, SCF_CMD_READ) ? 582 edma_param = ISSET(cmd->c_flags, SCF_CMD_READ) ?
583 sc->sc_edma_param_rx : sc->sc_edma_param_tx; 583 sc->sc_edma_param_rx : sc->sc_edma_param_tx;
584 584
585 DPRINTF(1, (sc->sc.sc_dev, "edma xfer: nsegs=%d ch# %d\n", 585 DPRINTF(1, (sc->sc.sc_dev, "edma xfer: nsegs=%d ch# %d\n",
586 cmd->c_dmamap->dm_nsegs, edma_channel_index(edma))); 586 cmd->c_dmamap->dm_nsegs, edma_channel_index(edma)));
587 587
588 if (cmd->c_dmamap->dm_nsegs > EDMA_MAX_PARAMS) { 588 if (cmd->c_dmamap->dm_nsegs > EDMA_MAX_PARAMS) {
589 return ENOMEM; 589 return ENOMEM;
590 } 590 }
591 591
592 for (seg = 0; seg < cmd->c_dmamap->dm_nsegs; seg++) { 592 for (seg = 0; seg < cmd->c_dmamap->dm_nsegs; seg++) {
593 KASSERT(resid > 0); 593 KASSERT(resid > 0);
594 const int xferlen = uimin(resid, 594 const int xferlen = uimin(resid,
595 cmd->c_dmamap->dm_segs[seg].ds_len); 595 cmd->c_dmamap->dm_segs[seg].ds_len);
596 KASSERT(xferlen == cmd->c_dmamap->dm_segs[seg].ds_len || 596 KASSERT(xferlen == cmd->c_dmamap->dm_segs[seg].ds_len ||
597 seg == cmd->c_dmamap->dm_nsegs - 1); 597 seg == cmd->c_dmamap->dm_nsegs - 1);
598 resid -= xferlen; 598 resid -= xferlen;
599 KASSERT((xferlen & 0x3) == 0); 599 KASSERT((xferlen & 0x3) == 0);
600 ep.ep_opt = __SHIFTIN(2, EDMA_PARAM_OPT_FWID) /* 32-bit */; 600 ep.ep_opt = __SHIFTIN(2, EDMA_PARAM_OPT_FWID) /* 32-bit */;
601 ep.ep_opt |= __SHIFTIN(edma_channel_index(edma), 601 ep.ep_opt |= __SHIFTIN(edma_channel_index(edma),
602 EDMA_PARAM_OPT_TCC); 602 EDMA_PARAM_OPT_TCC);
603 if (seg == cmd->c_dmamap->dm_nsegs - 1) { 603 if (seg == cmd->c_dmamap->dm_nsegs - 1) {
604 ep.ep_opt |= EDMA_PARAM_OPT_TCINTEN; 604 ep.ep_opt |= EDMA_PARAM_OPT_TCINTEN;
605 ep.ep_link = 0xffff; 605 ep.ep_link = 0xffff;
606 } else { 606 } else {
607 ep.ep_link = EDMA_PARAM_BASE(edma_param[seg+1]); 607 ep.ep_link = EDMA_PARAM_BASE(edma_param[seg+1]);
608 } 608 }
609 if (ISSET(cmd->c_flags, SCF_CMD_READ)) { 609 if (ISSET(cmd->c_flags, SCF_CMD_READ)) {
610 ep.ep_opt |= EDMA_PARAM_OPT_SAM; 610 ep.ep_opt |= EDMA_PARAM_OPT_SAM;
611 ep.ep_src = sc->sc_edma_fifo; 611 ep.ep_src = sc->sc_edma_fifo;
612 ep.ep_dst = cmd->c_dmamap->dm_segs[seg].ds_addr; 612 ep.ep_dst = cmd->c_dmamap->dm_segs[seg].ds_addr;
613 } else { 613 } else {
614 ep.ep_opt |= EDMA_PARAM_OPT_DAM; 614 ep.ep_opt |= EDMA_PARAM_OPT_DAM;
615 ep.ep_src = cmd->c_dmamap->dm_segs[seg].ds_addr; 615 ep.ep_src = cmd->c_dmamap->dm_segs[seg].ds_addr;
616 ep.ep_dst = sc->sc_edma_fifo; 616 ep.ep_dst = sc->sc_edma_fifo;
617 } 617 }
618 618
619 KASSERT(xferlen <= 65536 * 4); 619 KASSERT(xferlen <= 65536 * 4);
620 620
621 /* 621 /*
622 * In constant addressing mode, the address must be aligned 622 * In constant addressing mode, the address must be aligned
623 * to 256-bits. 623 * to 256-bits.
624 */ 624 */
625 KASSERT((cmd->c_dmamap->dm_segs[seg].ds_addr & 0x1f) == 0); 625 KASSERT((cmd->c_dmamap->dm_segs[seg].ds_addr & 0x1f) == 0);
626 626
627 /* 627 /*
628 * For unknown reason, the A-DMA transfers never completes for 628 * For unknown reason, the A-DMA transfers never completes for
629 * transfers larger than 64 butes. So use a AB transfer, 629 * transfers larger than 64 butes. So use a AB transfer,
630 * with a 64 bytes A len 630 * with a 64 bytes A len
631 */ 631 */
632 ep.ep_bcntrld = 0; /* not used for AB-synchronous mode */ 632 ep.ep_bcntrld = 0; /* not used for AB-synchronous mode */
633 ep.ep_opt |= EDMA_PARAM_OPT_SYNCDIM; 633 ep.ep_opt |= EDMA_PARAM_OPT_SYNCDIM;
634 ep.ep_acnt = uimin(xferlen, 64); 634 ep.ep_acnt = uimin(xferlen, 64);
635 ep.ep_bcnt = uimin(xferlen, blksize) / ep.ep_acnt; 635 ep.ep_bcnt = uimin(xferlen, blksize) / ep.ep_acnt;
636 ep.ep_ccnt = xferlen / (ep.ep_acnt * ep.ep_bcnt); 636 ep.ep_ccnt = xferlen / (ep.ep_acnt * ep.ep_bcnt);
637 ep.ep_srcbidx = ep.ep_dstbidx = 0; 637 ep.ep_srcbidx = ep.ep_dstbidx = 0;
638 ep.ep_srccidx = ep.ep_dstcidx = 0; 638 ep.ep_srccidx = ep.ep_dstcidx = 0;
639 if (ISSET(cmd->c_flags, SCF_CMD_READ)) { 639 if (ISSET(cmd->c_flags, SCF_CMD_READ)) {
640 ep.ep_dstbidx = ep.ep_acnt; 640 ep.ep_dstbidx = ep.ep_acnt;
641 ep.ep_dstcidx = ep.ep_acnt * ep.ep_bcnt; 641 ep.ep_dstcidx = ep.ep_acnt * ep.ep_bcnt;
642 } else { 642 } else {
643 ep.ep_srcbidx = ep.ep_acnt; 643 ep.ep_srcbidx = ep.ep_acnt;
644 ep.ep_srccidx = ep.ep_acnt * ep.ep_bcnt; 644 ep.ep_srccidx = ep.ep_acnt * ep.ep_bcnt;
645 } 645 }
646 646
647 edma_set_param(edma, edma_param[seg], &ep); 647 edma_set_param(edma, edma_param[seg], &ep);
648#ifdef TISDHC_DEBUG 648#ifdef TISDHC_DEBUG
649 if (tisdhcdebug >= 1) { 649 if (tisdhcdebug >= 1) {
650 printf("target OPT: %08x\n", ep.ep_opt); 650 printf("target OPT: %08x\n", ep.ep_opt);
651 edma_dump_param(edma, edma_param[seg]); 651 edma_dump_param(edma, edma_param[seg]);
652 } 652 }
653#endif 653#endif
654 } 654 }
655 655
656 error = 0; 656 error = 0;
657 sc->sc_edma_pending = true; 657 sc->sc_edma_pending = true;
658 edma_transfer_enable(edma, edma_param[0]); 658 edma_transfer_enable(edma, edma_param[0]);
659 while (sc->sc_edma_pending) { 659 while (sc->sc_edma_pending) {
660 error = cv_timedwait(&sc->sc_edma_cv, plock, hz*10); 660 error = cv_timedwait(&sc->sc_edma_cv, plock, hz*10);
661 if (error == EWOULDBLOCK) { 661 if (error == EWOULDBLOCK) {
662 device_printf(sc->sc.sc_dev, "transfer timeout!\n"); 662 device_printf(sc->sc.sc_dev, "transfer timeout!\n");
663 edma_dump(edma); 663 edma_dump(edma);
664 edma_dump_param(edma, edma_param[0]); 664 edma_dump_param(edma, edma_param[0]);
665 edma_halt(edma); 665 edma_halt(edma);
666 sc->sc_edma_pending = false; 666 sc->sc_edma_pending = false;
667 error = ETIMEDOUT; 667 error = ETIMEDOUT;
668 break; 668 break;
669 } 669 }
670 } 670 }
671 edma_halt(edma); 671 edma_halt(edma);
672 672
673 return error; 673 return error;
674} 674}
675 675
676static void 676static void
677ti_sdhc_edma_done(void *priv) 677ti_sdhc_edma_done(void *priv)
678{ 678{
679 struct ti_sdhc_softc *sc = priv; 679 struct ti_sdhc_softc *sc = priv;
680 kmutex_t *plock = sdhc_host_lock(sc->sc_hosts[0]); 680 kmutex_t *plock = sdhc_host_lock(sc->sc_hosts[0]);
681 681
682 mutex_enter(plock); 682 mutex_enter(plock);
683 KASSERT(sc->sc_edma_pending == true); 683 KASSERT(sc->sc_edma_pending == true);
684 sc->sc_edma_pending = false; 684 sc->sc_edma_pending = false;
685 cv_broadcast(&sc->sc_edma_cv); 685 cv_broadcast(&sc->sc_edma_cv);
686 mutex_exit(plock); 686 mutex_exit(plock);
687} 687}

cvs diff -r1.11 -r1.12 src/sys/arch/arm/ti/ti_iic.c (switch to unified diff)

--- src/sys/arch/arm/ti/ti_iic.c 2021/01/25 14:20:39 1.11
+++ src/sys/arch/arm/ti/ti_iic.c 2021/01/27 02:12:16 1.12
@@ -1,701 +1,701 @@ @@ -1,701 +1,701 @@
1/* $NetBSD: ti_iic.c,v 1.11 2021/01/25 14:20:39 thorpej Exp $ */ 1/* $NetBSD: ti_iic.c,v 1.12 2021/01/27 02:12:16 thorpej Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2013 Manuel Bouyer. All rights reserved. 4 * Copyright (c) 2013 Manuel Bouyer. All rights reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
14 * 14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */ 25 */
26 26
27/*- 27/*-
28 * Copyright (c) 2012 Jared D. McNeill <jmcneill@invisible.ca> 28 * Copyright (c) 2012 Jared D. McNeill <jmcneill@invisible.ca>
29 * All rights reserved. 29 * All rights reserved.
30 * 30 *
31 * Redistribution and use in source and binary forms, with or without 31 * Redistribution and use in source and binary forms, with or without
32 * modification, are permitted provided that the following conditions 32 * modification, are permitted provided that the following conditions
33 * are met: 33 * are met:
34 * 1. Redistributions of source code must retain the above copyright 34 * 1. Redistributions of source code must retain the above copyright
35 * notice, this list of conditions and the following disclaimer. 35 * notice, this list of conditions and the following disclaimer.
36 * 2. The name of the author may not be used to endorse or promote products 36 * 2. The name of the author may not be used to endorse or promote products
37 * derived from this software without specific prior written permission. 37 * derived from this software without specific prior written permission.
38 * 38 *
39 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 39 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
40 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 40 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
41 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 41 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
42 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 42 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
43 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 43 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
44 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 44 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 45 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
46 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 46 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
47 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 47 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
48 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 48 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
49 * SUCH DAMAGE. 49 * SUCH DAMAGE.
50 */ 50 */
51 51
52#include <sys/cdefs.h> 52#include <sys/cdefs.h>
53__KERNEL_RCSID(0, "$NetBSD: ti_iic.c,v 1.11 2021/01/25 14:20:39 thorpej Exp $"); 53__KERNEL_RCSID(0, "$NetBSD: ti_iic.c,v 1.12 2021/01/27 02:12:16 thorpej Exp $");
54 54
55#include <sys/param.h> 55#include <sys/param.h>
56#include <sys/systm.h> 56#include <sys/systm.h>
57#include <sys/device.h> 57#include <sys/device.h>
58#include <sys/conf.h> 58#include <sys/conf.h>
59#include <sys/bus.h> 59#include <sys/bus.h>
60#include <sys/proc.h> 60#include <sys/proc.h>
61#include <sys/kernel.h> 61#include <sys/kernel.h>
62#include <sys/mutex.h> 62#include <sys/mutex.h>
63#include <sys/condvar.h> 63#include <sys/condvar.h>
64 64
65#include <dev/i2c/i2cvar.h> 65#include <dev/i2c/i2cvar.h>
66 66
67#include <dev/fdt/fdtvar.h> 67#include <dev/fdt/fdtvar.h>
68 68
69#include <arm/ti/ti_prcm.h> 69#include <arm/ti/ti_prcm.h>
70#include <arm/ti/ti_iicreg.h> 70#include <arm/ti/ti_iicreg.h>
71 71
72#ifndef OMAP2_I2C_SLAVE_ADDR 72#ifndef OMAP2_I2C_SLAVE_ADDR
73#define OMAP2_I2C_SLAVE_ADDR 0x01 73#define OMAP2_I2C_SLAVE_ADDR 0x01
74#endif 74#endif
75 75
76#define OMAP2_I2C_FIFOBYTES(fd) (8 << (fd)) 76#define OMAP2_I2C_FIFOBYTES(fd) (8 << (fd))
77 77
78#ifdef I2CDEBUG 78#ifdef I2CDEBUG
79#define DPRINTF(args) printf args 79#define DPRINTF(args) printf args
80#else 80#else
81#define DPRINTF(args) 81#define DPRINTF(args)
82#endif 82#endif
83 83
84enum ti_iic_type { 84enum ti_iic_type {
85 TI_IIC_OMAP3, 85 TI_IIC_OMAP3,
86 TI_IIC_OMAP4, 86 TI_IIC_OMAP4,
87 TI_NTYPES 87 TI_NTYPES
88}; 88};
89 89
90enum { 90enum {
91 I2C_SYSC, 91 I2C_SYSC,
92 I2C_IRQSTATUS_RAW, 92 I2C_IRQSTATUS_RAW,
93 I2C_IRQSTATUS, 93 I2C_IRQSTATUS,
94 I2C_IRQENABLE, /* OMAP3 */ 94 I2C_IRQENABLE, /* OMAP3 */
95 I2C_IRQENABLE_SET, /* OMAP4 */ 95 I2C_IRQENABLE_SET, /* OMAP4 */
96 I2C_IRQENABLE_CLR, /* OMAP4 */ 96 I2C_IRQENABLE_CLR, /* OMAP4 */
97 I2C_SYSS, 97 I2C_SYSS,
98 I2C_BUF, 98 I2C_BUF,
99 I2C_CNT, 99 I2C_CNT,
100 I2C_DATA, 100 I2C_DATA,
101 I2C_CON, 101 I2C_CON,
102 I2C_OA, 102 I2C_OA,
103 I2C_SA, 103 I2C_SA,
104 I2C_PSC, 104 I2C_PSC,
105 I2C_SCLL, 105 I2C_SCLL,
106 I2C_SCLH, 106 I2C_SCLH,
107 I2C_BUFSTAT, 107 I2C_BUFSTAT,
108 TI_NREGS 108 TI_NREGS
109}; 109};
110 110
111static const u_int ti_iic_regmap[TI_NTYPES][TI_NREGS] = { 111static const u_int ti_iic_regmap[TI_NTYPES][TI_NREGS] = {
112 [TI_IIC_OMAP3] = { 112 [TI_IIC_OMAP3] = {
113 [I2C_SYSC] = 0x20, 113 [I2C_SYSC] = 0x20,
114 [I2C_IRQSTATUS_RAW] = 0x08, 114 [I2C_IRQSTATUS_RAW] = 0x08,
115 [I2C_IRQSTATUS] = 0x08, 115 [I2C_IRQSTATUS] = 0x08,
116 [I2C_IRQENABLE] = 0x04, 116 [I2C_IRQENABLE] = 0x04,
117 [I2C_SYSS] = 0x10, 117 [I2C_SYSS] = 0x10,
118 [I2C_BUF] = 0x14, 118 [I2C_BUF] = 0x14,
119 [I2C_CNT] = 0x18, 119 [I2C_CNT] = 0x18,
120 [I2C_DATA] = 0x1c, 120 [I2C_DATA] = 0x1c,
121 [I2C_CON] = 0x24, 121 [I2C_CON] = 0x24,
122 [I2C_OA] = 0x28, 122 [I2C_OA] = 0x28,
123 [I2C_SA] = 0x2c, 123 [I2C_SA] = 0x2c,
124 [I2C_PSC] = 0x30, 124 [I2C_PSC] = 0x30,
125 [I2C_SCLL] = 0x34, 125 [I2C_SCLL] = 0x34,
126 [I2C_SCLH] = 0x38, 126 [I2C_SCLH] = 0x38,
127 [I2C_BUFSTAT] = 0x40, 127 [I2C_BUFSTAT] = 0x40,
128 }, 128 },
129 [TI_IIC_OMAP4] = { 129 [TI_IIC_OMAP4] = {
130 [I2C_SYSC] = 0x10, 130 [I2C_SYSC] = 0x10,
131 [I2C_IRQSTATUS_RAW] = 0x24, 131 [I2C_IRQSTATUS_RAW] = 0x24,
132 [I2C_IRQSTATUS] = 0x28, 132 [I2C_IRQSTATUS] = 0x28,
133 [I2C_IRQENABLE_SET] = 0x2c, 133 [I2C_IRQENABLE_SET] = 0x2c,
134 [I2C_IRQENABLE_CLR] = 0x30, 134 [I2C_IRQENABLE_CLR] = 0x30,
135 [I2C_SYSS] = 0x90, 135 [I2C_SYSS] = 0x90,
136 [I2C_BUF] = 0x94, 136 [I2C_BUF] = 0x94,
137 [I2C_CNT] = 0x98, 137 [I2C_CNT] = 0x98,
138 [I2C_DATA] = 0x9c, 138 [I2C_DATA] = 0x9c,
139 [I2C_CON] = 0xa4, 139 [I2C_CON] = 0xa4,
140 [I2C_OA] = 0xa8, 140 [I2C_OA] = 0xa8,
141 [I2C_SA] = 0xac, 141 [I2C_SA] = 0xac,
142 [I2C_PSC] = 0xb0, 142 [I2C_PSC] = 0xb0,
143 [I2C_SCLL] = 0xb4, 143 [I2C_SCLL] = 0xb4,
144 [I2C_SCLH] = 0xb8, 144 [I2C_SCLH] = 0xb8,
145 [I2C_BUFSTAT] = 0xc0, 145 [I2C_BUFSTAT] = 0xc0,
146 }, 146 },
147}; 147};
148 148
149static const struct device_compatible_entry compat_data[] = { 149static const struct device_compatible_entry compat_data[] = {
150 /* compatible type */ 150 /* compatible type */
151 { .compat = "ti,omap3-i2c", .value = TI_IIC_OMAP3 }, 151 { .compat = "ti,omap3-i2c", .value = TI_IIC_OMAP3 },
152 { .compat = "ti,omap4-i2c", .value = TI_IIC_OMAP4 }, 152 { .compat = "ti,omap4-i2c", .value = TI_IIC_OMAP4 },
153 { } 153 DEVICE_COMPAT_EOL
154}; 154};
155 155
156/* operation in progress */ 156/* operation in progress */
157typedef enum { 157typedef enum {
158 TI_I2CREAD, 158 TI_I2CREAD,
159 TI_I2CWRITE, 159 TI_I2CWRITE,
160 TI_I2CDONE, 160 TI_I2CDONE,
161 TI_I2CERROR 161 TI_I2CERROR
162} ti_i2cop_t; 162} ti_i2cop_t;
163 163
164struct ti_iic_softc { 164struct ti_iic_softc {
165 device_t sc_dev; 165 device_t sc_dev;
166 struct i2c_controller sc_ic; 166 struct i2c_controller sc_ic;
167 kmutex_t sc_lock; 167 kmutex_t sc_lock;
168 device_t sc_i2cdev; 168 device_t sc_i2cdev;
169 169
170 bus_space_tag_t sc_iot; 170 bus_space_tag_t sc_iot;
171 bus_space_handle_t sc_ioh; 171 bus_space_handle_t sc_ioh;
172 172
173 enum ti_iic_type sc_type; 173 enum ti_iic_type sc_type;
174 174
175 void *sc_ih; 175 void *sc_ih;
176 kmutex_t sc_mtx; 176 kmutex_t sc_mtx;
177 kcondvar_t sc_cv; 177 kcondvar_t sc_cv;
178 ti_i2cop_t sc_op; 178 ti_i2cop_t sc_op;
179 int sc_opflags; 179 int sc_opflags;
180 int sc_buflen; 180 int sc_buflen;
181 int sc_bufidx; 181 int sc_bufidx;
182 char *sc_buf; 182 char *sc_buf;
183 183
184 bool sc_busy; 184 bool sc_busy;
185 185
186 int sc_rxthres; 186 int sc_rxthres;
187 int sc_txthres; 187 int sc_txthres;
188}; 188};
189 189
190#define I2C_READ_REG(sc, reg) \ 190#define I2C_READ_REG(sc, reg) \
191 bus_space_read_2((sc)->sc_iot, (sc)->sc_ioh, ti_iic_regmap[(sc)->sc_type][(reg)]) 191 bus_space_read_2((sc)->sc_iot, (sc)->sc_ioh, ti_iic_regmap[(sc)->sc_type][(reg)])
192#define I2C_READ_DATA(sc) \ 192#define I2C_READ_DATA(sc) \
193 bus_space_read_1((sc)->sc_iot, (sc)->sc_ioh, ti_iic_regmap[(sc)->sc_type][I2C_DATA]) 193 bus_space_read_1((sc)->sc_iot, (sc)->sc_ioh, ti_iic_regmap[(sc)->sc_type][I2C_DATA])
194#define I2C_WRITE_REG(sc, reg, val) \ 194#define I2C_WRITE_REG(sc, reg, val) \
195 bus_space_write_2((sc)->sc_iot, (sc)->sc_ioh, ti_iic_regmap[(sc)->sc_type][(reg)], (val)) 195 bus_space_write_2((sc)->sc_iot, (sc)->sc_ioh, ti_iic_regmap[(sc)->sc_type][(reg)], (val))
196#define I2C_WRITE_DATA(sc, val) \ 196#define I2C_WRITE_DATA(sc, val) \
197 bus_space_write_1((sc)->sc_iot, (sc)->sc_ioh, ti_iic_regmap[(sc)->sc_type][I2C_DATA], (val)) 197 bus_space_write_1((sc)->sc_iot, (sc)->sc_ioh, ti_iic_regmap[(sc)->sc_type][I2C_DATA], (val))
198 198
199static int ti_iic_match(device_t, cfdata_t, void *); 199static int ti_iic_match(device_t, cfdata_t, void *);
200static void ti_iic_attach(device_t, device_t, void *); 200static void ti_iic_attach(device_t, device_t, void *);
201 201
202static int ti_iic_intr(void *); 202static int ti_iic_intr(void *);
203 203
204static int ti_iic_acquire_bus(void *, int); 204static int ti_iic_acquire_bus(void *, int);
205static void ti_iic_release_bus(void *, int); 205static void ti_iic_release_bus(void *, int);
206static int ti_iic_exec(void *, i2c_op_t, i2c_addr_t, const void *, 206static int ti_iic_exec(void *, i2c_op_t, i2c_addr_t, const void *,
207 size_t, void *, size_t, int); 207 size_t, void *, size_t, int);
208 208
209static int ti_iic_reset(struct ti_iic_softc *); 209static int ti_iic_reset(struct ti_iic_softc *);
210static int ti_iic_op(struct ti_iic_softc *, i2c_addr_t, ti_i2cop_t, 210static int ti_iic_op(struct ti_iic_softc *, i2c_addr_t, ti_i2cop_t,
211 uint8_t *, size_t, int); 211 uint8_t *, size_t, int);
212static void ti_iic_handle_intr(struct ti_iic_softc *, uint32_t); 212static void ti_iic_handle_intr(struct ti_iic_softc *, uint32_t);
213static void ti_iic_do_read(struct ti_iic_softc *, uint32_t); 213static void ti_iic_do_read(struct ti_iic_softc *, uint32_t);
214static void ti_iic_do_write(struct ti_iic_softc *, uint32_t); 214static void ti_iic_do_write(struct ti_iic_softc *, uint32_t);
215 215
216static int ti_iic_wait(struct ti_iic_softc *, uint16_t, uint16_t, int); 216static int ti_iic_wait(struct ti_iic_softc *, uint16_t, uint16_t, int);
217static uint32_t ti_iic_stat(struct ti_iic_softc *, uint32_t); 217static uint32_t ti_iic_stat(struct ti_iic_softc *, uint32_t);
218static int ti_iic_flush(struct ti_iic_softc *); 218static int ti_iic_flush(struct ti_iic_softc *);
219 219
220CFATTACH_DECL_NEW(ti_iic, sizeof(struct ti_iic_softc), 220CFATTACH_DECL_NEW(ti_iic, sizeof(struct ti_iic_softc),
221 ti_iic_match, ti_iic_attach, NULL, NULL); 221 ti_iic_match, ti_iic_attach, NULL, NULL);
222 222
223static int 223static int
224ti_iic_match(device_t parent, cfdata_t match, void *opaque) 224ti_iic_match(device_t parent, cfdata_t match, void *opaque)
225{ 225{
226 struct fdt_attach_args * const faa = opaque; 226 struct fdt_attach_args * const faa = opaque;
227 227
228 return of_match_compat_data(faa->faa_phandle, compat_data); 228 return of_match_compat_data(faa->faa_phandle, compat_data);
229} 229}
230 230
231static void 231static void
232ti_iic_attach(device_t parent, device_t self, void *opaque) 232ti_iic_attach(device_t parent, device_t self, void *opaque)
233{ 233{
234 struct ti_iic_softc *sc = device_private(self); 234 struct ti_iic_softc *sc = device_private(self);
235 struct fdt_attach_args * const faa = opaque; 235 struct fdt_attach_args * const faa = opaque;
236 const int phandle = faa->faa_phandle; 236 const int phandle = faa->faa_phandle;
237 int fifodepth, fifo; 237 int fifodepth, fifo;
238 const char *modname; 238 const char *modname;
239 char intrstr[128]; 239 char intrstr[128];
240 bus_addr_t addr; 240 bus_addr_t addr;
241 bus_size_t size; 241 bus_size_t size;
242 242
243 if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { 243 if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
244 aprint_error(": couldn't get registers\n"); 244 aprint_error(": couldn't get registers\n");
245 return; 245 return;
246 } 246 }
247 if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) { 247 if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) {
248 aprint_error(": couldn't decode interrupt\n"); 248 aprint_error(": couldn't decode interrupt\n");
249 return; 249 return;
250 } 250 }
251 251
252 if (ti_prcm_enable_hwmod(phandle, 0) != 0) { 252 if (ti_prcm_enable_hwmod(phandle, 0) != 0) {
253 aprint_error(": couldn't enable module\n"); 253 aprint_error(": couldn't enable module\n");
254 return; 254 return;
255 } 255 }
256 256
257 sc->sc_dev = self; 257 sc->sc_dev = self;
258 sc->sc_iot = faa->faa_bst; 258 sc->sc_iot = faa->faa_bst;
259 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE); 259 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
260 mutex_init(&sc->sc_mtx, MUTEX_DEFAULT, IPL_NET); 260 mutex_init(&sc->sc_mtx, MUTEX_DEFAULT, IPL_NET);
261 cv_init(&sc->sc_cv, "tiiic"); 261 cv_init(&sc->sc_cv, "tiiic");
262 iic_tag_init(&sc->sc_ic); 262 iic_tag_init(&sc->sc_ic);
263 sc->sc_ic.ic_cookie = sc; 263 sc->sc_ic.ic_cookie = sc;
264 sc->sc_ic.ic_acquire_bus = ti_iic_acquire_bus; 264 sc->sc_ic.ic_acquire_bus = ti_iic_acquire_bus;
265 sc->sc_ic.ic_release_bus = ti_iic_release_bus; 265 sc->sc_ic.ic_release_bus = ti_iic_release_bus;
266 sc->sc_ic.ic_exec = ti_iic_exec; 266 sc->sc_ic.ic_exec = ti_iic_exec;
267 267
268 if (bus_space_map(sc->sc_iot, addr, size, 0, &sc->sc_ioh) != 0) { 268 if (bus_space_map(sc->sc_iot, addr, size, 0, &sc->sc_ioh) != 0) {
269 aprint_error(": couldn't map registers\n"); 269 aprint_error(": couldn't map registers\n");
270 return; 270 return;
271 } 271 }
272 sc->sc_type = of_search_compatible(phandle, compat_data)->value; 272 sc->sc_type = of_search_compatible(phandle, compat_data)->value;
273 273
274 sc->sc_ih = fdtbus_intr_establish_xname(phandle, 0, IPL_NET, 0, 274 sc->sc_ih = fdtbus_intr_establish_xname(phandle, 0, IPL_NET, 0,
275 ti_iic_intr, sc, device_xname(self)); 275 ti_iic_intr, sc, device_xname(self));
276 if (sc->sc_ih == NULL) { 276 if (sc->sc_ih == NULL) {
277 aprint_error(": couldn't establish interrupt\n"); 277 aprint_error(": couldn't establish interrupt\n");
278 return; 278 return;
279 } 279 }
280 280
281 modname = fdtbus_get_string(phandle, "ti,hwmods"); 281 modname = fdtbus_get_string(phandle, "ti,hwmods");
282 if (modname == NULL) 282 if (modname == NULL)
283 modname = fdtbus_get_string(OF_parent(phandle), "ti,hwmods"); 283 modname = fdtbus_get_string(OF_parent(phandle), "ti,hwmods");
284 284
285 fifodepth = I2C_BUFSTAT_FIFODEPTH(I2C_READ_REG(sc, I2C_BUFSTAT)); 285 fifodepth = I2C_BUFSTAT_FIFODEPTH(I2C_READ_REG(sc, I2C_BUFSTAT));
286 fifo = OMAP2_I2C_FIFOBYTES(fifodepth); 286 fifo = OMAP2_I2C_FIFOBYTES(fifodepth);
287 sc->sc_rxthres = sc->sc_txthres = fifo >> 1; 287 sc->sc_rxthres = sc->sc_txthres = fifo >> 1;
288 288
289 aprint_naive("\n"); 289 aprint_naive("\n");
290 if (modname != NULL) 290 if (modname != NULL)
291 aprint_normal(": I2C controller (%s), %d-bytes FIFO\n", modname, fifo); 291 aprint_normal(": I2C controller (%s), %d-bytes FIFO\n", modname, fifo);
292 else 292 else
293 aprint_normal(": I2C controller (i2c@%" PRIxBUSADDR "), %d-bytes FIFO\n", 293 aprint_normal(": I2C controller (i2c@%" PRIxBUSADDR "), %d-bytes FIFO\n",
294 addr, fifo); 294 addr, fifo);
295 295
296 ti_iic_reset(sc); 296 ti_iic_reset(sc);
297 ti_iic_flush(sc); 297 ti_iic_flush(sc);
298 298
299 fdtbus_register_i2c_controller(&sc->sc_ic, phandle); 299 fdtbus_register_i2c_controller(&sc->sc_ic, phandle);
300 300
301 fdtbus_attach_i2cbus(self, phandle, &sc->sc_ic, iicbus_print); 301 fdtbus_attach_i2cbus(self, phandle, &sc->sc_ic, iicbus_print);
302} 302}
303 303
304static int 304static int
305ti_iic_intr(void *arg) 305ti_iic_intr(void *arg)
306{ 306{
307 struct ti_iic_softc *sc = arg; 307 struct ti_iic_softc *sc = arg;
308 uint32_t stat; 308 uint32_t stat;
309 309
310 mutex_enter(&sc->sc_mtx); 310 mutex_enter(&sc->sc_mtx);
311 DPRINTF(("ti_iic_intr opflags=%#x\n", sc->sc_opflags)); 311 DPRINTF(("ti_iic_intr opflags=%#x\n", sc->sc_opflags));
312 if ((sc->sc_opflags & I2C_F_POLL) == 0) { 312 if ((sc->sc_opflags & I2C_F_POLL) == 0) {
313 stat = I2C_READ_REG(sc, I2C_IRQSTATUS); 313 stat = I2C_READ_REG(sc, I2C_IRQSTATUS);
314 DPRINTF(("ti_iic_intr pre handle sc->sc_op eq %#x\n", sc->sc_op)); 314 DPRINTF(("ti_iic_intr pre handle sc->sc_op eq %#x\n", sc->sc_op));
315 ti_iic_handle_intr(sc, stat); 315 ti_iic_handle_intr(sc, stat);
316 I2C_WRITE_REG(sc, I2C_IRQSTATUS, stat); 316 I2C_WRITE_REG(sc, I2C_IRQSTATUS, stat);
317 if (sc->sc_op == TI_I2CERROR || sc->sc_op == TI_I2CDONE) { 317 if (sc->sc_op == TI_I2CERROR || sc->sc_op == TI_I2CDONE) {
318 DPRINTF(("ti_iic_intr post handle sc->sc_op %#x\n", sc->sc_op)); 318 DPRINTF(("ti_iic_intr post handle sc->sc_op %#x\n", sc->sc_op));
319 cv_broadcast(&sc->sc_cv); 319 cv_broadcast(&sc->sc_cv);
320 } 320 }
321 } 321 }
322 mutex_exit(&sc->sc_mtx); 322 mutex_exit(&sc->sc_mtx);
323 DPRINTF(("ti_iic_intr status 0x%x\n", stat)); 323 DPRINTF(("ti_iic_intr status 0x%x\n", stat));
324 return 1; 324 return 1;
325} 325}
326 326
327static int 327static int
328ti_iic_acquire_bus(void *opaque, int flags) 328ti_iic_acquire_bus(void *opaque, int flags)
329{ 329{
330 struct ti_iic_softc *sc = opaque; 330 struct ti_iic_softc *sc = opaque;
331 331
332 mutex_enter(&sc->sc_lock); 332 mutex_enter(&sc->sc_lock);
333 while (sc->sc_busy) 333 while (sc->sc_busy)
334 cv_wait(&sc->sc_cv, &sc->sc_lock); 334 cv_wait(&sc->sc_cv, &sc->sc_lock);
335 sc->sc_busy = true; 335 sc->sc_busy = true;
336 mutex_exit(&sc->sc_lock); 336 mutex_exit(&sc->sc_lock);
337 337
338 return 0; 338 return 0;
339} 339}
340 340
341static void 341static void
342ti_iic_release_bus(void *opaque, int flags) 342ti_iic_release_bus(void *opaque, int flags)
343{ 343{
344 struct ti_iic_softc *sc = opaque; 344 struct ti_iic_softc *sc = opaque;
345 345
346 mutex_enter(&sc->sc_lock); 346 mutex_enter(&sc->sc_lock);
347 sc->sc_busy = false; 347 sc->sc_busy = false;
348 cv_broadcast(&sc->sc_cv); 348 cv_broadcast(&sc->sc_cv);
349 mutex_exit(&sc->sc_lock); 349 mutex_exit(&sc->sc_lock);
350} 350}
351 351
352static int 352static int
353ti_iic_exec(void *opaque, i2c_op_t op, i2c_addr_t addr, 353ti_iic_exec(void *opaque, i2c_op_t op, i2c_addr_t addr,
354 const void *cmdbuf, size_t cmdlen, void *buf, size_t len, int flags) 354 const void *cmdbuf, size_t cmdlen, void *buf, size_t len, int flags)
355{ 355{
356 struct ti_iic_softc *sc = opaque; 356 struct ti_iic_softc *sc = opaque;
357 int err; 357 int err;
358 358
359 DPRINTF(("ti_iic_exec: op 0x%x cmdlen %zd len %zd flags 0x%x\n", 359 DPRINTF(("ti_iic_exec: op 0x%x cmdlen %zd len %zd flags 0x%x\n",
360 op, cmdlen, len, flags)); 360 op, cmdlen, len, flags));
361 361
362 if (cmdlen > 0) { 362 if (cmdlen > 0) {
363 err = ti_iic_op(sc, addr, TI_I2CWRITE, 363 err = ti_iic_op(sc, addr, TI_I2CWRITE,
364 __UNCONST(cmdbuf), cmdlen, 364 __UNCONST(cmdbuf), cmdlen,
365 (I2C_OP_READ_P(op) ? 0 : I2C_F_STOP) | flags); 365 (I2C_OP_READ_P(op) ? 0 : I2C_F_STOP) | flags);
366 if (err) 366 if (err)
367 goto done; 367 goto done;
368 } 368 }
369 369
370 if (I2C_OP_STOP_P(op)) 370 if (I2C_OP_STOP_P(op))
371 flags |= I2C_F_STOP; 371 flags |= I2C_F_STOP;
372 372
373 /* 373 /*
374 * I2C controller doesn't allow for zero-byte transfers. 374 * I2C controller doesn't allow for zero-byte transfers.
375 */ 375 */
376 if (len == 0) { 376 if (len == 0) {
377 err = EINVAL; 377 err = EINVAL;
378 goto done; 378 goto done;
379 } 379 }
380 380
381 if (I2C_OP_READ_P(op)) { 381 if (I2C_OP_READ_P(op)) {
382 err = ti_iic_op(sc, addr, TI_I2CREAD, buf, len, flags); 382 err = ti_iic_op(sc, addr, TI_I2CREAD, buf, len, flags);
383 } else { 383 } else {
384 err = ti_iic_op(sc, addr, TI_I2CWRITE, buf, len, flags); 384 err = ti_iic_op(sc, addr, TI_I2CWRITE, buf, len, flags);
385 } 385 }
386 386
387done: 387done:
388 if (err) 388 if (err)
389 ti_iic_reset(sc); 389 ti_iic_reset(sc);
390 390
391 ti_iic_flush(sc); 391 ti_iic_flush(sc);
392 392
393 DPRINTF(("ti_iic_exec: done %d\n", err)); 393 DPRINTF(("ti_iic_exec: done %d\n", err));
394 return err; 394 return err;
395} 395}
396 396
397static int 397static int
398ti_iic_reset(struct ti_iic_softc *sc) 398ti_iic_reset(struct ti_iic_softc *sc)
399{ 399{
400 uint32_t psc, scll, sclh; 400 uint32_t psc, scll, sclh;
401 int i; 401 int i;
402 402
403 DPRINTF(("ti_iic_reset\n")); 403 DPRINTF(("ti_iic_reset\n"));
404 404
405 /* Disable */ 405 /* Disable */
406 I2C_WRITE_REG(sc, I2C_CON, 0); 406 I2C_WRITE_REG(sc, I2C_CON, 0);
407 /* Soft reset */ 407 /* Soft reset */
408 I2C_WRITE_REG(sc, I2C_SYSC, I2C_SYSC_SRST); 408 I2C_WRITE_REG(sc, I2C_SYSC, I2C_SYSC_SRST);
409 delay(1000); 409 delay(1000);
410 /* enable so that we can check for reset complete */ 410 /* enable so that we can check for reset complete */
411 I2C_WRITE_REG(sc, I2C_CON, I2C_CON_EN); 411 I2C_WRITE_REG(sc, I2C_CON, I2C_CON_EN);
412 delay(1000); 412 delay(1000);
413 for (i = 0; i < 1000; i++) { /* 1s delay for reset */ 413 for (i = 0; i < 1000; i++) { /* 1s delay for reset */
414 if (I2C_READ_REG(sc, I2C_SYSS) & I2C_SYSS_RDONE) 414 if (I2C_READ_REG(sc, I2C_SYSS) & I2C_SYSS_RDONE)
415 break; 415 break;
416 } 416 }
417 /* Disable again */ 417 /* Disable again */
418 I2C_WRITE_REG(sc, I2C_CON, 0); 418 I2C_WRITE_REG(sc, I2C_CON, 0);
419 delay(50000); 419 delay(50000);
420 420
421 if (i >= 1000) { 421 if (i >= 1000) {
422 aprint_error_dev(sc->sc_dev, ": couldn't reset module\n"); 422 aprint_error_dev(sc->sc_dev, ": couldn't reset module\n");
423 return 1; 423 return 1;
424 } 424 }
425 425
426 426
427 /* XXX standard speed only */ 427 /* XXX standard speed only */
428 if (sc->sc_type == TI_IIC_OMAP3) { 428 if (sc->sc_type == TI_IIC_OMAP3) {
429 psc = (96000000 / 19200000) - 1; 429 psc = (96000000 / 19200000) - 1;
430 scll = sclh = (19200000 / (2 * 100000)) - 6; 430 scll = sclh = (19200000 / (2 * 100000)) - 6;
431 } else { 431 } else {
432 psc = 3; 432 psc = 3;
433 scll = 53; 433 scll = 53;
434 sclh = 55; 434 sclh = 55;
435 } 435 }
436 436
437 /* Clocks */ 437 /* Clocks */
438 I2C_WRITE_REG(sc, I2C_PSC, psc); 438 I2C_WRITE_REG(sc, I2C_PSC, psc);
439 I2C_WRITE_REG(sc, I2C_SCLL, scll); 439 I2C_WRITE_REG(sc, I2C_SCLL, scll);
440 I2C_WRITE_REG(sc, I2C_SCLH, sclh); 440 I2C_WRITE_REG(sc, I2C_SCLH, sclh);
441 441
442 /* Own I2C address */ 442 /* Own I2C address */
443 I2C_WRITE_REG(sc, I2C_OA, OMAP2_I2C_SLAVE_ADDR); 443 I2C_WRITE_REG(sc, I2C_OA, OMAP2_I2C_SLAVE_ADDR);
444 444
445 /* 5 bytes fifo */ 445 /* 5 bytes fifo */
446 I2C_WRITE_REG(sc, I2C_BUF, 446 I2C_WRITE_REG(sc, I2C_BUF,
447 I2C_BUF_RXTRSH(sc->sc_rxthres) | I2C_BUF_TXTRSH(sc->sc_txthres)); 447 I2C_BUF_RXTRSH(sc->sc_rxthres) | I2C_BUF_TXTRSH(sc->sc_txthres));
448 448
449 /* Enable */ 449 /* Enable */
450 I2C_WRITE_REG(sc, I2C_CON, I2C_CON_EN); 450 I2C_WRITE_REG(sc, I2C_CON, I2C_CON_EN);
451 451
452 return 0; 452 return 0;
453} 453}
454 454
455static int 455static int
456ti_iic_op(struct ti_iic_softc *sc, i2c_addr_t addr, ti_i2cop_t op, 456ti_iic_op(struct ti_iic_softc *sc, i2c_addr_t addr, ti_i2cop_t op,
457 uint8_t *buf, size_t buflen, int flags) 457 uint8_t *buf, size_t buflen, int flags)
458{ 458{
459 uint16_t con, stat, mask; 459 uint16_t con, stat, mask;
460 int err, retry; 460 int err, retry;
461 461
462 KASSERT(op == TI_I2CREAD || op == TI_I2CWRITE); 462 KASSERT(op == TI_I2CREAD || op == TI_I2CWRITE);
463 DPRINTF(("ti_iic_op: addr %#x op %#x buf %p buflen %#x flags %#x\n", 463 DPRINTF(("ti_iic_op: addr %#x op %#x buf %p buflen %#x flags %#x\n",
464 addr, op, buf, (unsigned int) buflen, flags)); 464 addr, op, buf, (unsigned int) buflen, flags));
465 465
466 mask = I2C_IRQSTATUS_ARDY | I2C_IRQSTATUS_NACK | I2C_IRQSTATUS_AL; 466 mask = I2C_IRQSTATUS_ARDY | I2C_IRQSTATUS_NACK | I2C_IRQSTATUS_AL;
467 if (op == TI_I2CREAD) { 467 if (op == TI_I2CREAD) {
468 mask |= I2C_IRQSTATUS_RDR | I2C_IRQSTATUS_RRDY; 468 mask |= I2C_IRQSTATUS_RDR | I2C_IRQSTATUS_RRDY;
469 } else { 469 } else {
470 mask |= I2C_IRQSTATUS_XDR | I2C_IRQSTATUS_XRDY; 470 mask |= I2C_IRQSTATUS_XDR | I2C_IRQSTATUS_XRDY;
471 } 471 }
472 472
473 err = ti_iic_wait(sc, I2C_IRQSTATUS_BB, 0, flags); 473 err = ti_iic_wait(sc, I2C_IRQSTATUS_BB, 0, flags);
474 if (err) { 474 if (err) {
475 DPRINTF(("ti_iic_op: wait error %d\n", err)); 475 DPRINTF(("ti_iic_op: wait error %d\n", err));
476 return err; 476 return err;
477 } 477 }
478 478
479 con = I2C_CON_EN; 479 con = I2C_CON_EN;
480 con |= I2C_CON_MST; 480 con |= I2C_CON_MST;
481 con |= I2C_CON_STT; 481 con |= I2C_CON_STT;
482 if (flags & I2C_F_STOP) 482 if (flags & I2C_F_STOP)
483 con |= I2C_CON_STP; 483 con |= I2C_CON_STP;
484 if (addr & ~0x7f) 484 if (addr & ~0x7f)
485 con |= I2C_CON_XSA; 485 con |= I2C_CON_XSA;
486 if (op == TI_I2CWRITE) 486 if (op == TI_I2CWRITE)
487 con |= I2C_CON_TRX; 487 con |= I2C_CON_TRX;
488 488
489 mutex_enter(&sc->sc_mtx); 489 mutex_enter(&sc->sc_mtx);
490 sc->sc_op = op; 490 sc->sc_op = op;
491 sc->sc_opflags = flags; 491 sc->sc_opflags = flags;
492 sc->sc_buf = buf; 492 sc->sc_buf = buf;
493 sc->sc_buflen = buflen; 493 sc->sc_buflen = buflen;
494 sc->sc_bufidx = 0; 494 sc->sc_bufidx = 0;
495 495
496 I2C_WRITE_REG(sc, I2C_CON, I2C_CON_EN | I2C_CON_MST | I2C_CON_STP); 496 I2C_WRITE_REG(sc, I2C_CON, I2C_CON_EN | I2C_CON_MST | I2C_CON_STP);
497 DPRINTF(("ti_iic_op: op %d con 0x%x ", op, con)); 497 DPRINTF(("ti_iic_op: op %d con 0x%x ", op, con));
498 I2C_WRITE_REG(sc, I2C_CNT, buflen); 498 I2C_WRITE_REG(sc, I2C_CNT, buflen);
499 I2C_WRITE_REG(sc, I2C_SA, (addr & I2C_SA_MASK)); 499 I2C_WRITE_REG(sc, I2C_SA, (addr & I2C_SA_MASK));
500 DPRINTF(("SA 0x%x len %d\n", I2C_READ_REG(sc, I2C_SA), I2C_READ_REG(sc, I2C_CNT))); 500 DPRINTF(("SA 0x%x len %d\n", I2C_READ_REG(sc, I2C_SA), I2C_READ_REG(sc, I2C_CNT)));
501 501
502 if ((flags & I2C_F_POLL) == 0 || sc->sc_type == TI_IIC_OMAP3) { 502 if ((flags & I2C_F_POLL) == 0 || sc->sc_type == TI_IIC_OMAP3) {
503 /* clear any pending interrupt */ 503 /* clear any pending interrupt */
504 I2C_WRITE_REG(sc, I2C_IRQSTATUS, 504 I2C_WRITE_REG(sc, I2C_IRQSTATUS,
505 I2C_READ_REG(sc, I2C_IRQSTATUS)); 505 I2C_READ_REG(sc, I2C_IRQSTATUS));
506 /* and enable */ 506 /* and enable */
507 if (sc->sc_type == TI_IIC_OMAP4) { 507 if (sc->sc_type == TI_IIC_OMAP4) {
508 I2C_WRITE_REG(sc, I2C_IRQENABLE_SET, mask); 508 I2C_WRITE_REG(sc, I2C_IRQENABLE_SET, mask);
509 } else { 509 } else {
510 I2C_WRITE_REG(sc, I2C_IRQENABLE, mask); 510 I2C_WRITE_REG(sc, I2C_IRQENABLE, mask);
511 } 511 }
512 } 512 }
513 /* start transfer */ 513 /* start transfer */
514 I2C_WRITE_REG(sc, I2C_CON, con); 514 I2C_WRITE_REG(sc, I2C_CON, con);
515 515
516 if ((flags & I2C_F_POLL) == 0) { 516 if ((flags & I2C_F_POLL) == 0) {
517 /* and wait for completion */ 517 /* and wait for completion */
518 DPRINTF(("ti_iic_op waiting, op %#x\n", sc->sc_op)); 518 DPRINTF(("ti_iic_op waiting, op %#x\n", sc->sc_op));
519 while (sc->sc_op == op) { 519 while (sc->sc_op == op) {
520 if (cv_timedwait(&sc->sc_cv, &sc->sc_mtx, 520 if (cv_timedwait(&sc->sc_cv, &sc->sc_mtx,
521 mstohz(5000)) == EWOULDBLOCK) { 521 mstohz(5000)) == EWOULDBLOCK) {
522 /* timeout */ 522 /* timeout */
523 op = TI_I2CERROR; 523 op = TI_I2CERROR;
524 } 524 }
525 } 525 }
526 DPRINTF(("ti_iic_op waiting done, op %#x\n", sc->sc_op)); 526 DPRINTF(("ti_iic_op waiting done, op %#x\n", sc->sc_op));
527 527
528 /* disable interrupts */ 528 /* disable interrupts */
529 if (sc->sc_type == TI_IIC_OMAP4) { 529 if (sc->sc_type == TI_IIC_OMAP4) {
530 I2C_WRITE_REG(sc, I2C_IRQENABLE_CLR, 0xffff); 530 I2C_WRITE_REG(sc, I2C_IRQENABLE_CLR, 0xffff);
531 } else { 531 } else {
532 I2C_WRITE_REG(sc, I2C_IRQENABLE, 0); 532 I2C_WRITE_REG(sc, I2C_IRQENABLE, 0);
533 } 533 }
534 } else { 534 } else {
535 /* poll for completion */ 535 /* poll for completion */
536 DPRINTF(("ti_iic_op polling, op %x\n", sc->sc_op)); 536 DPRINTF(("ti_iic_op polling, op %x\n", sc->sc_op));
537 while (sc->sc_op == op) { 537 while (sc->sc_op == op) {
538 stat = ti_iic_stat(sc, mask); 538 stat = ti_iic_stat(sc, mask);
539 DPRINTF(("ti_iic_op stat 0x%x\n", stat)); 539 DPRINTF(("ti_iic_op stat 0x%x\n", stat));
540 if (stat == 0) { 540 if (stat == 0) {
541 /* timeout */ 541 /* timeout */
542 sc->sc_op = TI_I2CERROR; 542 sc->sc_op = TI_I2CERROR;
543 } else { 543 } else {
544 ti_iic_handle_intr(sc, stat); 544 ti_iic_handle_intr(sc, stat);
545 } 545 }
546 I2C_WRITE_REG(sc, I2C_IRQSTATUS, stat); 546 I2C_WRITE_REG(sc, I2C_IRQSTATUS, stat);
547 } 547 }
548 DPRINTF(("ti_iic_op polling done, op now %x\n", sc->sc_op)); 548 DPRINTF(("ti_iic_op polling done, op now %x\n", sc->sc_op));
549 } 549 }
550 mutex_exit(&sc->sc_mtx); 550 mutex_exit(&sc->sc_mtx);
551 retry = 10000; 551 retry = 10000;
552 I2C_WRITE_REG(sc, I2C_CON, 0); 552 I2C_WRITE_REG(sc, I2C_CON, 0);
553 while (I2C_READ_REG(sc, I2C_CON) & I2C_CON_MST) { 553 while (I2C_READ_REG(sc, I2C_CON) & I2C_CON_MST) {
554 delay(100); 554 delay(100);
555 if (--retry == 0) 555 if (--retry == 0)
556 break; 556 break;
557 } 557 }
558 return (sc->sc_op == TI_I2CDONE) ? 0 : EIO; 558 return (sc->sc_op == TI_I2CDONE) ? 0 : EIO;
559} 559}
560 560
561static void 561static void
562ti_iic_handle_intr(struct ti_iic_softc *sc, uint32_t stat) 562ti_iic_handle_intr(struct ti_iic_softc *sc, uint32_t stat)
563{ 563{
564 KASSERT(mutex_owned(&sc->sc_mtx)); 564 KASSERT(mutex_owned(&sc->sc_mtx));
565 KASSERT(stat != 0); 565 KASSERT(stat != 0);
566 DPRINTF(("ti_iic_handle_intr stat %#x\n", stat)); 566 DPRINTF(("ti_iic_handle_intr stat %#x\n", stat));
567 567
568 if (stat & 568 if (stat &
569 (I2C_IRQSTATUS_NACK|I2C_IRQSTATUS_AL)) { 569 (I2C_IRQSTATUS_NACK|I2C_IRQSTATUS_AL)) {
570 sc->sc_op = TI_I2CERROR; 570 sc->sc_op = TI_I2CERROR;
571 return; 571 return;
572 } 572 }
573 if (stat & I2C_IRQSTATUS_ARDY) { 573 if (stat & I2C_IRQSTATUS_ARDY) {
574 sc->sc_op = TI_I2CDONE; 574 sc->sc_op = TI_I2CDONE;
575 return; 575 return;
576 } 576 }
577 if (sc->sc_op == TI_I2CREAD) 577 if (sc->sc_op == TI_I2CREAD)
578 ti_iic_do_read(sc, stat); 578 ti_iic_do_read(sc, stat);
579 else if (sc->sc_op == TI_I2CWRITE) 579 else if (sc->sc_op == TI_I2CWRITE)
580 ti_iic_do_write(sc, stat); 580 ti_iic_do_write(sc, stat);
581 else 581 else
582 return; 582 return;
583} 583}
584void 584void
585ti_iic_do_read(struct ti_iic_softc *sc, uint32_t stat) 585ti_iic_do_read(struct ti_iic_softc *sc, uint32_t stat)
586{ 586{
587 int len = 0; 587 int len = 0;
588 588
589 KASSERT(mutex_owned(&sc->sc_mtx)); 589 KASSERT(mutex_owned(&sc->sc_mtx));
590 DPRINTF(("ti_iic_do_read stat %#x\n", stat)); 590 DPRINTF(("ti_iic_do_read stat %#x\n", stat));
591 if (stat & I2C_IRQSTATUS_RDR) { 591 if (stat & I2C_IRQSTATUS_RDR) {
592 len = I2C_READ_REG(sc, I2C_BUFSTAT); 592 len = I2C_READ_REG(sc, I2C_BUFSTAT);
593 len = I2C_BUFSTAT_RXSTAT(len); 593 len = I2C_BUFSTAT_RXSTAT(len);
594 DPRINTF(("ti_iic_do_read receive drain len %d left %d\n", 594 DPRINTF(("ti_iic_do_read receive drain len %d left %d\n",
595 len, I2C_READ_REG(sc, I2C_CNT))); 595 len, I2C_READ_REG(sc, I2C_CNT)));
596 } else if (stat & I2C_IRQSTATUS_RRDY) { 596 } else if (stat & I2C_IRQSTATUS_RRDY) {
597 len = sc->sc_rxthres + 1; 597 len = sc->sc_rxthres + 1;
598 DPRINTF(("ti_iic_do_read receive len %d left %d\n", 598 DPRINTF(("ti_iic_do_read receive len %d left %d\n",
599 len, I2C_READ_REG(sc, I2C_CNT))); 599 len, I2C_READ_REG(sc, I2C_CNT)));
600 } 600 }
601 for (; 601 for (;
602 sc->sc_bufidx < sc->sc_buflen && len > 0; 602 sc->sc_bufidx < sc->sc_buflen && len > 0;
603 sc->sc_bufidx++, len--) { 603 sc->sc_bufidx++, len--) {
604 sc->sc_buf[sc->sc_bufidx] = I2C_READ_DATA(sc); 604 sc->sc_buf[sc->sc_bufidx] = I2C_READ_DATA(sc);
605 DPRINTF(("ti_iic_do_read got b[%d]=0x%x\n", sc->sc_bufidx, 605 DPRINTF(("ti_iic_do_read got b[%d]=0x%x\n", sc->sc_bufidx,
606 sc->sc_buf[sc->sc_bufidx])); 606 sc->sc_buf[sc->sc_bufidx]));
607 } 607 }
608 DPRINTF(("ti_iic_do_read done\n")); 608 DPRINTF(("ti_iic_do_read done\n"));
609} 609}
610 610
611void 611void
612ti_iic_do_write(struct ti_iic_softc *sc, uint32_t stat) 612ti_iic_do_write(struct ti_iic_softc *sc, uint32_t stat)
613{ 613{
614 int len = 0; 614 int len = 0;
615 615
616 DPRINTF(("ti_iic_do_write stat %#x\n", stat)); 616 DPRINTF(("ti_iic_do_write stat %#x\n", stat));
617 KASSERT(mutex_owned(&sc->sc_mtx)); 617 KASSERT(mutex_owned(&sc->sc_mtx));
618 if (stat & I2C_IRQSTATUS_XDR) { 618 if (stat & I2C_IRQSTATUS_XDR) {
619 len = I2C_READ_REG(sc, I2C_BUFSTAT); 619 len = I2C_READ_REG(sc, I2C_BUFSTAT);
620 len = I2C_BUFSTAT_TXSTAT(len); 620 len = I2C_BUFSTAT_TXSTAT(len);
621 DPRINTF(("ti_iic_do_write xmit drain len %d left %d\n", 621 DPRINTF(("ti_iic_do_write xmit drain len %d left %d\n",
622 len, I2C_READ_REG(sc, I2C_CNT))); 622 len, I2C_READ_REG(sc, I2C_CNT)));
623 } else if (stat & I2C_IRQSTATUS_XRDY) { 623 } else if (stat & I2C_IRQSTATUS_XRDY) {
624 len = sc->sc_txthres + 1; 624 len = sc->sc_txthres + 1;
625 DPRINTF(("ti_iic_do_write xmit len %d left %d\n", 625 DPRINTF(("ti_iic_do_write xmit len %d left %d\n",
626 len, I2C_READ_REG(sc, I2C_CNT))); 626 len, I2C_READ_REG(sc, I2C_CNT)));
627 } 627 }
628 for (; 628 for (;
629 sc->sc_bufidx < sc->sc_buflen && len > 0; 629 sc->sc_bufidx < sc->sc_buflen && len > 0;
630 sc->sc_bufidx++, len--) { 630 sc->sc_bufidx++, len--) {
631 DPRINTF(("ti_iic_do_write send b[%d]=0x%x\n", 631 DPRINTF(("ti_iic_do_write send b[%d]=0x%x\n",
632 sc->sc_bufidx, sc->sc_buf[sc->sc_bufidx])); 632 sc->sc_bufidx, sc->sc_buf[sc->sc_bufidx]));
633 I2C_WRITE_DATA(sc, sc->sc_buf[sc->sc_bufidx]); 633 I2C_WRITE_DATA(sc, sc->sc_buf[sc->sc_bufidx]);
634 } 634 }
635 DPRINTF(("ti_iic_do_write done\n")); 635 DPRINTF(("ti_iic_do_write done\n"));
636} 636}
637 637
638static int 638static int
639ti_iic_wait(struct ti_iic_softc *sc, uint16_t mask, uint16_t val, int flags) 639ti_iic_wait(struct ti_iic_softc *sc, uint16_t mask, uint16_t val, int flags)
640{ 640{
641 int retry = 10; 641 int retry = 10;
642 uint16_t v; 642 uint16_t v;
643 DPRINTF(("ti_iic_wait mask %#x val %#x flags %#x\n", mask, val, flags)); 643 DPRINTF(("ti_iic_wait mask %#x val %#x flags %#x\n", mask, val, flags));
644 644
645 while (((v = I2C_READ_REG(sc, I2C_IRQSTATUS_RAW)) & mask) != val) { 645 while (((v = I2C_READ_REG(sc, I2C_IRQSTATUS_RAW)) & mask) != val) {
646 --retry; 646 --retry;
647 if (retry == 0) { 647 if (retry == 0) {
648 aprint_error_dev(sc->sc_dev, ": wait timeout, " 648 aprint_error_dev(sc->sc_dev, ": wait timeout, "
649 "mask = %#x val = %#x stat = %#x\n", 649 "mask = %#x val = %#x stat = %#x\n",
650 mask, val, v); 650 mask, val, v);
651 return EBUSY; 651 return EBUSY;
652 } 652 }
653 if (flags & I2C_F_POLL) { 653 if (flags & I2C_F_POLL) {
654 delay(50000); 654 delay(50000);
655 } else { 655 } else {
656 kpause("tiiic", false, mstohz(50), NULL); 656 kpause("tiiic", false, mstohz(50), NULL);
657 } 657 }
658 } 658 }
659 DPRINTF(("ti_iic_wait done retry %#x\n", retry)); 659 DPRINTF(("ti_iic_wait done retry %#x\n", retry));
660 660
661 return 0; 661 return 0;
662} 662}
663 663
664static uint32_t 664static uint32_t
665ti_iic_stat(struct ti_iic_softc *sc, uint32_t mask) 665ti_iic_stat(struct ti_iic_softc *sc, uint32_t mask)
666{ 666{
667 uint32_t v; 667 uint32_t v;
668 int retry = 500; 668 int retry = 500;
669 DPRINTF(("ti_iic_wait mask %#x\n", mask)); 669 DPRINTF(("ti_iic_wait mask %#x\n", mask));
670 while (--retry > 0) { 670 while (--retry > 0) {
671 v = I2C_READ_REG(sc, I2C_IRQSTATUS_RAW) & mask; 671 v = I2C_READ_REG(sc, I2C_IRQSTATUS_RAW) & mask;
672 if (v != 0) 672 if (v != 0)
673 break; 673 break;
674 delay(100); 674 delay(100);
675 } 675 }
676 DPRINTF(("ti_iic_wait done retry %#x\n", retry)); 676 DPRINTF(("ti_iic_wait done retry %#x\n", retry));
677 return v; 677 return v;
678} 678}
679 679
680static int 680static int
681ti_iic_flush(struct ti_iic_softc *sc) 681ti_iic_flush(struct ti_iic_softc *sc)
682{ 682{
683 DPRINTF(("ti_iic_flush\n")); 683 DPRINTF(("ti_iic_flush\n"));
684#if 0 684#if 0
685 int retry = 1000; 685 int retry = 1000;
686 uint16_t v; 686 uint16_t v;
687 687
688 while ((v = I2C_READ_REG(sc, I2C_IRQSTATUS_RAW)) & I2C_IRQSTATUS_RRDY) { 688 while ((v = I2C_READ_REG(sc, I2C_IRQSTATUS_RAW)) & I2C_IRQSTATUS_RRDY) {
689 if (--retry == 0) { 689 if (--retry == 0) {
690 aprint_error_dev(sc->sc_dev, 690 aprint_error_dev(sc->sc_dev,
691 ": flush timeout, stat = %#x\n", v); 691 ": flush timeout, stat = %#x\n", v);
692 return EBUSY; 692 return EBUSY;
693 } 693 }
694 (void)I2C_READ_DATA(sc); 694 (void)I2C_READ_DATA(sc);
695 delay(1000); 695 delay(1000);
696 } 696 }
697#endif 697#endif
698 698
699 I2C_WRITE_REG(sc, I2C_CNT, 0); 699 I2C_WRITE_REG(sc, I2C_CNT, 0);
700 return 0; 700 return 0;
701} 701}

cvs diff -r1.6 -r1.7 src/sys/arch/arm/ti/ti_omapintc.c (switch to unified diff)

--- src/sys/arch/arm/ti/ti_omapintc.c 2021/01/25 14:20:39 1.6
+++ src/sys/arch/arm/ti/ti_omapintc.c 2021/01/27 02:12:16 1.7
@@ -1,285 +1,285 @@ @@ -1,285 +1,285 @@
1/* $NetBSD: ti_omapintc.c,v 1.6 2021/01/25 14:20:39 thorpej Exp $ */ 1/* $NetBSD: ti_omapintc.c,v 1.7 2021/01/27 02:12:16 thorpej Exp $ */
2/* 2/*
3 * Define the SDP2430 specific information and then include the generic OMAP 3 * Define the SDP2430 specific information and then include the generic OMAP
4 * interrupt header. 4 * interrupt header.
5 */ 5 */
6 6
7/* 7/*
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain this list of conditions 11 * 1. Redistributions of source code must retain this list of conditions
12 * and the following disclaimer. 12 * and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce this list of conditions 13 * 2. Redistributions in binary form must reproduce this list of conditions
14 * and the following disclaimer in the documentation and/or other materials 14 * and the following disclaimer in the documentation and/or other materials
15 * provided with the distribution. 15 * provided with the distribution.
16 * 16 *
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 18 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
19 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY 19 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY
20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29#define _INTR_PRIVATE 29#define _INTR_PRIVATE
30 30
31#include <sys/cdefs.h> 31#include <sys/cdefs.h>
32__KERNEL_RCSID(0, "$NetBSD: ti_omapintc.c,v 1.6 2021/01/25 14:20:39 thorpej Exp $"); 32__KERNEL_RCSID(0, "$NetBSD: ti_omapintc.c,v 1.7 2021/01/27 02:12:16 thorpej Exp $");
33 33
34#include <sys/param.h> 34#include <sys/param.h>
35#include <sys/evcnt.h> 35#include <sys/evcnt.h>
36#include <sys/device.h> 36#include <sys/device.h>
37#include <sys/kmem.h> 37#include <sys/kmem.h>
38 38
39#include <uvm/uvm_extern.h> 39#include <uvm/uvm_extern.h>
40 40
41#include <machine/intr.h> 41#include <machine/intr.h>
42#include <sys/bus.h> 42#include <sys/bus.h>
43 43
44#include <arm/cpu.h> 44#include <arm/cpu.h>
45#include <arm/armreg.h> 45#include <arm/armreg.h>
46#include <arm/cpufunc.h> 46#include <arm/cpufunc.h>
47 47
48#include <dev/fdt/fdtvar.h> 48#include <dev/fdt/fdtvar.h>
49 49
50#define INTC_CONTROL 0x048 50#define INTC_CONTROL 0x048
51#define INTC_CONTROL_NEWIRQAGR __BIT(0) 51#define INTC_CONTROL_NEWIRQAGR __BIT(0)
52#define INTC_ITR 0x080 52#define INTC_ITR 0x080
53#define INTC_MIR 0x084 53#define INTC_MIR 0x084
54#define INTC_MIR_CLEAR 0x088 54#define INTC_MIR_CLEAR 0x088
55#define INTC_MIR_SET 0x08c 55#define INTC_MIR_SET 0x08c
56#define INTC_PENDING_IRQ 0x098 56#define INTC_PENDING_IRQ 0x098
57 57
58#define INTC_MAX_SOURCES 128 58#define INTC_MAX_SOURCES 128
59 59
60static const struct device_compatible_entry compat_data[] = { 60static const struct device_compatible_entry compat_data[] = {
61 /* compatible number of banks */ 61 /* compatible number of banks */
62 { .compat = "ti,omap3-intc", .value = 3 }, 62 { .compat = "ti,omap3-intc", .value = 3 },
63 { .compat = "ti,am33xx-intc", .value = 4 }, 63 { .compat = "ti,am33xx-intc", .value = 4 },
64 { } 64 DEVICE_COMPAT_EOL
65}; 65};
66 66
67#define INTC_READ(sc, g, o) \ 67#define INTC_READ(sc, g, o) \
68 bus_space_read_4((sc)->sc_memt, (sc)->sc_memh, (g) * 0x20 + (o)) 68 bus_space_read_4((sc)->sc_memt, (sc)->sc_memh, (g) * 0x20 + (o))
69#define INTC_WRITE(sc, g, o, v) \ 69#define INTC_WRITE(sc, g, o, v) \
70 bus_space_write_4((sc)->sc_memt, (sc)->sc_memh, (g) * 0x20 + (o), v) 70 bus_space_write_4((sc)->sc_memt, (sc)->sc_memh, (g) * 0x20 + (o), v)
71 71
72static int omap2icu_match(device_t, cfdata_t, void *); 72static int omap2icu_match(device_t, cfdata_t, void *);
73static void omap2icu_attach(device_t, device_t, void *); 73static void omap2icu_attach(device_t, device_t, void *);
74 74
75static void omap2icu_unblock_irqs(struct pic_softc *, size_t, uint32_t); 75static void omap2icu_unblock_irqs(struct pic_softc *, size_t, uint32_t);
76static void omap2icu_block_irqs(struct pic_softc *, size_t, uint32_t); 76static void omap2icu_block_irqs(struct pic_softc *, size_t, uint32_t);
77static void omap2icu_establish_irq(struct pic_softc *, struct intrsource *); 77static void omap2icu_establish_irq(struct pic_softc *, struct intrsource *);
78static void omap2icu_set_priority(struct pic_softc *, int); 78static void omap2icu_set_priority(struct pic_softc *, int);
79#if 0 79#if 0
80static void omap2icu_source_name(struct pic_softc *, int, char *, size_t); 80static void omap2icu_source_name(struct pic_softc *, int, char *, size_t);
81#endif 81#endif
82 82
83static const struct pic_ops omap2icu_picops = { 83static const struct pic_ops omap2icu_picops = {
84 .pic_unblock_irqs = omap2icu_unblock_irqs, 84 .pic_unblock_irqs = omap2icu_unblock_irqs,
85 .pic_block_irqs = omap2icu_block_irqs, 85 .pic_block_irqs = omap2icu_block_irqs,
86 .pic_establish_irq = omap2icu_establish_irq, 86 .pic_establish_irq = omap2icu_establish_irq,
87 .pic_set_priority = omap2icu_set_priority, 87 .pic_set_priority = omap2icu_set_priority,
88#if 0 88#if 0
89 .pic_source_name = omap2icu_source_name, 89 .pic_source_name = omap2icu_source_name,
90#endif 90#endif
91}; 91};
92 92
93#define PICTOSOFTC(pic) \ 93#define PICTOSOFTC(pic) \
94 ((struct omap2icu_softc *)((uintptr_t)(pic) - offsetof(struct omap2icu_softc, sc_pic))) 94 ((struct omap2icu_softc *)((uintptr_t)(pic) - offsetof(struct omap2icu_softc, sc_pic)))
95 95
96struct omap2icu_softc { 96struct omap2icu_softc {
97 device_t sc_dev; 97 device_t sc_dev;
98 bus_space_tag_t sc_memt; 98 bus_space_tag_t sc_memt;
99 bus_space_handle_t sc_memh; 99 bus_space_handle_t sc_memh;
100 struct pic_softc sc_pic; 100 struct pic_softc sc_pic;
101 uint32_t *sc_enabled_irqs; 101 uint32_t *sc_enabled_irqs;
102 u_int sc_nbank; 102 u_int sc_nbank;
103}; 103};
104 104
105static struct omap2icu_softc *intc_softc; 105static struct omap2icu_softc *intc_softc;
106 106
107static void 107static void
108omap2icu_unblock_irqs(struct pic_softc *pic, size_t irqbase, uint32_t irq_mask) 108omap2icu_unblock_irqs(struct pic_softc *pic, size_t irqbase, uint32_t irq_mask)
109{ 109{
110 struct omap2icu_softc * const sc = PICTOSOFTC(pic); 110 struct omap2icu_softc * const sc = PICTOSOFTC(pic);
111 const size_t group = irqbase / 32; 111 const size_t group = irqbase / 32;
112 KASSERT((irq_mask & sc->sc_enabled_irqs[group]) == 0); 112 KASSERT((irq_mask & sc->sc_enabled_irqs[group]) == 0);
113 sc->sc_enabled_irqs[group] |= irq_mask; 113 sc->sc_enabled_irqs[group] |= irq_mask;
114 INTC_WRITE(sc, group, INTC_MIR_CLEAR, irq_mask); 114 INTC_WRITE(sc, group, INTC_MIR_CLEAR, irq_mask);
115 115
116 /* Force INTC to recompute IRQ availability */ 116 /* Force INTC to recompute IRQ availability */
117 INTC_WRITE(sc, 0, INTC_CONTROL, INTC_CONTROL_NEWIRQAGR); 117 INTC_WRITE(sc, 0, INTC_CONTROL, INTC_CONTROL_NEWIRQAGR);
118} 118}
119 119
120static void 120static void
121omap2icu_block_irqs(struct pic_softc *pic, size_t irqbase, uint32_t irq_mask) 121omap2icu_block_irqs(struct pic_softc *pic, size_t irqbase, uint32_t irq_mask)
122{ 122{
123 struct omap2icu_softc * const sc = PICTOSOFTC(pic); 123 struct omap2icu_softc * const sc = PICTOSOFTC(pic);
124 const size_t group = irqbase / 32; 124 const size_t group = irqbase / 32;
125 125
126 INTC_WRITE(sc, group, INTC_MIR_SET, irq_mask); 126 INTC_WRITE(sc, group, INTC_MIR_SET, irq_mask);
127 sc->sc_enabled_irqs[group] &= ~irq_mask; 127 sc->sc_enabled_irqs[group] &= ~irq_mask;
128} 128}
129 129
130/* 130/*
131 * Called with interrupts disabled 131 * Called with interrupts disabled
132 */ 132 */
133static int 133static int
134find_pending_irqs(struct omap2icu_softc *sc, size_t group) 134find_pending_irqs(struct omap2icu_softc *sc, size_t group)
135{ 135{
136 uint32_t pending = INTC_READ(sc, group, INTC_PENDING_IRQ); 136 uint32_t pending = INTC_READ(sc, group, INTC_PENDING_IRQ);
137 137
138 KASSERT((sc->sc_enabled_irqs[group] & pending) == pending); 138 KASSERT((sc->sc_enabled_irqs[group] & pending) == pending);
139 139
140 if (pending == 0) 140 if (pending == 0)
141 return 0; 141 return 0;
142 142
143 return pic_mark_pending_sources(&sc->sc_pic, group * 32, pending); 143 return pic_mark_pending_sources(&sc->sc_pic, group * 32, pending);
144} 144}
145 145
146static void 146static void
147omap_irq_handler(void *frame) 147omap_irq_handler(void *frame)
148{ 148{
149 struct cpu_info * const ci = curcpu(); 149 struct cpu_info * const ci = curcpu();
150 struct omap2icu_softc * const sc = intc_softc; 150 struct omap2icu_softc * const sc = intc_softc;
151 const int oldipl = ci->ci_cpl; 151 const int oldipl = ci->ci_cpl;
152 const uint32_t oldipl_mask = __BIT(oldipl); 152 const uint32_t oldipl_mask = __BIT(oldipl);
153 int ipl_mask = 0, n; 153 int ipl_mask = 0, n;
154 154
155 ci->ci_data.cpu_nintr++; 155 ci->ci_data.cpu_nintr++;
156 156
157 for (n = 0; n < sc->sc_nbank; n++) { 157 for (n = 0; n < sc->sc_nbank; n++) {
158 if (sc->sc_enabled_irqs[n]) 158 if (sc->sc_enabled_irqs[n])
159 ipl_mask |= find_pending_irqs(sc, n); 159 ipl_mask |= find_pending_irqs(sc, n);
160 } 160 }
161 161
162 /* force INTC to recompute IRQ */ 162 /* force INTC to recompute IRQ */
163 INTC_WRITE(sc, 0, INTC_CONTROL, INTC_CONTROL_NEWIRQAGR); 163 INTC_WRITE(sc, 0, INTC_CONTROL, INTC_CONTROL_NEWIRQAGR);
164 164
165 /* 165 /*
166 * Record the pending_ipls and deliver them if we can. 166 * Record the pending_ipls and deliver them if we can.
167 */ 167 */
168 if ((ipl_mask & ~oldipl_mask) > oldipl_mask) 168 if ((ipl_mask & ~oldipl_mask) > oldipl_mask)
169 pic_do_pending_ints(I32_bit, oldipl, frame); 169 pic_do_pending_ints(I32_bit, oldipl, frame);
170} 170}
171 171
172void 172void
173omap2icu_establish_irq(struct pic_softc *pic, struct intrsource *is) 173omap2icu_establish_irq(struct pic_softc *pic, struct intrsource *is)
174{ 174{
175 KASSERT(is->is_irq < PICTOSOFTC(pic)->sc_pic.pic_maxsources); 175 KASSERT(is->is_irq < PICTOSOFTC(pic)->sc_pic.pic_maxsources);
176 KASSERT(is->is_type == IST_LEVEL); 176 KASSERT(is->is_type == IST_LEVEL);
177} 177}
178 178
179static void 179static void
180omap2icu_set_priority(struct pic_softc *pic, int ipl) 180omap2icu_set_priority(struct pic_softc *pic, int ipl)
181{ 181{
182 curcpu()->ci_cpl = ipl; 182 curcpu()->ci_cpl = ipl;
183} 183}
184 184
185static void * 185static void *
186omapintc_fdt_establish(device_t dev, u_int *specifier, int ipl, int flags, 186omapintc_fdt_establish(device_t dev, u_int *specifier, int ipl, int flags,
187 int (*func)(void *), void *arg, const char *xname) 187 int (*func)(void *), void *arg, const char *xname)
188{ 188{
189 const u_int irq = be32toh(specifier[0]); 189 const u_int irq = be32toh(specifier[0]);
190 if (irq >= INTC_MAX_SOURCES) { 190 if (irq >= INTC_MAX_SOURCES) {
191 device_printf(dev, "IRQ %u is invalid\n", irq); 191 device_printf(dev, "IRQ %u is invalid\n", irq);
192 return NULL; 192 return NULL;
193 } 193 }
194 194
195 const u_int mpsafe = (flags & FDT_INTR_MPSAFE) ? IST_MPSAFE : 0; 195 const u_int mpsafe = (flags & FDT_INTR_MPSAFE) ? IST_MPSAFE : 0;
196 return intr_establish_xname(irq, ipl, IST_LEVEL | mpsafe, func, arg, 196 return intr_establish_xname(irq, ipl, IST_LEVEL | mpsafe, func, arg,
197 xname); 197 xname);
198} 198}
199 199
200static void 200static void
201omapintc_fdt_disestablish(device_t dev, void *ih) 201omapintc_fdt_disestablish(device_t dev, void *ih)
202{ 202{
203 intr_disestablish(ih); 203 intr_disestablish(ih);
204} 204}
205 205
206static bool 206static bool
207omapintc_fdt_intrstr(device_t dev, u_int *specifier, char *buf, size_t buflen) 207omapintc_fdt_intrstr(device_t dev, u_int *specifier, char *buf, size_t buflen)
208{ 208{
209 if (!specifier) 209 if (!specifier)
210 return false; 210 return false;
211 211
212 const u_int irq = be32toh(specifier[0]); 212 const u_int irq = be32toh(specifier[0]);
213 snprintf(buf, buflen, "INTC irq %d", irq); 213 snprintf(buf, buflen, "INTC irq %d", irq);
214 return true; 214 return true;
215} 215}
216 216
217static const struct fdtbus_interrupt_controller_func omapintc_fdt_funcs = { 217static const struct fdtbus_interrupt_controller_func omapintc_fdt_funcs = {
218 .establish = omapintc_fdt_establish, 218 .establish = omapintc_fdt_establish,
219 .disestablish = omapintc_fdt_disestablish, 219 .disestablish = omapintc_fdt_disestablish,
220 .intrstr = omapintc_fdt_intrstr, 220 .intrstr = omapintc_fdt_intrstr,
221}; 221};
222 222
223int 223int
224omap2icu_match(device_t parent, cfdata_t cf, void *aux) 224omap2icu_match(device_t parent, cfdata_t cf, void *aux)
225{ 225{
226 struct fdt_attach_args * const faa = aux; 226 struct fdt_attach_args * const faa = aux;
227 227
228 return of_match_compat_data(faa->faa_phandle, compat_data); 228 return of_match_compat_data(faa->faa_phandle, compat_data);
229} 229}
230 230
231void 231void
232omap2icu_attach(device_t parent, device_t self, void *aux) 232omap2icu_attach(device_t parent, device_t self, void *aux)
233{ 233{
234 struct omap2icu_softc * const sc = device_private(self); 234 struct omap2icu_softc * const sc = device_private(self);
235 struct fdt_attach_args * const faa = aux; 235 struct fdt_attach_args * const faa = aux;
236 const int phandle = faa->faa_phandle; 236 const int phandle = faa->faa_phandle;
237 bus_addr_t addr; 237 bus_addr_t addr;
238 bus_size_t size; 238 bus_size_t size;
239 int error, n; 239 int error, n;
240 240
241 if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { 241 if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
242 aprint_error(": couldn't get registers\n"); 242 aprint_error(": couldn't get registers\n");
243 return; 243 return;
244 } 244 }
245 245
246 sc->sc_dev = self; 246 sc->sc_dev = self;
247 sc->sc_memt = faa->faa_bst; 247 sc->sc_memt = faa->faa_bst;
248 if (bus_space_map(sc->sc_memt, addr, size, 0, &sc->sc_memh) != 0) { 248 if (bus_space_map(sc->sc_memt, addr, size, 0, &sc->sc_memh) != 0) {
249 aprint_error(": couldn't map registers\n"); 249 aprint_error(": couldn't map registers\n");
250 return; 250 return;
251 } 251 }
252 sc->sc_nbank = of_search_compatible(phandle, compat_data)->value; 252 sc->sc_nbank = of_search_compatible(phandle, compat_data)->value;
253 sc->sc_enabled_irqs = 253 sc->sc_enabled_irqs =
254 kmem_zalloc(sizeof(*sc->sc_enabled_irqs) * sc->sc_nbank, KM_SLEEP); 254 kmem_zalloc(sizeof(*sc->sc_enabled_irqs) * sc->sc_nbank, KM_SLEEP);
255 255
256 aprint_naive("\n"); 256 aprint_naive("\n");
257 aprint_normal("\n"); 257 aprint_normal("\n");
258 258
259 for (n = 0; n < sc->sc_nbank; n++) 259 for (n = 0; n < sc->sc_nbank; n++)
260 INTC_WRITE(sc, n, INTC_MIR_SET, 0xffffffff); 260 INTC_WRITE(sc, n, INTC_MIR_SET, 0xffffffff);
261 261
262 sc->sc_dev = self; 262 sc->sc_dev = self;
263 self->dv_private = sc; 263 self->dv_private = sc;
264 264
265 sc->sc_pic.pic_ops = &omap2icu_picops; 265 sc->sc_pic.pic_ops = &omap2icu_picops;
266 sc->sc_pic.pic_maxsources = sc->sc_nbank * 32; 266 sc->sc_pic.pic_maxsources = sc->sc_nbank * 32;
267 snprintf(sc->sc_pic.pic_name, sizeof(sc->sc_pic.pic_name), "intc"); 267 snprintf(sc->sc_pic.pic_name, sizeof(sc->sc_pic.pic_name), "intc");
268 pic_add(&sc->sc_pic, 0); 268 pic_add(&sc->sc_pic, 0);
269 error = fdtbus_register_interrupt_controller(self, phandle, 269 error = fdtbus_register_interrupt_controller(self, phandle,
270 &omapintc_fdt_funcs); 270 &omapintc_fdt_funcs);
271 if (error) { 271 if (error) {
272 aprint_error_dev(self, "couldn't register with fdtbus: %d\n", 272 aprint_error_dev(self, "couldn't register with fdtbus: %d\n",
273 error); 273 error);
274 return; 274 return;
275 } 275 }
276 276
277 KASSERT(intc_softc == NULL); 277 KASSERT(intc_softc == NULL);
278 intc_softc = sc; 278 intc_softc = sc;
279 arm_fdt_irq_set_handler(omap_irq_handler); 279 arm_fdt_irq_set_handler(omap_irq_handler);
280} 280}
281 281
282CFATTACH_DECL_NEW(omapintc, 282CFATTACH_DECL_NEW(omapintc,
283 sizeof(struct omap2icu_softc), 283 sizeof(struct omap2icu_softc),
284 omap2icu_match, omap2icu_attach, 284 omap2icu_match, omap2icu_attach,
285 NULL, NULL); 285 NULL, NULL);

cvs diff -r1.7 -r1.8 src/sys/arch/arm/ti/ti_omaptimer.c (switch to unified diff)

--- src/sys/arch/arm/ti/ti_omaptimer.c 2021/01/25 14:20:39 1.7
+++ src/sys/arch/arm/ti/ti_omaptimer.c 2021/01/27 02:12:16 1.8
@@ -1,215 +1,215 @@ @@ -1,215 +1,215 @@
1/* $NetBSD: ti_omaptimer.c,v 1.7 2021/01/25 14:20:39 thorpej Exp $ */ 1/* $NetBSD: ti_omaptimer.c,v 1.8 2021/01/27 02:12:16 thorpej Exp $ */
2 2
3#include <sys/cdefs.h> 3#include <sys/cdefs.h>
4__KERNEL_RCSID(0, "$NetBSD: ti_omaptimer.c,v 1.7 2021/01/25 14:20:39 thorpej Exp $"); 4__KERNEL_RCSID(0, "$NetBSD: ti_omaptimer.c,v 1.8 2021/01/27 02:12:16 thorpej Exp $");
5 5
6#include <sys/types.h> 6#include <sys/types.h>
7#include <sys/param.h> 7#include <sys/param.h>
8#include <sys/bus.h> 8#include <sys/bus.h>
9#include <sys/device.h> 9#include <sys/device.h>
10#include <sys/timetc.h> 10#include <sys/timetc.h>
11#include <sys/kernel.h> 11#include <sys/kernel.h>
12 12
13#include <arm/locore.h> 13#include <arm/locore.h>
14#include <arm/fdt/arm_fdtvar.h> 14#include <arm/fdt/arm_fdtvar.h>
15 15
16#include <dev/fdt/fdtvar.h> 16#include <dev/fdt/fdtvar.h>
17 17
18#include <arm/ti/ti_prcm.h> 18#include <arm/ti/ti_prcm.h>
19 19
20enum omaptimer_type { 20enum omaptimer_type {
21 DM_TIMER_AM335X, 21 DM_TIMER_AM335X,
22 DM_TIMER_OMAP3430, 22 DM_TIMER_OMAP3430,
23 _DM_NTIMER 23 _DM_NTIMER
24}; 24};
25 25
26enum { 26enum {
27 TIMER_TISR, 27 TIMER_TISR,
28 TIMER_TIER, 28 TIMER_TIER,
29 TIMER_TCLR, 29 TIMER_TCLR,
30 TIMER_TCRR, 30 TIMER_TCRR,
31 TIMER_TLDR, 31 TIMER_TLDR,
32 _TIMER_NREG 32 _TIMER_NREG
33}; 33};
34 34
35/* TISR bits */ 35/* TISR bits */
36#define OVF_IT_FLAG __BIT(1) 36#define OVF_IT_FLAG __BIT(1)
37 37
38/* TIER bits */ 38/* TIER bits */
39#define MAT_EN_FLAG __BIT(0) 39#define MAT_EN_FLAG __BIT(0)
40#define OVF_EN_FLAG __BIT(1) 40#define OVF_EN_FLAG __BIT(1)
41#define TCAR_EN_FLAG __BIT(2) 41#define TCAR_EN_FLAG __BIT(2)
42 42
43/* TCLR bits */ 43/* TCLR bits */
44#define TCLR_ST __BIT(0) 44#define TCLR_ST __BIT(0)
45#define TCLR_AR __BIT(1) 45#define TCLR_AR __BIT(1)
46 46
47static uint8_t omaptimer_regmap[_DM_NTIMER][_TIMER_NREG] = { 47static uint8_t omaptimer_regmap[_DM_NTIMER][_TIMER_NREG] = {
48 [DM_TIMER_AM335X] = { 48 [DM_TIMER_AM335X] = {
49 [TIMER_TISR] = 0x28, 49 [TIMER_TISR] = 0x28,
50 [TIMER_TIER] = 0x2c, 50 [TIMER_TIER] = 0x2c,
51 [TIMER_TCLR] = 0x38, 51 [TIMER_TCLR] = 0x38,
52 [TIMER_TCRR] = 0x3c, 52 [TIMER_TCRR] = 0x3c,
53 [TIMER_TLDR] = 0x40, 53 [TIMER_TLDR] = 0x40,
54 }, 54 },
55 [DM_TIMER_OMAP3430] = { 55 [DM_TIMER_OMAP3430] = {
56 [TIMER_TISR] = 0x18, 56 [TIMER_TISR] = 0x18,
57 [TIMER_TIER] = 0x1c, 57 [TIMER_TIER] = 0x1c,
58 [TIMER_TCLR] = 0x24, 58 [TIMER_TCLR] = 0x24,
59 [TIMER_TCRR] = 0x28, 59 [TIMER_TCRR] = 0x28,
60 [TIMER_TLDR] = 0x2c, 60 [TIMER_TLDR] = 0x2c,
61 }, 61 },
62}; 62};
63 63
64static const struct device_compatible_entry compat_data[] = { 64static const struct device_compatible_entry compat_data[] = {
65 { .compat = "ti,am335x-timer-1ms", .value = DM_TIMER_AM335X }, 65 { .compat = "ti,am335x-timer-1ms", .value = DM_TIMER_AM335X },
66 { .compat = "ti,am335x-timer", .value = DM_TIMER_AM335X }, 66 { .compat = "ti,am335x-timer", .value = DM_TIMER_AM335X },
67 { .compat = "ti,omap3430-timer", .value = DM_TIMER_OMAP3430 }, 67 { .compat = "ti,omap3430-timer", .value = DM_TIMER_OMAP3430 },
68 { } 68 DEVICE_COMPAT_EOL
69}; 69};
70 70
71struct omaptimer_softc { 71struct omaptimer_softc {
72 device_t sc_dev; 72 device_t sc_dev;
73 bus_space_tag_t sc_bst; 73 bus_space_tag_t sc_bst;
74 bus_space_handle_t sc_bsh; 74 bus_space_handle_t sc_bsh;
75 int sc_phandle; 75 int sc_phandle;
76 enum omaptimer_type sc_type; 76 enum omaptimer_type sc_type;
77 struct timecounter sc_tc; 77 struct timecounter sc_tc;
78}; 78};
79 79
80#define RD4(sc, reg) \ 80#define RD4(sc, reg) \
81 bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, omaptimer_regmap[(sc)->sc_type][(reg)]) 81 bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, omaptimer_regmap[(sc)->sc_type][(reg)])
82#define WR4(sc, reg, val) \ 82#define WR4(sc, reg, val) \
83 bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, omaptimer_regmap[(sc)->sc_type][(reg)], val) 83 bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, omaptimer_regmap[(sc)->sc_type][(reg)], val)
84 84
85static struct omaptimer_softc *timer_softc; 85static struct omaptimer_softc *timer_softc;
86 86
87static int 87static int
88omaptimer_intr(void *arg) 88omaptimer_intr(void *arg)
89{ 89{
90 struct omaptimer_softc * const sc = timer_softc; 90 struct omaptimer_softc * const sc = timer_softc;
91 struct clockframe * const frame = arg; 91 struct clockframe * const frame = arg;
92 92
93 WR4(sc, TIMER_TISR, OVF_IT_FLAG); 93 WR4(sc, TIMER_TISR, OVF_IT_FLAG);
94 hardclock(frame); 94 hardclock(frame);
95 95
96 return 1; 96 return 1;
97} 97}
98 98
99static void 99static void
100omaptimer_cpu_initclocks(void) 100omaptimer_cpu_initclocks(void)
101{ 101{
102 struct omaptimer_softc * const sc = timer_softc; 102 struct omaptimer_softc * const sc = timer_softc;
103 char intrstr[128]; 103 char intrstr[128];
104 void *ih; 104 void *ih;
105 105
106 KASSERT(sc != NULL); 106 KASSERT(sc != NULL);
107 if (!fdtbus_intr_str(sc->sc_phandle, 0, intrstr, sizeof(intrstr))) 107 if (!fdtbus_intr_str(sc->sc_phandle, 0, intrstr, sizeof(intrstr)))
108 panic("%s: failed to decode interrupt", __func__); 108 panic("%s: failed to decode interrupt", __func__);
109 ih = fdtbus_intr_establish_xname(sc->sc_phandle, 0, IPL_CLOCK, 109 ih = fdtbus_intr_establish_xname(sc->sc_phandle, 0, IPL_CLOCK,
110 FDT_INTR_MPSAFE, omaptimer_intr, NULL, device_xname(sc->sc_dev)); 110 FDT_INTR_MPSAFE, omaptimer_intr, NULL, device_xname(sc->sc_dev));
111 if (ih == NULL) 111 if (ih == NULL)
112 panic("%s: failed to establish timer interrupt", __func__); 112 panic("%s: failed to establish timer interrupt", __func__);
113 113
114 aprint_normal_dev(sc->sc_dev, "interrupting on %s\n", intrstr); 114 aprint_normal_dev(sc->sc_dev, "interrupting on %s\n", intrstr);
115 115
116 /* Enable interrupts */ 116 /* Enable interrupts */
117 WR4(sc, TIMER_TIER, OVF_EN_FLAG); 117 WR4(sc, TIMER_TIER, OVF_EN_FLAG);
118} 118}
119 119
120static u_int 120static u_int
121omaptimer_get_timecount(struct timecounter *tc) 121omaptimer_get_timecount(struct timecounter *tc)
122{ 122{
123 struct omaptimer_softc * const sc = tc->tc_priv; 123 struct omaptimer_softc * const sc = tc->tc_priv;
124 124
125 return RD4(sc, TIMER_TCRR); 125 return RD4(sc, TIMER_TCRR);
126} 126}
127 127
128static void 128static void
129omaptimer_enable(struct omaptimer_softc *sc, uint32_t value) 129omaptimer_enable(struct omaptimer_softc *sc, uint32_t value)
130{ 130{
131 /* Configure the timer */ 131 /* Configure the timer */
132 WR4(sc, TIMER_TLDR, value); 132 WR4(sc, TIMER_TLDR, value);
133 WR4(sc, TIMER_TCRR, value); 133 WR4(sc, TIMER_TCRR, value);
134 WR4(sc, TIMER_TIER, 0); 134 WR4(sc, TIMER_TIER, 0);
135 WR4(sc, TIMER_TCLR, TCLR_ST | TCLR_AR); 135 WR4(sc, TIMER_TCLR, TCLR_ST | TCLR_AR);
136} 136}
137 137
138static int 138static int
139omaptimer_match(device_t parent, cfdata_t match, void *aux) 139omaptimer_match(device_t parent, cfdata_t match, void *aux)
140{ 140{
141 struct fdt_attach_args * const faa = aux; 141 struct fdt_attach_args * const faa = aux;
142 142
143 return of_match_compat_data(faa->faa_phandle, compat_data); 143 return of_match_compat_data(faa->faa_phandle, compat_data);
144} 144}
145 145
146static void 146static void
147omaptimer_attach(device_t parent, device_t self, void *aux) 147omaptimer_attach(device_t parent, device_t self, void *aux)
148{ 148{
149 struct omaptimer_softc * const sc = device_private(self); 149 struct omaptimer_softc * const sc = device_private(self);
150 struct fdt_attach_args * const faa = aux; 150 struct fdt_attach_args * const faa = aux;
151 const int phandle = faa->faa_phandle; 151 const int phandle = faa->faa_phandle;
152 struct timecounter *tc = &sc->sc_tc; 152 struct timecounter *tc = &sc->sc_tc;
153 const char *modname; 153 const char *modname;
154 struct clk *hwmod; 154 struct clk *hwmod;
155 bus_addr_t addr; 155 bus_addr_t addr;
156 bus_size_t size; 156 bus_size_t size;
157 u_int rate; 157 u_int rate;
158 158
159 if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { 159 if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
160 aprint_error(": couldn't get registers\n"); 160 aprint_error(": couldn't get registers\n");
161 return; 161 return;
162 } 162 }
163 163
164 sc->sc_dev = self; 164 sc->sc_dev = self;
165 sc->sc_phandle = phandle; 165 sc->sc_phandle = phandle;
166 sc->sc_bst = faa->faa_bst; 166 sc->sc_bst = faa->faa_bst;
167 sc->sc_type = of_search_compatible(phandle, compat_data)->value; 167 sc->sc_type = of_search_compatible(phandle, compat_data)->value;
168 168
169 if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) { 169 if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) {
170 device_printf(self, "unable to map bus space"); 170 device_printf(self, "unable to map bus space");
171 return; 171 return;
172 } 172 }
173 173
174 hwmod = ti_prcm_get_hwmod(phandle, 0); 174 hwmod = ti_prcm_get_hwmod(phandle, 0);
175 if (hwmod == NULL || clk_enable(hwmod) != 0) { 175 if (hwmod == NULL || clk_enable(hwmod) != 0) {
176 aprint_error(": couldn't enable module\n"); 176 aprint_error(": couldn't enable module\n");
177 return; 177 return;
178 } 178 }
179 179
180 modname = fdtbus_get_string(phandle, "ti,hwmods"); 180 modname = fdtbus_get_string(phandle, "ti,hwmods");
181 if (modname == NULL) 181 if (modname == NULL)
182 modname = fdtbus_get_string(OF_parent(phandle), "ti,hwmods"); 182 modname = fdtbus_get_string(OF_parent(phandle), "ti,hwmods");
183 183
184 aprint_naive("\n"); 184 aprint_naive("\n");
185 aprint_normal(": Timer (%s)\n", modname); 185 aprint_normal(": Timer (%s)\n", modname);
186 186
187 rate = clk_get_rate(hwmod); 187 rate = clk_get_rate(hwmod);
188 188
189 if (strcmp(modname, "timer2") == 0) { 189 if (strcmp(modname, "timer2") == 0) {
190 omaptimer_enable(sc, 0); 190 omaptimer_enable(sc, 0);
191 191
192 /* Install timecounter */ 192 /* Install timecounter */
193 tc->tc_get_timecount = omaptimer_get_timecount; 193 tc->tc_get_timecount = omaptimer_get_timecount;
194 tc->tc_counter_mask = ~0u; 194 tc->tc_counter_mask = ~0u;
195 tc->tc_frequency = rate; 195 tc->tc_frequency = rate;
196 tc->tc_name = modname; 196 tc->tc_name = modname;
197 tc->tc_quality = 200; 197 tc->tc_quality = 200;
198 tc->tc_priv = sc; 198 tc->tc_priv = sc;
199 tc_init(tc); 199 tc_init(tc);
200 200
201 } else if (strcmp(modname, "timer3") == 0) { 201 } else if (strcmp(modname, "timer3") == 0) {
202 const uint32_t value = (0xffffffff - ((rate / hz) - 1)); 202 const uint32_t value = (0xffffffff - ((rate / hz) - 1));
203 omaptimer_enable(sc, value); 203 omaptimer_enable(sc, value);
204 204
205 /* Use this as the OS timer in UP configurations */ 205 /* Use this as the OS timer in UP configurations */
206 if (!arm_has_mpext_p) { 206 if (!arm_has_mpext_p) {
207 timer_softc = sc; 207 timer_softc = sc;
208 arm_fdt_timer_register(omaptimer_cpu_initclocks); 208 arm_fdt_timer_register(omaptimer_cpu_initclocks);
209 } 209 }
210 } 210 }
211} 211}
212 212
213CFATTACH_DECL_NEW(omaptimer, sizeof(struct omaptimer_softc), 213CFATTACH_DECL_NEW(omaptimer, sizeof(struct omaptimer_softc),
214 omaptimer_match, omaptimer_attach, NULL, NULL); 214 omaptimer_match, omaptimer_attach, NULL, NULL);
215 215