Working SDHOST/FatFS, boot partition mounts, some other minor fixes too.
[rpi-open-firmware.git] / arm_chainloader / drivers / sdhost_impl.cc
1 /*=============================================================================
2 Copyright (C) 2016 Kristina Brooks
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 SDHSTS_TRANSFER_ERROR_MASK (SDHSTS_CRC7_ERROR|SDHSTS_CRC16_ERROR|SDHSTS_REW_TIME_OUT|SDHSTS_FIFO_ERROR)
46 #define SDHSTS_ERROR_MASK (SDHSTS_CMD_TIME_OUT|SDHSTS_TRANSFER_ERROR_MASK)
47
48 #define logf(fmt, ...) printf("[EMMC:%s]: " fmt, __FUNCTION__, ##__VA_ARGS__);
49
50 struct SdhostImpl : BlockDevice {
51 bool is_sdhc;
52 bool is_high_capacity;
53 bool card_ready;
54
55 uint32_t ocr;
56 uint32_t rca;
57
58 uint32_t cid[4];
59 uint32_t csd[4];
60
61 uint32_t capacity_bytes;
62
63 uint32_t r[4];
64
65 uint32_t current_cmd;
66
67 void set_power(bool on) {
68 SH_VDD = on ? SH_VDD_POWER_ON_SET : 0x0;
69 }
70
71 bool wait(uint32_t timeout = 100000) {
72 uint32_t t = timeout;
73
74 while(SH_CMD & SH_CMD_NEW_FLAG_SET) {
75 if (t == 0) {
76 logf("timed out after %dus!\n", timeout)
77 return false;
78 }
79 t--;
80 udelay(10);
81 }
82
83 return true;
84 }
85
86 bool send_raw(uint32_t command, uint32_t arg = 0) {
87 uint32_t sts;
88
89 wait();
90
91 sts = SH_HSTS;
92 if (sts & SDHSTS_ERROR_MASK)
93 SH_HSTS = sts;
94
95 current_cmd = command & SH_CMD_COMMAND_SET;
96
97 SH_ARG = arg;
98 SH_CMD = command | SH_CMD_NEW_FLAG_SET;
99
100 mfence();
101
102 return true;
103 }
104
105 bool send(uint32_t command, uint32_t arg = 0) {
106 return send_raw(command & SH_CMD_COMMAND_SET, arg);
107 }
108
109 bool send_136_resp(uint32_t command, uint32_t arg = 0) {
110 return send_raw((command & SH_CMD_COMMAND_SET) | SH_CMD_LONG_RESPONSE_SET, arg);
111 }
112
113 bool send_no_resp(uint32_t command, uint32_t arg = 0) {
114 return send_raw((command & SH_CMD_COMMAND_SET) | SH_CMD_NO_RESPONSE_SET, arg);
115 }
116
117 void configure_pinmux() {
118 GP_FSEL4 = 0x24000000;
119 GP_FSEL5 = 0x924;
120 GP_PUD = 2;
121
122 logf("GPIOs set!\n");
123
124 mfence();
125 }
126
127 void reset() {
128 logf("resetting controller ...\n");
129 set_power(false);
130
131 SH_CMD = 0;
132 SH_ARG = 0;
133 SH_TOUT = 0xF00000;
134 SH_CDIV = 0;
135 SH_HSTS = 0x7f8;
136 SH_HCFG = 0;
137 SH_HBCT = 0;
138 SH_HBLC = 0;
139
140 uint32_t temp = SH_EDM;
141
142 temp &= ~((SDEDM_THRESHOLD_MASK<<SDEDM_READ_THRESHOLD_SHIFT) |
143 (SDEDM_THRESHOLD_MASK<<SDEDM_WRITE_THRESHOLD_SHIFT));
144 temp |= (SAFE_READ_THRESHOLD << SDEDM_READ_THRESHOLD_SHIFT) |
145 (SAFE_WRITE_THRESHOLD << SDEDM_WRITE_THRESHOLD_SHIFT);
146
147 SH_EDM = temp;
148 udelay(300);
149
150 set_power(true);
151
152 udelay(300);
153 mfence();
154 }
155
156 inline void get_response() {
157 r[0] = SH_RSP0;
158 r[1] = SH_RSP1;
159 r[2] = SH_RSP2;
160 r[3] = SH_RSP3;
161 }
162
163 bool wait_and_get_response() {
164 if (!wait())
165 return false;
166
167 get_response();
168
169 //printf("Cmd: 0x%x Resp: %08x %08x %08x %08x\n", current_cmd, r[0], r[1], r[2], r[3]);
170
171 if (SH_CMD & SH_CMD_FAIL_FLAG_SET) {
172 if (SH_HSTS & SDHSTS_ERROR_MASK) {
173 logf("ERROR: sdhost status: 0x%x\n", SH_HSTS);
174 return false;
175 }
176 logf("ERROR: unknown error, SH_CMD=0x%x\n", SH_CMD);
177 return false;
178 }
179
180
181 return true;
182 }
183
184 bool query_voltage_and_type() {
185 uint32_t t;
186
187 /* identify */
188 send(SD_SEND_IF_COND, 0x1AA);
189 wait_and_get_response();
190
191 /* set voltage */
192 t = MMC_OCR_3_2V_3_3V;
193 if (r[0] == 0x1AA) {
194 t |= MMC_OCR_HCS;
195 is_sdhc = true;
196 }
197
198 /* query voltage and type */
199 for (;;) {
200 send(MMC_APP_CMD);
201 send(SD_APP_OP_COND, t);
202
203 if (!wait_and_get_response())
204 return false;
205
206 if (r[0] & MMC_OCR_MEM_READY)
207 break;
208
209 logf("waiting for SD (0x%x) ...\n", r[0]);
210 udelay(100);
211 }
212
213 logf("SD card has arrived!\n", r);
214
215 is_high_capacity = (r[0] & MMC_OCR_HCS) == MMC_OCR_HCS;
216
217 if (is_high_capacity)
218 logf("This is an SDHC card!\n");
219
220 return true;
221
222 }
223
224 inline void copy_136_to(uint32_t* dest) {
225 dest[0] = r[0];
226 dest[1] = r[1];
227 dest[2] = r[2];
228 dest[3] = r[3];
229 }
230
231 bool identify_card() {
232 logf("identifying card ...\n");
233
234 send_136_resp(MMC_ALL_SEND_CID);
235 if (!wait_and_get_response())
236 return false;
237
238 /* for SD this gets RCA */
239 send(MMC_SET_RELATIVE_ADDR);
240 if (!wait_and_get_response())
241 return false;
242 rca = SD_R6_RCA(r);
243
244 logf("RCA = 0x%x\n", rca);
245
246 send_136_resp(MMC_SEND_CID, MMC_ARG_RCA(rca));
247 if (!wait_and_get_response())
248 return false;
249
250 copy_136_to(cid);
251
252 /* get card specific data */
253 send_136_resp(MMC_SEND_CSD, MMC_ARG_RCA(rca));
254 if (!wait_and_get_response())
255 return false;
256
257 copy_136_to(csd);
258
259 return true;
260 }
261
262 inline bool wait_for_data_xfer() {
263 for (int i = 0; i < 1000; i++) {
264 if (SH_HSTS & SH_HSTS_DATA_FLAG_SET) {
265 SH_HSTS = SH_HSTS_DATA_FLAG_SET;
266 return true;
267 }
268 udelay(100);
269 }
270 return false;
271 }
272
273 //#define DUMP_READ
274
275 virtual bool read_block(uint32_t sector, uint32_t* buf) override {
276 if (!card_ready)
277 panic("card not ready");
278
279 #ifdef DUMP_READ
280 logf("Reading %d bytes from sector %d ...\n", block_size, sector);
281 #endif
282
283 if (!is_high_capacity)
284 sector <<= 9;
285
286 send_raw(MMC_READ_BLOCK_SINGLE | SH_CMD_READ_CMD_SET | SH_CMD_BUSY_CMD_SET, sector);
287 if (!wait()) {
288 return false;
289 }
290
291 uint32_t remaining = block_size;
292
293 #ifdef DUMP_READ
294 printf("----------------------------------------------------\n");
295 #endif
296
297 while (remaining) {
298 if (!wait_for_data_xfer()) {
299 #ifdef DUMP_READ
300 putchar('\n');
301 #endif
302 logf("ERROR: Timeout while reading block\n");
303 break;
304 }
305
306 *buf = SH_DATA;
307 #ifdef DUMP_READ
308 printf("%08x ", *buf);
309 #endif
310 buf++;
311 remaining -= 4;
312 }
313
314 #ifdef DUMP_READ
315 printf("\n----------------------------------------------------\n");
316 #endif
317
318 send(MMC_STOP_TRANSMISSION);
319
320 uint32_t sdhsts_errs = SH_HSTS & SDHSTS_ERROR_MASK;
321 if (sdhsts_errs) {
322 logf("ERROR: Transfer error, status: 0x%x\n", SH_HSTS);
323 }
324
325 if (remaining) {
326 logf("ERROR: Read failed, %d bytes left to copy\n", remaining);
327 return false;
328 }
329 else {
330 #ifdef DUMP_READ
331 logf("Completed read for %d\n", sector);
332 #endif
333 return true;
334 }
335 }
336
337 bool select_card() {
338 send(MMC_SELECT_CARD, MMC_ARG_RCA(rca));
339
340 if (!wait())
341 return false;
342
343 return true;
344 }
345
346 bool init_card() {
347 char pnm[8];
348 uint32_t block_length;
349
350 send_no_resp(MMC_GO_IDLE_STATE | SH_CMD_NO_RESPONSE_SET);
351
352 if (!query_voltage_and_type()) {
353 logf("ERROR: Failed to query card voltage!\n");
354 return false;
355 }
356
357 if (!identify_card()) {
358 logf("ERROR: Failed to identify card!\n");
359 return false;
360 }
361
362 SD_CID_PNM_CPY(cid, pnm);
363
364 logf("Detected SD card:\n");
365 printf(" Product : %s\n", &pnm);
366
367 if (SD_CSD_CSDVER(csd) == SD_CSD_CSDVER_2_0) {
368 printf(" CSD : Ver 2.0\n");
369 printf(" Capacity: %d\n", SD_CSD_V2_CAPACITY(csd));
370 printf(" Size : %d\n", SD_CSD_V2_C_SIZE(csd));
371
372 block_length = SD_CSD_V2_BL_LEN;
373 }
374 else if (SD_CSD_CSDVER(csd) == SD_CSD_CSDVER_1_0) {
375 printf(" CSD : Ver 1.0\n");
376 printf(" Capacity: %d\n", SD_CSD_CAPACITY(csd));
377 printf(" Size : %d\n", SD_CSD_C_SIZE(csd));
378
379 block_length = 1 << SD_CSD_READ_BL_LEN(csd);
380 }
381 else {
382 printf("ERROR: Unknown CSD version 0x%x!\n", SD_CSD_CSDVER(csd));
383
384
385 return false;
386 }
387
388 printf(" BlockLen: 0x%x\n", block_length);
389
390 /* work out the capacity of the card in bytes */
391 capacity_bytes = (SD_CSD_CAPACITY(csd) * block_length);
392
393 if (!select_card()) {
394 logf("ERROR: Failed to select card!\n");
395 return false;
396 }
397
398 if (SD_CSD_CSDVER(csd) == SD_CSD_CSDVER_1_0) {
399 /*
400 * only needed for 1.0 ones, the 2.0 ones have this
401 * fixed at 512.
402 */
403 logf("Setting block length to 512 ...\n");
404 send(MMC_SET_BLOCKLEN, 512);
405 if (!wait()) {
406 logf("ERROR: Failed to set block length!\n");
407 return false;
408 }
409 }
410
411 block_size = 512;
412
413 logf("Card iniitlization complete: %s %dMB SD%s Card\n", &pnm, capacity_bytes >> 20, is_high_capacity ? "HC" : "");
414
415 return true;
416 }
417
418 void restart_controller() {
419 is_sdhc = false;
420
421 logf("Restarting the eMMC controller ...\n");
422
423 configure_pinmux();
424 reset();
425
426 SH_HCFG &= ~SH_HCFG_WIDE_EXT_BUS_SET;
427 SH_HCFG = SH_HCFG_SLOW_CARD_SET | SH_HCFG_WIDE_INT_BUS_SET;
428 SH_CDIV = 0x96;
429
430 udelay(300);
431 mfence();
432
433 if (init_card()) {
434 card_ready = true;
435 }
436 else {
437 panic("failed to reinitialize the eMMC controller");
438 }
439 }
440
441 SdhostImpl() {
442 restart_controller();
443 logf("eMMC driver sucessfully started!\n");
444 }
445 };
446
447 SdhostImpl STATIC_DRIVER g_SDHostDriver {};
448
449 BlockDevice* get_sdhost_device() {
450 return &g_SDHostDriver;
451 }
This page took 0.12415 seconds and 4 git commands to generate.