initial commit, pull in sys/arch/armv7/omap
[bbb-pru.git] / ommmc.c
1 /* $OpenBSD: ommmc.c,v 1.18 2016/05/02 07:38:34 jsg Exp $ */
2
3 /*
4 * Copyright (c) 2009 Dale Rahn <drahn@openbsd.org>
5 * Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org>
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20 /* Omap SD/MMC support derived from /sys/dev/sdmmc/sdhc.c */
21
22
23 #include <sys/param.h>
24 #include <sys/device.h>
25 #include <sys/kernel.h>
26 #include <sys/kthread.h>
27 #include <sys/malloc.h>
28 #include <sys/systm.h>
29 #include <machine/bus.h>
30
31 #include <dev/sdmmc/sdmmcchip.h>
32 #include <dev/sdmmc/sdmmcvar.h>
33
34 #include <armv7/armv7/armv7var.h>
35 #include <armv7/omap/prcmvar.h>
36
37 /*
38 * NOTE: on OMAP4430/AM335x these registers skew by 0x100
39 * this is handled by mapping at base address + 0x100
40 */
41 /* registers */
42 #define MMCHS_SYSCONFIG 0x010
43 #define MMCHS_SYSSTATUS 0x014
44 #define MMCHS_CSRE 0x024
45 #define MMCHS_SYSTEST 0x028
46 #define MMCHS_SYSTEST_SDCD (1 << 15)
47 #define MMCHS_CON 0x02C
48 #define MMCHS_CON_INIT (1<<1)
49 #define MMCHS_CON_DW8 (1<<5)
50 #define MMCHS_CON_OD (1<<0)
51 #define MMCHS_PWCNT 0x030
52 #define MMCHS_BLK 0x104
53 #define MMCHS_BLK_NBLK_MAX 0xffff
54 #define MMCHS_BLK_NBLK_SHIFT 16
55 #define MMCHS_BLK_NBLK_MASK (MMCHS_BLK_NBLK_MAX<<MMCHS_BLK_NBLK_SHIFT)
56 #define MMCHS_BLK_BLEN_MAX 0x400
57 #define MMCHS_BLK_BLEN_SHIFT 0
58 #define MMCHS_BLK_BLEN_MASK (MMCHS_BLK_BLEN_MAX<<MMCHS_BLK_BLEN_SHIFT)
59 #define MMCHS_ARG 0x108
60 #define MMCHS_CMD 0x10C
61 #define MMCHS_CMD_INDX_SHIFT 24
62 #define MMCHS_CMD_INDX_SHIFT_MASK (0x3f << MMCHS_CMD_INDX_SHIFT)
63 #define MMCHS_CMD_CMD_TYPE_SHIFT 22
64 #define MMCHS_CMD_DP_SHIFT 21
65 #define MMCHS_CMD_DP (1 << MMCHS_CMD_DP_SHIFT)
66 #define MMCHS_CMD_CICE_SHIFT 20
67 #define MMCHS_CMD_CICE (1 << MMCHS_CMD_CICE_SHIFT)
68 #define MMCHS_CMD_CCCE_SHIFT 19
69 #define MMCHS_CMD_CCCE (1 << MMCHS_CMD_CCCE_SHIFT)
70 #define MMCHS_CMD_RSP_TYPE_SHIFT 16
71 #define MMCHS_CMD_RESP_NONE (0x0 << MMCHS_CMD_RSP_TYPE_SHIFT)
72 #define MMCHS_CMD_RESP136 (0x1 << MMCHS_CMD_RSP_TYPE_SHIFT)
73 #define MMCHS_CMD_RESP48 (0x2 << MMCHS_CMD_RSP_TYPE_SHIFT)
74 #define MMCHS_CMD_RESP48B (0x3 << MMCHS_CMD_RSP_TYPE_SHIFT)
75 #define MMCHS_CMD_MSBS (1 << 5)
76 #define MMCHS_CMD_DDIR (1 << 4)
77 #define MMCHS_CMD_ACEN (1 << 2)
78 #define MMCHS_CMD_BCE (1 << 1)
79 #define MMCHS_CMD_DE (1 << 0)
80 #define MMCHS_RSP10 0x110
81 #define MMCHS_RSP32 0x114
82 #define MMCHS_RSP54 0x118
83 #define MMCHS_RSP76 0x11C
84 #define MMCHS_DATA 0x120
85 #define MMCHS_PSTATE 0x124
86 #define MMCHS_PSTATE_CLEV (1<<24)
87 #define MMCHS_PSTATE_DLEV_SH 20
88 #define MMCHS_PSTATE_DLEV_M (0xf << MMCHS_PSTATE_DLEV_SH)
89 #define MMCHS_PSTATE_BRE (1<<11)
90 #define MMCHS_PSTATE_BWE (1<<10)
91 #define MMCHS_PSTATE_RTA (1<<9)
92 #define MMCHS_PSTATE_WTA (1<<8)
93 #define MMCHS_PSTATE_DLA (1<<2)
94 #define MMCHS_PSTATE_DATI (1<<1)
95 #define MMCHS_PSTATE_CMDI (1<<0)
96 #define MMCHS_PSTATE_FMT "\20" \
97 "\x098_CLEV" \
98 "\x08b_BRE" \
99 "\x08a_BWE" \
100 "\x089_RTA" \
101 "\x088_WTA" \
102 "\x082_DLA" \
103 "\x081_DATI" \
104 "\x080_CMDI"
105 #define MMCHS_HCTL 0x128
106 #define MMCHS_HCTL_SDVS_SHIFT 9
107 #define MMCHS_HCTL_SDVS_MASK (0x7<<MMCHS_HCTL_SDVS_SHIFT)
108 #define MMCHS_HCTL_SDVS_V18 (0x5<<MMCHS_HCTL_SDVS_SHIFT)
109 #define MMCHS_HCTL_SDVS_V30 (0x6<<MMCHS_HCTL_SDVS_SHIFT)
110 #define MMCHS_HCTL_SDVS_V33 (0x7<<MMCHS_HCTL_SDVS_SHIFT)
111 #define MMCHS_HCTL_SDBP (1<<8)
112 #define MMCHS_HCTL_HSPE (1<<2)
113 #define MMCHS_HCTL_DTW (1<<1)
114 #define MMCHS_SYSCTL 0x12C
115 #define MMCHS_SYSCTL_SRD (1<<26)
116 #define MMCHS_SYSCTL_SRC (1<<25)
117 #define MMCHS_SYSCTL_SRA (1<<24)
118 #define MMCHS_SYSCTL_DTO_SH 16
119 #define MMCHS_SYSCTL_DTO_MASK 0x000f0000
120 #define MMCHS_SYSCTL_CLKD_SH 6
121 #define MMCHS_SYSCTL_CLKD_MASK 0x0000ffc0
122 #define MMCHS_SYSCTL_CEN (1<<2)
123 #define MMCHS_SYSCTL_ICS (1<<1)
124 #define MMCHS_SYSCTL_ICE (1<<0)
125 #define MMCHS_STAT 0x130
126 #define MMCHS_STAT_BADA (1<<29)
127 #define MMCHS_STAT_CERR (1<<28)
128 #define MMCHS_STAT_ACE (1<<24)
129 #define MMCHS_STAT_DEB (1<<22)
130 #define MMCHS_STAT_DCRC (1<<21)
131 #define MMCHS_STAT_DTO (1<<20)
132 #define MMCHS_STAT_CIE (1<<19)
133 #define MMCHS_STAT_CEB (1<<18)
134 #define MMCHS_STAT_CCRC (1<<17)
135 #define MMCHS_STAT_CTO (1<<16)
136 #define MMCHS_STAT_ERRI (1<<15)
137 #define MMCHS_STAT_OBI (1<<9)
138 #define MMCHS_STAT_CIRQ (1<<8)
139 #define MMCHS_STAT_BRR (1<<5)
140 #define MMCHS_STAT_BWR (1<<4)
141 #define MMCHS_STAT_BGE (1<<2)
142 #define MMCHS_STAT_TC (1<<1)
143 #define MMCHS_STAT_CC (1<<0)
144 #define MMCHS_STAT_FMT "\20" \
145 "\x09d_BADA" \
146 "\x09c_CERR" \
147 "\x098_ACE" \
148 "\x096_DEB" \
149 "\x095_DCRC" \
150 "\x094_DTO" \
151 "\x093_CIE" \
152 "\x092_CEB" \
153 "\x091_CCRC" \
154 "\x090_CTO" \
155 "\x08f_ERRI" \
156 "\x089_OBI" \
157 "\x088_CIRQ" \
158 "\x085_BRR" \
159 "\x084_BWR" \
160 "\x082_BGE" \
161 "\x081_TC" \
162 "\x080_CC"
163 #define MMCHS_IE 0x134
164 #define MMCHS_ISE 0x138
165 #define MMCHS_AC12 0x13C
166 #define MMCHS_CAPA 0x140
167 #define MMCHS_CAPA_VS18 (1 << 26)
168 #define MMCHS_CAPA_VS30 (1 << 25)
169 #define MMCHS_CAPA_VS33 (1 << 24)
170 #define MMCHS_CAPA_SRS (1 << 23)
171 #define MMCHS_CAPA_DS (1 << 22)
172 #define MMCHS_CAPA_HSS (1 << 21)
173 #define MMCHS_CAPA_MBL_SHIFT 16
174 #define MMCHS_CAPA_MBL_MASK (3 << MMCHS_CAPA_MBL_SHIFT)
175 #define MMCHS_CUR_CAPA 0x148
176 #define MMCHS_REV 0x1fc
177
178 #define SDHC_COMMAND_TIMEOUT hz
179 #define SDHC_BUFFER_TIMEOUT hz
180 #define SDHC_TRANSFER_TIMEOUT hz
181
182 void ommmc_attach(struct device *parent, struct device *self, void *args);
183
184 struct ommmc_softc {
185 struct device sc_dev;
186 bus_space_tag_t sc_iot;
187 bus_space_handle_t sc_ioh;
188 void *sc_ih; /* Interrupt handler */
189 uint32_t sc_flags;
190
191 struct device *sdmmc; /* generic SD/MMC device */
192 int clockbit; /* clock control bit */
193 uint32_t clkbase; /* base clock frequency in KHz */
194 int maxblklen; /* maximum block length */
195 int flags; /* flags for this host */
196 uint32_t ocr; /* OCR value from capabilities */
197 uint32_t intr_status; /* soft interrupt status */
198 uint32_t intr_error_status; /* */
199 };
200
201
202 /* Host controller functions called by the attachment driver. */
203 int ommmc_host_found(struct ommmc_softc *, bus_space_tag_t,
204 bus_space_handle_t, bus_size_t, int);
205 void ommmc_power(int, void *);
206 void ommmc_shutdown(void *);
207 int ommmc_intr(void *);
208
209 /* RESET MODES */
210 #define MMC_RESET_DAT 1
211 #define MMC_RESET_CMD 2
212 #define MMC_RESET_ALL (MMC_RESET_CMD|MMC_RESET_DAT)
213
214 /* flag values */
215 #define SHF_USE_DMA 0x0001
216
217 #define HREAD4(sc, reg) \
218 (bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg)))
219 #define HWRITE4(sc, reg, val) \
220 bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val))
221 #define HSET4(sc, reg, bits) \
222 HWRITE4((sc), (reg), HREAD4((sc), (reg)) | (bits))
223 #define HCLR4(sc, reg, bits) \
224 HWRITE4((sc), (reg), HREAD4((sc), (reg)) & ~(bits))
225
226 int ommmc_host_reset(sdmmc_chipset_handle_t);
227 uint32_t ommmc_host_ocr(sdmmc_chipset_handle_t);
228 int ommmc_host_maxblklen(sdmmc_chipset_handle_t);
229 int ommmc_card_detect(sdmmc_chipset_handle_t);
230 int ommmc_bus_power(sdmmc_chipset_handle_t, uint32_t);
231 int ommmc_bus_clock(sdmmc_chipset_handle_t, int);
232 int ommmc_bus_width(sdmmc_chipset_handle_t, int);
233 void ommmc_card_intr_mask(sdmmc_chipset_handle_t, int);
234 void ommmc_card_intr_ack(sdmmc_chipset_handle_t);
235 void ommmc_exec_command(sdmmc_chipset_handle_t, struct sdmmc_command *);
236 int ommmc_start_command(struct ommmc_softc *, struct sdmmc_command *);
237 int ommmc_wait_state(struct ommmc_softc *, uint32_t, uint32_t);
238 int ommmc_soft_reset(struct ommmc_softc *, int);
239 int ommmc_wait_intr(struct ommmc_softc *, int, int);
240 void ommmc_transfer_data(struct ommmc_softc *, struct sdmmc_command *);
241 void ommmc_read_data(struct ommmc_softc *, uint8_t *, int);
242 void ommmc_write_data(struct ommmc_softc *, uint8_t *, int);
243
244 /* #define SDHC_DEBUG */
245 #ifdef SDHC_DEBUG
246 int ommmcdebug = 20;
247 #define DPRINTF(n,s) do { if ((n) <= ommmcdebug) printf s; } while (0)
248 void ommmc_dump_regs(struct ommmc_softc *);
249 #else
250 #define DPRINTF(n,s) do {} while(0)
251 #endif
252
253 struct sdmmc_chip_functions ommmc_functions = {
254 /* host controller reset */
255 ommmc_host_reset,
256 /* host controller capabilities */
257 ommmc_host_ocr,
258 ommmc_host_maxblklen,
259 /* card detection */
260 ommmc_card_detect,
261 /* bus power and clock frequency */
262 ommmc_bus_power,
263 ommmc_bus_clock,
264 ommmc_bus_width,
265 /* command execution */
266 ommmc_exec_command,
267 /* card interrupt */
268 ommmc_card_intr_mask,
269 ommmc_card_intr_ack
270 };
271
272 struct cfdriver ommmc_cd = {
273 NULL, "ommmc", DV_DULL
274 };
275
276 struct cfattach ommmc_ca = {
277 sizeof(struct ommmc_softc), NULL, ommmc_attach
278 };
279
280 void
281 ommmc_attach(struct device *parent, struct device *self, void *args)
282 {
283 struct ommmc_softc *sc = (struct ommmc_softc *) self;
284 struct armv7_attach_args *aa = args;
285 struct sdmmcbus_attach_args saa;
286 uint32_t caps;
287
288 sc->sc_iot = aa->aa_iot;
289 if (bus_space_map(sc->sc_iot, aa->aa_dev->mem[0].addr,
290 aa->aa_dev->mem[0].size, 0, &sc->sc_ioh))
291 panic("%s: bus_space_map failed!", __func__);
292
293 printf("\n");
294
295 /* Enable ICLKEN, FCLKEN? */
296 prcm_enablemodule(PRCM_MMC0 + aa->aa_dev->unit);
297
298 sc->sc_ih = arm_intr_establish(aa->aa_dev->irq[0], IPL_SDMMC,
299 ommmc_intr, sc, DEVNAME(sc));
300 if (sc->sc_ih == NULL) {
301 printf("%s: cannot map interrupt\n", DEVNAME(sc));
302 goto err;
303 }
304
305 /* Controller Voltage Capabilities Initialization */
306 HSET4(sc, MMCHS_CAPA, MMCHS_CAPA_VS18 | MMCHS_CAPA_VS30);
307
308 #ifdef SDHC_DEBUG
309 ommmc_dump_regs(sc);
310 #endif
311
312 /*
313 * Reset the host controller and enable interrupts.
314 */
315 ommmc_host_reset(sc);
316
317 /* Determine host capabilities. */
318 caps = HREAD4(sc, MMCHS_CAPA);
319
320 #if 0
321 /* we want this !! */
322 /* Use DMA if the host system and the controller support it. */
323 if (usedma && ISSET(caps, SDHC_DMA_SUPPORT))
324 SET(sc->flags, SHF_USE_DMA);
325 #endif
326
327 /*
328 * Determine the base clock frequency. (2.2.24)
329 */
330
331 sc->clkbase = 96 * 1000;
332 #if 0
333 if (SDHC_BASE_FREQ_KHZ(caps) != 0)
334 sc->clkbase = SDHC_BASE_FREQ_KHZ(caps);
335 sc->clkbase = SDHC_BASE_FREQ_KHZ(caps);
336 #endif
337 if (sc->clkbase == 0) {
338 /* The attachment driver must tell us. */
339 printf("%s: base clock frequency unknown\n", DEVNAME(sc));
340 goto err;
341 } else if (sc->clkbase < 10000 || sc->clkbase > 96000) {
342 /* SDHC 1.0 supports only 10-63 MHz. */
343 printf("%s: base clock frequency out of range: %u MHz\n",
344 DEVNAME(sc), sc->clkbase / 1000);
345 goto err;
346 }
347
348 /*
349 * XXX Set the data timeout counter value according to
350 * capabilities. (2.2.15)
351 */
352
353
354 /*
355 * Determine SD bus voltage levels supported by the controller.
356 */
357 if (caps & MMCHS_CAPA_VS18)
358 SET(sc->ocr, MMC_OCR_1_65V_1_95V);
359 if (caps & MMCHS_CAPA_VS30)
360 SET(sc->ocr, MMC_OCR_2_9V_3_0V | MMC_OCR_3_0V_3_1V);
361 if (caps & MMCHS_CAPA_VS33)
362 SET(sc->ocr, MMC_OCR_3_2V_3_3V | MMC_OCR_3_3V_3_4V);
363
364 /*
365 * Omap max block size is fixed (single buffer), could limit
366 * this to 512 for double buffering, but dont see the point.
367 */
368 switch ((caps & MMCHS_CAPA_MBL_MASK) >> MMCHS_CAPA_MBL_SHIFT) {
369 case 0:
370 sc->maxblklen = 512;
371 break;
372 case 1:
373 sc->maxblklen = 1024;
374 break;
375 case 2:
376 sc->maxblklen = 2048;
377 break;
378 default:
379 sc->maxblklen = 512;
380 printf("invalid capability blocksize in capa %08x,"
381 " trying 512\n", HREAD4(sc, MMCHS_CAPA));
382 }
383 /*
384 * MMC does not support blksize > 512 yet
385 */
386 sc->maxblklen = 512;
387 /*
388 * Attach the generic SD/MMC bus driver. (The bus driver must
389 * not invoke any chipset functions before it is attached.)
390 */
391 bzero(&saa, sizeof(saa));
392 saa.saa_busname = "sdmmc";
393 saa.sct = &ommmc_functions;
394 saa.sch = sc;
395 saa.caps = SMC_CAPS_4BIT_MODE;
396 if (caps & MMCHS_CAPA_HSS)
397 saa.caps |= SMC_CAPS_MMC_HIGHSPEED;
398
399 sc->sdmmc = config_found(&sc->sc_dev, &saa, NULL);
400 if (sc->sdmmc == NULL) {
401 printf("%s: can't attach sdmmc\n", DEVNAME(sc));
402 goto err;
403 }
404
405 return;
406 err:
407 if (sc->sc_ih != NULL)
408 arm_intr_disestablish(sc->sc_ih);
409 bus_space_unmap(sc->sc_iot, sc->sc_ioh, aa->aa_dev->mem[0].size);
410 }
411
412
413 /*
414 * Power hook established by or called from attachment driver.
415 */
416 void
417 ommmc_power(int why, void *arg)
418 {
419 #if 0
420 struct ommmc_softc *sc = arg;
421 int n, i;
422 #endif
423
424 switch(why) {
425 case DVACT_SUSPEND:
426 /* XXX poll for command completion or suspend command
427 * in progress */
428
429 /* Save the host controller state. */
430 #if 0
431 for (i = 0; i < sizeof sc->regs; i++)
432 sc->regs[i] = HREAD1(sc, i);
433 #endif
434 break;
435
436 case DVACT_RESUME:
437 /* Restore the host controller state. */
438 #if 0
439 (void)ommmc_host_reset(sc);
440 for (i = 0; i < sizeof sc->regs; i++)
441 HWRITE1(sc, i, sc->regs[i]);
442 #endif
443 break;
444 }
445 }
446
447 /*
448 * Shutdown hook established by or called from attachment driver.
449 */
450 void
451 ommmc_shutdown(void *arg)
452 {
453 struct ommmc_softc *sc = arg;
454
455 /* XXX chip locks up if we don't disable it before reboot. */
456 (void)ommmc_host_reset(sc);
457 }
458
459 /*
460 * Reset the host controller. Called during initialization, when
461 * cards are removed, upon resume, and during error recovery.
462 */
463 int
464 ommmc_host_reset(sdmmc_chipset_handle_t sch)
465 {
466 struct ommmc_softc *sc = sch;
467 uint32_t imask;
468 int error;
469 int s;
470
471 s = splsdmmc();
472
473 /* Disable all interrupts. */
474 HWRITE4(sc, MMCHS_IE, 0);
475 HWRITE4(sc, MMCHS_ISE, 0);
476
477 /*
478 * Reset the entire host controller and wait up to 100ms for
479 * the controller to clear the reset bit.
480 */
481 if ((error = ommmc_soft_reset(sc, MMCHS_SYSCTL_SRA)) != 0) {
482 splx(s);
483 return (error);
484 }
485
486 #if 0
487 HSET4(sc, MMCHS_CON, MMCHS_CON_INIT);
488 HWRITE4(sc, MMCHS_CMD, 0);
489 delay(100); /* should delay 1ms */
490
491 HWRITE4(sc, MMCHS_STAT, MMCHS_STAT_CC);
492 HCLR4(sc, MMCHS_CON, MMCHS_CON_INIT);
493 HWRITE4(sc, MMCHS_STAT, ~0);
494 #endif
495
496
497 /* Set data timeout counter value to max for now. */
498 HSET4(sc, MMCHS_SYSCTL, 0xe << MMCHS_SYSCTL_DTO_SH);
499
500 /* Enable interrupts. */
501 imask = MMCHS_STAT_BRR | MMCHS_STAT_BWR | MMCHS_STAT_BGE |
502 MMCHS_STAT_TC | MMCHS_STAT_CC;
503
504 imask |= MMCHS_STAT_BADA | MMCHS_STAT_CERR | MMCHS_STAT_DEB |
505 MMCHS_STAT_DCRC | MMCHS_STAT_DTO | MMCHS_STAT_CIE |
506 MMCHS_STAT_CEB | MMCHS_STAT_CCRC | MMCHS_STAT_CTO;
507
508 HWRITE4(sc, MMCHS_IE, imask);
509 HWRITE4(sc, MMCHS_ISE, imask);
510
511 splx(s);
512 return (0);
513 }
514
515 uint32_t
516 ommmc_host_ocr(sdmmc_chipset_handle_t sch)
517 {
518 struct ommmc_softc *sc = sch;
519 return (sc->ocr);
520 }
521
522 int
523 ommmc_host_maxblklen(sdmmc_chipset_handle_t sch)
524 {
525 struct ommmc_softc *sc = sch;
526 return (sc->maxblklen);
527 }
528
529 /*
530 * Return non-zero if the card is currently inserted.
531 */
532 int
533 ommmc_card_detect(sdmmc_chipset_handle_t sch)
534 {
535 struct ommmc_softc *sc = sch;
536 return !ISSET(HREAD4(sc, MMCHS_SYSTEST), MMCHS_SYSTEST_SDCD) ?
537 1 : 0;
538 }
539
540 /*
541 * Set or change SD bus voltage and enable or disable SD bus power.
542 * Return zero on success.
543 */
544 int
545 ommmc_bus_power(sdmmc_chipset_handle_t sch, uint32_t ocr)
546 {
547 struct ommmc_softc *sc = sch;
548 uint32_t vdd;
549 uint32_t reg;
550 int s;
551
552 s = splsdmmc();
553
554 /*
555 * Disable bus power before voltage change.
556 */
557 HCLR4(sc, MMCHS_HCTL, MMCHS_HCTL_SDBP);
558
559 /* If power is disabled, reset the host and return now. */
560 if (ocr == 0) {
561 splx(s);
562 (void)ommmc_host_reset(sc);
563 return (0);
564 }
565
566 /*
567 * Select the maximum voltage according to capabilities.
568 */
569 ocr &= sc->ocr;
570
571 if (ISSET(ocr, MMC_OCR_3_2V_3_3V | MMC_OCR_3_3V_3_4V))
572 vdd = MMCHS_HCTL_SDVS_V33;
573 else if (ISSET(ocr, MMC_OCR_2_9V_3_0V | MMC_OCR_3_0V_3_1V))
574 vdd = MMCHS_HCTL_SDVS_V30;
575 else if (ISSET(ocr, MMC_OCR_1_65V_1_95V))
576 vdd = MMCHS_HCTL_SDVS_V18;
577 else {
578 /* Unsupported voltage level requested. */
579 splx(s);
580 return (EINVAL);
581 }
582
583 /*
584 * Enable bus power. Wait at least 1 ms (or 74 clocks) plus
585 * voltage ramp until power rises.
586 */
587 reg = HREAD4(sc, MMCHS_HCTL);
588 reg &= ~MMCHS_HCTL_SDVS_MASK;
589 reg |= vdd;
590 HWRITE4(sc, MMCHS_HCTL, reg);
591
592 HSET4(sc, MMCHS_HCTL, MMCHS_HCTL_SDBP);
593 delay(10000); /* XXX */
594
595 /*
596 * The host system may not power the bus due to battery low,
597 * etc. In that case, the host controller should clear the
598 * bus power bit.
599 */
600 if (!ISSET(HREAD4(sc, MMCHS_HCTL), MMCHS_HCTL_SDBP)) {
601 splx(s);
602 return (ENXIO);
603 }
604
605 splx(s);
606 return (0);
607 }
608
609 /*
610 * Return the smallest possible base clock frequency divisor value
611 * for the CLOCK_CTL register to produce `freq' (KHz).
612 */
613 static int
614 ommmc_clock_divisor(struct ommmc_softc *sc, uint32_t freq)
615 {
616 int div;
617 uint32_t maxclk = MMCHS_SYSCTL_CLKD_MASK>>MMCHS_SYSCTL_CLKD_SH;
618
619 for (div = 1; div <= maxclk; div++)
620 if ((sc->clkbase / div) <= freq) {
621 return (div);
622 }
623
624 printf("divisor failure\n");
625 /* No divisor found. */
626 return (-1);
627 }
628
629 /*
630 * Set or change SDCLK frequency or disable the SD clock.
631 * Return zero on success.
632 */
633 int
634 ommmc_bus_clock(sdmmc_chipset_handle_t sch, int freq)
635 {
636 int error = 0;
637 struct ommmc_softc *sc = sch;
638 uint32_t reg;
639 int s;
640 int div;
641 int timo;
642
643 s = splsdmmc();
644
645 /* Must not stop the clock if commands are in progress. */
646 for (timo = 1000; timo > 0; timo--) {
647 if (!ISSET(HREAD4(sc, MMCHS_PSTATE),
648 MMCHS_PSTATE_CMDI|MMCHS_PSTATE_DATI))
649 break;
650 delay(10);
651 }
652 if (timo == 0) {
653 error = ETIMEDOUT;
654 goto ret;
655 }
656
657 /*
658 * Stop SD clock before changing the frequency.
659 */
660 HCLR4(sc, MMCHS_SYSCTL, MMCHS_SYSCTL_CEN);
661 if (freq == SDMMC_SDCLK_OFF)
662 goto ret;
663
664 /*
665 * Set the minimum base clock frequency divisor.
666 */
667 if ((div = ommmc_clock_divisor(sc, freq)) < 0) {
668 /* Invalid base clock frequency or `freq' value. */
669 error = EINVAL;
670 goto ret;
671 }
672 reg = HREAD4(sc, MMCHS_SYSCTL);
673 reg &= ~MMCHS_SYSCTL_CLKD_MASK;
674 reg |= div << MMCHS_SYSCTL_CLKD_SH;
675 HWRITE4(sc, MMCHS_SYSCTL, reg);
676
677 /*
678 * Start internal clock. Wait 10ms for stabilization.
679 */
680 HSET4(sc, MMCHS_SYSCTL, MMCHS_SYSCTL_ICE);
681 for (timo = 1000; timo > 0; timo--) {
682 if (ISSET(HREAD4(sc, MMCHS_SYSCTL), MMCHS_SYSCTL_ICS))
683 break;
684 delay(10);
685 }
686 if (timo == 0) {
687 error = ETIMEDOUT;
688 goto ret;
689 }
690
691 /*
692 * Enable SD clock.
693 */
694 HSET4(sc, MMCHS_SYSCTL, MMCHS_SYSCTL_CEN);
695 ret:
696 splx(s);
697 return (error);
698 }
699
700 int
701 ommmc_bus_width(sdmmc_chipset_handle_t sch, int width)
702 {
703 struct ommmc_softc *sc = sch;
704 int s;
705
706 if (width != 1 && width != 4 && width != 8)
707 return (1);
708
709 s = splsdmmc();
710
711 if (width == 8)
712 HSET4(sc, MMCHS_CON, MMCHS_CON_DW8);
713 else
714 HCLR4(sc, MMCHS_CON, MMCHS_CON_DW8);
715
716 if (width == 4)
717 HSET4(sc, MMCHS_HCTL, MMCHS_HCTL_DTW);
718 else if (width == 1)
719 HCLR4(sc, MMCHS_HCTL, MMCHS_HCTL_DTW);
720
721 splx(s);
722
723 return (0);
724 }
725
726 void
727 ommmc_card_intr_mask(sdmmc_chipset_handle_t sch, int enable)
728 {
729 /* - this is SDIO card interrupt */
730 struct ommmc_softc *sc = sch;
731
732 if (enable) {
733 HSET4(sc, MMCHS_IE, MMCHS_STAT_CIRQ);
734 HSET4(sc, MMCHS_ISE, MMCHS_STAT_CIRQ);
735 } else {
736 HCLR4(sc, MMCHS_IE, MMCHS_STAT_CIRQ);
737 HCLR4(sc, MMCHS_ISE, MMCHS_STAT_CIRQ);
738 }
739 }
740
741 void
742 ommmc_card_intr_ack(sdmmc_chipset_handle_t sch)
743 {
744 struct ommmc_softc *sc = sch;
745
746 HWRITE4(sc, MMCHS_STAT, MMCHS_STAT_CIRQ);
747 }
748
749 int
750 ommmc_wait_state(struct ommmc_softc *sc, uint32_t mask, uint32_t value)
751 {
752 uint32_t state;
753 int timeout;
754
755 state = HREAD4(sc, MMCHS_PSTATE);
756 DPRINTF(3,("%s: wait_state %x %x %x(state=%b)\n", DEVNAME(sc),
757 mask, value, state, state, MMCHS_PSTATE_FMT));
758 for (timeout = 1000; timeout > 0; timeout--) {
759 if (((state = HREAD4(sc, MMCHS_PSTATE)) & mask) == value)
760 return (0);
761 delay(10);
762 }
763 DPRINTF(0,("%s: timeout waiting for %x (state=%b)\n", DEVNAME(sc),
764 value, state, MMCHS_PSTATE_FMT));
765 return (ETIMEDOUT);
766 }
767
768 void
769 ommmc_exec_command(sdmmc_chipset_handle_t sch, struct sdmmc_command *cmd)
770 {
771 struct ommmc_softc *sc = sch;
772 int error;
773
774 /*
775 * Start the MMC command, or mark `cmd' as failed and return.
776 */
777 error = ommmc_start_command(sc, cmd);
778 if (error != 0) {
779 cmd->c_error = error;
780 SET(cmd->c_flags, SCF_ITSDONE);
781 return;
782 }
783
784 /*
785 * Wait until the command phase is done, or until the command
786 * is marked done for any other reason.
787 */
788 if (!ommmc_wait_intr(sc, MMCHS_STAT_CC, SDHC_COMMAND_TIMEOUT)) {
789 cmd->c_error = ETIMEDOUT;
790 SET(cmd->c_flags, SCF_ITSDONE);
791 return;
792 }
793
794 /*
795 * The host controller removes bits [0:7] from the response
796 * data (CRC) and we pass the data up unchanged to the bus
797 * driver (without padding).
798 */
799 if (cmd->c_error == 0 && ISSET(cmd->c_flags, SCF_RSP_PRESENT)) {
800 if (ISSET(cmd->c_flags, SCF_RSP_136)) {
801 uint32_t v0,v1,v2,v3;
802 v0 = HREAD4(sc, MMCHS_RSP10);
803 v1 = HREAD4(sc, MMCHS_RSP32);
804 v2 = HREAD4(sc, MMCHS_RSP54);
805 v3 = HREAD4(sc, MMCHS_RSP76);
806
807 cmd->c_resp[0] = (v0 >> 8) | ((v1 & 0xff) << 24);
808 cmd->c_resp[1] = (v1 >> 8) | ((v2 & 0xff) << 24);
809 cmd->c_resp[2] = (v2 >> 8) | ((v3 & 0xff) << 24);
810 cmd->c_resp[3] = v3 >> 8;
811 #ifdef SDHC_DEBUG
812 printf("resp[0] 0x%08x\nresp[1] 0x%08x\nresp[2] 0x%08x\nresp[3] 0x%08x\n", cmd->c_resp[0], cmd->c_resp[1], cmd->c_resp[2], cmd->c_resp[3]);
813 #endif
814 } else {
815 cmd->c_resp[0] = HREAD4(sc, MMCHS_RSP10);
816 #ifdef SDHC_DEBUG
817 printf("resp[0] 0x%08x\n", cmd->c_resp[0]);
818 #endif
819 }
820 }
821
822 /*
823 * If the command has data to transfer in any direction,
824 * execute the transfer now.
825 */
826 if (cmd->c_error == 0 && cmd->c_data != NULL)
827 ommmc_transfer_data(sc, cmd);
828
829 #if 0
830 /* Turn off the LED. */
831 HCLR1(sc, SDHC_HOST_CTL, SDHC_LED_ON);
832 #endif
833
834 DPRINTF(1,("%s: cmd %u done (flags=%#x error=%d)\n",
835 DEVNAME(sc), cmd->c_opcode, cmd->c_flags, cmd->c_error));
836 SET(cmd->c_flags, SCF_ITSDONE);
837 }
838
839 int
840 ommmc_start_command(struct ommmc_softc *sc, struct sdmmc_command *cmd)
841 {
842 uint32_t blksize = 0;
843 uint32_t blkcount = 0;
844 uint32_t command;
845 int error;
846 int s;
847
848 DPRINTF(1,("%s: start cmd %u arg=%#x data=%p dlen=%d flags=%#x "
849 "proc=\"%s\"\n", DEVNAME(sc), cmd->c_opcode, cmd->c_arg,
850 cmd->c_data, cmd->c_datalen, cmd->c_flags, curproc ?
851 curproc->p_comm : ""));
852
853 /*
854 * The maximum block length for commands should be the minimum
855 * of the host buffer size and the card buffer size. (1.7.2)
856 */
857
858 /* Fragment the data into proper blocks. */
859 if (cmd->c_datalen > 0) {
860 blksize = MIN(cmd->c_datalen, cmd->c_blklen);
861 blkcount = cmd->c_datalen / blksize;
862 if (cmd->c_datalen % blksize > 0) {
863 /* XXX: Split this command. (1.7.4) */
864 printf("%s: data not a multiple of %d bytes\n",
865 DEVNAME(sc), blksize);
866 return (EINVAL);
867 }
868 }
869
870 /* Check limit imposed by 9-bit block count. (1.7.2) */
871 if (blkcount > MMCHS_BLK_NBLK_MAX) {
872 printf("%s: too much data\n", DEVNAME(sc));
873 return (EINVAL);
874 }
875
876 /* Prepare transfer mode register value. (2.2.5) */
877 command = 0;
878 if (ISSET(cmd->c_flags, SCF_CMD_READ))
879 command |= MMCHS_CMD_DDIR;
880 if (blkcount > 0) {
881 command |= MMCHS_CMD_BCE;
882 if (blkcount > 1) {
883 command |= MMCHS_CMD_MSBS;
884 /* XXX only for memory commands? */
885 command |= MMCHS_CMD_ACEN;
886 }
887 }
888 #ifdef notyet
889 if (ISSET(sc->flags, SHF_USE_DMA))
890 command |= MMCHS_CMD_DE;
891 #endif
892
893 /*
894 * Prepare command register value. (2.2.6)
895 */
896 command |= (cmd->c_opcode << MMCHS_CMD_INDX_SHIFT) &
897 MMCHS_CMD_INDX_SHIFT_MASK;
898
899 if (ISSET(cmd->c_flags, SCF_RSP_CRC))
900 command |= MMCHS_CMD_CCCE;
901 if (ISSET(cmd->c_flags, SCF_RSP_IDX))
902 command |= MMCHS_CMD_CICE;
903 if (cmd->c_data != NULL)
904 command |= MMCHS_CMD_DP;
905
906 if (!ISSET(cmd->c_flags, SCF_RSP_PRESENT))
907 command |= MMCHS_CMD_RESP_NONE;
908 else if (ISSET(cmd->c_flags, SCF_RSP_136))
909 command |= MMCHS_CMD_RESP136;
910 else if (ISSET(cmd->c_flags, SCF_RSP_BSY))
911 command |= MMCHS_CMD_RESP48B;
912 else
913 command |= MMCHS_CMD_RESP48;
914
915 /* Wait until command and data inhibit bits are clear. (1.5) */
916 if ((error = ommmc_wait_state(sc, MMCHS_PSTATE_CMDI, 0)) != 0)
917 return (error);
918
919 s = splsdmmc();
920
921 #if 0
922 /* Alert the user not to remove the card. */
923 HSET1(sc, SDHC_HOST_CTL, SDHC_LED_ON);
924 #endif
925
926 /* XXX: Set DMA start address if SHF_USE_DMA is set. */
927
928 DPRINTF(1,("%s: cmd=%#x blksize=%d blkcount=%d\n",
929 DEVNAME(sc), command, blksize, blkcount));
930
931 /*
932 * Start a CPU data transfer. Writing to the high order byte
933 * of the SDHC_COMMAND register triggers the SD command. (1.5)
934 */
935 HWRITE4(sc, MMCHS_BLK, (blkcount << MMCHS_BLK_NBLK_SHIFT) |
936 (blksize << MMCHS_BLK_BLEN_SHIFT));
937 HWRITE4(sc, MMCHS_ARG, cmd->c_arg);
938 HWRITE4(sc, MMCHS_CMD, command);
939
940 splx(s);
941 return (0);
942 }
943
944 void
945 ommmc_transfer_data(struct ommmc_softc *sc, struct sdmmc_command *cmd)
946 {
947 uint8_t *datap = cmd->c_data;
948 int i, datalen;
949 int mask;
950 int error;
951
952 mask = ISSET(cmd->c_flags, SCF_CMD_READ) ?
953 MMCHS_PSTATE_BRE : MMCHS_PSTATE_BWE;
954 error = 0;
955 datalen = cmd->c_datalen;
956
957 DPRINTF(1,("%s: resp=%#x datalen=%d\n", DEVNAME(sc),
958 MMC_R1(cmd->c_resp), datalen));
959
960 while (datalen > 0) {
961 if (!ommmc_wait_intr(sc, MMCHS_STAT_BRR| MMCHS_STAT_BWR,
962 SDHC_BUFFER_TIMEOUT)) {
963 error = ETIMEDOUT;
964 break;
965 }
966
967 if ((error = ommmc_wait_state(sc, mask, mask)) != 0)
968 break;
969
970 i = MIN(datalen, cmd->c_blklen);
971 if (ISSET(cmd->c_flags, SCF_CMD_READ))
972 ommmc_read_data(sc, datap, i);
973 else
974 ommmc_write_data(sc, datap, i);
975
976 datap += i;
977 datalen -= i;
978 }
979
980 if (error == 0 && !ommmc_wait_intr(sc, MMCHS_STAT_TC,
981 SDHC_TRANSFER_TIMEOUT))
982 error = ETIMEDOUT;
983
984 if (error != 0)
985 cmd->c_error = error;
986 SET(cmd->c_flags, SCF_ITSDONE);
987
988 DPRINTF(1,("%s: data transfer done (error=%d)\n",
989 DEVNAME(sc), cmd->c_error));
990 }
991
992 void
993 ommmc_read_data(struct ommmc_softc *sc, uint8_t *datap, int datalen)
994 {
995 while (datalen > 3) {
996 *(uint32_t *)datap = HREAD4(sc, MMCHS_DATA);
997 datap += 4;
998 datalen -= 4;
999 }
1000 if (datalen > 0) {
1001 uint32_t rv = HREAD4(sc, MMCHS_DATA);
1002 do {
1003 *datap++ = rv & 0xff;
1004 rv = rv >> 8;
1005 } while (--datalen > 0);
1006 }
1007 }
1008
1009 void
1010 ommmc_write_data(struct ommmc_softc *sc, uint8_t *datap, int datalen)
1011 {
1012 while (datalen > 3) {
1013 DPRINTF(3,("%08x\n", *(uint32_t *)datap));
1014 HWRITE4(sc, MMCHS_DATA, *((uint32_t *)datap));
1015 datap += 4;
1016 datalen -= 4;
1017 }
1018 if (datalen > 0) {
1019 uint32_t rv = *datap++;
1020 if (datalen > 1)
1021 rv |= *datap++ << 8;
1022 if (datalen > 2)
1023 rv |= *datap++ << 16;
1024 DPRINTF(3,("rv %08x\n", rv));
1025 HWRITE4(sc, MMCHS_DATA, rv);
1026 }
1027 }
1028
1029 /* Prepare for another command. */
1030 int
1031 ommmc_soft_reset(struct ommmc_softc *sc, int mask)
1032 {
1033
1034 int timo;
1035
1036 DPRINTF(1,("%s: software reset reg=%#x\n", DEVNAME(sc), mask));
1037
1038 HSET4(sc, MMCHS_SYSCTL, mask);
1039 delay(10);
1040 for (timo = 1000; timo > 0; timo--) {
1041 if (!ISSET(HREAD4(sc, MMCHS_SYSCTL), mask))
1042 break;
1043 delay(10);
1044 }
1045 if (timo == 0) {
1046 DPRINTF(1,("%s: timeout reg=%#x\n", DEVNAME(sc),
1047 HREAD4(sc, MMCHS_SYSCTL)));
1048 return (ETIMEDOUT);
1049 }
1050
1051 return (0);
1052 }
1053
1054 int
1055 ommmc_wait_intr(struct ommmc_softc *sc, int mask, int timo)
1056 {
1057 int status;
1058 int s;
1059
1060 mask |= MMCHS_STAT_ERRI;
1061
1062 s = splsdmmc();
1063 status = sc->intr_status & mask;
1064 while (status == 0) {
1065 if (tsleep(&sc->intr_status, PWAIT, "hcintr", timo)
1066 == EWOULDBLOCK) {
1067 status |= MMCHS_STAT_ERRI;
1068 break;
1069 }
1070 status = sc->intr_status & mask;
1071 }
1072 sc->intr_status &= ~status;
1073
1074 DPRINTF(2,("%s: intr status %#x error %#x\n", DEVNAME(sc), status,
1075 sc->intr_error_status));
1076
1077 /* Command timeout has higher priority than command complete. */
1078 if (ISSET(status, MMCHS_STAT_ERRI)) {
1079 sc->intr_error_status = 0;
1080 (void)ommmc_soft_reset(sc, MMCHS_SYSCTL_SRC|MMCHS_SYSCTL_SRD);
1081 status = 0;
1082 }
1083
1084 splx(s);
1085 return (status);
1086 }
1087
1088 /*
1089 * Established by attachment driver at interrupt priority IPL_SDMMC.
1090 */
1091 int
1092 ommmc_intr(void *arg)
1093 {
1094 struct ommmc_softc *sc = arg;
1095
1096 uint32_t status;
1097
1098 /* Find out which interrupts are pending. */
1099 status = HREAD4(sc, MMCHS_STAT);
1100
1101 /* Acknowledge the interrupts we are about to handle. */
1102 HWRITE4(sc, MMCHS_STAT, status);
1103 DPRINTF(2,("%s: interrupt status=%b\n", DEVNAME(sc),
1104 status, MMCHS_STAT_FMT));
1105
1106 /*
1107 * Service error interrupts.
1108 */
1109 if (ISSET(status, MMCHS_STAT_ERRI)) {
1110 if (ISSET(status, MMCHS_STAT_CTO|
1111 MMCHS_STAT_DTO)) {
1112 sc->intr_status |= status;
1113 sc->intr_error_status |= status & 0xffff0000;
1114 wakeup(&sc->intr_status);
1115 }
1116 }
1117
1118 #if 0
1119 /*
1120 * Wake up the sdmmc event thread to scan for cards.
1121 */
1122 if (ISSET(status, SDHC_CARD_REMOVAL|SDHC_CARD_INSERTION))
1123 ommmc_needs_discover(sc->sdmmc);
1124 #endif
1125
1126 /*
1127 * Wake up the blocking process to service command
1128 * related interrupt(s).
1129 */
1130 if (ISSET(status, MMCHS_STAT_BRR|
1131 MMCHS_STAT_BWR|MMCHS_STAT_TC|
1132 MMCHS_STAT_CC)) {
1133 sc->intr_status |= status;
1134 wakeup(&sc->intr_status);
1135 }
1136
1137 /*
1138 * Service SD card interrupts.
1139 */
1140 if (ISSET(status, MMCHS_STAT_CIRQ)) {
1141 DPRINTF(0,("%s: card interrupt\n", DEVNAME(sc)));
1142 HCLR4(sc, MMCHS_STAT, MMCHS_STAT_CIRQ);
1143 sdmmc_card_intr(sc->sdmmc);
1144 }
1145 return 1;
1146 }
1147
1148 #ifdef SDHC_DEBUG
1149 void
1150 ommmc_dump_regs(struct ommmc_softc *sc)
1151 {
1152 }
1153 #endif