This source file includes following definitions.
- sdmmc_io_enable
- sdmmc_io_scan
- sdmmc_io_init
- sdmmc_io_function_ready
- sdmmc_io_function_enable
- sdmmc_io_function_disable
- sdmmc_io_attach
- sdmmc_submatch
- sdmmc_print
- sdmmc_io_detach
- sdmmc_io_rw_direct
- sdmmc_io_rw_extended
- sdmmc_io_read_1
- sdmmc_io_write_1
- sdmmc_io_read_2
- sdmmc_io_write_2
- sdmmc_io_read_4
- sdmmc_io_write_4
- sdmmc_io_read_multi_1
- sdmmc_io_write_multi_1
- sdmmc_io_xchg
- sdmmc_io_reset
- sdmmc_io_send_op_cond
- sdmmc_intr_enable
- sdmmc_intr_disable
- sdmmc_intr_establish
- sdmmc_intr_disestablish
- sdmmc_card_intr
- sdmmc_intr_task
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 #include <sys/param.h>
22 #include <sys/kernel.h>
23 #include <sys/malloc.h>
24 #include <sys/proc.h>
25 #include <sys/systm.h>
26
27 #include <dev/sdmmc/sdmmc_ioreg.h>
28 #include <dev/sdmmc/sdmmcchip.h>
29 #include <dev/sdmmc/sdmmcreg.h>
30 #include <dev/sdmmc/sdmmcvar.h>
31
32 struct sdmmc_intr_handler {
33 struct sdmmc_softc *ih_softc;
34 char *ih_name;
35 int (*ih_fun)(void *);
36 void *ih_arg;
37 TAILQ_ENTRY(sdmmc_intr_handler) entry;
38 };
39
40 int sdmmc_submatch(struct device *, void *, void *);
41 int sdmmc_print(void *, const char *);
42 int sdmmc_io_rw_direct(struct sdmmc_softc *, struct sdmmc_function *,
43 int, u_char *, int);
44 int sdmmc_io_rw_extended(struct sdmmc_softc *, struct sdmmc_function *,
45 int, u_char *, int, int);
46 int sdmmc_io_xchg(struct sdmmc_softc *, struct sdmmc_function *,
47 int, u_char *);
48 void sdmmc_io_reset(struct sdmmc_softc *);
49 int sdmmc_io_send_op_cond(struct sdmmc_softc *, u_int32_t, u_int32_t *);
50
51 #ifdef SDMMC_DEBUG
52 #define DPRINTF(s) printf s
53 #else
54 #define DPRINTF(s)
55 #endif
56
57 #ifdef SDMMC_DEBUG
58 int sdmmc_verbose = 1;
59 #else
60 int sdmmc_verbose = 0;
61 #endif
62
63
64
65
66
67
68 int
69 sdmmc_io_enable(struct sdmmc_softc *sc)
70 {
71 u_int32_t host_ocr;
72 u_int32_t card_ocr;
73
74
75 SET(sc->sc_flags, SMF_SD_MODE|SMF_IO_MODE|SMF_MEM_MODE);
76
77
78 sdmmc_io_reset(sc);
79
80
81
82
83
84
85
86 if (sdmmc_io_send_op_cond(sc, 0, &card_ocr) != 0) {
87
88 CLR(sc->sc_flags, SMF_IO_MODE);
89 return 0;
90 }
91
92
93 if (!ISSET(card_ocr, SD_IO_OCR_MEM_PRESENT)) {
94
95 DPRINTF(("%s: no memory present\n", SDMMCDEVNAME(sc)));
96 CLR(sc->sc_flags, SMF_MEM_MODE);
97 }
98 sc->sc_function_count = SD_IO_OCR_NUM_FUNCTIONS(card_ocr);
99 if (sc->sc_function_count == 0) {
100
101 DPRINTF(("%s: no I/O functions\n", SDMMCDEVNAME(sc)));
102 CLR(sc->sc_flags, SMF_IO_MODE);
103 return 0;
104 }
105 card_ocr &= SD_IO_OCR_MASK;
106
107
108 host_ocr = sdmmc_chip_host_ocr(sc->sct, sc->sch);
109 if (sdmmc_set_bus_power(sc, host_ocr, card_ocr) != 0) {
110 printf("%s: can't supply voltage requested by card\n",
111 SDMMCDEVNAME(sc));
112 return 1;
113 }
114
115
116 sdmmc_io_reset(sc);
117
118
119 if (sdmmc_io_send_op_cond(sc, host_ocr, NULL) != 0) {
120 printf("%s: can't send I/O OCR\n", SDMMCDEVNAME(sc));
121 return 1;
122 }
123 return 0;
124 }
125
126
127
128
129
130 void
131 sdmmc_io_scan(struct sdmmc_softc *sc)
132 {
133 struct sdmmc_function *sf0, *sf;
134 int i;
135
136 sf0 = sdmmc_function_alloc(sc);
137 sf0->number = 0;
138 if (sdmmc_set_relative_addr(sc, sf0) != 0) {
139 printf("%s: can't set I/O RCA\n", SDMMCDEVNAME(sc));
140 SET(sf0->flags, SFF_ERROR);
141 return;
142 }
143 sc->sc_fn0 = sf0;
144 SIMPLEQ_INSERT_TAIL(&sc->sf_head, sf0, sf_list);
145
146
147 if (sdmmc_select_card(sc, sf0) != 0) {
148 printf("%s: can't select I/O RCA %d\n", SDMMCDEVNAME(sc),
149 sf0->rca);
150 SET(sf0->flags, SFF_ERROR);
151 return;
152 }
153
154 for (i = 1; i <= sc->sc_function_count; i++) {
155 sf = sdmmc_function_alloc(sc);
156 sf->number = i;
157 sf->rca = sf0->rca;
158
159 SIMPLEQ_INSERT_TAIL(&sc->sf_head, sf, sf_list);
160 }
161 }
162
163
164
165
166 int
167 sdmmc_io_init(struct sdmmc_softc *sc, struct sdmmc_function *sf)
168 {
169 if (sf->number == 0) {
170 sdmmc_io_write_1(sf, SD_IO_CCCR_BUS_WIDTH,
171 CCCR_BUS_WIDTH_1);
172
173 if (sdmmc_read_cis(sf, &sf->cis) != 0) {
174 printf("%s: can't read CIS\n", SDMMCDEVNAME(sc));
175 SET(sf->flags, SFF_ERROR);
176 return 1;
177 }
178
179 sdmmc_check_cis_quirks(sf);
180
181 if (sdmmc_verbose)
182 sdmmc_print_cis(sf);
183 }
184 return 0;
185 }
186
187
188
189
190 int
191 sdmmc_io_function_ready(struct sdmmc_function *sf)
192 {
193 struct sdmmc_softc *sc = sf->sc;
194 struct sdmmc_function *sf0 = sc->sc_fn0;
195 u_int8_t rv;
196
197 if (sf->number == 0)
198 return 1;
199
200 rv = sdmmc_io_read_1(sf0, SD_IO_CCCR_FN_READY);
201 return (rv & (1 << sf->number)) != 0;
202 }
203
204
205
206
207
208 int
209 sdmmc_io_function_enable(struct sdmmc_function *sf)
210 {
211 struct sdmmc_softc *sc = sf->sc;
212 struct sdmmc_function *sf0 = sc->sc_fn0;
213 u_int8_t rv;
214 int retry = 5;
215
216 if (sf->number == 0)
217 return 0;
218
219 SDMMC_LOCK(sc);
220 rv = sdmmc_io_read_1(sf0, SD_IO_CCCR_FN_ENABLE);
221 rv |= (1<<sf->number);
222 sdmmc_io_write_1(sf0, SD_IO_CCCR_FN_ENABLE, rv);
223 SDMMC_UNLOCK(sc);
224
225 while (!sdmmc_io_function_ready(sf) && retry-- > 0)
226 tsleep(&lbolt, PPAUSE, "pause", 0);
227 return (retry >= 0) ? 0 : ETIMEDOUT;
228 }
229
230
231
232
233
234 void
235 sdmmc_io_function_disable(struct sdmmc_function *sf)
236 {
237 struct sdmmc_softc *sc = sf->sc;
238 struct sdmmc_function *sf0 = sc->sc_fn0;
239 u_int8_t rv;
240
241 if (sf->number == 0)
242 return;
243
244 SDMMC_LOCK(sc);
245 rv = sdmmc_io_read_1(sf0, SD_IO_CCCR_FN_ENABLE);
246 rv &= ~(1<<sf->number);
247 sdmmc_io_write_1(sf0, SD_IO_CCCR_FN_ENABLE, rv);
248 SDMMC_UNLOCK(sc);
249 }
250
251 void
252 sdmmc_io_attach(struct sdmmc_softc *sc)
253 {
254 struct sdmmc_function *sf;
255 struct sdmmc_attach_args saa;
256
257 SIMPLEQ_FOREACH(sf, &sc->sf_head, sf_list) {
258 if (sf->number < 1)
259 continue;
260
261 bzero(&saa, sizeof saa);
262 saa.sf = sf;
263
264 sf->child = config_found_sm(&sc->sc_dev, &saa, sdmmc_print,
265 sdmmc_submatch);
266 }
267 }
268
269 int
270 sdmmc_submatch(struct device *parent, void *match, void *aux)
271 {
272 struct cfdata *cf = match;
273
274
275 if (strcmp(cf->cf_driver->cd_name, "scsibus") == 0)
276 return 0;
277
278 return cf->cf_attach->ca_match(parent, cf, aux);
279 }
280
281 int
282 sdmmc_print(void *aux, const char *pnp)
283 {
284 struct sdmmc_attach_args *sa = aux;
285 struct sdmmc_function *sf = sa->sf;
286 struct sdmmc_cis *cis = &sf->sc->sc_fn0->cis;
287 int i;
288
289 if (pnp) {
290 if (sf->number == 0)
291 return QUIET;
292
293 for (i = 0; i < 4 && cis->cis1_info[i]; i++)
294 printf("%s%s", i ? ", " : "\"", cis->cis1_info[i]);
295 if (i != 0)
296 printf("\"");
297
298 if (cis->manufacturer != SDMMC_VENDOR_INVALID &&
299 cis->product != SDMMC_PRODUCT_INVALID) {
300 printf("%s(", i ? " " : "");
301 if (cis->manufacturer != SDMMC_VENDOR_INVALID)
302 printf("manufacturer 0x%x%s",
303 cis->manufacturer,
304 cis->product == SDMMC_PRODUCT_INVALID ?
305 "" : ", ");
306 if (cis->product != SDMMC_PRODUCT_INVALID)
307 printf("product 0x%x", cis->product);
308 printf(")");
309 }
310 printf("%sat %s", i ? " " : "", pnp);
311 }
312 printf(" function %d", sf->number);
313
314 if (!pnp) {
315 for (i = 0; i < 3 && cis->cis1_info[i]; i++)
316 printf("%s%s", i ? ", " : " \"", cis->cis1_info[i]);
317 if (i != 0)
318 printf("\"");
319 }
320 return UNCONF;
321 }
322
323 void
324 sdmmc_io_detach(struct sdmmc_softc *sc)
325 {
326 struct sdmmc_function *sf;
327
328 SIMPLEQ_FOREACH(sf, &sc->sf_head, sf_list) {
329 if (sf->child != NULL) {
330 config_detach(sf->child, DETACH_FORCE);
331 sf->child = NULL;
332 }
333 }
334
335 KASSERT(TAILQ_EMPTY(&sc->sc_intrq));
336 }
337
338 int
339 sdmmc_io_rw_direct(struct sdmmc_softc *sc, struct sdmmc_function *sf,
340 int reg, u_char *datap, int arg)
341 {
342 struct sdmmc_command cmd;
343 int error;
344
345 SDMMC_LOCK(sc);
346
347
348 if ((error = sdmmc_select_card(sc, sf)) != 0) {
349 SDMMC_UNLOCK(sc);
350 return error;
351 }
352
353 arg |= ((sf == NULL ? 0 : sf->number) & SD_ARG_CMD52_FUNC_MASK) <<
354 SD_ARG_CMD52_FUNC_SHIFT;
355 arg |= (reg & SD_ARG_CMD52_REG_MASK) <<
356 SD_ARG_CMD52_REG_SHIFT;
357 arg |= (*datap & SD_ARG_CMD52_DATA_MASK) <<
358 SD_ARG_CMD52_DATA_SHIFT;
359
360 bzero(&cmd, sizeof cmd);
361 cmd.c_opcode = SD_IO_RW_DIRECT;
362 cmd.c_arg = arg;
363 cmd.c_flags = SCF_CMD_AC | SCF_RSP_R5;
364
365 error = sdmmc_mmc_command(sc, &cmd);
366 *datap = SD_R5_DATA(cmd.c_resp);
367
368 SDMMC_UNLOCK(sc);
369 return error;
370 }
371
372
373
374
375
376
377
378 int
379 sdmmc_io_rw_extended(struct sdmmc_softc *sc, struct sdmmc_function *sf,
380 int reg, u_char *datap, int datalen, int arg)
381 {
382 struct sdmmc_command cmd;
383 int error;
384
385 SDMMC_LOCK(sc);
386
387 #if 0
388
389 if ((error = sdmmc_select_card(sc, sf)) != 0) {
390 SDMMC_UNLOCK(sc);
391 return error;
392 }
393 #endif
394
395 arg |= ((sf == NULL ? 0 : sf->number) & SD_ARG_CMD53_FUNC_MASK) <<
396 SD_ARG_CMD53_FUNC_SHIFT;
397 arg |= (reg & SD_ARG_CMD53_REG_MASK) <<
398 SD_ARG_CMD53_REG_SHIFT;
399 arg |= (datalen & SD_ARG_CMD53_LENGTH_MASK) <<
400 SD_ARG_CMD53_LENGTH_SHIFT;
401
402 bzero(&cmd, sizeof cmd);
403 cmd.c_opcode = SD_IO_RW_EXTENDED;
404 cmd.c_arg = arg;
405 cmd.c_flags = SCF_CMD_AC | SCF_RSP_R5;
406 cmd.c_data = datap;
407 cmd.c_datalen = datalen;
408 cmd.c_blklen = MIN(datalen, sdmmc_chip_host_maxblklen(sc->sct, sc->sch));
409
410 if (!ISSET(arg, SD_ARG_CMD53_WRITE))
411 cmd.c_flags |= SCF_CMD_READ;
412
413 error = sdmmc_mmc_command(sc, &cmd);
414 SDMMC_UNLOCK(sc);
415 return error;
416 }
417
418 u_int8_t
419 sdmmc_io_read_1(struct sdmmc_function *sf, int reg)
420 {
421 u_int8_t data = 0;
422
423 (void)sdmmc_io_rw_direct(sf->sc, sf, reg, (u_char *)&data,
424 SD_ARG_CMD52_READ);
425 return data;
426 }
427
428 void
429 sdmmc_io_write_1(struct sdmmc_function *sf, int reg, u_int8_t data)
430 {
431 (void)sdmmc_io_rw_direct(sf->sc, sf, reg, (u_char *)&data,
432 SD_ARG_CMD52_WRITE);
433 }
434
435 u_int16_t
436 sdmmc_io_read_2(struct sdmmc_function *sf, int reg)
437 {
438 u_int16_t data = 0;
439
440 (void)sdmmc_io_rw_extended(sf->sc, sf, reg, (u_char *)&data, 2,
441 SD_ARG_CMD53_READ | SD_ARG_CMD53_INCREMENT);
442 return data;
443 }
444
445 void
446 sdmmc_io_write_2(struct sdmmc_function *sf, int reg, u_int16_t data)
447 {
448 (void)sdmmc_io_rw_extended(sf->sc, sf, reg, (u_char *)&data, 2,
449 SD_ARG_CMD53_WRITE | SD_ARG_CMD53_INCREMENT);
450 }
451
452 u_int32_t
453 sdmmc_io_read_4(struct sdmmc_function *sf, int reg)
454 {
455 u_int32_t data = 0;
456
457 (void)sdmmc_io_rw_extended(sf->sc, sf, reg, (u_char *)&data, 4,
458 SD_ARG_CMD53_READ | SD_ARG_CMD53_INCREMENT);
459 return data;
460 }
461
462 void
463 sdmmc_io_write_4(struct sdmmc_function *sf, int reg, u_int32_t data)
464 {
465 (void)sdmmc_io_rw_extended(sf->sc, sf, reg, (u_char *)&data, 4,
466 SD_ARG_CMD53_WRITE | SD_ARG_CMD53_INCREMENT);
467 }
468
469 int
470 sdmmc_io_read_multi_1(struct sdmmc_function *sf, int reg, u_char *data,
471 int datalen)
472 {
473 int error;
474
475 while (datalen > SD_ARG_CMD53_LENGTH_MAX) {
476 error = sdmmc_io_rw_extended(sf->sc, sf, reg, data,
477 SD_ARG_CMD53_LENGTH_MAX, SD_ARG_CMD53_READ);
478 if (error)
479 return error;
480 data += SD_ARG_CMD53_LENGTH_MAX;
481 datalen -= SD_ARG_CMD53_LENGTH_MAX;
482 }
483
484 return sdmmc_io_rw_extended(sf->sc, sf, reg, data, datalen,
485 SD_ARG_CMD53_READ);
486 }
487
488 int
489 sdmmc_io_write_multi_1(struct sdmmc_function *sf, int reg, u_char *data,
490 int datalen)
491 {
492 int error;
493
494 while (datalen > SD_ARG_CMD53_LENGTH_MAX) {
495 error = sdmmc_io_rw_extended(sf->sc, sf, reg, data,
496 SD_ARG_CMD53_LENGTH_MAX, SD_ARG_CMD53_WRITE);
497 if (error)
498 return error;
499 data += SD_ARG_CMD53_LENGTH_MAX;
500 datalen -= SD_ARG_CMD53_LENGTH_MAX;
501 }
502
503 return sdmmc_io_rw_extended(sf->sc, sf, reg, data, datalen,
504 SD_ARG_CMD53_WRITE);
505 }
506
507 int
508 sdmmc_io_xchg(struct sdmmc_softc *sc, struct sdmmc_function *sf,
509 int reg, u_char *datap)
510 {
511 return sdmmc_io_rw_direct(sc, sf, reg, datap,
512 SD_ARG_CMD52_WRITE|SD_ARG_CMD52_EXCHANGE);
513 }
514
515
516
517
518 void
519 sdmmc_io_reset(struct sdmmc_softc *sc)
520 {
521 #if 0
522 (void)sdmmc_io_write(sc, NULL, SD_IO_REG_CCCR_CTL, CCCR_CTL_RES);
523 sdmmc_delay(100000);
524 #endif
525 }
526
527
528
529
530 int
531 sdmmc_io_send_op_cond(struct sdmmc_softc *sc, u_int32_t ocr, u_int32_t *ocrp)
532 {
533 struct sdmmc_command cmd;
534 int error;
535 int i;
536
537 SDMMC_LOCK(sc);
538
539
540
541
542
543
544 for (i = 0; i < 100; i++) {
545 bzero(&cmd, sizeof cmd);
546 cmd.c_opcode = SD_IO_SEND_OP_COND;
547 cmd.c_arg = ocr;
548 cmd.c_flags = SCF_CMD_BCR | SCF_RSP_R4;
549
550 error = sdmmc_mmc_command(sc, &cmd);
551 if (error != 0)
552 break;
553 if (ISSET(MMC_R4(cmd.c_resp), SD_IO_OCR_MEM_READY) ||
554 ocr == 0)
555 break;
556 error = ETIMEDOUT;
557 sdmmc_delay(10000);
558 }
559 if (error == 0 && ocrp != NULL)
560 *ocrp = MMC_R4(cmd.c_resp);
561
562 SDMMC_UNLOCK(sc);
563 return error;
564 }
565
566
567
568
569
570 void
571 sdmmc_intr_enable(struct sdmmc_function *sf)
572 {
573 struct sdmmc_softc *sc = sf->sc;
574 struct sdmmc_function *sf0 = sc->sc_fn0;
575 u_int8_t imask;
576
577 SDMMC_LOCK(sc);
578 imask = sdmmc_io_read_1(sf0, SD_IO_CCCR_INT_ENABLE);
579 imask |= 1 << sf->number;
580 sdmmc_io_write_1(sf0, SD_IO_CCCR_INT_ENABLE, imask);
581 SDMMC_UNLOCK(sc);
582 }
583
584 void
585 sdmmc_intr_disable(struct sdmmc_function *sf)
586 {
587 struct sdmmc_softc *sc = sf->sc;
588 struct sdmmc_function *sf0 = sc->sc_fn0;
589 u_int8_t imask;
590
591 SDMMC_LOCK(sc);
592 imask = sdmmc_io_read_1(sf0, SD_IO_CCCR_INT_ENABLE);
593 imask &= ~(1 << sf->number);
594 sdmmc_io_write_1(sf0, SD_IO_CCCR_INT_ENABLE, imask);
595 SDMMC_UNLOCK(sc);
596 }
597
598
599
600
601
602
603 void *
604 sdmmc_intr_establish(struct device *sdmmc, int (*fun)(void *),
605 void *arg, const char *name)
606 {
607 struct sdmmc_softc *sc = (struct sdmmc_softc *)sdmmc;
608 struct sdmmc_intr_handler *ih;
609 int s;
610
611 if (sc->sct->card_intr_mask == NULL)
612 return NULL;
613
614 ih = malloc(sizeof *ih, M_DEVBUF, M_WAITOK | M_CANFAIL);
615 if (ih == NULL)
616 return NULL;
617
618 bzero(ih, sizeof *ih);
619 ih->ih_name = malloc(strlen(name), M_DEVBUF, M_WAITOK | M_CANFAIL);
620 if (ih->ih_name == NULL) {
621 free(ih, M_DEVBUF);
622 return NULL;
623 }
624 strlcpy(ih->ih_name, name, strlen(name));
625 ih->ih_softc = sc;
626 ih->ih_fun = fun;
627 ih->ih_arg = arg;
628
629 s = splhigh();
630 if (TAILQ_EMPTY(&sc->sc_intrq)) {
631 sdmmc_intr_enable(sc->sc_fn0);
632 sdmmc_chip_card_intr_mask(sc->sct, sc->sch, 1);
633 }
634 TAILQ_INSERT_TAIL(&sc->sc_intrq, ih, entry);
635 splx(s);
636 return ih;
637 }
638
639
640
641
642 void
643 sdmmc_intr_disestablish(void *cookie)
644 {
645 struct sdmmc_intr_handler *ih = cookie;
646 struct sdmmc_softc *sc = ih->ih_softc;
647 int s;
648
649 if (sc->sct->card_intr_mask == NULL)
650 return;
651
652 s = splhigh();
653 TAILQ_REMOVE(&sc->sc_intrq, ih, entry);
654 if (TAILQ_EMPTY(&sc->sc_intrq)) {
655 sdmmc_chip_card_intr_mask(sc->sct, sc->sch, 0);
656 sdmmc_intr_disable(sc->sc_fn0);
657 }
658 splx(s);
659
660 free(ih->ih_name, M_DEVBUF);
661 free(ih, M_DEVBUF);
662 }
663
664
665
666
667
668
669 void
670 sdmmc_card_intr(struct device *sdmmc)
671 {
672 struct sdmmc_softc *sc = (struct sdmmc_softc *)sdmmc;
673
674 if (sc->sct->card_intr_mask == NULL)
675 return;
676
677 if (!sdmmc_task_pending(&sc->sc_intr_task))
678 sdmmc_add_task(sc, &sc->sc_intr_task);
679 }
680
681 void
682 sdmmc_intr_task(void *arg)
683 {
684 struct sdmmc_softc *sc = arg;
685 struct sdmmc_intr_handler *ih;
686 int s;
687
688 s = splhigh();
689 TAILQ_FOREACH(ih, &sc->sc_intrq, entry) {
690 splx(s);
691
692
693 (void)ih->ih_fun(ih->ih_arg);
694
695 s = splhigh();
696 }
697 sdmmc_chip_card_intr_ack(sc->sct, sc->sch);
698 splx(s);
699 }