This source file includes following definitions.
- sdhc_host_found
- sdhc_power
- sdhc_shutdown
- sdhc_host_reset
- sdhc_host_ocr
- sdhc_host_maxblklen
- sdhc_card_detect
- sdhc_bus_power
- sdhc_clock_divisor
- sdhc_bus_clock
- sdhc_card_intr_mask
- sdhc_card_intr_ack
- sdhc_wait_state
- sdhc_exec_command
- sdhc_start_command
- sdhc_transfer_data
- sdhc_read_data
- sdhc_write_data
- sdhc_soft_reset
- sdhc_wait_intr
- sdhc_intr
- sdhc_dump_regs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 #include <sys/param.h>
25 #include <sys/device.h>
26 #include <sys/kernel.h>
27 #include <sys/kthread.h>
28 #include <sys/malloc.h>
29 #include <sys/systm.h>
30
31 #include <dev/sdmmc/sdhcreg.h>
32 #include <dev/sdmmc/sdhcvar.h>
33 #include <dev/sdmmc/sdmmcchip.h>
34 #include <dev/sdmmc/sdmmcreg.h>
35 #include <dev/sdmmc/sdmmcvar.h>
36
37 #define SDHC_COMMAND_TIMEOUT hz
38 #define SDHC_BUFFER_TIMEOUT hz
39 #define SDHC_TRANSFER_TIMEOUT hz
40
41 struct sdhc_host {
42 struct sdhc_softc *sc;
43 struct device *sdmmc;
44 bus_space_tag_t iot;
45 bus_space_handle_t ioh;
46 u_int clkbase;
47 int maxblklen;
48 int flags;
49 u_int32_t ocr;
50 u_int8_t regs[14];
51 u_int16_t intr_status;
52 u_int16_t intr_error_status;
53 };
54
55 #define HDEVNAME(hp) ((hp)->sc->sc_dev.dv_xname)
56
57
58 #define SHF_USE_DMA 0x0001
59
60 #define HREAD1(hp, reg) \
61 (bus_space_read_1((hp)->iot, (hp)->ioh, (reg)))
62 #define HREAD2(hp, reg) \
63 (bus_space_read_2((hp)->iot, (hp)->ioh, (reg)))
64 #define HREAD4(hp, reg) \
65 (bus_space_read_4((hp)->iot, (hp)->ioh, (reg)))
66 #define HWRITE1(hp, reg, val) \
67 bus_space_write_1((hp)->iot, (hp)->ioh, (reg), (val))
68 #define HWRITE2(hp, reg, val) \
69 bus_space_write_2((hp)->iot, (hp)->ioh, (reg), (val))
70 #define HWRITE4(hp, reg, val) \
71 bus_space_write_4((hp)->iot, (hp)->ioh, (reg), (val))
72 #define HCLR1(hp, reg, bits) \
73 HWRITE1((hp), (reg), HREAD1((hp), (reg)) & ~(bits))
74 #define HCLR2(hp, reg, bits) \
75 HWRITE2((hp), (reg), HREAD2((hp), (reg)) & ~(bits))
76 #define HSET1(hp, reg, bits) \
77 HWRITE1((hp), (reg), HREAD1((hp), (reg)) | (bits))
78 #define HSET2(hp, reg, bits) \
79 HWRITE2((hp), (reg), HREAD2((hp), (reg)) | (bits))
80
81 int sdhc_host_reset(sdmmc_chipset_handle_t);
82 u_int32_t sdhc_host_ocr(sdmmc_chipset_handle_t);
83 int sdhc_host_maxblklen(sdmmc_chipset_handle_t);
84 int sdhc_card_detect(sdmmc_chipset_handle_t);
85 int sdhc_bus_power(sdmmc_chipset_handle_t, u_int32_t);
86 int sdhc_bus_clock(sdmmc_chipset_handle_t, int);
87 void sdhc_card_intr_mask(sdmmc_chipset_handle_t, int);
88 void sdhc_card_intr_ack(sdmmc_chipset_handle_t);
89 void sdhc_exec_command(sdmmc_chipset_handle_t, struct sdmmc_command *);
90 int sdhc_start_command(struct sdhc_host *, struct sdmmc_command *);
91 int sdhc_wait_state(struct sdhc_host *, u_int32_t, u_int32_t);
92 int sdhc_soft_reset(struct sdhc_host *, int);
93 int sdhc_wait_intr(struct sdhc_host *, int, int);
94 void sdhc_transfer_data(struct sdhc_host *, struct sdmmc_command *);
95 void sdhc_read_data(struct sdhc_host *, u_char *, int);
96 void sdhc_write_data(struct sdhc_host *, u_char *, int);
97
98 #ifdef SDHC_DEBUG
99 int sdhcdebug = 0;
100 #define DPRINTF(n,s) do { if ((n) <= sdhcdebug) printf s; } while (0)
101 void sdhc_dump_regs(struct sdhc_host *);
102 #else
103 #define DPRINTF(n,s) do {} while(0)
104 #endif
105
106 struct sdmmc_chip_functions sdhc_functions = {
107
108 sdhc_host_reset,
109
110 sdhc_host_ocr,
111 sdhc_host_maxblklen,
112
113 sdhc_card_detect,
114
115 sdhc_bus_power,
116 sdhc_bus_clock,
117
118 sdhc_exec_command,
119
120 sdhc_card_intr_mask,
121 sdhc_card_intr_ack
122 };
123
124 struct cfdriver sdhc_cd = {
125 NULL, "sdhc", DV_DULL
126 };
127
128
129
130
131
132 int
133 sdhc_host_found(struct sdhc_softc *sc, bus_space_tag_t iot,
134 bus_space_handle_t ioh, bus_size_t iosize, int usedma)
135 {
136 struct sdmmcbus_attach_args saa;
137 struct sdhc_host *hp;
138 u_int32_t caps;
139 int error = 1;
140 #ifdef SDHC_DEBUG
141 u_int16_t version;
142
143 version = bus_space_read_2(iot, ioh, SDHC_HOST_CTL_VERSION);
144 printf("%s: SD Host Specification/Vendor Version ",
145 sc->sc_dev.dv_xname);
146 switch(SDHC_SPEC_VERSION(version)) {
147 case 0x00:
148 printf("1.0/%u\n", SDHC_VENDOR_VERSION(version));
149 break;
150 default:
151 printf(">1.0/%u\n", SDHC_VENDOR_VERSION(version));
152 break;
153 }
154 #endif
155
156
157 sc->sc_nhosts++;
158 MALLOC(hp, struct sdhc_host *, sizeof(struct sdhc_host),
159 M_DEVBUF, M_WAITOK);
160 sc->sc_host[sc->sc_nhosts - 1] = hp;
161
162
163 bzero(hp, sizeof(struct sdhc_host));
164 hp->sc = sc;
165 hp->iot = iot;
166 hp->ioh = ioh;
167
168
169
170
171 (void)sdhc_host_reset(hp);
172
173
174 caps = HREAD4(hp, SDHC_CAPABILITIES);
175
176
177 if (usedma && ISSET(caps, SDHC_DMA_SUPPORT))
178 SET(hp->flags, SHF_USE_DMA);
179
180
181
182
183 if (SDHC_BASE_FREQ_KHZ(caps) != 0)
184 hp->clkbase = SDHC_BASE_FREQ_KHZ(caps);
185 if (hp->clkbase == 0) {
186
187 printf("%s: base clock frequency unknown\n",
188 sc->sc_dev.dv_xname);
189 goto err;
190 } else if (hp->clkbase < 10000 || hp->clkbase > 63000) {
191
192 printf("%s: base clock frequency out of range: %u MHz\n",
193 sc->sc_dev.dv_xname, hp->clkbase / 1000);
194 goto err;
195 }
196
197
198
199
200
201
202
203
204
205 if (ISSET(caps, SDHC_VOLTAGE_SUPP_1_8V))
206 SET(hp->ocr, MMC_OCR_1_7V_1_8V | MMC_OCR_1_8V_1_9V);
207 if (ISSET(caps, SDHC_VOLTAGE_SUPP_3_0V))
208 SET(hp->ocr, MMC_OCR_2_9V_3_0V | MMC_OCR_3_0V_3_1V);
209 if (ISSET(caps, SDHC_VOLTAGE_SUPP_3_3V))
210 SET(hp->ocr, MMC_OCR_3_2V_3_3V | MMC_OCR_3_3V_3_4V);
211
212
213
214
215
216 switch((caps >> SDHC_MAX_BLK_LEN_SHIFT) & SDHC_MAX_BLK_LEN_MASK) {
217 case SDHC_MAX_BLK_LEN_512:
218 hp->maxblklen = 512;
219 break;
220 case SDHC_MAX_BLK_LEN_1024:
221 hp->maxblklen = 1024;
222 break;
223 case SDHC_MAX_BLK_LEN_2048:
224 hp->maxblklen = 2048;
225 break;
226 default:
227 hp->maxblklen = 1;
228 break;
229 }
230
231
232
233
234
235 bzero(&saa, sizeof(saa));
236 saa.saa_busname = "sdmmc";
237 saa.sct = &sdhc_functions;
238 saa.sch = hp;
239
240 hp->sdmmc = config_found(&sc->sc_dev, &saa, NULL);
241 if (hp->sdmmc == NULL) {
242 error = 0;
243 goto err;
244 }
245
246 return 0;
247
248 err:
249 FREE(hp, M_DEVBUF);
250 sc->sc_host[sc->sc_nhosts - 1] = NULL;
251 sc->sc_nhosts--;
252 return (error);
253 }
254
255
256
257
258 void
259 sdhc_power(int why, void *arg)
260 {
261 struct sdhc_softc *sc = arg;
262 struct sdhc_host *hp;
263 int n, i;
264
265 switch(why) {
266 case PWR_STANDBY:
267 case PWR_SUSPEND:
268
269
270
271
272 for (n = 0; n < sc->sc_nhosts; n++) {
273 hp = sc->sc_host[n];
274 for (i = 0; i < sizeof hp->regs; i++)
275 hp->regs[i] = HREAD1(hp, i);
276 }
277 break;
278
279 case PWR_RESUME:
280
281 for (n = 0; n < sc->sc_nhosts; n++) {
282 hp = sc->sc_host[n];
283 (void)sdhc_host_reset(hp);
284 for (i = 0; i < sizeof hp->regs; i++)
285 HWRITE1(hp, i, hp->regs[i]);
286 }
287 break;
288 }
289 }
290
291
292
293
294 void
295 sdhc_shutdown(void *arg)
296 {
297 struct sdhc_softc *sc = arg;
298 struct sdhc_host *hp;
299 int i;
300
301
302 for (i = 0; i < sc->sc_nhosts; i++) {
303 hp = sc->sc_host[i];
304 (void)sdhc_host_reset(hp);
305 }
306 }
307
308
309
310
311
312 int
313 sdhc_host_reset(sdmmc_chipset_handle_t sch)
314 {
315 struct sdhc_host *hp = sch;
316 u_int16_t imask;
317 int error;
318 int s;
319
320 s = splsdmmc();
321
322
323 HWRITE2(hp, SDHC_NINTR_SIGNAL_EN, 0);
324
325
326
327
328
329 if ((error = sdhc_soft_reset(hp, SDHC_RESET_ALL)) != 0) {
330 splx(s);
331 return (error);
332 }
333
334
335 HWRITE1(hp, SDHC_TIMEOUT_CTL, SDHC_TIMEOUT_MAX);
336
337
338 imask = SDHC_CARD_REMOVAL | SDHC_CARD_INSERTION |
339 SDHC_BUFFER_READ_READY | SDHC_BUFFER_WRITE_READY |
340 SDHC_DMA_INTERRUPT | SDHC_BLOCK_GAP_EVENT |
341 SDHC_TRANSFER_COMPLETE | SDHC_COMMAND_COMPLETE;
342
343 HWRITE2(hp, SDHC_NINTR_STATUS_EN, imask);
344 HWRITE2(hp, SDHC_EINTR_STATUS_EN, SDHC_EINTR_STATUS_MASK);
345 HWRITE2(hp, SDHC_NINTR_SIGNAL_EN, imask);
346 HWRITE2(hp, SDHC_EINTR_SIGNAL_EN, SDHC_EINTR_SIGNAL_MASK);
347
348 splx(s);
349 return 0;
350 }
351
352 u_int32_t
353 sdhc_host_ocr(sdmmc_chipset_handle_t sch)
354 {
355 struct sdhc_host *hp = sch;
356 return hp->ocr;
357 }
358
359 int
360 sdhc_host_maxblklen(sdmmc_chipset_handle_t sch)
361 {
362 struct sdhc_host *hp = sch;
363 return hp->maxblklen;
364 }
365
366
367
368
369 int
370 sdhc_card_detect(sdmmc_chipset_handle_t sch)
371 {
372 struct sdhc_host *hp = sch;
373 return ISSET(HREAD4(hp, SDHC_PRESENT_STATE), SDHC_CARD_INSERTED) ?
374 1 : 0;
375 }
376
377
378
379
380
381 int
382 sdhc_bus_power(sdmmc_chipset_handle_t sch, u_int32_t ocr)
383 {
384 struct sdhc_host *hp = sch;
385 u_int8_t vdd;
386 int s;
387
388 s = splsdmmc();
389
390
391
392
393 HWRITE1(hp, SDHC_POWER_CTL, 0);
394
395
396 if (ocr == 0) {
397 splx(s);
398 (void)sdhc_host_reset(hp);
399 return 0;
400 }
401
402
403
404
405 ocr &= hp->ocr;
406 if (ISSET(ocr, MMC_OCR_3_2V_3_3V|MMC_OCR_3_3V_3_4V))
407 vdd = SDHC_VOLTAGE_3_3V;
408 else if (ISSET(ocr, MMC_OCR_2_9V_3_0V|MMC_OCR_3_0V_3_1V))
409 vdd = SDHC_VOLTAGE_3_0V;
410 else if (ISSET(ocr, MMC_OCR_1_7V_1_8V|MMC_OCR_1_8V_1_9V))
411 vdd = SDHC_VOLTAGE_1_8V;
412 else {
413
414 splx(s);
415 return EINVAL;
416 }
417
418
419
420
421
422 HWRITE1(hp, SDHC_POWER_CTL, (vdd << SDHC_VOLTAGE_SHIFT) |
423 SDHC_BUS_POWER);
424 sdmmc_delay(10000);
425
426
427
428
429
430
431 if (!ISSET(HREAD1(hp, SDHC_POWER_CTL), SDHC_BUS_POWER)) {
432 splx(s);
433 return ENXIO;
434 }
435
436 splx(s);
437 return 0;
438 }
439
440
441
442
443
444 static int
445 sdhc_clock_divisor(struct sdhc_host *hp, u_int freq)
446 {
447 int div;
448
449 for (div = 1; div <= 256; div *= 2)
450 if ((hp->clkbase / div) <= freq)
451 return (div / 2);
452
453 return -1;
454 }
455
456
457
458
459
460 int
461 sdhc_bus_clock(sdmmc_chipset_handle_t sch, int freq)
462 {
463 struct sdhc_host *hp = sch;
464 int s;
465 int div;
466 int timo;
467 int error = 0;
468
469 s = splsdmmc();
470
471 #ifdef DIAGNOSTIC
472
473 if (ISSET(HREAD4(hp, SDHC_PRESENT_STATE), SDHC_CMD_INHIBIT_MASK) &&
474 sdhc_card_detect(hp))
475 printf("sdhc_sdclk_frequency_select: command in progress\n");
476 #endif
477
478
479
480
481 HWRITE2(hp, SDHC_CLOCK_CTL, 0);
482 if (freq == SDMMC_SDCLK_OFF)
483 goto ret;
484
485
486
487
488 if ((div = sdhc_clock_divisor(hp, freq)) < 0) {
489
490 error = EINVAL;
491 goto ret;
492 }
493 HWRITE2(hp, SDHC_CLOCK_CTL, div << SDHC_SDCLK_DIV_SHIFT);
494
495
496
497
498 HSET2(hp, SDHC_CLOCK_CTL, SDHC_INTCLK_ENABLE);
499 for (timo = 1000; timo > 0; timo--) {
500 if (ISSET(HREAD2(hp, SDHC_CLOCK_CTL), SDHC_INTCLK_STABLE))
501 break;
502 sdmmc_delay(10);
503 }
504 if (timo == 0) {
505 error = ETIMEDOUT;
506 goto ret;
507 }
508
509
510
511
512 HSET2(hp, SDHC_CLOCK_CTL, SDHC_SDCLK_ENABLE);
513
514 ret:
515 splx(s);
516 return error;
517 }
518
519 void
520 sdhc_card_intr_mask(sdmmc_chipset_handle_t sch, int enable)
521 {
522 struct sdhc_host *hp = sch;
523
524 if (enable) {
525 HSET2(hp, SDHC_NINTR_STATUS_EN, SDHC_CARD_INTERRUPT);
526 HSET2(hp, SDHC_NINTR_SIGNAL_EN, SDHC_CARD_INTERRUPT);
527 } else {
528 HCLR2(hp, SDHC_NINTR_SIGNAL_EN, SDHC_CARD_INTERRUPT);
529 HCLR2(hp, SDHC_NINTR_STATUS_EN, SDHC_CARD_INTERRUPT);
530 }
531 }
532
533 void
534 sdhc_card_intr_ack(sdmmc_chipset_handle_t sch)
535 {
536 struct sdhc_host *hp = sch;
537
538 HSET2(hp, SDHC_NINTR_STATUS_EN, SDHC_CARD_INTERRUPT);
539 }
540
541 int
542 sdhc_wait_state(struct sdhc_host *hp, u_int32_t mask, u_int32_t value)
543 {
544 u_int32_t state;
545 int timeout;
546
547 for (timeout = 10; timeout > 0; timeout--) {
548 if (((state = HREAD4(hp, SDHC_PRESENT_STATE)) & mask)
549 == value)
550 return 0;
551 sdmmc_delay(10000);
552 }
553 DPRINTF(0,("%s: timeout waiting for %x (state=%b)\n", HDEVNAME(hp),
554 value, state, SDHC_PRESENT_STATE_BITS));
555 return ETIMEDOUT;
556 }
557
558 void
559 sdhc_exec_command(sdmmc_chipset_handle_t sch, struct sdmmc_command *cmd)
560 {
561 struct sdhc_host *hp = sch;
562 int error;
563
564
565
566
567 error = sdhc_start_command(hp, cmd);
568 if (error != 0) {
569 cmd->c_error = error;
570 SET(cmd->c_flags, SCF_ITSDONE);
571 return;
572 }
573
574
575
576
577
578 if (!sdhc_wait_intr(hp, SDHC_COMMAND_COMPLETE,
579 SDHC_COMMAND_TIMEOUT)) {
580 cmd->c_error = ETIMEDOUT;
581 SET(cmd->c_flags, SCF_ITSDONE);
582 return;
583 }
584
585
586
587
588
589
590 if (cmd->c_error == 0 && ISSET(cmd->c_flags, SCF_RSP_PRESENT)) {
591 if (ISSET(cmd->c_flags, SCF_RSP_136)) {
592 u_char *p = (u_char *)cmd->c_resp;
593 int i;
594
595 for (i = 0; i < 15; i++)
596 *p++ = HREAD1(hp, SDHC_RESPONSE + i);
597 } else
598 cmd->c_resp[0] = HREAD4(hp, SDHC_RESPONSE);
599 }
600
601
602
603
604
605 if (cmd->c_error == 0 && cmd->c_data != NULL)
606 sdhc_transfer_data(hp, cmd);
607
608
609 HCLR1(hp, SDHC_HOST_CTL, SDHC_LED_ON);
610
611 DPRINTF(1,("%s: cmd %u done (flags=%#x error=%d)\n",
612 HDEVNAME(hp), cmd->c_opcode, cmd->c_flags, cmd->c_error));
613 SET(cmd->c_flags, SCF_ITSDONE);
614 }
615
616 int
617 sdhc_start_command(struct sdhc_host *hp, struct sdmmc_command *cmd)
618 {
619 u_int16_t blksize = 0;
620 u_int16_t blkcount = 0;
621 u_int16_t mode;
622 u_int16_t command;
623 int error;
624 int s;
625
626 DPRINTF(1,("%s: start cmd %u arg=%#x data=%#x dlen=%d flags=%#x "
627 "proc=\"%s\"\n", HDEVNAME(hp), cmd->c_opcode, cmd->c_arg,
628 cmd->c_data, cmd->c_datalen, cmd->c_flags, curproc ?
629 curproc->p_comm : ""));
630
631
632
633
634
635
636
637 if (cmd->c_datalen > 0) {
638 blksize = MIN(cmd->c_datalen, cmd->c_blklen);
639 blkcount = cmd->c_datalen / blksize;
640 if (cmd->c_datalen % blksize > 0) {
641
642 printf("%s: data not a multiple of %d bytes\n",
643 HDEVNAME(hp), blksize);
644 return EINVAL;
645 }
646 }
647
648
649 if (blkcount > SDHC_BLOCK_COUNT_MAX) {
650 printf("%s: too much data\n", HDEVNAME(hp));
651 return EINVAL;
652 }
653
654
655 mode = 0;
656 if (ISSET(cmd->c_flags, SCF_CMD_READ))
657 mode |= SDHC_READ_MODE;
658 if (blkcount > 0) {
659 mode |= SDHC_BLOCK_COUNT_ENABLE;
660 if (blkcount > 1) {
661 mode |= SDHC_MULTI_BLOCK_MODE;
662
663 mode |= SDHC_AUTO_CMD12_ENABLE;
664 }
665 }
666 #ifdef notyet
667 if (ISSET(hp->flags, SHF_USE_DMA))
668 mode |= SDHC_DMA_ENABLE;
669 #endif
670
671
672
673
674 command = (cmd->c_opcode & SDHC_COMMAND_INDEX_MASK) <<
675 SDHC_COMMAND_INDEX_SHIFT;
676
677 if (ISSET(cmd->c_flags, SCF_RSP_CRC))
678 command |= SDHC_CRC_CHECK_ENABLE;
679 if (ISSET(cmd->c_flags, SCF_RSP_IDX))
680 command |= SDHC_INDEX_CHECK_ENABLE;
681 if (cmd->c_data != NULL)
682 command |= SDHC_DATA_PRESENT_SELECT;
683
684 if (!ISSET(cmd->c_flags, SCF_RSP_PRESENT))
685 command |= SDHC_NO_RESPONSE;
686 else if (ISSET(cmd->c_flags, SCF_RSP_136))
687 command |= SDHC_RESP_LEN_136;
688 else if (ISSET(cmd->c_flags, SCF_RSP_BSY))
689 command |= SDHC_RESP_LEN_48_CHK_BUSY;
690 else
691 command |= SDHC_RESP_LEN_48;
692
693
694 if ((error = sdhc_wait_state(hp, SDHC_CMD_INHIBIT_MASK, 0)) != 0)
695 return error;
696
697 s = splsdmmc();
698
699
700 HSET1(hp, SDHC_HOST_CTL, SDHC_LED_ON);
701
702
703
704 DPRINTF(1,("%s: cmd=%#x mode=%#x blksize=%d blkcount=%d\n",
705 HDEVNAME(hp), command, mode, blksize, blkcount));
706
707
708
709
710
711 HWRITE2(hp, SDHC_TRANSFER_MODE, mode);
712 HWRITE2(hp, SDHC_BLOCK_SIZE, blksize);
713 if (blkcount > 1)
714 HWRITE2(hp, SDHC_BLOCK_COUNT, blkcount);
715 HWRITE4(hp, SDHC_ARGUMENT, cmd->c_arg);
716 HWRITE2(hp, SDHC_COMMAND, command);
717
718 splx(s);
719 return 0;
720 }
721
722 void
723 sdhc_transfer_data(struct sdhc_host *hp, struct sdmmc_command *cmd)
724 {
725 u_char *datap = cmd->c_data;
726 int i, datalen;
727 int mask;
728 int error;
729
730 mask = ISSET(cmd->c_flags, SCF_CMD_READ) ?
731 SDHC_BUFFER_READ_ENABLE : SDHC_BUFFER_WRITE_ENABLE;
732 error = 0;
733 datalen = cmd->c_datalen;
734
735 DPRINTF(1,("%s: resp=%#x datalen=%d\n", HDEVNAME(hp),
736 MMC_R1(cmd->c_resp), datalen));
737
738 #ifdef SDHC_DEBUG
739
740 if ((cmd->c_opcode == 52 || cmd->c_opcode == 53) &&
741 ISSET(MMC_R1(cmd->c_resp), 0xcb00))
742 printf("%s: CMD52/53 error response flags %#x\n",
743 HDEVNAME(hp), MMC_R1(cmd->c_resp) & 0xff00);
744 #endif
745
746 while (datalen > 0) {
747 if (!sdhc_wait_intr(hp, SDHC_BUFFER_READ_READY|
748 SDHC_BUFFER_WRITE_READY, SDHC_BUFFER_TIMEOUT)) {
749 error = ETIMEDOUT;
750 break;
751 }
752
753 if ((error = sdhc_wait_state(hp, mask, mask)) != 0)
754 break;
755
756 i = MIN(datalen, cmd->c_blklen);
757 if (ISSET(cmd->c_flags, SCF_CMD_READ))
758 sdhc_read_data(hp, datap, i);
759 else
760 sdhc_write_data(hp, datap, i);
761
762 datap += i;
763 datalen -= i;
764 }
765
766 if (error == 0 && !sdhc_wait_intr(hp, SDHC_TRANSFER_COMPLETE,
767 SDHC_TRANSFER_TIMEOUT))
768 error = ETIMEDOUT;
769
770 if (error != 0)
771 cmd->c_error = error;
772 SET(cmd->c_flags, SCF_ITSDONE);
773
774 DPRINTF(1,("%s: data transfer done (error=%d)\n",
775 HDEVNAME(hp), cmd->c_error));
776 }
777
778 void
779 sdhc_read_data(struct sdhc_host *hp, u_char *datap, int datalen)
780 {
781 while (datalen > 3) {
782 *(u_int32_t *)datap = HREAD4(hp, SDHC_DATA);
783 datap += 4;
784 datalen -= 4;
785 }
786 if (datalen > 0) {
787 u_int32_t rv = HREAD4(hp, SDHC_DATA);
788 do {
789 *datap++ = rv & 0xff;
790 rv = rv >> 8;
791 } while (--datalen > 0);
792 }
793 }
794
795 void
796 sdhc_write_data(struct sdhc_host *hp, u_char *datap, int datalen)
797 {
798 while (datalen > 3) {
799 DPRINTF(3,("%08x\n", *(u_int32_t *)datap));
800 HWRITE4(hp, SDHC_DATA, *((u_int32_t *)datap)++);
801 datalen -= 4;
802 }
803 if (datalen > 0) {
804 u_int32_t rv = *datap++;
805 if (datalen > 1)
806 rv |= *datap++ << 8;
807 if (datalen > 2)
808 rv |= *datap++ << 16;
809 DPRINTF(3,("rv %08x\n", rv));
810 HWRITE4(hp, SDHC_DATA, rv);
811 }
812 }
813
814
815 int
816 sdhc_soft_reset(struct sdhc_host *hp, int mask)
817 {
818 int timo;
819
820 DPRINTF(1,("%s: software reset reg=%#x\n", HDEVNAME(hp), mask));
821
822 HWRITE1(hp, SDHC_SOFTWARE_RESET, mask);
823 for (timo = 10; timo > 0; timo--) {
824 if (!ISSET(HREAD1(hp, SDHC_SOFTWARE_RESET), mask))
825 break;
826 sdmmc_delay(10000);
827 HWRITE1(hp, SDHC_SOFTWARE_RESET, 0);
828 }
829 if (timo == 0) {
830 DPRINTF(1,("%s: timeout reg=%#x\n", HDEVNAME(hp),
831 HREAD1(hp, SDHC_SOFTWARE_RESET)));
832 HWRITE1(hp, SDHC_SOFTWARE_RESET, 0);
833 return (ETIMEDOUT);
834 }
835
836 return (0);
837 }
838
839 int
840 sdhc_wait_intr(struct sdhc_host *hp, int mask, int timo)
841 {
842 int status;
843 int s;
844
845 mask |= SDHC_ERROR_INTERRUPT;
846
847 s = splsdmmc();
848 status = hp->intr_status & mask;
849 while (status == 0) {
850 if (tsleep(&hp->intr_status, PWAIT, "hcintr", timo)
851 == EWOULDBLOCK) {
852 status |= SDHC_ERROR_INTERRUPT;
853 break;
854 }
855 status = hp->intr_status & mask;
856 }
857 hp->intr_status &= ~status;
858
859 DPRINTF(2,("%s: intr status %#x error %#x\n", HDEVNAME(hp), status,
860 hp->intr_error_status));
861
862
863 if (ISSET(status, SDHC_ERROR_INTERRUPT)) {
864 hp->intr_error_status = 0;
865 (void)sdhc_soft_reset(hp, SDHC_RESET_DAT|SDHC_RESET_CMD);
866 status = 0;
867 }
868
869 splx(s);
870 return status;
871 }
872
873
874
875
876 int
877 sdhc_intr(void *arg)
878 {
879 struct sdhc_softc *sc = arg;
880 int host;
881 int done = 0;
882
883
884 for (host = 0; host < sc->sc_nhosts; host++) {
885 struct sdhc_host *hp = sc->sc_host[host];
886 u_int16_t status;
887
888 if (hp == NULL)
889 continue;
890
891
892 status = HREAD2(hp, SDHC_NINTR_STATUS);
893 if (!ISSET(status, SDHC_NINTR_STATUS_MASK))
894 continue;
895
896
897 HWRITE2(hp, SDHC_NINTR_STATUS, status);
898 DPRINTF(2,("%s: interrupt status=%b\n", HDEVNAME(hp),
899 status, SDHC_NINTR_STATUS_BITS));
900
901
902 done = 1;
903
904
905
906
907 if (ISSET(status, SDHC_ERROR_INTERRUPT)) {
908 u_int16_t error;
909
910
911 error = HREAD2(hp, SDHC_EINTR_STATUS);
912 HWRITE2(hp, SDHC_EINTR_STATUS, error);
913 DPRINTF(2,("%s: error interrupt, status=%b\n",
914 HDEVNAME(hp), error, SDHC_EINTR_STATUS_BITS));
915
916 if (ISSET(error, SDHC_CMD_TIMEOUT_ERROR|
917 SDHC_DATA_TIMEOUT_ERROR)) {
918 hp->intr_error_status |= error;
919 hp->intr_status |= status;
920 wakeup(&hp->intr_status);
921 }
922 }
923
924
925
926
927 if (ISSET(status, SDHC_CARD_REMOVAL|SDHC_CARD_INSERTION))
928 sdmmc_needs_discover(hp->sdmmc);
929
930
931
932
933
934 if (ISSET(status, SDHC_BUFFER_READ_READY|
935 SDHC_BUFFER_WRITE_READY|SDHC_COMMAND_COMPLETE|
936 SDHC_TRANSFER_COMPLETE)) {
937 hp->intr_status |= status;
938 wakeup(&hp->intr_status);
939 }
940
941
942
943
944 if (ISSET(status, SDHC_CARD_INTERRUPT)) {
945 DPRINTF(0,("%s: card interrupt\n", HDEVNAME(hp)));
946 HCLR2(hp, SDHC_NINTR_STATUS_EN, SDHC_CARD_INTERRUPT);
947 sdmmc_card_intr(hp->sdmmc);
948 }
949 }
950 return done;
951 }
952
953 #ifdef SDHC_DEBUG
954 void
955 sdhc_dump_regs(struct sdhc_host *hp)
956 {
957 printf("0x%02x PRESENT_STATE: %b\n", SDHC_PRESENT_STATE,
958 HREAD4(hp, SDHC_PRESENT_STATE), SDHC_PRESENT_STATE_BITS);
959 printf("0x%02x POWER_CTL: %x\n", SDHC_POWER_CTL,
960 HREAD1(hp, SDHC_POWER_CTL));
961 printf("0x%02x NINTR_STATUS: %x\n", SDHC_NINTR_STATUS,
962 HREAD2(hp, SDHC_NINTR_STATUS));
963 printf("0x%02x EINTR_STATUS: %x\n", SDHC_EINTR_STATUS,
964 HREAD2(hp, SDHC_EINTR_STATUS));
965 printf("0x%02x NINTR_STATUS_EN: %x\n", SDHC_NINTR_STATUS_EN,
966 HREAD2(hp, SDHC_NINTR_STATUS_EN));
967 printf("0x%02x EINTR_STATUS_EN: %x\n", SDHC_EINTR_STATUS_EN,
968 HREAD2(hp, SDHC_EINTR_STATUS_EN));
969 printf("0x%02x NINTR_SIGNAL_EN: %x\n", SDHC_NINTR_SIGNAL_EN,
970 HREAD2(hp, SDHC_NINTR_SIGNAL_EN));
971 printf("0x%02x EINTR_SIGNAL_EN: %x\n", SDHC_EINTR_SIGNAL_EN,
972 HREAD2(hp, SDHC_EINTR_SIGNAL_EN));
973 printf("0x%02x CAPABILITIES: %x\n", SDHC_CAPABILITIES,
974 HREAD4(hp, SDHC_CAPABILITIES));
975 printf("0x%02x MAX_CAPABILITIES: %x\n", SDHC_MAX_CAPABILITIES,
976 HREAD4(hp, SDHC_MAX_CAPABILITIES));
977 }
978 #endif