Revert "misc cleanup"
[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("[EMMC:%s]: " fmt, __FUNCTION__, ##__VA_ARGS__);
66
67 #define kIdentSafeClockRate 0x148
68
69 struct BCM2708SDHost : BlockDevice {
70 bool is_sdhc;
71 bool is_high_capacity;
72 bool card_ready;
73
74 uint32_t ocr;
75 uint32_t rca;
76
77 uint32_t cid[4];
78 uint32_t csd[4];
79
80 uint32_t capacity_bytes;
81
82 uint32_t r[4];
83
84 uint32_t current_cmd;
85
86 void set_power(bool on) {
87 SH_VDD = on ? SH_VDD_POWER_ON_SET : 0x0;
88 }
89
90 bool wait(uint32_t timeout = 100000) {
91 uint32_t t = timeout;
92
93 while(SH_CMD & SH_CMD_NEW_FLAG_SET) {
94 if (t == 0) {
95 logf("timed out after %dus!\n", timeout)
96 return false;
97 }
98 t--;
99 udelay(10);
100 }
101
102 return true;
103 }
104
105 bool send_raw(uint32_t command, uint32_t arg = 0) {
106 uint32_t sts;
107
108 wait();
109
110 sts = SH_HSTS;
111 if (sts & SDHSTS_ERROR_MASK)
112 SH_HSTS = sts;
113
114 current_cmd = command & SH_CMD_COMMAND_SET;
115
116 SH_ARG = arg;
117 SH_CMD = command | SH_CMD_NEW_FLAG_SET;
118
119 mfence();
120
121 return true;
122 }
123
124 bool send(uint32_t command, uint32_t arg = 0) {
125 return send_raw(command & SH_CMD_COMMAND_SET, arg);
126 }
127
128 bool send_136_resp(uint32_t command, uint32_t arg = 0) {
129 return send_raw((command & SH_CMD_COMMAND_SET) | SH_CMD_LONG_RESPONSE_SET, arg);
130 }
131
132 bool send_no_resp(uint32_t command, uint32_t arg = 0) {
133 return send_raw((command & SH_CMD_COMMAND_SET) | SH_CMD_NO_RESPONSE_SET, arg);
134 }
135
136 void configure_pinmux() {
137 GP_FSEL4 = 0x24000000;
138 GP_FSEL5 = 0x924;
139
140 logf("waiting for pinmux pull update ...\n");
141
142 GP_PUD = 2;
143 mfence();
144 udelay(500);
145 GP_PUD = 0;
146
147 logf("waiting for pinmux clock update ...\n");
148
149 /* are these in bank 1 or 2? ah who gives a fuck ... */
150 GP_PUDCLK1 = GP_PUDCLK1_PUDCLKn32_SET;
151 GP_PUDCLK2 = GP_PUDCLK2_PUDCLKn64_SET;
152 udelay(500);
153
154 logf("ok ...\n");
155 GP_PUDCLK1 = 0;
156 GP_PUDCLK2 = 0;
157
158 logf("pinmux configured for aux0\n");
159 }
160
161 void reset() {
162 logf("resetting controller ...\n");
163 set_power(false);
164
165 SH_CMD = 0;
166 SH_ARG = 0;
167 SH_TOUT = 0xF00000;
168 SH_CDIV = 0;
169 SH_HSTS = 0x7f8;
170 SH_HCFG = 0;
171 SH_HBCT = 0;
172 SH_HBLC = 0;
173
174 uint32_t temp = SH_EDM;
175
176 temp &= ~((SDEDM_THRESHOLD_MASK<<SDEDM_READ_THRESHOLD_SHIFT) |
177 (SDEDM_THRESHOLD_MASK<<SDEDM_WRITE_THRESHOLD_SHIFT));
178 temp |= (SAFE_READ_THRESHOLD << SDEDM_READ_THRESHOLD_SHIFT) |
179 (SAFE_WRITE_THRESHOLD << SDEDM_WRITE_THRESHOLD_SHIFT);
180
181 SH_EDM = temp;
182 udelay(300);
183
184 set_power(true);
185
186 udelay(300);
187 mfence();
188 }
189
190 inline void get_response() {
191 r[0] = SH_RSP0;
192 r[1] = SH_RSP1;
193 r[2] = SH_RSP2;
194 r[3] = SH_RSP3;
195 }
196
197 bool wait_and_get_response() {
198 if (!wait())
199 return false;
200
201 get_response();
202
203 //printf("Cmd: 0x%x Resp: %08x %08x %08x %08x\n", current_cmd, r[0], r[1], r[2], r[3]);
204
205 if (SH_CMD & SH_CMD_FAIL_FLAG_SET) {
206 if (SH_HSTS & SDHSTS_ERROR_MASK) {
207 logf("ERROR: sdhost status: 0x%x\n", SH_HSTS);
208 return false;
209 }
210 logf("ERROR: unknown error, SH_CMD=0x%x\n", SH_CMD);
211 return false;
212 }
213
214
215 return true;
216 }
217
218 bool query_voltage_and_type() {
219 uint32_t t;
220
221 /* identify */
222 send(SD_SEND_IF_COND, 0x1AA);
223 wait_and_get_response();
224
225 /* set voltage */
226 t = MMC_OCR_3_3V_3_4V;
227 if (r[0] == 0x1AA) {
228 t |= MMC_OCR_HCS;
229 is_sdhc = true;
230 }
231
232 /* query voltage and type */
233 for (;;) {
234 send(MMC_APP_CMD); /* 55 */
235 send_no_resp(SD_APP_OP_COND, t);
236
237 if (!wait_and_get_response())
238 return false;
239
240 if (r[0] & MMC_OCR_MEM_READY)
241 break;
242
243 logf("waiting for SD (0x%x) ...\n", r[0]);
244 udelay(100);
245 }
246
247 logf("SD card has arrived!\n", r);
248
249 is_high_capacity = (r[0] & MMC_OCR_HCS) == MMC_OCR_HCS;
250
251 if (is_high_capacity)
252 logf("This is an SDHC card!\n");
253
254 return true;
255
256 }
257
258 inline void copy_136_to(uint32_t* dest) {
259 dest[0] = r[0];
260 dest[1] = r[1];
261 dest[2] = r[2];
262 dest[3] = r[3];
263 }
264
265 bool identify_card() {
266 logf("identifying card ...\n");
267
268 send_136_resp(MMC_ALL_SEND_CID);
269 if (!wait_and_get_response())
270 return false;
271
272 /* for SD this gets RCA */
273 send(MMC_SET_RELATIVE_ADDR);
274 if (!wait_and_get_response())
275 return false;
276 rca = SD_R6_RCA(r);
277
278 logf("RCA = 0x%x\n", rca);
279
280 send_136_resp(MMC_SEND_CID, MMC_ARG_RCA(rca));
281 if (!wait_and_get_response())
282 return false;
283
284 copy_136_to(cid);
285
286 /* get card specific data */
287 send_136_resp(MMC_SEND_CSD, MMC_ARG_RCA(rca));
288 if (!wait_and_get_response())
289 return false;
290
291 copy_136_to(csd);
292
293 return true;
294 }
295
296 //#define DUMP_READ
297
298 bool wait_for_fifo_data(uint32_t timeout = 100000) {
299 uint32_t t = timeout;
300
301 while ((SH_HSTS & SH_HSTS_DATA_FLAG_SET) == 0) {
302 if (t == 0) {
303 putchar('\n');
304 logf("ERROR: no FIFO data, timed out after %dus!\n", timeout)
305 return false;
306 }
307 t--;
308 udelay(10);
309 }
310
311 return true;
312 }
313
314 void drain_fifo() {
315 /* fuck me with a rake ... gently */
316
317 wait();
318
319 while (SH_HSTS & SH_HSTS_DATA_FLAG_SET) {
320 SH_DATA;
321 mfence();
322 }
323 }
324
325 void drain_fifo_nowait() {
326 while (true) {
327 SH_DATA;
328
329 uint32_t hsts = SH_HSTS;
330 if (hsts != SH_HSTS_DATA_FLAG_SET)
331 break;
332 }
333 }
334
335 virtual bool read_block(uint32_t sector, uint32_t* buf) override {
336 if (!card_ready)
337 panic("card not ready");
338
339 if (!is_high_capacity)
340 sector <<= 9;
341
342 /* drain junk from FIFO */
343 drain_fifo();
344
345 /* enter READ mode */
346 send_raw(MMC_READ_BLOCK_MULTIPLE | SH_CMD_READ_CMD_SET, sector);
347
348 int i;
349 uint32_t hsts_err = 0;
350
351 #ifdef DUMP_READ
352 if (buf)
353 logf("Reading %d bytes from sector %d using FIFO ...\n", block_size, sector);
354 #endif
355
356 #ifdef DUMP_READ
357 if (buf)
358 printf("----------------------------------------------------\n");
359 #endif
360
361 /* drain useful data from FIFO */
362 for (i = 0; i < 128; i++) {
363 /* wait for FIFO */
364 if (!wait_for_fifo_data()) {
365 break;
366 }
367
368 uint32_t hsts_err = SH_HSTS & SDHSTS_ERROR_MASK;
369 if (hsts_err) {
370 logf("ERROR: transfer error on FIFO word %d: 0x%x\n", i, SH_HSTS);
371 break;
372 }
373
374
375 volatile uint32_t data = SH_DATA;
376
377 #ifdef DUMP_READ
378 printf("%08x ", data);
379 #endif
380 if (buf)
381 *(buf++) = data;
382 }
383
384 send_raw(MMC_STOP_TRANSMISSION | SH_CMD_BUSY_CMD_SET);
385
386 #ifdef DUMP_READ
387 if (buf)
388 printf("\n----------------------------------------------------\n");
389 #endif
390
391 if (hsts_err) {
392 logf("ERROR: Transfer error, status: 0x%x\n", SH_HSTS);
393 return false;
394 }
395
396 #ifdef DUMP_READ
397 if (buf)
398 logf("Completed read for %d\n", sector);
399 #endif
400 return true;
401 }
402
403
404
405 bool select_card() {
406 send(MMC_SELECT_CARD, MMC_ARG_RCA(rca));
407
408 if (!wait())
409 return false;
410
411 return true;
412 }
413
414 bool init_card() {
415 char pnm[8];
416 uint32_t block_length;
417 uint32_t clock_div = 0;
418
419 send_no_resp(MMC_GO_IDLE_STATE);
420
421 if (!query_voltage_and_type()) {
422 logf("ERROR: Failed to query card voltage!\n");
423 return false;
424 }
425
426 if (!identify_card()) {
427 logf("ERROR: Failed to identify card!\n");
428 return false;
429 }
430
431 SD_CID_PNM_CPY(cid, pnm);
432
433 logf("Detected SD card:\n");
434 printf(" Product : %s\n", &pnm);
435
436 if (SD_CSD_CSDVER(csd) == SD_CSD_CSDVER_2_0) {
437 printf(" CSD : Ver 2.0\n");
438 printf(" Capacity: %d\n", SD_CSD_V2_CAPACITY(csd));
439 printf(" Size : %d\n", SD_CSD_V2_C_SIZE(csd));
440
441 block_length = 1 << SD_CSD_V2_BL_LEN;
442
443 /* work out the capacity of the card in bytes */
444 capacity_bytes = (SD_CSD_V2_CAPACITY(csd) * block_length);
445
446 clock_div = 5;
447 } else if (SD_CSD_CSDVER(csd) == SD_CSD_CSDVER_1_0) {
448 printf(" CSD : Ver 1.0\n");
449 printf(" Capacity: %d\n", SD_CSD_CAPACITY(csd));
450 printf(" Size : %d\n", SD_CSD_C_SIZE(csd));
451
452 block_length = 1 << SD_CSD_READ_BL_LEN(csd);
453
454 /* work out the capacity of the card in bytes */
455 capacity_bytes = (SD_CSD_CAPACITY(csd) * block_length);
456
457 clock_div = 10;
458 } else {
459 printf("ERROR: Unknown CSD version 0x%x!\n", SD_CSD_CSDVER(csd));
460 return false;
461 }
462
463 printf(" BlockLen: 0x%x\n", block_length);
464
465 if (!select_card()) {
466 logf("ERROR: Failed to select card!\n");
467 return false;
468 }
469
470 if (SD_CSD_CSDVER(csd) == SD_CSD_CSDVER_1_0) {
471 /*
472 * only needed for 1.0 ones, the 2.0 ones have this
473 * fixed at 512.
474 */
475 logf("Setting block length to 512 ...\n");
476 send(MMC_SET_BLOCKLEN, 512);
477 if (!wait()) {
478 logf("ERROR: Failed to set block length!\n");
479 return false;
480 }
481 }
482
483 block_size = 512;
484
485 logf("Card initialization complete: %s %dMB SD%s Card\n", &pnm, capacity_bytes >> 20, is_high_capacity ? "HC" : "");
486
487 /*
488 * this makes some dangerous assumptions that the all csd2 cards are sdio cards
489 * and all csd1 cards are sd cards and that mmc cards won't be used. this also assumes
490 * PLLC.CORE0 is at 250MHz which is probably a safe assumption since we set it.
491 */
492 if (clock_div) {
493 logf("Identification complete, changing clock to %dMHz for data mode ...\n", 250 / clock_div);
494 SH_CDIV = clock_div - 2;
495 }
496
497 return true;
498 }
499
500 void restart_controller() {
501 is_sdhc = false;
502
503 logf("hcfg 0x%X, cdiv 0x%X, edm 0x%X, hsts 0x%X\n",
504 SH_HCFG,
505 SH_CDIV,
506 SH_EDM,
507 SH_HSTS);
508
509 logf("Restarting the eMMC controller ...\n");
510
511 configure_pinmux();
512 reset();
513
514 SH_HCFG &= ~SH_HCFG_WIDE_EXT_BUS_SET;
515 SH_HCFG = SH_HCFG_SLOW_CARD_SET | SH_HCFG_WIDE_INT_BUS_SET;
516 SH_CDIV = kIdentSafeClockRate;
517
518 udelay(300);
519 mfence();
520
521 if (init_card()) {
522 card_ready = true;
523
524 /*
525 * looks like a silicon bug to me or a quirk of csd2, who knows
526 */
527 for (int i = 0; i < 3; i++) {
528 if (!read_block(0, nullptr)) {
529 panic("fifo flush cycle %d failed", i);
530 }
531 }
532 } else {
533 panic("failed to reinitialize the eMMC controller");
534 }
535 }
536
537 virtual void stop() override {
538 if (card_ready) {
539 logf("flushing fifo ...\n");
540 drain_fifo_nowait();
541
542 logf("asking card to enter idle state ...\n");
543 SH_CDIV = kIdentSafeClockRate;
544 udelay(150);
545
546 send_no_resp(MMC_GO_IDLE_STATE);
547 udelay(500);
548 }
549
550 logf("stopping sdhost controller driver ...\n");
551
552 SH_CMD = 0;
553 SH_ARG = 0;
554 SH_TOUT = 0xA00000;
555 SH_CDIV = 0x1FB;
556
557 logf("powering down controller ...\n");
558 SH_VDD = 0;
559 SH_HCFG = 0;
560 SH_HBCT = 0x400;
561 SH_HBLC = 0;
562 SH_HSTS = 0x7F8;
563
564 logf("resetting state machine ...\n");
565
566 SH_CMD = 0;
567 SH_ARG = 0;
568 }
569
570 BCM2708SDHost() {
571 restart_controller();
572 logf("eMMC driver sucessfully started!\n");
573 }
574 };
575
576 BCM2708SDHost STATIC_DRIVER g_SDHostDriver {};
577
578 BlockDevice* get_sdhost_device() {
579 return &g_SDHostDriver;
580 }
This page took 0.145147 seconds and 4 git commands to generate.