1 /* 2 * (C) Copyright 2007-2011 3 * Allwinner Technology Co., Ltd. <www.allwinnertech.com> 4 * Aaron <leafy.myeh@allwinnertech.com> 5 * 6 * MMC driver for allwinner sunxi platform. 7 * 8 * SPDX-License-Identifier: GPL-2.0+ 9 */ 10 11 #include <common.h> 12 #include <malloc.h> 13 #include <mmc.h> 14 #include <asm/io.h> 15 #include <asm/arch/clock.h> 16 #include <asm/arch/cpu.h> 17 #include <asm/arch/mmc.h> 18 19 struct sunxi_mmc_host { 20 unsigned mmc_no; 21 uint32_t *mclkreg; 22 unsigned database; 23 unsigned fatal_err; 24 unsigned mod_clk; 25 struct sunxi_mmc *reg; 26 struct mmc_config cfg; 27 }; 28 29 /* support 4 mmc hosts */ 30 struct sunxi_mmc_host mmc_host[4]; 31 32 static int mmc_resource_init(int sdc_no) 33 { 34 struct sunxi_mmc_host *mmchost = &mmc_host[sdc_no]; 35 struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; 36 37 debug("init mmc %d resource\n", sdc_no); 38 39 switch (sdc_no) { 40 case 0: 41 mmchost->reg = (struct sunxi_mmc *)SUNXI_MMC0_BASE; 42 mmchost->mclkreg = &ccm->sd0_clk_cfg; 43 break; 44 case 1: 45 mmchost->reg = (struct sunxi_mmc *)SUNXI_MMC1_BASE; 46 mmchost->mclkreg = &ccm->sd1_clk_cfg; 47 break; 48 case 2: 49 mmchost->reg = (struct sunxi_mmc *)SUNXI_MMC2_BASE; 50 mmchost->mclkreg = &ccm->sd2_clk_cfg; 51 break; 52 case 3: 53 mmchost->reg = (struct sunxi_mmc *)SUNXI_MMC3_BASE; 54 mmchost->mclkreg = &ccm->sd3_clk_cfg; 55 break; 56 default: 57 printf("Wrong mmc number %d\n", sdc_no); 58 return -1; 59 } 60 mmchost->database = (unsigned int)mmchost->reg + 0x100; 61 mmchost->mmc_no = sdc_no; 62 63 return 0; 64 } 65 66 static int mmc_clk_io_on(int sdc_no) 67 { 68 unsigned int pll_clk; 69 unsigned int divider; 70 struct sunxi_mmc_host *mmchost = &mmc_host[sdc_no]; 71 struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; 72 73 debug("init mmc %d clock and io\n", sdc_no); 74 75 /* config ahb clock */ 76 setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MMC(sdc_no)); 77 78 /* config mod clock */ 79 pll_clk = clock_get_pll6(); 80 /* should be close to 100 MHz but no more, so round up */ 81 divider = ((pll_clk + 99999999) / 100000000) - 1; 82 writel(CCM_MMC_CTRL_ENABLE | CCM_MMC_CTRL_PLL6 | divider, 83 mmchost->mclkreg); 84 mmchost->mod_clk = pll_clk / (divider + 1); 85 86 return 0; 87 } 88 89 static int mmc_update_clk(struct mmc *mmc) 90 { 91 struct sunxi_mmc_host *mmchost = mmc->priv; 92 unsigned int cmd; 93 unsigned timeout_msecs = 2000; 94 95 cmd = SUNXI_MMC_CMD_START | 96 SUNXI_MMC_CMD_UPCLK_ONLY | 97 SUNXI_MMC_CMD_WAIT_PRE_OVER; 98 writel(cmd, &mmchost->reg->cmd); 99 while (readl(&mmchost->reg->cmd) & SUNXI_MMC_CMD_START) { 100 if (!timeout_msecs--) 101 return -1; 102 udelay(1000); 103 } 104 105 /* clock update sets various irq status bits, clear these */ 106 writel(readl(&mmchost->reg->rint), &mmchost->reg->rint); 107 108 return 0; 109 } 110 111 static int mmc_config_clock(struct mmc *mmc, unsigned div) 112 { 113 struct sunxi_mmc_host *mmchost = mmc->priv; 114 unsigned rval = readl(&mmchost->reg->clkcr); 115 116 /* Disable Clock */ 117 rval &= ~SUNXI_MMC_CLK_ENABLE; 118 writel(rval, &mmchost->reg->clkcr); 119 if (mmc_update_clk(mmc)) 120 return -1; 121 122 /* Change Divider Factor */ 123 rval &= ~SUNXI_MMC_CLK_DIVIDER_MASK; 124 rval |= div; 125 writel(rval, &mmchost->reg->clkcr); 126 if (mmc_update_clk(mmc)) 127 return -1; 128 /* Re-enable Clock */ 129 rval |= SUNXI_MMC_CLK_ENABLE; 130 writel(rval, &mmchost->reg->clkcr); 131 132 if (mmc_update_clk(mmc)) 133 return -1; 134 135 return 0; 136 } 137 138 static void mmc_set_ios(struct mmc *mmc) 139 { 140 struct sunxi_mmc_host *mmchost = mmc->priv; 141 unsigned int clkdiv = 0; 142 143 debug("set ios: bus_width: %x, clock: %d, mod_clk: %d\n", 144 mmc->bus_width, mmc->clock, mmchost->mod_clk); 145 146 /* Change clock first */ 147 clkdiv = (mmchost->mod_clk + (mmc->clock >> 1)) / mmc->clock / 2; 148 if (mmc->clock) { 149 if (mmc_config_clock(mmc, clkdiv)) { 150 mmchost->fatal_err = 1; 151 return; 152 } 153 } 154 155 /* Change bus width */ 156 if (mmc->bus_width == 8) 157 writel(0x2, &mmchost->reg->width); 158 else if (mmc->bus_width == 4) 159 writel(0x1, &mmchost->reg->width); 160 else 161 writel(0x0, &mmchost->reg->width); 162 } 163 164 static int mmc_core_init(struct mmc *mmc) 165 { 166 struct sunxi_mmc_host *mmchost = mmc->priv; 167 168 /* Reset controller */ 169 writel(SUNXI_MMC_GCTRL_RESET, &mmchost->reg->gctrl); 170 udelay(1000); 171 172 return 0; 173 } 174 175 static int mmc_trans_data_by_cpu(struct mmc *mmc, struct mmc_data *data) 176 { 177 struct sunxi_mmc_host *mmchost = mmc->priv; 178 const int reading = !!(data->flags & MMC_DATA_READ); 179 const uint32_t status_bit = reading ? SUNXI_MMC_STATUS_FIFO_EMPTY : 180 SUNXI_MMC_STATUS_FIFO_FULL; 181 unsigned i; 182 unsigned byte_cnt = data->blocksize * data->blocks; 183 unsigned timeout_msecs = 2000; 184 unsigned *buff = (unsigned int *)(reading ? data->dest : data->src); 185 186 /* Always read / write data through the CPU */ 187 setbits_le32(&mmchost->reg->gctrl, SUNXI_MMC_GCTRL_ACCESS_BY_AHB); 188 189 for (i = 0; i < (byte_cnt >> 2); i++) { 190 while (readl(&mmchost->reg->status) & status_bit) { 191 if (!timeout_msecs--) 192 return -1; 193 udelay(1000); 194 } 195 196 if (reading) 197 buff[i] = readl(mmchost->database); 198 else 199 writel(buff[i], mmchost->database); 200 } 201 202 return 0; 203 } 204 205 static int mmc_rint_wait(struct mmc *mmc, unsigned int timeout_msecs, 206 unsigned int done_bit, const char *what) 207 { 208 struct sunxi_mmc_host *mmchost = mmc->priv; 209 unsigned int status; 210 211 do { 212 status = readl(&mmchost->reg->rint); 213 if (!timeout_msecs-- || 214 (status & SUNXI_MMC_RINT_INTERRUPT_ERROR_BIT)) { 215 debug("%s timeout %x\n", what, 216 status & SUNXI_MMC_RINT_INTERRUPT_ERROR_BIT); 217 return TIMEOUT; 218 } 219 udelay(1000); 220 } while (!(status & done_bit)); 221 222 return 0; 223 } 224 225 static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, 226 struct mmc_data *data) 227 { 228 struct sunxi_mmc_host *mmchost = mmc->priv; 229 unsigned int cmdval = SUNXI_MMC_CMD_START; 230 unsigned int timeout_msecs; 231 int error = 0; 232 unsigned int status = 0; 233 unsigned int bytecnt = 0; 234 235 if (mmchost->fatal_err) 236 return -1; 237 if (cmd->resp_type & MMC_RSP_BUSY) 238 debug("mmc cmd %d check rsp busy\n", cmd->cmdidx); 239 if (cmd->cmdidx == 12) 240 return 0; 241 242 if (!cmd->cmdidx) 243 cmdval |= SUNXI_MMC_CMD_SEND_INIT_SEQ; 244 if (cmd->resp_type & MMC_RSP_PRESENT) 245 cmdval |= SUNXI_MMC_CMD_RESP_EXPIRE; 246 if (cmd->resp_type & MMC_RSP_136) 247 cmdval |= SUNXI_MMC_CMD_LONG_RESPONSE; 248 if (cmd->resp_type & MMC_RSP_CRC) 249 cmdval |= SUNXI_MMC_CMD_CHK_RESPONSE_CRC; 250 251 if (data) { 252 if ((u32) data->dest & 0x3) { 253 error = -1; 254 goto out; 255 } 256 257 cmdval |= SUNXI_MMC_CMD_DATA_EXPIRE|SUNXI_MMC_CMD_WAIT_PRE_OVER; 258 if (data->flags & MMC_DATA_WRITE) 259 cmdval |= SUNXI_MMC_CMD_WRITE; 260 if (data->blocks > 1) 261 cmdval |= SUNXI_MMC_CMD_AUTO_STOP; 262 writel(data->blocksize, &mmchost->reg->blksz); 263 writel(data->blocks * data->blocksize, &mmchost->reg->bytecnt); 264 } 265 266 debug("mmc %d, cmd %d(0x%08x), arg 0x%08x\n", mmchost->mmc_no, 267 cmd->cmdidx, cmdval | cmd->cmdidx, cmd->cmdarg); 268 writel(cmd->cmdarg, &mmchost->reg->arg); 269 270 if (!data) 271 writel(cmdval | cmd->cmdidx, &mmchost->reg->cmd); 272 273 /* 274 * transfer data and check status 275 * STATREG[2] : FIFO empty 276 * STATREG[3] : FIFO full 277 */ 278 if (data) { 279 int ret = 0; 280 281 bytecnt = data->blocksize * data->blocks; 282 debug("trans data %d bytes\n", bytecnt); 283 writel(cmdval | cmd->cmdidx, &mmchost->reg->cmd); 284 ret = mmc_trans_data_by_cpu(mmc, data); 285 if (ret) { 286 error = readl(&mmchost->reg->rint) & \ 287 SUNXI_MMC_RINT_INTERRUPT_ERROR_BIT; 288 error = TIMEOUT; 289 goto out; 290 } 291 } 292 293 error = mmc_rint_wait(mmc, 0xfffff, SUNXI_MMC_RINT_COMMAND_DONE, "cmd"); 294 if (error) 295 goto out; 296 297 if (data) { 298 timeout_msecs = 120; 299 debug("cacl timeout %x msec\n", timeout_msecs); 300 error = mmc_rint_wait(mmc, timeout_msecs, 301 data->blocks > 1 ? 302 SUNXI_MMC_RINT_AUTO_COMMAND_DONE : 303 SUNXI_MMC_RINT_DATA_OVER, 304 "data"); 305 if (error) 306 goto out; 307 } 308 309 if (cmd->resp_type & MMC_RSP_BUSY) { 310 timeout_msecs = 2000; 311 do { 312 status = readl(&mmchost->reg->status); 313 if (!timeout_msecs--) { 314 debug("busy timeout\n"); 315 error = TIMEOUT; 316 goto out; 317 } 318 udelay(1000); 319 } while (status & SUNXI_MMC_STATUS_CARD_DATA_BUSY); 320 } 321 322 if (cmd->resp_type & MMC_RSP_136) { 323 cmd->response[0] = readl(&mmchost->reg->resp3); 324 cmd->response[1] = readl(&mmchost->reg->resp2); 325 cmd->response[2] = readl(&mmchost->reg->resp1); 326 cmd->response[3] = readl(&mmchost->reg->resp0); 327 debug("mmc resp 0x%08x 0x%08x 0x%08x 0x%08x\n", 328 cmd->response[3], cmd->response[2], 329 cmd->response[1], cmd->response[0]); 330 } else { 331 cmd->response[0] = readl(&mmchost->reg->resp0); 332 debug("mmc resp 0x%08x\n", cmd->response[0]); 333 } 334 out: 335 if (error < 0) { 336 writel(SUNXI_MMC_GCTRL_RESET, &mmchost->reg->gctrl); 337 mmc_update_clk(mmc); 338 } 339 writel(0xffffffff, &mmchost->reg->rint); 340 writel(readl(&mmchost->reg->gctrl) | SUNXI_MMC_GCTRL_FIFO_RESET, 341 &mmchost->reg->gctrl); 342 343 return error; 344 } 345 346 static const struct mmc_ops sunxi_mmc_ops = { 347 .send_cmd = mmc_send_cmd, 348 .set_ios = mmc_set_ios, 349 .init = mmc_core_init, 350 }; 351 352 int sunxi_mmc_init(int sdc_no) 353 { 354 struct mmc_config *cfg = &mmc_host[sdc_no].cfg; 355 356 memset(&mmc_host[sdc_no], 0, sizeof(struct sunxi_mmc_host)); 357 358 cfg->name = "SUNXI SD/MMC"; 359 cfg->ops = &sunxi_mmc_ops; 360 361 cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; 362 cfg->host_caps = MMC_MODE_4BIT; 363 cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS; 364 cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; 365 366 cfg->f_min = 400000; 367 cfg->f_max = 52000000; 368 369 mmc_resource_init(sdc_no); 370 mmc_clk_io_on(sdc_no); 371 372 if (mmc_create(cfg, &mmc_host[sdc_no]) == NULL) 373 return -1; 374 375 return 0; 376 } 377