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