1 /* 2 * Marvell MMC/SD/SDIO driver 3 * 4 * (C) Copyright 2012-2014 5 * Marvell Semiconductor <www.marvell.com> 6 * Written-by: Maen Suleiman, Gerald Kerma 7 * 8 * SPDX-License-Identifier: GPL-2.0+ 9 */ 10 11 #include <common.h> 12 #include <errno.h> 13 #include <malloc.h> 14 #include <part.h> 15 #include <mmc.h> 16 #include <asm/io.h> 17 #include <asm/arch/cpu.h> 18 #include <asm/arch/soc.h> 19 #include <mvebu_mmc.h> 20 21 DECLARE_GLOBAL_DATA_PTR; 22 23 #define DRIVER_NAME "MVEBU_MMC" 24 25 #define MVEBU_TARGET_DRAM 0 26 27 #define TIMEOUT_DELAY 5*CONFIG_SYS_HZ /* wait 5 seconds */ 28 29 static void mvebu_mmc_write(u32 offs, u32 val) 30 { 31 writel(val, CONFIG_SYS_MMC_BASE + (offs)); 32 } 33 34 static u32 mvebu_mmc_read(u32 offs) 35 { 36 return readl(CONFIG_SYS_MMC_BASE + (offs)); 37 } 38 39 static int mvebu_mmc_setup_data(struct mmc_data *data) 40 { 41 u32 ctrl_reg; 42 43 debug("%s, data %s : blocks=%d blksz=%d\n", DRIVER_NAME, 44 (data->flags & MMC_DATA_READ) ? "read" : "write", 45 data->blocks, data->blocksize); 46 47 /* default to maximum timeout */ 48 ctrl_reg = mvebu_mmc_read(SDIO_HOST_CTRL); 49 ctrl_reg |= SDIO_HOST_CTRL_TMOUT(SDIO_HOST_CTRL_TMOUT_MAX); 50 mvebu_mmc_write(SDIO_HOST_CTRL, ctrl_reg); 51 52 if (data->flags & MMC_DATA_READ) { 53 mvebu_mmc_write(SDIO_SYS_ADDR_LOW, (u32)data->dest & 0xffff); 54 mvebu_mmc_write(SDIO_SYS_ADDR_HI, (u32)data->dest >> 16); 55 } else { 56 mvebu_mmc_write(SDIO_SYS_ADDR_LOW, (u32)data->src & 0xffff); 57 mvebu_mmc_write(SDIO_SYS_ADDR_HI, (u32)data->src >> 16); 58 } 59 60 mvebu_mmc_write(SDIO_BLK_COUNT, data->blocks); 61 mvebu_mmc_write(SDIO_BLK_SIZE, data->blocksize); 62 63 return 0; 64 } 65 66 static int mvebu_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, 67 struct mmc_data *data) 68 { 69 ulong start; 70 ushort waittype = 0; 71 ushort resptype = 0; 72 ushort xfertype = 0; 73 ushort resp_indx = 0; 74 75 debug("%s: cmdidx [0x%x] resp_type[0x%x] cmdarg[0x%x]\n", 76 DRIVER_NAME, cmd->cmdidx, cmd->resp_type, cmd->cmdarg); 77 78 debug("%s: cmd %d (hw state 0x%04x)\n", DRIVER_NAME, 79 cmd->cmdidx, mvebu_mmc_read(SDIO_HW_STATE)); 80 81 /* 82 * Hardware weirdness. The FIFO_EMPTY bit of the HW_STATE 83 * register is sometimes not set before a while when some 84 * "unusual" data block sizes are used (such as with the SWITCH 85 * command), even despite the fact that the XFER_DONE interrupt 86 * was raised. And if another data transfer starts before 87 * this bit comes to good sense (which eventually happens by 88 * itself) then the new transfer simply fails with a timeout. 89 */ 90 if (!(mvebu_mmc_read(SDIO_HW_STATE) & CMD_FIFO_EMPTY)) { 91 ushort hw_state, count = 0; 92 93 start = get_timer(0); 94 do { 95 hw_state = mvebu_mmc_read(SDIO_HW_STATE); 96 if ((get_timer(0) - start) > TIMEOUT_DELAY) { 97 printf("%s : FIFO_EMPTY bit missing\n", 98 DRIVER_NAME); 99 break; 100 } 101 count++; 102 } while (!(hw_state & CMD_FIFO_EMPTY)); 103 debug("%s *** wait for FIFO_EMPTY bit (hw=0x%04x, count=%d, jiffies=%ld)\n", 104 DRIVER_NAME, hw_state, count, (get_timer(0) - (start))); 105 } 106 107 /* Clear status */ 108 mvebu_mmc_write(SDIO_NOR_INTR_STATUS, SDIO_POLL_MASK); 109 mvebu_mmc_write(SDIO_ERR_INTR_STATUS, SDIO_POLL_MASK); 110 111 resptype = SDIO_CMD_INDEX(cmd->cmdidx); 112 113 /* Analyzing resptype/xfertype/waittype for the command */ 114 if (cmd->resp_type & MMC_RSP_BUSY) 115 resptype |= SDIO_CMD_RSP_48BUSY; 116 else if (cmd->resp_type & MMC_RSP_136) 117 resptype |= SDIO_CMD_RSP_136; 118 else if (cmd->resp_type & MMC_RSP_PRESENT) 119 resptype |= SDIO_CMD_RSP_48; 120 else 121 resptype |= SDIO_CMD_RSP_NONE; 122 123 if (cmd->resp_type & MMC_RSP_CRC) 124 resptype |= SDIO_CMD_CHECK_CMDCRC; 125 126 if (cmd->resp_type & MMC_RSP_OPCODE) 127 resptype |= SDIO_CMD_INDX_CHECK; 128 129 if (cmd->resp_type & MMC_RSP_PRESENT) { 130 resptype |= SDIO_UNEXPECTED_RESP; 131 waittype |= SDIO_NOR_UNEXP_RSP; 132 } 133 134 if (data) { 135 int err = mvebu_mmc_setup_data(data); 136 137 if (err) { 138 debug("%s: command DATA error :%x\n", 139 DRIVER_NAME, err); 140 return err; 141 } 142 143 resptype |= SDIO_CMD_DATA_PRESENT | SDIO_CMD_CHECK_DATACRC16; 144 xfertype |= SDIO_XFER_MODE_HW_WR_DATA_EN; 145 if (data->flags & MMC_DATA_READ) { 146 xfertype |= SDIO_XFER_MODE_TO_HOST; 147 waittype = SDIO_NOR_DMA_INI; 148 } else { 149 waittype |= SDIO_NOR_XFER_DONE; 150 } 151 } else { 152 waittype |= SDIO_NOR_CMD_DONE; 153 } 154 155 /* Setting cmd arguments */ 156 mvebu_mmc_write(SDIO_ARG_LOW, cmd->cmdarg & 0xffff); 157 mvebu_mmc_write(SDIO_ARG_HI, cmd->cmdarg >> 16); 158 159 /* Setting Xfer mode */ 160 mvebu_mmc_write(SDIO_XFER_MODE, xfertype); 161 162 /* Sending command */ 163 mvebu_mmc_write(SDIO_CMD, resptype); 164 165 start = get_timer(0); 166 167 while (!((mvebu_mmc_read(SDIO_NOR_INTR_STATUS)) & waittype)) { 168 if (mvebu_mmc_read(SDIO_NOR_INTR_STATUS) & SDIO_NOR_ERROR) { 169 debug("%s: error! cmdidx : %d, err reg: %04x\n", 170 DRIVER_NAME, cmd->cmdidx, 171 mvebu_mmc_read(SDIO_ERR_INTR_STATUS)); 172 if (mvebu_mmc_read(SDIO_ERR_INTR_STATUS) & 173 (SDIO_ERR_CMD_TIMEOUT | SDIO_ERR_DATA_TIMEOUT)) { 174 debug("%s: command READ timed out\n", 175 DRIVER_NAME); 176 return -ETIMEDOUT; 177 } 178 debug("%s: command READ error\n", DRIVER_NAME); 179 return -ECOMM; 180 } 181 182 if ((get_timer(0) - start) > TIMEOUT_DELAY) { 183 debug("%s: command timed out\n", DRIVER_NAME); 184 return -ETIMEDOUT; 185 } 186 } 187 188 /* Handling response */ 189 if (cmd->resp_type & MMC_RSP_136) { 190 uint response[8]; 191 192 for (resp_indx = 0; resp_indx < 8; resp_indx++) 193 response[resp_indx] 194 = mvebu_mmc_read(SDIO_RSP(resp_indx)); 195 196 cmd->response[0] = ((response[0] & 0x03ff) << 22) | 197 ((response[1] & 0xffff) << 6) | 198 ((response[2] & 0xfc00) >> 10); 199 cmd->response[1] = ((response[2] & 0x03ff) << 22) | 200 ((response[3] & 0xffff) << 6) | 201 ((response[4] & 0xfc00) >> 10); 202 cmd->response[2] = ((response[4] & 0x03ff) << 22) | 203 ((response[5] & 0xffff) << 6) | 204 ((response[6] & 0xfc00) >> 10); 205 cmd->response[3] = ((response[6] & 0x03ff) << 22) | 206 ((response[7] & 0x3fff) << 8); 207 } else if (cmd->resp_type & MMC_RSP_PRESENT) { 208 uint response[3]; 209 210 for (resp_indx = 0; resp_indx < 3; resp_indx++) 211 response[resp_indx] 212 = mvebu_mmc_read(SDIO_RSP(resp_indx)); 213 214 cmd->response[0] = ((response[2] & 0x003f) << (8 - 8)) | 215 ((response[1] & 0xffff) << (14 - 8)) | 216 ((response[0] & 0x03ff) << (30 - 8)); 217 cmd->response[1] = ((response[0] & 0xfc00) >> 10); 218 cmd->response[2] = 0; 219 cmd->response[3] = 0; 220 } else { 221 cmd->response[0] = 0; 222 cmd->response[1] = 0; 223 cmd->response[2] = 0; 224 cmd->response[3] = 0; 225 } 226 227 debug("%s: resp[0x%x] ", DRIVER_NAME, cmd->resp_type); 228 debug("[0x%x] ", cmd->response[0]); 229 debug("[0x%x] ", cmd->response[1]); 230 debug("[0x%x] ", cmd->response[2]); 231 debug("[0x%x] ", cmd->response[3]); 232 debug("\n"); 233 234 if (mvebu_mmc_read(SDIO_ERR_INTR_STATUS) & 235 (SDIO_ERR_CMD_TIMEOUT | SDIO_ERR_DATA_TIMEOUT)) 236 return -ETIMEDOUT; 237 238 return 0; 239 } 240 241 static void mvebu_mmc_power_up(void) 242 { 243 debug("%s: power up\n", DRIVER_NAME); 244 245 /* disable interrupts */ 246 mvebu_mmc_write(SDIO_NOR_INTR_EN, 0); 247 mvebu_mmc_write(SDIO_ERR_INTR_EN, 0); 248 249 /* SW reset */ 250 mvebu_mmc_write(SDIO_SW_RESET, SDIO_SW_RESET_NOW); 251 252 mvebu_mmc_write(SDIO_XFER_MODE, 0); 253 254 /* enable status */ 255 mvebu_mmc_write(SDIO_NOR_STATUS_EN, SDIO_POLL_MASK); 256 mvebu_mmc_write(SDIO_ERR_STATUS_EN, SDIO_POLL_MASK); 257 258 /* enable interrupts status */ 259 mvebu_mmc_write(SDIO_NOR_INTR_STATUS, SDIO_POLL_MASK); 260 mvebu_mmc_write(SDIO_ERR_INTR_STATUS, SDIO_POLL_MASK); 261 } 262 263 static void mvebu_mmc_set_clk(unsigned int clock) 264 { 265 unsigned int m; 266 267 if (clock == 0) { 268 debug("%s: clock off\n", DRIVER_NAME); 269 mvebu_mmc_write(SDIO_XFER_MODE, SDIO_XFER_MODE_STOP_CLK); 270 mvebu_mmc_write(SDIO_CLK_DIV, MVEBU_MMC_BASE_DIV_MAX); 271 } else { 272 m = MVEBU_MMC_BASE_FAST_CLOCK/(2*clock) - 1; 273 if (m > MVEBU_MMC_BASE_DIV_MAX) 274 m = MVEBU_MMC_BASE_DIV_MAX; 275 mvebu_mmc_write(SDIO_CLK_DIV, m & MVEBU_MMC_BASE_DIV_MAX); 276 debug("%s: clock (%d) div : %d\n", DRIVER_NAME, clock, m); 277 } 278 } 279 280 static void mvebu_mmc_set_bus(unsigned int bus) 281 { 282 u32 ctrl_reg = 0; 283 284 ctrl_reg = mvebu_mmc_read(SDIO_HOST_CTRL); 285 ctrl_reg &= ~SDIO_HOST_CTRL_DATA_WIDTH_4_BITS; 286 287 switch (bus) { 288 case 4: 289 ctrl_reg |= SDIO_HOST_CTRL_DATA_WIDTH_4_BITS; 290 break; 291 case 1: 292 default: 293 ctrl_reg |= SDIO_HOST_CTRL_DATA_WIDTH_1_BIT; 294 } 295 296 /* default transfer mode */ 297 ctrl_reg |= SDIO_HOST_CTRL_BIG_ENDIAN; 298 ctrl_reg &= ~SDIO_HOST_CTRL_LSB_FIRST; 299 300 /* default to maximum timeout */ 301 ctrl_reg |= SDIO_HOST_CTRL_TMOUT(SDIO_HOST_CTRL_TMOUT_MAX); 302 ctrl_reg |= SDIO_HOST_CTRL_TMOUT_EN; 303 304 ctrl_reg |= SDIO_HOST_CTRL_PUSH_PULL_EN; 305 306 ctrl_reg |= SDIO_HOST_CTRL_CARD_TYPE_MEM_ONLY; 307 308 debug("%s: ctrl 0x%04x: %s %s %s\n", DRIVER_NAME, ctrl_reg, 309 (ctrl_reg & SDIO_HOST_CTRL_PUSH_PULL_EN) ? 310 "push-pull" : "open-drain", 311 (ctrl_reg & SDIO_HOST_CTRL_DATA_WIDTH_4_BITS) ? 312 "4bit-width" : "1bit-width", 313 (ctrl_reg & SDIO_HOST_CTRL_HI_SPEED_EN) ? 314 "high-speed" : ""); 315 316 mvebu_mmc_write(SDIO_HOST_CTRL, ctrl_reg); 317 } 318 319 static int mvebu_mmc_set_ios(struct mmc *mmc) 320 { 321 debug("%s: bus[%d] clock[%d]\n", DRIVER_NAME, 322 mmc->bus_width, mmc->clock); 323 mvebu_mmc_set_bus(mmc->bus_width); 324 mvebu_mmc_set_clk(mmc->clock); 325 326 return 0; 327 } 328 329 /* 330 * Set window register. 331 */ 332 static void mvebu_window_setup(void) 333 { 334 int i; 335 336 for (i = 0; i < 4; i++) { 337 mvebu_mmc_write(WINDOW_CTRL(i), 0); 338 mvebu_mmc_write(WINDOW_BASE(i), 0); 339 } 340 for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { 341 u32 size, base, attrib; 342 343 /* Enable DRAM bank */ 344 switch (i) { 345 case 0: 346 attrib = KWCPU_ATTR_DRAM_CS0; 347 break; 348 case 1: 349 attrib = KWCPU_ATTR_DRAM_CS1; 350 break; 351 case 2: 352 attrib = KWCPU_ATTR_DRAM_CS2; 353 break; 354 case 3: 355 attrib = KWCPU_ATTR_DRAM_CS3; 356 break; 357 default: 358 /* invalide bank, disable access */ 359 attrib = 0; 360 break; 361 } 362 363 size = gd->bd->bi_dram[i].size; 364 base = gd->bd->bi_dram[i].start; 365 if (size && attrib) { 366 mvebu_mmc_write(WINDOW_CTRL(i), 367 MVCPU_WIN_CTRL_DATA(size, 368 MVEBU_TARGET_DRAM, 369 attrib, 370 MVCPU_WIN_ENABLE)); 371 } else { 372 mvebu_mmc_write(WINDOW_CTRL(i), MVCPU_WIN_DISABLE); 373 } 374 mvebu_mmc_write(WINDOW_BASE(i), base); 375 } 376 } 377 378 static int mvebu_mmc_initialize(struct mmc *mmc) 379 { 380 debug("%s: mvebu_mmc_initialize\n", DRIVER_NAME); 381 382 /* 383 * Setting host parameters 384 * Initial Host Ctrl : Timeout : max , Normal Speed mode, 385 * 4-bit data mode, Big Endian, SD memory Card, Push_pull CMD Line 386 */ 387 mvebu_mmc_write(SDIO_HOST_CTRL, 388 SDIO_HOST_CTRL_TMOUT(SDIO_HOST_CTRL_TMOUT_MAX) | 389 SDIO_HOST_CTRL_DATA_WIDTH_4_BITS | 390 SDIO_HOST_CTRL_BIG_ENDIAN | 391 SDIO_HOST_CTRL_PUSH_PULL_EN | 392 SDIO_HOST_CTRL_CARD_TYPE_MEM_ONLY); 393 394 mvebu_mmc_write(SDIO_CLK_CTRL, 0); 395 396 /* enable status */ 397 mvebu_mmc_write(SDIO_NOR_STATUS_EN, SDIO_POLL_MASK); 398 mvebu_mmc_write(SDIO_ERR_STATUS_EN, SDIO_POLL_MASK); 399 400 /* disable interrupts */ 401 mvebu_mmc_write(SDIO_NOR_INTR_EN, 0); 402 mvebu_mmc_write(SDIO_ERR_INTR_EN, 0); 403 404 mvebu_window_setup(); 405 406 /* SW reset */ 407 mvebu_mmc_write(SDIO_SW_RESET, SDIO_SW_RESET_NOW); 408 409 return 0; 410 } 411 412 static const struct mmc_ops mvebu_mmc_ops = { 413 .send_cmd = mvebu_mmc_send_cmd, 414 .set_ios = mvebu_mmc_set_ios, 415 .init = mvebu_mmc_initialize, 416 }; 417 418 static struct mmc_config mvebu_mmc_cfg = { 419 .name = DRIVER_NAME, 420 .ops = &mvebu_mmc_ops, 421 .f_min = MVEBU_MMC_BASE_FAST_CLOCK / MVEBU_MMC_BASE_DIV_MAX, 422 .f_max = MVEBU_MMC_CLOCKRATE_MAX, 423 .voltages = MMC_VDD_32_33 | MMC_VDD_33_34, 424 .host_caps = MMC_MODE_4BIT | MMC_MODE_HS | 425 MMC_MODE_HS_52MHz, 426 .part_type = PART_TYPE_DOS, 427 .b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT, 428 }; 429 430 int mvebu_mmc_init(bd_t *bis) 431 { 432 struct mmc *mmc; 433 434 mvebu_mmc_power_up(); 435 436 mmc = mmc_create(&mvebu_mmc_cfg, bis); 437 if (mmc == NULL) 438 return -1; 439 440 return 0; 441 } 442