1 /* $OpenBSD: ommmc.c,v 1.18 2016/05/02 07:38:34 jsg Exp $ */
4 * Copyright (c) 2009 Dale Rahn <drahn@openbsd.org>
5 * Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org>
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.
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.
20 /* Omap SD/MMC support derived from /sys/dev/sdmmc/sdhc.c */
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>
31 #include <dev/sdmmc/sdmmcchip.h>
32 #include <dev/sdmmc/sdmmcvar.h>
34 #include <armv7/armv7/armv7var.h>
35 #include <armv7/omap/prcmvar.h>
38 * NOTE: on OMAP4430/AM335x these registers skew by 0x100
39 * this is handled by mapping at base address + 0x100
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" \
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" \
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
178 #define SDHC_COMMAND_TIMEOUT hz
179 #define SDHC_BUFFER_TIMEOUT hz
180 #define SDHC_TRANSFER_TIMEOUT hz
182 void ommmc_attach(struct device
*parent
, struct device
*self
, void *args
);
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 */
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
; /* */
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 *);
210 #define MMC_RESET_DAT 1
211 #define MMC_RESET_CMD 2
212 #define MMC_RESET_ALL (MMC_RESET_CMD|MMC_RESET_DAT)
215 #define SHF_USE_DMA 0x0001
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))
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);
244 /* #define SDHC_DEBUG */
247 #define DPRINTF(n,s) do { if ((n) <= ommmcdebug) printf s; } while (0)
248 void ommmc_dump_regs(struct ommmc_softc
*);
250 #define DPRINTF(n,s) do {} while(0)
253 struct sdmmc_chip_functions ommmc_functions
= {
254 /* host controller reset */
256 /* host controller capabilities */
258 ommmc_host_maxblklen
,
261 /* bus power and clock frequency */
265 /* command execution */
268 ommmc_card_intr_mask
,
272 struct cfdriver ommmc_cd
= {
273 NULL
, "ommmc", DV_DULL
276 struct cfattach ommmc_ca
= {
277 sizeof(struct ommmc_softc
), NULL
, ommmc_attach
281 ommmc_attach(struct device
*parent
, struct device
*self
, void *args
)
283 struct ommmc_softc
*sc
= (struct ommmc_softc
*) self
;
284 struct armv7_attach_args
*aa
= args
;
285 struct sdmmcbus_attach_args saa
;
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__
);
295 /* Enable ICLKEN, FCLKEN? */
296 prcm_enablemodule(PRCM_MMC0
+ aa
->aa_dev
->unit
);
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
));
305 /* Controller Voltage Capabilities Initialization */
306 HSET4(sc
, MMCHS_CAPA
, MMCHS_CAPA_VS18
| MMCHS_CAPA_VS30
);
313 * Reset the host controller and enable interrupts.
315 ommmc_host_reset(sc
);
317 /* Determine host capabilities. */
318 caps
= HREAD4(sc
, MMCHS_CAPA
);
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
);
328 * Determine the base clock frequency. (2.2.24)
331 sc
->clkbase
= 96 * 1000;
333 if (SDHC_BASE_FREQ_KHZ(caps
) != 0)
334 sc
->clkbase
= SDHC_BASE_FREQ_KHZ(caps
);
335 sc
->clkbase
= SDHC_BASE_FREQ_KHZ(caps
);
337 if (sc
->clkbase
== 0) {
338 /* The attachment driver must tell us. */
339 printf("%s: base clock frequency unknown\n", DEVNAME(sc
));
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);
349 * XXX Set the data timeout counter value according to
350 * capabilities. (2.2.15)
355 * Determine SD bus voltage levels supported by the controller.
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
);
365 * Omap max block size is fixed (single buffer), could limit
366 * this to 512 for double buffering, but dont see the point.
368 switch ((caps
& MMCHS_CAPA_MBL_MASK
) >> MMCHS_CAPA_MBL_SHIFT
) {
373 sc
->maxblklen
= 1024;
376 sc
->maxblklen
= 2048;
380 printf("invalid capability blocksize in capa %08x,"
381 " trying 512\n", HREAD4(sc
, MMCHS_CAPA
));
384 * MMC does not support blksize > 512 yet
388 * Attach the generic SD/MMC bus driver. (The bus driver must
389 * not invoke any chipset functions before it is attached.)
391 bzero(&saa
, sizeof(saa
));
392 saa
.saa_busname
= "sdmmc";
393 saa
.sct
= &ommmc_functions
;
395 saa
.caps
= SMC_CAPS_4BIT_MODE
;
396 if (caps
& MMCHS_CAPA_HSS
)
397 saa
.caps
|= SMC_CAPS_MMC_HIGHSPEED
;
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
));
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
);
414 * Power hook established by or called from attachment driver.
417 ommmc_power(int why
, void *arg
)
420 struct ommmc_softc
*sc
= arg
;
426 /* XXX poll for command completion or suspend command
429 /* Save the host controller state. */
431 for (i
= 0; i
< sizeof sc
->regs
; i
++)
432 sc
->regs
[i
] = HREAD1(sc
, i
);
437 /* Restore the host controller state. */
439 (void)ommmc_host_reset(sc
);
440 for (i
= 0; i
< sizeof sc
->regs
; i
++)
441 HWRITE1(sc
, i
, sc
->regs
[i
]);
448 * Shutdown hook established by or called from attachment driver.
451 ommmc_shutdown(void *arg
)
453 struct ommmc_softc
*sc
= arg
;
455 /* XXX chip locks up if we don't disable it before reboot. */
456 (void)ommmc_host_reset(sc
);
460 * Reset the host controller. Called during initialization, when
461 * cards are removed, upon resume, and during error recovery.
464 ommmc_host_reset(sdmmc_chipset_handle_t sch
)
466 struct ommmc_softc
*sc
= sch
;
473 /* Disable all interrupts. */
474 HWRITE4(sc
, MMCHS_IE
, 0);
475 HWRITE4(sc
, MMCHS_ISE
, 0);
478 * Reset the entire host controller and wait up to 100ms for
479 * the controller to clear the reset bit.
481 if ((error
= ommmc_soft_reset(sc
, MMCHS_SYSCTL_SRA
)) != 0) {
487 HSET4(sc
, MMCHS_CON
, MMCHS_CON_INIT
);
488 HWRITE4(sc
, MMCHS_CMD
, 0);
489 delay(100); /* should delay 1ms */
491 HWRITE4(sc
, MMCHS_STAT
, MMCHS_STAT_CC
);
492 HCLR4(sc
, MMCHS_CON
, MMCHS_CON_INIT
);
493 HWRITE4(sc
, MMCHS_STAT
, ~0);
497 /* Set data timeout counter value to max for now. */
498 HSET4(sc
, MMCHS_SYSCTL
, 0xe << MMCHS_SYSCTL_DTO_SH
);
500 /* Enable interrupts. */
501 imask
= MMCHS_STAT_BRR
| MMCHS_STAT_BWR
| MMCHS_STAT_BGE
|
502 MMCHS_STAT_TC
| MMCHS_STAT_CC
;
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
;
508 HWRITE4(sc
, MMCHS_IE
, imask
);
509 HWRITE4(sc
, MMCHS_ISE
, imask
);
516 ommmc_host_ocr(sdmmc_chipset_handle_t sch
)
518 struct ommmc_softc
*sc
= sch
;
523 ommmc_host_maxblklen(sdmmc_chipset_handle_t sch
)
525 struct ommmc_softc
*sc
= sch
;
526 return (sc
->maxblklen
);
530 * Return non-zero if the card is currently inserted.
533 ommmc_card_detect(sdmmc_chipset_handle_t sch
)
535 struct ommmc_softc
*sc
= sch
;
536 return !ISSET(HREAD4(sc
, MMCHS_SYSTEST
), MMCHS_SYSTEST_SDCD
) ?
541 * Set or change SD bus voltage and enable or disable SD bus power.
542 * Return zero on success.
545 ommmc_bus_power(sdmmc_chipset_handle_t sch
, uint32_t ocr
)
547 struct ommmc_softc
*sc
= sch
;
555 * Disable bus power before voltage change.
557 HCLR4(sc
, MMCHS_HCTL
, MMCHS_HCTL_SDBP
);
559 /* If power is disabled, reset the host and return now. */
562 (void)ommmc_host_reset(sc
);
567 * Select the maximum voltage according to capabilities.
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
;
578 /* Unsupported voltage level requested. */
584 * Enable bus power. Wait at least 1 ms (or 74 clocks) plus
585 * voltage ramp until power rises.
587 reg
= HREAD4(sc
, MMCHS_HCTL
);
588 reg
&= ~MMCHS_HCTL_SDVS_MASK
;
590 HWRITE4(sc
, MMCHS_HCTL
, reg
);
592 HSET4(sc
, MMCHS_HCTL
, MMCHS_HCTL_SDBP
);
593 delay(10000); /* XXX */
596 * The host system may not power the bus due to battery low,
597 * etc. In that case, the host controller should clear the
600 if (!ISSET(HREAD4(sc
, MMCHS_HCTL
), MMCHS_HCTL_SDBP
)) {
610 * Return the smallest possible base clock frequency divisor value
611 * for the CLOCK_CTL register to produce `freq' (KHz).
614 ommmc_clock_divisor(struct ommmc_softc
*sc
, uint32_t freq
)
617 uint32_t maxclk
= MMCHS_SYSCTL_CLKD_MASK
>>MMCHS_SYSCTL_CLKD_SH
;
619 for (div
= 1; div
<= maxclk
; div
++)
620 if ((sc
->clkbase
/ div
) <= freq
) {
624 printf("divisor failure\n");
625 /* No divisor found. */
630 * Set or change SDCLK frequency or disable the SD clock.
631 * Return zero on success.
634 ommmc_bus_clock(sdmmc_chipset_handle_t sch
, int freq
)
637 struct ommmc_softc
*sc
= sch
;
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
))
658 * Stop SD clock before changing the frequency.
660 HCLR4(sc
, MMCHS_SYSCTL
, MMCHS_SYSCTL_CEN
);
661 if (freq
== SDMMC_SDCLK_OFF
)
665 * Set the minimum base clock frequency divisor.
667 if ((div
= ommmc_clock_divisor(sc
, freq
)) < 0) {
668 /* Invalid base clock frequency or `freq' value. */
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
);
678 * Start internal clock. Wait 10ms for stabilization.
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
))
694 HSET4(sc
, MMCHS_SYSCTL
, MMCHS_SYSCTL_CEN
);
701 ommmc_bus_width(sdmmc_chipset_handle_t sch
, int width
)
703 struct ommmc_softc
*sc
= sch
;
706 if (width
!= 1 && width
!= 4 && width
!= 8)
712 HSET4(sc
, MMCHS_CON
, MMCHS_CON_DW8
);
714 HCLR4(sc
, MMCHS_CON
, MMCHS_CON_DW8
);
717 HSET4(sc
, MMCHS_HCTL
, MMCHS_HCTL_DTW
);
719 HCLR4(sc
, MMCHS_HCTL
, MMCHS_HCTL_DTW
);
727 ommmc_card_intr_mask(sdmmc_chipset_handle_t sch
, int enable
)
729 /* - this is SDIO card interrupt */
730 struct ommmc_softc
*sc
= sch
;
733 HSET4(sc
, MMCHS_IE
, MMCHS_STAT_CIRQ
);
734 HSET4(sc
, MMCHS_ISE
, MMCHS_STAT_CIRQ
);
736 HCLR4(sc
, MMCHS_IE
, MMCHS_STAT_CIRQ
);
737 HCLR4(sc
, MMCHS_ISE
, MMCHS_STAT_CIRQ
);
742 ommmc_card_intr_ack(sdmmc_chipset_handle_t sch
)
744 struct ommmc_softc
*sc
= sch
;
746 HWRITE4(sc
, MMCHS_STAT
, MMCHS_STAT_CIRQ
);
750 ommmc_wait_state(struct ommmc_softc
*sc
, uint32_t mask
, uint32_t value
)
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
)
763 DPRINTF(0,("%s: timeout waiting for %x (state=%b)\n", DEVNAME(sc
),
764 value
, state
, MMCHS_PSTATE_FMT
));
769 ommmc_exec_command(sdmmc_chipset_handle_t sch
, struct sdmmc_command
*cmd
)
771 struct ommmc_softc
*sc
= sch
;
775 * Start the MMC command, or mark `cmd' as failed and return.
777 error
= ommmc_start_command(sc
, cmd
);
779 cmd
->c_error
= error
;
780 SET(cmd
->c_flags
, SCF_ITSDONE
);
785 * Wait until the command phase is done, or until the command
786 * is marked done for any other reason.
788 if (!ommmc_wait_intr(sc
, MMCHS_STAT_CC
, SDHC_COMMAND_TIMEOUT
)) {
789 cmd
->c_error
= ETIMEDOUT
;
790 SET(cmd
->c_flags
, SCF_ITSDONE
);
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).
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
);
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;
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]);
815 cmd
->c_resp
[0] = HREAD4(sc
, MMCHS_RSP10
);
817 printf("resp[0] 0x%08x\n", cmd
->c_resp
[0]);
823 * If the command has data to transfer in any direction,
824 * execute the transfer now.
826 if (cmd
->c_error
== 0 && cmd
->c_data
!= NULL
)
827 ommmc_transfer_data(sc
, cmd
);
830 /* Turn off the LED. */
831 HCLR1(sc
, SDHC_HOST_CTL
, SDHC_LED_ON
);
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
);
840 ommmc_start_command(struct ommmc_softc
*sc
, struct sdmmc_command
*cmd
)
842 uint32_t blksize
= 0;
843 uint32_t blkcount
= 0;
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
: ""));
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)
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
);
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
));
876 /* Prepare transfer mode register value. (2.2.5) */
878 if (ISSET(cmd
->c_flags
, SCF_CMD_READ
))
879 command
|= MMCHS_CMD_DDIR
;
881 command
|= MMCHS_CMD_BCE
;
883 command
|= MMCHS_CMD_MSBS
;
884 /* XXX only for memory commands? */
885 command
|= MMCHS_CMD_ACEN
;
889 if (ISSET(sc
->flags
, SHF_USE_DMA
))
890 command
|= MMCHS_CMD_DE
;
894 * Prepare command register value. (2.2.6)
896 command
|= (cmd
->c_opcode
<< MMCHS_CMD_INDX_SHIFT
) &
897 MMCHS_CMD_INDX_SHIFT_MASK
;
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
;
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
;
913 command
|= MMCHS_CMD_RESP48
;
915 /* Wait until command and data inhibit bits are clear. (1.5) */
916 if ((error
= ommmc_wait_state(sc
, MMCHS_PSTATE_CMDI
, 0)) != 0)
922 /* Alert the user not to remove the card. */
923 HSET1(sc
, SDHC_HOST_CTL
, SDHC_LED_ON
);
926 /* XXX: Set DMA start address if SHF_USE_DMA is set. */
928 DPRINTF(1,("%s: cmd=%#x blksize=%d blkcount=%d\n",
929 DEVNAME(sc
), command
, blksize
, blkcount
));
932 * Start a CPU data transfer. Writing to the high order byte
933 * of the SDHC_COMMAND register triggers the SD command. (1.5)
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
);
945 ommmc_transfer_data(struct ommmc_softc
*sc
, struct sdmmc_command
*cmd
)
947 uint8_t *datap
= cmd
->c_data
;
952 mask
= ISSET(cmd
->c_flags
, SCF_CMD_READ
) ?
953 MMCHS_PSTATE_BRE
: MMCHS_PSTATE_BWE
;
955 datalen
= cmd
->c_datalen
;
957 DPRINTF(1,("%s: resp=%#x datalen=%d\n", DEVNAME(sc
),
958 MMC_R1(cmd
->c_resp
), datalen
));
960 while (datalen
> 0) {
961 if (!ommmc_wait_intr(sc
, MMCHS_STAT_BRR
| MMCHS_STAT_BWR
,
962 SDHC_BUFFER_TIMEOUT
)) {
967 if ((error
= ommmc_wait_state(sc
, mask
, mask
)) != 0)
970 i
= MIN(datalen
, cmd
->c_blklen
);
971 if (ISSET(cmd
->c_flags
, SCF_CMD_READ
))
972 ommmc_read_data(sc
, datap
, i
);
974 ommmc_write_data(sc
, datap
, i
);
980 if (error
== 0 && !ommmc_wait_intr(sc
, MMCHS_STAT_TC
,
981 SDHC_TRANSFER_TIMEOUT
))
985 cmd
->c_error
= error
;
986 SET(cmd
->c_flags
, SCF_ITSDONE
);
988 DPRINTF(1,("%s: data transfer done (error=%d)\n",
989 DEVNAME(sc
), cmd
->c_error
));
993 ommmc_read_data(struct ommmc_softc
*sc
, uint8_t *datap
, int datalen
)
995 while (datalen
> 3) {
996 *(uint32_t *)datap
= HREAD4(sc
, MMCHS_DATA
);
1001 uint32_t rv
= HREAD4(sc
, MMCHS_DATA
);
1003 *datap
++ = rv
& 0xff;
1005 } while (--datalen
> 0);
1010 ommmc_write_data(struct ommmc_softc
*sc
, uint8_t *datap
, int datalen
)
1012 while (datalen
> 3) {
1013 DPRINTF(3,("%08x\n", *(uint32_t *)datap
));
1014 HWRITE4(sc
, MMCHS_DATA
, *((uint32_t *)datap
));
1019 uint32_t rv
= *datap
++;
1021 rv
|= *datap
++ << 8;
1023 rv
|= *datap
++ << 16;
1024 DPRINTF(3,("rv %08x\n", rv
));
1025 HWRITE4(sc
, MMCHS_DATA
, rv
);
1029 /* Prepare for another command. */
1031 ommmc_soft_reset(struct ommmc_softc
*sc
, int mask
)
1036 DPRINTF(1,("%s: software reset reg=%#x\n", DEVNAME(sc
), mask
));
1038 HSET4(sc
, MMCHS_SYSCTL
, mask
);
1040 for (timo
= 1000; timo
> 0; timo
--) {
1041 if (!ISSET(HREAD4(sc
, MMCHS_SYSCTL
), mask
))
1046 DPRINTF(1,("%s: timeout reg=%#x\n", DEVNAME(sc
),
1047 HREAD4(sc
, MMCHS_SYSCTL
)));
1055 ommmc_wait_intr(struct ommmc_softc
*sc
, int mask
, int timo
)
1060 mask
|= MMCHS_STAT_ERRI
;
1063 status
= sc
->intr_status
& mask
;
1064 while (status
== 0) {
1065 if (tsleep(&sc
->intr_status
, PWAIT
, "hcintr", timo
)
1067 status
|= MMCHS_STAT_ERRI
;
1070 status
= sc
->intr_status
& mask
;
1072 sc
->intr_status
&= ~status
;
1074 DPRINTF(2,("%s: intr status %#x error %#x\n", DEVNAME(sc
), status
,
1075 sc
->intr_error_status
));
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
);
1089 * Established by attachment driver at interrupt priority IPL_SDMMC.
1092 ommmc_intr(void *arg
)
1094 struct ommmc_softc
*sc
= arg
;
1098 /* Find out which interrupts are pending. */
1099 status
= HREAD4(sc
, MMCHS_STAT
);
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
));
1107 * Service error interrupts.
1109 if (ISSET(status
, MMCHS_STAT_ERRI
)) {
1110 if (ISSET(status
, MMCHS_STAT_CTO
|
1112 sc
->intr_status
|= status
;
1113 sc
->intr_error_status
|= status
& 0xffff0000;
1114 wakeup(&sc
->intr_status
);
1120 * Wake up the sdmmc event thread to scan for cards.
1122 if (ISSET(status
, SDHC_CARD_REMOVAL
|SDHC_CARD_INSERTION
))
1123 ommmc_needs_discover(sc
->sdmmc
);
1127 * Wake up the blocking process to service command
1128 * related interrupt(s).
1130 if (ISSET(status
, MMCHS_STAT_BRR
|
1131 MMCHS_STAT_BWR
|MMCHS_STAT_TC
|
1133 sc
->intr_status
|= status
;
1134 wakeup(&sc
->intr_status
);
1138 * Service SD card interrupts.
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
);
1150 ommmc_dump_regs(struct ommmc_softc
*sc
)