blob: efcd6dbb0eb64328328e057aec77e5c085fc1817 [file] [log] [blame]
Ying-Chun Liu (PaulLiu)7eee8ef2019-01-30 04:17:32 +08001/*
2 * Copyright (c) 2019, Linaro Limited
3 * Copyright (c) 2019, Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8#include <arch.h>
9#include <arch_helpers.h>
10#include <assert.h>
11#include <common/debug.h>
12#include <lib/mmio.h>
13#include <drivers/delay_timer.h>
14#include <drivers/rpi3/sdhost/rpi3_sdhost.h>
15#include <drivers/mmc.h>
16#include <drivers/rpi3/gpio/rpi3_gpio.h>
17#include <errno.h>
18#include <string.h>
19
20static void rpi3_sdhost_initialize(void);
21static int rpi3_sdhost_send_cmd(struct mmc_cmd *cmd);
22static int rpi3_sdhost_set_ios(unsigned int clk, unsigned int width);
23static int rpi3_sdhost_prepare(int lba, uintptr_t buf, size_t size);
24static int rpi3_sdhost_read(int lba, uintptr_t buf, size_t size);
25static int rpi3_sdhost_write(int lba, uintptr_t buf, size_t size);
26
27static const struct mmc_ops rpi3_sdhost_ops = {
28 .init = rpi3_sdhost_initialize,
29 .send_cmd = rpi3_sdhost_send_cmd,
30 .set_ios = rpi3_sdhost_set_ios,
31 .prepare = rpi3_sdhost_prepare,
32 .read = rpi3_sdhost_read,
33 .write = rpi3_sdhost_write,
34};
35
36static struct rpi3_sdhost_params rpi3_sdhost_params;
37
38/**
39 * Wait for command being processed.
40 *
41 * This function waits the command being processed. It compares
42 * the ENABLE flag of the HC_COMMAND register. When ENABLE flag disappeared
43 * it means the command is processed by the SDHOST.
44 * The timeout is currently 1000*100 us = 100 ms.
45 *
46 * @return 0: command finished. 1: command timed out.
47 */
48static int rpi3_sdhost_waitcommand(void)
49{
50 uintptr_t reg_base = rpi3_sdhost_params.reg_base;
51
52 volatile int timeout = 1000;
53
54 while ((mmio_read_32(reg_base + HC_COMMAND) & HC_CMD_ENABLE)
55 && (--timeout > 0)) {
56 udelay(100);
57 }
58
59 return ((timeout > 0) ? 0 : (-(ETIMEDOUT)));
60}
61
62/**
63 * Send the command and argument to the SDHOST
64 *
65 * This function will wait for the previous command finished. And then
66 * clear any error status of previous command. And then
67 * send out the command and args. The command will be turned on the ENABLE
68 * flag before sending out.
69 */
70static void send_command_raw(unsigned int cmd, unsigned int arg)
71{
72 unsigned int status;
73 uintptr_t reg_base = rpi3_sdhost_params.reg_base;
74
75 /* wait for previous command finish */
76 rpi3_sdhost_waitcommand();
77
78 /* clean error status */
79 status = mmio_read_32(reg_base + HC_HOSTSTATUS);
80 if (status & HC_HSTST_MASK_ERROR_ALL)
81 mmio_write_32(reg_base + HC_HOSTSTATUS, status);
82
83 /* recording the command */
84 rpi3_sdhost_params.current_cmd = cmd & HC_CMD_COMMAND_MASK;
85
86 /* send the argument and command */
87 mmio_write_32(reg_base + HC_ARGUMENT, arg);
88 mmio_write_32(reg_base + HC_COMMAND, cmd | HC_CMD_ENABLE);
89}
90
91/**
92 * Send the command and argument to the SDHOST, decorated with control
93 * flags.
94 *
95 * This function will use send_command_raw to send the commands to SDHOST.
96 * But before sending it will decorate the command with control flags specific
97 * to SDHOST.
98 */
99static void send_command_decorated(unsigned int cmd, unsigned int arg)
100{
101 unsigned int cmd_flags = 0;
102
103 switch (cmd & HC_CMD_COMMAND_MASK) {
104 case MMC_CMD(0):
105 cmd_flags |= HC_CMD_RESPONSE_NONE;
106 break;
107 case MMC_ACMD(51):
108 cmd_flags |= HC_CMD_READ;
109 break;
110 case MMC_CMD(8):
111 case MMC_CMD(11):
112 case MMC_CMD(17):
113 case MMC_CMD(18):
114 cmd_flags |= HC_CMD_READ;
115 break;
116 case MMC_CMD(20):
117 case MMC_CMD(24):
118 case MMC_CMD(25):
119 cmd_flags |= HC_CMD_WRITE;
120 break;
121 case MMC_CMD(12):
122 cmd_flags |= HC_CMD_BUSY;
123 break;
124 default:
125 break;
126 }
127 send_command_raw(cmd | cmd_flags, arg);
128}
129
130/**
131 * drains the FIFO on DATA port
132 *
133 * This function drains any data left in the DATA port.
134 */
135static void rpi3_drain_fifo(void)
136{
137 uintptr_t reg_base = rpi3_sdhost_params.reg_base;
138 volatile int timeout = 100000;
139
140 rpi3_sdhost_waitcommand();
141
142 while (mmio_read_32(reg_base + HC_HOSTSTATUS) & HC_HSTST_HAVEDATA) {
143 mmio_read_32(reg_base + HC_DATAPORT);
144 udelay(100);
145 }
146
147 while (1) {
148 uint32_t edm, fsm;
149
150 edm = mmio_read_32(reg_base + HC_DEBUG);
151 fsm = edm & HC_DBG_FSM_MASK;
152
153 if ((fsm == HC_DBG_FSM_IDENTMODE) ||
154 (fsm == HC_DBG_FSM_DATAMODE))
155 break;
156
157 if ((fsm == HC_DBG_FSM_READWAIT) ||
158 (fsm == HC_DBG_FSM_WRITESTART1) ||
159 (fsm == HC_DBG_FSM_READDATA)) {
160 mmio_write_32(reg_base + HC_DEBUG,
161 edm | HC_DBG_FORCE_DATA_MODE);
162 break;
163 }
164
165 if (--timeout <= 0) {
166 ERROR("rpi3_sdhost: %s cannot recover stat\n",
167 __func__);
168 return;
169 }
170 }
171}
172
173/**
174 * Dump SDHOST registers
175 */
176static void rpi3_sdhost_print_regs(void)
177{
178 uintptr_t reg_base = rpi3_sdhost_params.reg_base;
179
180 INFO("rpi3_sdhost: HC_COMMAND: 0x%08x\n",
181 mmio_read_32(reg_base + HC_COMMAND));
182 INFO("rpi3_sdhost: HC_ARGUMENT: 0x%08x\n",
183 mmio_read_32(reg_base + HC_ARGUMENT));
184 INFO("rpi3_sdhost: HC_TIMEOUTCOUNTER: 0x%08x\n",
185 mmio_read_32(reg_base + HC_TIMEOUTCOUNTER));
186 INFO("rpi3_sdhost: HC_CLOCKDIVISOR: 0x%08x\n",
187 mmio_read_32(reg_base + HC_CLOCKDIVISOR));
188 INFO("rpi3_sdhost: HC_RESPONSE_0: 0x%08x\n",
189 mmio_read_32(reg_base + HC_RESPONSE_0));
190 INFO("rpi3_sdhost: HC_RESPONSE_1: 0x%08x\n",
191 mmio_read_32(reg_base + HC_RESPONSE_1));
192 INFO("rpi3_sdhost: HC_RESPONSE_2: 0x%08x\n",
193 mmio_read_32(reg_base + HC_RESPONSE_2));
194 INFO("rpi3_sdhost: HC_RESPONSE_3: 0x%08x\n",
195 mmio_read_32(reg_base + HC_RESPONSE_3));
196 INFO("rpi3_sdhost: HC_HOSTSTATUS: 0x%08x\n",
197 mmio_read_32(reg_base + HC_HOSTSTATUS));
198 INFO("rpi3_sdhost: HC_POWER: 0x%08x\n",
199 mmio_read_32(reg_base + HC_POWER));
200 INFO("rpi3_sdhost: HC_DEBUG: 0x%08x\n",
201 mmio_read_32(reg_base + HC_DEBUG));
202 INFO("rpi3_sdhost: HC_HOSTCONFIG: 0x%08x\n",
203 mmio_read_32(reg_base + HC_HOSTCONFIG));
204 INFO("rpi3_sdhost: HC_BLOCKSIZE: 0x%08x\n",
205 mmio_read_32(reg_base + HC_BLOCKSIZE));
206 INFO("rpi3_sdhost: HC_BLOCKCOUNT: 0x%08x\n",
207 mmio_read_32(reg_base + HC_BLOCKCOUNT));
208}
209
210/**
211 * Reset SDHOST
212 */
213static void rpi3_sdhost_reset(void)
214{
215 uintptr_t reg_base = rpi3_sdhost_params.reg_base;
216 unsigned int dbg;
217 uint32_t tmp1;
218
219 mmio_write_32(reg_base + HC_POWER, 0);
220 mmio_write_32(reg_base + HC_COMMAND, 0);
221 mmio_write_32(reg_base + HC_ARGUMENT, 0);
222
223 mmio_write_32(reg_base + HC_TIMEOUTCOUNTER, HC_TIMEOUT_DEFAULT);
224 mmio_write_32(reg_base + HC_CLOCKDIVISOR, 0);
225 mmio_write_32(reg_base + HC_HOSTSTATUS, HC_HSTST_RESET);
226 mmio_write_32(reg_base + HC_HOSTCONFIG, 0);
227 mmio_write_32(reg_base + HC_BLOCKSIZE, 0);
228 mmio_write_32(reg_base + HC_BLOCKCOUNT, 0);
229
230 dbg = mmio_read_32(reg_base + HC_DEBUG);
231 dbg &= ~((HC_DBG_FIFO_THRESH_MASK << HC_DBG_FIFO_THRESH_READ_SHIFT) |
232 (HC_DBG_FIFO_THRESH_MASK << HC_DBG_FIFO_THRESH_WRITE_SHIFT));
233 dbg |= (HC_FIFO_THRESH_READ << HC_DBG_FIFO_THRESH_READ_SHIFT) |
234 (HC_FIFO_THRESH_WRITE << HC_DBG_FIFO_THRESH_WRITE_SHIFT);
235 mmio_write_32(reg_base + HC_DEBUG, dbg);
236 mdelay(250);
237 mmio_write_32(reg_base + HC_POWER, 1);
238 mdelay(250);
239 rpi3_sdhost_params.clk_rate = 0;
240
241 mmio_write_32(reg_base + HC_CLOCKDIVISOR, HC_CLOCKDIVISOR_MAXVAL);
242 tmp1 = mmio_read_32(reg_base + HC_HOSTCONFIG);
243 mmio_write_32(reg_base + HC_HOSTCONFIG, tmp1 | HC_HSTCF_INT_BUSY);
244}
245
246static void rpi3_sdhost_initialize(void)
247{
248 uintptr_t reg_base = rpi3_sdhost_params.reg_base;
249
250 assert((rpi3_sdhost_params.reg_base & MMC_BLOCK_MASK) == 0);
251
252 rpi3_sdhost_reset();
253
254 mmio_write_32(reg_base + HC_CLOCKDIVISOR, HC_CLOCKDIVISOR_PREFERVAL);
255 udelay(300);
256}
257
258static int rpi3_sdhost_send_cmd(struct mmc_cmd *cmd)
259{
260 uintptr_t reg_base = rpi3_sdhost_params.reg_base;
261 int err = 0;
262 uint32_t cmd_idx;
263 uint32_t cmd_arg;
264 uint32_t cmd_flags = 0;
265 uint32_t intmask;
266
267 /* Wait for the command done */
268 err = rpi3_sdhost_waitcommand();
269 if (err != 0) {
270 WARN("previous command not done yet\n");
271 return err;
272 }
273
274 cmd_idx = cmd->cmd_idx & HC_CMD_COMMAND_MASK;
275 if (cmd_idx == MMC_CMD(17))
276 cmd_idx = MMC_CMD(18);
277
278 cmd_arg = cmd->cmd_arg;
279 if (cmd_idx == MMC_ACMD(51)) {
280 /* if previous cmd send to SDHOST is not MMC_CMD(55).
281 * It means this MMC_ACMD(51) is a resend.
282 * And we must also resend MMC_CMD(55) in this case
283 */
284 if (rpi3_sdhost_params.current_cmd != MMC_CMD(55)) {
285 send_command_decorated(
286 MMC_CMD(55),
287 rpi3_sdhost_params.sdcard_rca <<
288 RCA_SHIFT_OFFSET);
289 rpi3_sdhost_params.mmc_app_cmd = 1;
290 rpi3_sdhost_waitcommand();
291
292 /* Also we need to call prepare to clean the buffer */
293 rpi3_sdhost_prepare(0, (uintptr_t)NULL, 8);
294 }
295 }
296
297 /* We ignore MMC_CMD(12) sending from the TF-A's MMC driver
298 * because we send MMC_CMD(12) by ourselves.
299 */
300 if (cmd_idx == MMC_CMD(12))
301 return 0;
302
303 if ((cmd->resp_type & MMC_RSP_136) &&
304 (cmd->resp_type & MMC_RSP_BUSY)) {
305 ERROR("rpi3_sdhost: unsupported response type!\n");
306 return -(EOPNOTSUPP);
307 }
308
309 if (cmd->resp_type & MMC_RSP_48 && cmd->resp_type != MMC_RESPONSE_R2) {
310 /* 48-bit command
311 * We don't need to set any flags here because it is default.
312 */
313 } else if (cmd->resp_type & MMC_RSP_136) {
314 /* 136-bit command */
315 cmd_flags |= HC_CMD_RESPONSE_LONG;
316 } else {
317 /* no respond command */
318 cmd_flags |= HC_CMD_RESPONSE_NONE;
319 }
320
321 rpi3_sdhost_params.cmdbusy = 0;
322 if (cmd->resp_type & MMC_RSP_BUSY) {
323 cmd_flags |= HC_CMD_BUSY;
324 rpi3_sdhost_params.cmdbusy = 1;
325 }
326
327 if (rpi3_sdhost_params.mmc_app_cmd) {
328 switch (cmd_idx) {
329 case MMC_ACMD(41):
330 if (cmd_arg == OCR_HCS)
331 cmd_arg |= OCR_3_3_3_4;
332 break;
333 default:
334 break;
335 }
336 rpi3_sdhost_params.mmc_app_cmd = 0;
337 }
338
339 if (cmd_idx == MMC_CMD(55))
340 rpi3_sdhost_params.mmc_app_cmd = 1;
341
342 send_command_decorated(cmd_idx | cmd_flags, cmd_arg);
343
344 intmask = mmio_read_32(reg_base + HC_HOSTSTATUS);
345 if (rpi3_sdhost_params.cmdbusy && (intmask & HC_HSTST_INT_BUSY)) {
346 mmio_write_32(reg_base + HC_HOSTSTATUS, HC_HSTST_INT_BUSY);
347 rpi3_sdhost_params.cmdbusy = 0;
348 }
349
350 if (!(cmd_flags & HC_CMD_RESPONSE_NONE)) {
351 err = rpi3_sdhost_waitcommand();
352 if (err != 0)
353 ERROR("rpi3_sdhost: cmd cannot be finished\n");
354 }
355
356 cmd->resp_data[0] = mmio_read_32(reg_base + HC_RESPONSE_0);
357 cmd->resp_data[1] = mmio_read_32(reg_base + HC_RESPONSE_1);
358 cmd->resp_data[2] = mmio_read_32(reg_base + HC_RESPONSE_2);
359 cmd->resp_data[3] = mmio_read_32(reg_base + HC_RESPONSE_3);
360
361 if (mmio_read_32(reg_base + HC_COMMAND) & HC_CMD_FAILED) {
362 uint32_t sdhsts = mmio_read_32(reg_base + HC_HOSTSTATUS);
363
364 mmio_write_32(reg_base + HC_HOSTSTATUS,
365 HC_HSTST_MASK_ERROR_ALL);
366
367 if (!(sdhsts & HC_HSTST_ERROR_CRC7)
368 || (cmd_idx != MMC_ACMD(51))) {
369 if (sdhsts & HC_HSTST_TIMEOUT_CMD) {
370 ERROR("rpi3_sdhost: timeout status 0x%x\n",
371 sdhsts);
372 err = -(ETIMEDOUT);
373 } else {
374 ERROR("rpi3_sdhost: unknown err, cmd = 0x%x\n",
375 mmio_read_32(reg_base + HC_COMMAND));
376 ERROR("rpi3_sdhost status: 0x%x\n", sdhsts);
377 err = -(EILSEQ);
378 }
379 }
380 }
381
382 if ((!err) && (cmd_idx == MMC_CMD(3))) {
383 /* we keep the RCA in case to send MMC_CMD(55) ourselves */
384 rpi3_sdhost_params.sdcard_rca = (cmd->resp_data[0]
385 & 0xFFFF0000U) >> 16;
386 }
387
388 return err;
389}
390
391static int rpi3_sdhost_set_clock(unsigned int clk)
392{
393 uintptr_t reg_base = rpi3_sdhost_params.reg_base;
394 uint32_t max_clk = 250000000;
395 uint32_t div;
396
397 if (clk < 100000) {
398 mmio_write_32(reg_base + HC_CLOCKDIVISOR,
399 HC_CLOCKDIVISOR_MAXVAL);
400 return 0;
401 }
402
403 div = max_clk / clk;
404 if (div < 2)
405 div = 2;
406
407 if ((max_clk / div) > clk)
408 div++;
409
410 div -= 2;
411 if (div > HC_CLOCKDIVISOR_MAXVAL)
412 div = HC_CLOCKDIVISOR_MAXVAL;
413
414 rpi3_sdhost_params.clk_rate = max_clk / (div + 2);
415 rpi3_sdhost_params.ns_per_fifo_word = (1000000000 /
416 rpi3_sdhost_params.clk_rate)
417 * 8;
418
419 mmio_write_32(reg_base + HC_CLOCKDIVISOR, div);
420 return 0;
421}
422
423static int rpi3_sdhost_set_ios(unsigned int clk, unsigned int width)
424{
425 uintptr_t reg_base = rpi3_sdhost_params.reg_base;
426 uint32_t tmp1;
427
428 rpi3_sdhost_set_clock(clk);
429 VERBOSE("rpi3_sdhost: Changing clock to %dHz for data mode\n", clk);
430
431 if (width != MMC_BUS_WIDTH_4 && width != MMC_BUS_WIDTH_1) {
432 ERROR("rpi3_sdhost: width %d not supported\n", width);
433 return -(EOPNOTSUPP);
434 }
435 rpi3_sdhost_params.bus_width = width;
436
437 tmp1 = mmio_read_32(reg_base + HC_HOSTCONFIG);
438 tmp1 &= ~(HC_HSTCF_EXTBUS_4BIT);
439 if (rpi3_sdhost_params.bus_width == MMC_BUS_WIDTH_4)
440 tmp1 |= HC_HSTCF_EXTBUS_4BIT;
441
442 mmio_write_32(reg_base + HC_HOSTCONFIG, tmp1);
443 tmp1 = mmio_read_32(reg_base + HC_HOSTCONFIG);
444 mmio_write_32(reg_base + HC_HOSTCONFIG, tmp1 |
445 HC_HSTCF_SLOW_CARD | HC_HSTCF_INTBUS_WIDE);
446
447 return 0;
448}
449
450static int rpi3_sdhost_prepare(int lba, uintptr_t buf, size_t size)
451{
452 uintptr_t reg_base = rpi3_sdhost_params.reg_base;
453 size_t blocks;
454 size_t blocksize;
455
456 if (size < 512) {
457 blocksize = size;
458 blocks = 1;
459 } else {
460 blocksize = 512;
461 blocks = size / blocksize;
462 if (size % blocksize != 0)
463 blocks++;
464 }
465
466 rpi3_drain_fifo();
467
468 mmio_write_32(reg_base + HC_BLOCKSIZE, blocksize);
469 mmio_write_32(reg_base + HC_BLOCKCOUNT, blocks);
470 udelay(100);
471 return 0;
472}
473
474static int rpi3_sdhost_read(int lba, uintptr_t buf, size_t size)
475{
476 int err = 0;
477 uint32_t *buf1 = ((uint32_t *) buf);
478 uintptr_t reg_base = rpi3_sdhost_params.reg_base;
479 int timeout = 100000;
480 int remaining_words = 0;
481
482 for (int i = 0; i < size / 4; i++) {
483 volatile int t = timeout;
484 uint32_t hsts_err;
485
486 while ((mmio_read_32(reg_base + HC_HOSTSTATUS)
487 & HC_HSTST_HAVEDATA) == 0) {
488 if (t == 0) {
489 ERROR("rpi3_sdhost: fifo timeout after %dus\n",
490 timeout);
491 err = -(ETIMEDOUT);
492 break;
493 }
494 t--;
495 udelay(10);
496 }
497 if (t == 0)
498 break;
499
500 uint32_t data = mmio_read_32(reg_base + HC_DATAPORT);
501
502 hsts_err = mmio_read_32(reg_base + HC_HOSTSTATUS)
503 & HC_HSTST_MASK_ERROR_ALL;
504 if (hsts_err) {
505 ERROR("rpi3_sdhost: transfer FIFO word %d: 0x%x\n",
506 i,
507 mmio_read_32(reg_base + HC_HOSTSTATUS));
508 rpi3_sdhost_print_regs();
509
510 err = -(EILSEQ);
511
512 /* clean the error status */
513 mmio_write_32(reg_base + HC_HOSTSTATUS, hsts_err);
514 }
515
516 if (buf1)
517 buf1[i] = data;
518
519 /* speeding up if the remaining words are still a lot */
520 remaining_words = (mmio_read_32(reg_base + HC_DEBUG) >> 4)
521 & HC_DBG_FIFO_THRESH_MASK;
522 if (remaining_words >= 7)
523 continue;
524
525 /* delay. slowing down the read process */
526 udelay(100);
527 }
528
529 /* We decide to stop by ourselves.
530 * It is because MMC_CMD(18) -> MMC_CMD(13) -> MMC_CMD(12)
531 * doesn't work for RPi3 SDHost.
532 */
533 if (rpi3_sdhost_params.current_cmd == MMC_CMD(18))
534 send_command_decorated(MMC_CMD(12), 0);
535
536 if (err == -(EILSEQ)) {
537 const int max_retries = 20;
538 int r;
539
540 rpi3_sdhost_params.crc_err_retries++;
541 if (rpi3_sdhost_params.crc_err_retries < max_retries) {
542 /* retries if there's an CRC error */
543 r = rpi3_sdhost_prepare(lba, buf, size);
544 send_command_decorated(MMC_CMD(18), lba);
545 r = rpi3_sdhost_read(lba, buf, size);
546 if (r == 0)
547 err = 0;
548 }
549 }
550
551 return err;
552}
553
554static int rpi3_sdhost_write(int lba, uintptr_t buf, size_t size)
555{
556 uint32_t *buf1 = ((uint32_t *) buf);
557 uintptr_t reg_base = rpi3_sdhost_params.reg_base;
558 int err = 0;
559 int remaining_words = 0;
560
561 for (int i = 0; i < size / 4; i++) {
562 uint32_t hsts_err;
563 uint32_t data = buf1[i];
564 uint32_t dbg;
565 uint32_t fsm_state;
566
567 mmio_write_32(reg_base + HC_DATAPORT, data);
568
569 dbg = mmio_read_32(reg_base + HC_DEBUG);
570 fsm_state = dbg & HC_DBG_FSM_MASK;
571 if (fsm_state != HC_DBG_FSM_WRITEDATA
572 && fsm_state != HC_DBG_FSM_WRITESTART1
573 && fsm_state != HC_DBG_FSM_WRITESTART2
574 && fsm_state != HC_DBG_FSM_WRITECRC
575 && fsm_state != HC_DBG_FSM_WRITEWAIT1
576 && fsm_state != HC_DBG_FSM_WRITEWAIT2) {
577 hsts_err = mmio_read_32(reg_base + HC_HOSTSTATUS)
578 & HC_HSTST_MASK_ERROR_ALL;
579 if (hsts_err)
580 err = -(EILSEQ);
581 }
582
583 /* speeding up if the remaining words are not many */
584 remaining_words = (mmio_read_32(reg_base + HC_DEBUG) >> 4)
585 & HC_DBG_FIFO_THRESH_MASK;
586 if (remaining_words <= 4)
587 continue;
588
589 udelay(100);
590 }
591
592 /* We decide to stop by ourselves.
593 * It is because MMC_CMD(25) -> MMC_CMD(13) -> MMC_CMD(12)
594 * doesn't work for RPi3 SDHost.
595 */
596 if (rpi3_sdhost_params.current_cmd == MMC_CMD(25))
597 send_command_decorated(MMC_CMD(12), 0);
598
599 return err;
600}
601
602void rpi3_sdhost_init(struct rpi3_sdhost_params *params,
603 struct mmc_device_info *mmc_dev_info)
604{
605 assert((params != 0) &&
606 ((params->reg_base & MMC_BLOCK_MASK) == 0));
607
608 memcpy(&rpi3_sdhost_params, params, sizeof(struct rpi3_sdhost_params));
609
610 /* backup GPIO 48 to 53 configurations */
611 for (int i = 48; i <= 53; i++) {
612 rpi3_sdhost_params.gpio48_pinselect[i - 48]
613 = rpi3_gpio_get_select(i);
614 VERBOSE("rpi3_sdhost: Original GPIO state %d: %d\n",
615 i,
616 rpi3_sdhost_params.gpio48_pinselect[i - 48]);
617 }
618
619 /* setting pull resistors for 48 to 53.
620 * GPIO 48 (SD_CLK) to GPIO_PULL_UP
621 * GPIO 49 (SD_CMD) to GPIO_PULL_NONE
622 * GPIO 50 (SD_D0) to GPIO_PULL_NONE
623 * GPIO 51 (SD_D1) to GPIO_PULL_NONE
624 * GPIO 52 (SD_D2) to GPIO_PULL_NONE
625 * GPIO 53 (SD_D3) to GPIO_PULL_NONE
626 */
627 gpio_set_pull(48, GPIO_PULL_UP);
628 for (int i = 49; i <= 53; i++)
629 gpio_set_pull(i, GPIO_PULL_NONE);
630
631 /* Set pin 48-53 to alt-0. It means route SDHOST to card slot */
632 for (int i = 48; i <= 53; i++)
633 rpi3_gpio_set_select(i, RPI3_GPIO_FUNC_ALT0);
634
635 mmc_init(&rpi3_sdhost_ops, params->clk_rate, params->bus_width,
636 params->flags, mmc_dev_info);
637}
638
639void rpi3_sdhost_stop(void)
640{
641 uintptr_t reg_base = rpi3_sdhost_params.reg_base;
642
643 VERBOSE("rpi3_sdhost: Shutting down: drain FIFO out\n");
644 rpi3_drain_fifo();
645
646 VERBOSE("rpi3_sdhost: Shutting down: slowing down the clock\n");
647 mmio_write_32(reg_base+HC_CLOCKDIVISOR, HC_CLOCKDIVISOR_SLOWVAL);
648 udelay(500);
649
650 VERBOSE("rpi3_sdhost: Shutting down: put SDHost into idle state\n");
651 send_command_decorated(MMC_CMD(0), 0);
652 udelay(500);
653
654 mmio_write_32(reg_base + HC_COMMAND, 0);
655 mmio_write_32(reg_base + HC_ARGUMENT, 0);
656 mmio_write_32(reg_base + HC_TIMEOUTCOUNTER, HC_TIMEOUT_IDLE);
657 mmio_write_32(reg_base + HC_CLOCKDIVISOR, HC_CLOCKDIVISOR_STOPVAL);
658
659 udelay(100);
660
661 mmio_write_32(reg_base + HC_POWER, 0);
662 mmio_write_32(reg_base + HC_HOSTCONFIG, 0);
663 mmio_write_32(reg_base + HC_BLOCKSIZE, 0x400);
664 mmio_write_32(reg_base + HC_BLOCKCOUNT, 0);
665 mmio_write_32(reg_base + HC_HOSTSTATUS, 0x7f8);
666
667 mmio_write_32(reg_base + HC_COMMAND, 0);
668 mmio_write_32(reg_base + HC_ARGUMENT, 0);
669
670 udelay(100);
671
672 /* Restore the pinmux to original state */
673 for (int i = 48; i <= 53; i++) {
674 rpi3_gpio_set_select(i,
675 rpi3_sdhost_params.gpio48_pinselect[i-48]);
676 }
677
678 /* Must reset the pull resistors for u-boot to work.
679 * GPIO 48 (SD_CLK) to GPIO_PULL_NONE
680 * GPIO 49 (SD_CMD) to GPIO_PULL_UP
681 * GPIO 50 (SD_D0) to GPIO_PULL_UP
682 * GPIO 51 (SD_D1) to GPIO_PULL_UP
683 * GPIO 52 (SD_D2) to GPIO_PULL_UP
684 * GPIO 53 (SD_D3) to GPIO_PULL_UP
685 */
686 gpio_set_pull(48, GPIO_PULL_NONE);
687 for (int i = 49; i <= 53; i++)
688 gpio_set_pull(i, GPIO_PULL_UP);
689}