Moved author names into a master AUTHORS file.
[rpi-open-firmware.git] / arm_chainloader / drivers / sdhost_impl.cc
1 /*=============================================================================
2 Copyright (C) 2016-2017 Authors of rpi-open-firmware
3 All rights reserved.
4
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 FILE DESCRIPTION
16 SDHOST driver. This used to be known as ALTMMC.
17
18 =============================================================================*/
19
20 #include <chainloader.h>
21 #include <hardware.h>
22
23 #include "sd_proto.hpp"
24 #include "block_device.hpp"
25
26 #define SDEDM_WRITE_THRESHOLD_SHIFT 9
27 #define SDEDM_READ_THRESHOLD_SHIFT 14
28 #define SDEDM_THRESHOLD_MASK 0x1f
29
30 #define SAFE_READ_THRESHOLD 4
31 #define SAFE_WRITE_THRESHOLD 4
32
33 #define VOLTAGE_SUPPLY_RANGE 0x100
34 #define CHECK_PATTERN 0x55
35
36 #define SDHSTS_BUSY_IRPT 0x400
37 #define SDHSTS_BLOCK_IRPT 0x200
38 #define SDHSTS_SDIO_IRPT 0x100
39 #define SDHSTS_REW_TIME_OUT 0x80
40 #define SDHSTS_CMD_TIME_OUT 0x40
41 #define SDHSTS_CRC16_ERROR 0x20
42 #define SDHSTS_CRC7_ERROR 0x10
43 #define SDHSTS_FIFO_ERROR 0x08
44
45 #define SDEDM_FSM_MASK 0xf
46 #define SDEDM_FSM_IDENTMODE 0x0
47 #define SDEDM_FSM_DATAMODE 0x1
48 #define SDEDM_FSM_READDATA 0x2
49 #define SDEDM_FSM_WRITEDATA 0x3
50 #define SDEDM_FSM_READWAIT 0x4
51 #define SDEDM_FSM_READCRC 0x5
52 #define SDEDM_FSM_WRITECRC 0x6
53 #define SDEDM_FSM_WRITEWAIT1 0x7
54 #define SDEDM_FSM_POWERDOWN 0x8
55 #define SDEDM_FSM_POWERUP 0x9
56 #define SDEDM_FSM_WRITESTART1 0xa
57 #define SDEDM_FSM_WRITESTART2 0xb
58 #define SDEDM_FSM_GENPULSES 0xc
59 #define SDEDM_FSM_WRITEWAIT2 0xd
60 #define SDEDM_FSM_STARTPOWDOWN 0xf
61
62 #define SDHSTS_TRANSFER_ERROR_MASK (SDHSTS_CRC7_ERROR|SDHSTS_CRC16_ERROR|SDHSTS_REW_TIME_OUT|SDHSTS_FIFO_ERROR)
63 #define SDHSTS_ERROR_MASK (SDHSTS_CMD_TIME_OUT|SDHSTS_TRANSFER_ERROR_MASK)
64
65 #define logf(fmt, ...) printf("[GPIO:%s]: " fmt, __FUNCTION__, ##__VA_ARGS__);
66
67 enum BCM2708PinmuxSetting {
68 kBCM2708PinmuxIn = 0,
69 kBCM2708PinmuxOut = 1,
70 kBCM2708Pinmux_ALT5 = 2,
71 kBCM2708Pinmux_ALT4 = 3,
72 kBCM2708Pinmux_ALT0 = 4,
73 kBCM2708Pinmux_ALT1 = 5,
74 kBCM2708Pinmux_ALT2 = 6,
75 kBCM2708Pinmux_ALT3 = 7
76 };
77
78 struct BCM2708GPIO {
79
80 static void set(uint32_t pin_num, BCM2708PinmuxSetting setting) {
81 uint32_t* fsel = reinterpret_cast<uint32_t*>(
82 reinterpret_cast<uint32_t>(&GP_FSEL0) + (0x4 * (pin_num/10))
83 );
84 uint32_t pin_shift = (pin_num % 10) * 3;
85
86
87
88 }
89 };
90
91 #undef logf
92 #define logf(fmt, ...) printf("[EMMC:%s]: " fmt, __FUNCTION__, ##__VA_ARGS__);
93
94 #define kIdentSafeClockRate 0x148
95
96 struct BCM2708SDHost : BlockDevice {
97 bool is_sdhc;
98 bool is_high_capacity;
99 bool card_ready;
100
101 uint32_t ocr;
102 uint32_t rca;
103
104 uint32_t cid[4];
105 uint32_t csd[4];
106
107 uint32_t capacity_bytes;
108
109 uint32_t r[4];
110
111 uint32_t current_cmd;
112
113 void set_power(bool on) {
114 SH_VDD = on ? SH_VDD_POWER_ON_SET : 0x0;
115 }
116
117 bool wait(uint32_t timeout = 100000) {
118 uint32_t t = timeout;
119
120 while(SH_CMD & SH_CMD_NEW_FLAG_SET) {
121 if (t == 0) {
122 logf("timed out after %dus!\n", timeout)
123 return false;
124 }
125 t--;
126 udelay(10);
127 }
128
129 return true;
130 }
131
132 bool send_raw(uint32_t command, uint32_t arg = 0) {
133 uint32_t sts;
134
135 wait();
136
137 sts = SH_HSTS;
138 if (sts & SDHSTS_ERROR_MASK)
139 SH_HSTS = sts;
140
141 current_cmd = command & SH_CMD_COMMAND_SET;
142
143 SH_ARG = arg;
144 SH_CMD = command | SH_CMD_NEW_FLAG_SET;
145
146 mfence();
147
148 return true;
149 }
150
151 bool send(uint32_t command, uint32_t arg = 0) {
152 return send_raw(command & SH_CMD_COMMAND_SET, arg);
153 }
154
155 bool send_136_resp(uint32_t command, uint32_t arg = 0) {
156 return send_raw((command & SH_CMD_COMMAND_SET) | SH_CMD_LONG_RESPONSE_SET, arg);
157 }
158
159 bool send_no_resp(uint32_t command, uint32_t arg = 0) {
160 return send_raw((command & SH_CMD_COMMAND_SET) | SH_CMD_NO_RESPONSE_SET, arg);
161 }
162
163 void configure_pinmux() {
164 GP_FSEL4 = 0x24000000;
165 GP_FSEL5 = 0x924;
166
167 logf("waiting for pinmux pull update ...\n");
168
169 GP_PUD = 2;
170 mfence();
171 udelay(500);
172 GP_PUD = 0;
173
174 logf("waiting for pinmux clock update ...\n");
175
176 /* are these in bank 1 or 2? ah who gives a fuck ... */
177 GP_PUDCLK1 = GP_PUDCLK1_PUDCLKn32_SET;
178 GP_PUDCLK2 = GP_PUDCLK2_PUDCLKn64_SET;
179 udelay(500);
180
181 logf("ok ...\n");
182 GP_PUDCLK1 = 0;
183 GP_PUDCLK2 = 0;
184
185 logf("pinmux configured for aux0\n");
186 }
187
188 void reset() {
189 logf("resetting controller ...\n");
190 set_power(false);
191
192 SH_CMD = 0;
193 SH_ARG = 0;
194 SH_TOUT = 0xF00000;
195 SH_CDIV = 0;
196 SH_HSTS = 0x7f8;
197 SH_HCFG = 0;
198 SH_HBCT = 0;
199 SH_HBLC = 0;
200
201 uint32_t temp = SH_EDM;
202
203 temp &= ~((SDEDM_THRESHOLD_MASK<<SDEDM_READ_THRESHOLD_SHIFT) |
204 (SDEDM_THRESHOLD_MASK<<SDEDM_WRITE_THRESHOLD_SHIFT));
205 temp |= (SAFE_READ_THRESHOLD << SDEDM_READ_THRESHOLD_SHIFT) |
206 (SAFE_WRITE_THRESHOLD << SDEDM_WRITE_THRESHOLD_SHIFT);
207
208 SH_EDM = temp;
209 udelay(300);
210
211 set_power(true);
212
213 udelay(300);
214 mfence();
215 }
216
217 inline void get_response() {
218 r[0] = SH_RSP0;
219 r[1] = SH_RSP1;
220 r[2] = SH_RSP2;
221 r[3] = SH_RSP3;
222 }
223
224 bool wait_and_get_response() {
225 if (!wait())
226 return false;
227
228 get_response();
229
230 //printf("Cmd: 0x%x Resp: %08x %08x %08x %08x\n", current_cmd, r[0], r[1], r[2], r[3]);
231
232 if (SH_CMD & SH_CMD_FAIL_FLAG_SET) {
233 if (SH_HSTS & SDHSTS_ERROR_MASK) {
234 logf("ERROR: sdhost status: 0x%x\n", SH_HSTS);
235 return false;
236 }
237 logf("ERROR: unknown error, SH_CMD=0x%x\n", SH_CMD);
238 return false;
239 }
240
241
242 return true;
243 }
244
245 bool query_voltage_and_type() {
246 uint32_t t;
247
248 /* identify */
249 send(SD_SEND_IF_COND, 0x1AA);
250 wait_and_get_response();
251
252 /* set voltage */
253 t = MMC_OCR_3_3V_3_4V;
254 if (r[0] == 0x1AA) {
255 t |= MMC_OCR_HCS;
256 is_sdhc = true;
257 }
258
259 /* query voltage and type */
260 for (;;) {
261 send(MMC_APP_CMD); /* 55 */
262 send_no_resp(SD_APP_OP_COND, t);
263
264 if (!wait_and_get_response())
265 return false;
266
267 if (r[0] & MMC_OCR_MEM_READY)
268 break;
269
270 logf("waiting for SD (0x%x) ...\n", r[0]);
271 udelay(100);
272 }
273
274 logf("SD card has arrived!\n", r);
275
276 is_high_capacity = (r[0] & MMC_OCR_HCS) == MMC_OCR_HCS;
277
278 if (is_high_capacity)
279 logf("This is an SDHC card!\n");
280
281 return true;
282
283 }
284
285 inline void copy_136_to(uint32_t* dest) {
286 dest[0] = r[0];
287 dest[1] = r[1];
288 dest[2] = r[2];
289 dest[3] = r[3];
290 }
291
292 bool identify_card() {
293 logf("identifying card ...\n");
294
295 send_136_resp(MMC_ALL_SEND_CID);
296 if (!wait_and_get_response())
297 return false;
298
299 /* for SD this gets RCA */
300 send(MMC_SET_RELATIVE_ADDR);
301 if (!wait_and_get_response())
302 return false;
303 rca = SD_R6_RCA(r);
304
305 logf("RCA = 0x%x\n", rca);
306
307 send_136_resp(MMC_SEND_CID, MMC_ARG_RCA(rca));
308 if (!wait_and_get_response())
309 return false;
310
311 copy_136_to(cid);
312
313 /* get card specific data */
314 send_136_resp(MMC_SEND_CSD, MMC_ARG_RCA(rca));
315 if (!wait_and_get_response())
316 return false;
317
318 copy_136_to(csd);
319
320 return true;
321 }
322
323 //#define DUMP_READ
324
325 bool wait_for_fifo_data(uint32_t timeout = 100000) {
326 uint32_t t = timeout;
327
328 while ((SH_HSTS & SH_HSTS_DATA_FLAG_SET) == 0) {
329 if (t == 0) {
330 putchar('\n');
331 logf("ERROR: no FIFO data, timed out after %dus!\n", timeout)
332 return false;
333 }
334 t--;
335 udelay(10);
336 }
337
338 return true;
339 }
340
341 void drain_fifo() {
342 /* fuck me with a rake ... gently */
343
344 wait();
345
346 while (SH_HSTS & SH_HSTS_DATA_FLAG_SET) {
347 SH_DATA;
348 mfence();
349 }
350 }
351
352 void drain_fifo_nowait() {
353 while (true) {
354 SH_DATA;
355
356 uint32_t hsts = SH_HSTS;
357 if (hsts != SH_HSTS_DATA_FLAG_SET)
358 break;
359 }
360 }
361
362 virtual bool read_block(uint32_t sector, uint32_t* buf) override {
363 if (!card_ready)
364 panic("card not ready");
365
366 if (!is_high_capacity)
367 sector <<= 9;
368
369 /* drain junk from FIFO */
370 drain_fifo();
371
372 /* enter READ mode */
373 send_raw(MMC_READ_BLOCK_MULTIPLE | SH_CMD_READ_CMD_SET, sector);
374
375 int i;
376 uint32_t hsts_err = 0;
377
378 #ifdef DUMP_READ
379 if (buf)
380 logf("Reading %d bytes from sector %d using FIFO ...\n", block_size, sector);
381 #endif
382
383 #ifdef DUMP_READ
384 if (buf)
385 printf("----------------------------------------------------\n");
386 #endif
387
388 /* drain useful data from FIFO */
389 for (i = 0; i < 128; i++) {
390 /* wait for FIFO */
391 if (!wait_for_fifo_data()) {
392 break;
393 }
394
395 uint32_t hsts_err = SH_HSTS & SDHSTS_ERROR_MASK;
396 if (hsts_err) {
397 logf("ERROR: transfer error on FIFO word %d: 0x%x\n", i, SH_HSTS);
398 break;
399 }
400
401
402 volatile uint32_t data = SH_DATA;
403
404 #ifdef DUMP_READ
405 printf("%08x ", data);
406 #endif
407 if (buf)
408 *(buf++) = data;
409 }
410
411 send_raw(MMC_STOP_TRANSMISSION | SH_CMD_BUSY_CMD_SET);
412
413 #ifdef DUMP_READ
414 if (buf)
415 printf("\n----------------------------------------------------\n");
416 #endif
417
418 if (hsts_err) {
419 logf("ERROR: Transfer error, status: 0x%x\n", SH_HSTS);
420 return false;
421 }
422
423 #ifdef DUMP_READ
424 if (buf)
425 logf("Completed read for %d\n", sector);
426 #endif
427 return true;
428 }
429
430
431
432 bool select_card() {
433 send(MMC_SELECT_CARD, MMC_ARG_RCA(rca));
434
435 if (!wait())
436 return false;
437
438 return true;
439 }
440
441 bool init_card() {
442 char pnm[8];
443 uint32_t block_length;
444 uint32_t clock_div = 0;
445
446 send_no_resp(MMC_GO_IDLE_STATE);
447
448 if (!query_voltage_and_type()) {
449 logf("ERROR: Failed to query card voltage!\n");
450 return false;
451 }
452
453 if (!identify_card()) {
454 logf("ERROR: Failed to identify card!\n");
455 return false;
456 }
457
458 SD_CID_PNM_CPY(cid, pnm);
459
460 logf("Detected SD card:\n");
461 printf(" Product : %s\n", &pnm);
462
463 if (SD_CSD_CSDVER(csd) == SD_CSD_CSDVER_2_0) {
464 printf(" CSD : Ver 2.0\n");
465 printf(" Capacity: %d\n", SD_CSD_V2_CAPACITY(csd));
466 printf(" Size : %d\n", SD_CSD_V2_C_SIZE(csd));
467
468 block_length = 1 << SD_CSD_V2_BL_LEN;
469
470 /* work out the capacity of the card in bytes */
471 capacity_bytes = (SD_CSD_V2_CAPACITY(csd) * block_length);
472
473 clock_div = 5;
474 }
475 else if (SD_CSD_CSDVER(csd) == SD_CSD_CSDVER_1_0) {
476 printf(" CSD : Ver 1.0\n");
477 printf(" Capacity: %d\n", SD_CSD_CAPACITY(csd));
478 printf(" Size : %d\n", SD_CSD_C_SIZE(csd));
479
480 block_length = 1 << SD_CSD_READ_BL_LEN(csd);
481
482 /* work out the capacity of the card in bytes */
483 capacity_bytes = (SD_CSD_CAPACITY(csd) * block_length);
484
485 clock_div = 10;
486 }
487 else {
488 printf("ERROR: Unknown CSD version 0x%x!\n", SD_CSD_CSDVER(csd));
489 return false;
490 }
491
492 printf(" BlockLen: 0x%x\n", block_length);
493
494 if (!select_card()) {
495 logf("ERROR: Failed to select card!\n");
496 return false;
497 }
498
499 if (SD_CSD_CSDVER(csd) == SD_CSD_CSDVER_1_0) {
500 /*
501 * only needed for 1.0 ones, the 2.0 ones have this
502 * fixed at 512.
503 */
504 logf("Setting block length to 512 ...\n");
505 send(MMC_SET_BLOCKLEN, 512);
506 if (!wait()) {
507 logf("ERROR: Failed to set block length!\n");
508 return false;
509 }
510 }
511
512 block_size = 512;
513
514 logf("Card initialization complete: %s %dMB SD%s Card\n", &pnm, capacity_bytes >> 20, is_high_capacity ? "HC" : "");
515
516 /*
517 * this makes some dangerous assumptions that the all csd2 cards are sdio cards
518 * and all csd1 cards are sd cards and that mmc cards won't be used. this also assumes
519 * PLLC.CORE0 is at 250MHz which is probably a safe assumption since we set it.
520 */
521 if (clock_div) {
522 logf("Identification complete, changing clock to %dMHz for data mode ...\n", 250 / clock_div);
523 SH_CDIV = clock_div - 2;
524 }
525
526 return true;
527 }
528
529 void restart_controller() {
530 is_sdhc = false;
531
532 logf("hcfg 0x%X, cdiv 0x%X, edm 0x%X, hsts 0x%X\n",
533 SH_HCFG,
534 SH_CDIV,
535 SH_EDM,
536 SH_HSTS);
537
538 logf("Restarting the eMMC controller ...\n");
539
540 configure_pinmux();
541 reset();
542
543 SH_HCFG &= ~SH_HCFG_WIDE_EXT_BUS_SET;
544 SH_HCFG = SH_HCFG_SLOW_CARD_SET | SH_HCFG_WIDE_INT_BUS_SET;
545 SH_CDIV = kIdentSafeClockRate;
546
547 udelay(300);
548 mfence();
549
550 if (init_card()) {
551 card_ready = true;
552
553 /*
554 * looks like a silicon bug to me or a quirk of csd2, who knows
555 */
556 for (int i = 0; i < 3; i++) {
557 if (!read_block(0, nullptr)) {
558 panic("fifo flush cycle %d failed", i);
559 }
560 }
561 }
562 else {
563 panic("failed to reinitialize the eMMC controller");
564 }
565 }
566
567 virtual void stop() override {
568 if (card_ready) {
569 logf("flushing fifo ...\n");
570 drain_fifo_nowait();
571
572 logf("asking card to enter idle state ...\n");
573 SH_CDIV = kIdentSafeClockRate;
574 udelay(150);
575
576 send_no_resp(MMC_GO_IDLE_STATE);
577 udelay(500);
578 }
579
580 logf("stopping sdhost controller driver ...\n");
581
582 SH_CMD = 0;
583 SH_ARG = 0;
584 SH_TOUT = 0xA00000;
585 SH_CDIV = 0x1FB;
586
587 logf("powering down controller ...\n");
588 SH_VDD = 0;
589 SH_HCFG = 0;
590 SH_HBCT = 0x400;
591 SH_HBLC = 0;
592 SH_HSTS = 0x7F8;
593
594 logf("resetting state machine ...\n");
595
596 SH_CMD = 0;
597 SH_ARG = 0;
598 }
599
600 BCM2708SDHost() {
601 restart_controller();
602 logf("eMMC driver sucessfully started!\n");
603 }
604 };
605
606 BCM2708SDHost STATIC_DRIVER g_SDHostDriver {};
607
608 BlockDevice* get_sdhost_device() {
609 return &g_SDHostDriver;
610 }
This page took 0.134857 seconds and 4 git commands to generate.