1 /* 2 * MMCIF driver. 3 * 4 * Copyright (C) 2011 Renesas Solutions Corp. 5 * 6 * SPDX-License-Identifier: GPL-2.0 7 */ 8 9 #include <config.h> 10 #include <common.h> 11 #include <watchdog.h> 12 #include <command.h> 13 #include <mmc.h> 14 #include <malloc.h> 15 #include <linux/errno.h> 16 #include <asm/io.h> 17 #include "sh_mmcif.h" 18 19 #define DRIVER_NAME "sh_mmcif" 20 21 static int sh_mmcif_intr(void *dev_id) 22 { 23 struct sh_mmcif_host *host = dev_id; 24 u32 state = 0; 25 26 state = sh_mmcif_read(&host->regs->ce_int); 27 state &= sh_mmcif_read(&host->regs->ce_int_mask); 28 29 if (state & INT_RBSYE) { 30 sh_mmcif_write(~(INT_RBSYE | INT_CRSPE), &host->regs->ce_int); 31 sh_mmcif_bitclr(MASK_MRBSYE, &host->regs->ce_int_mask); 32 goto end; 33 } else if (state & INT_CRSPE) { 34 sh_mmcif_write(~INT_CRSPE, &host->regs->ce_int); 35 sh_mmcif_bitclr(MASK_MCRSPE, &host->regs->ce_int_mask); 36 /* one more interrupt (INT_RBSYE) */ 37 if (sh_mmcif_read(&host->regs->ce_cmd_set) & CMD_SET_RBSY) 38 return -EAGAIN; 39 goto end; 40 } else if (state & INT_BUFREN) { 41 sh_mmcif_write(~INT_BUFREN, &host->regs->ce_int); 42 sh_mmcif_bitclr(MASK_MBUFREN, &host->regs->ce_int_mask); 43 goto end; 44 } else if (state & INT_BUFWEN) { 45 sh_mmcif_write(~INT_BUFWEN, &host->regs->ce_int); 46 sh_mmcif_bitclr(MASK_MBUFWEN, &host->regs->ce_int_mask); 47 goto end; 48 } else if (state & INT_CMD12DRE) { 49 sh_mmcif_write(~(INT_CMD12DRE | INT_CMD12RBE | INT_CMD12CRE | 50 INT_BUFRE), &host->regs->ce_int); 51 sh_mmcif_bitclr(MASK_MCMD12DRE, &host->regs->ce_int_mask); 52 goto end; 53 } else if (state & INT_BUFRE) { 54 sh_mmcif_write(~INT_BUFRE, &host->regs->ce_int); 55 sh_mmcif_bitclr(MASK_MBUFRE, &host->regs->ce_int_mask); 56 goto end; 57 } else if (state & INT_DTRANE) { 58 sh_mmcif_write(~INT_DTRANE, &host->regs->ce_int); 59 sh_mmcif_bitclr(MASK_MDTRANE, &host->regs->ce_int_mask); 60 goto end; 61 } else if (state & INT_CMD12RBE) { 62 sh_mmcif_write(~(INT_CMD12RBE | INT_CMD12CRE), 63 &host->regs->ce_int); 64 sh_mmcif_bitclr(MASK_MCMD12RBE, &host->regs->ce_int_mask); 65 goto end; 66 } else if (state & INT_ERR_STS) { 67 /* err interrupts */ 68 sh_mmcif_write(~state, &host->regs->ce_int); 69 sh_mmcif_bitclr(state, &host->regs->ce_int_mask); 70 goto err; 71 } else 72 return -EAGAIN; 73 74 err: 75 host->sd_error = 1; 76 debug("%s: int err state = %08x\n", DRIVER_NAME, state); 77 end: 78 host->wait_int = 1; 79 return 0; 80 } 81 82 static int mmcif_wait_interrupt_flag(struct sh_mmcif_host *host) 83 { 84 int timeout = 10000000; 85 86 while (1) { 87 timeout--; 88 if (timeout < 0) { 89 printf("timeout\n"); 90 return 0; 91 } 92 93 if (!sh_mmcif_intr(host)) 94 break; 95 96 udelay(1); /* 1 usec */ 97 } 98 99 return 1; /* Return value: NOT 0 = complete waiting */ 100 } 101 102 static void sh_mmcif_clock_control(struct sh_mmcif_host *host, unsigned int clk) 103 { 104 sh_mmcif_bitclr(CLK_ENABLE, &host->regs->ce_clk_ctrl); 105 sh_mmcif_bitclr(CLK_CLEAR, &host->regs->ce_clk_ctrl); 106 107 if (!clk) 108 return; 109 110 if (clk == CLKDEV_EMMC_DATA) 111 sh_mmcif_bitset(CLK_PCLK, &host->regs->ce_clk_ctrl); 112 else 113 sh_mmcif_bitset((fls(DIV_ROUND_UP(host->clk, 114 clk) - 1) - 1) << 16, 115 &host->regs->ce_clk_ctrl); 116 sh_mmcif_bitset(CLK_ENABLE, &host->regs->ce_clk_ctrl); 117 } 118 119 static void sh_mmcif_sync_reset(struct sh_mmcif_host *host) 120 { 121 u32 tmp; 122 123 tmp = sh_mmcif_read(&host->regs->ce_clk_ctrl) & (CLK_ENABLE | 124 CLK_CLEAR); 125 126 sh_mmcif_write(SOFT_RST_ON, &host->regs->ce_version); 127 sh_mmcif_write(SOFT_RST_OFF, &host->regs->ce_version); 128 sh_mmcif_bitset(tmp | SRSPTO_256 | SRBSYTO_29 | SRWDTO_29 | SCCSTO_29, 129 &host->regs->ce_clk_ctrl); 130 /* byte swap on */ 131 sh_mmcif_bitset(BUF_ACC_ATYP, &host->regs->ce_buf_acc); 132 } 133 134 static int sh_mmcif_error_manage(struct sh_mmcif_host *host) 135 { 136 u32 state1, state2; 137 int ret, timeout = 10000000; 138 139 host->sd_error = 0; 140 host->wait_int = 0; 141 142 state1 = sh_mmcif_read(&host->regs->ce_host_sts1); 143 state2 = sh_mmcif_read(&host->regs->ce_host_sts2); 144 debug("%s: ERR HOST_STS1 = %08x\n", \ 145 DRIVER_NAME, sh_mmcif_read(&host->regs->ce_host_sts1)); 146 debug("%s: ERR HOST_STS2 = %08x\n", \ 147 DRIVER_NAME, sh_mmcif_read(&host->regs->ce_host_sts2)); 148 149 if (state1 & STS1_CMDSEQ) { 150 debug("%s: Forced end of command sequence\n", DRIVER_NAME); 151 sh_mmcif_bitset(CMD_CTRL_BREAK, &host->regs->ce_cmd_ctrl); 152 sh_mmcif_bitset(~CMD_CTRL_BREAK, &host->regs->ce_cmd_ctrl); 153 while (1) { 154 timeout--; 155 if (timeout < 0) { 156 printf(DRIVER_NAME": Forceed end of " \ 157 "command sequence timeout err\n"); 158 return -EILSEQ; 159 } 160 if (!(sh_mmcif_read(&host->regs->ce_host_sts1) 161 & STS1_CMDSEQ)) 162 break; 163 } 164 sh_mmcif_sync_reset(host); 165 return -EILSEQ; 166 } 167 168 if (state2 & STS2_CRC_ERR) 169 ret = -EILSEQ; 170 else if (state2 & STS2_TIMEOUT_ERR) 171 ret = -ETIMEDOUT; 172 else 173 ret = -EILSEQ; 174 return ret; 175 } 176 177 static int sh_mmcif_single_read(struct sh_mmcif_host *host, 178 struct mmc_data *data) 179 { 180 long time; 181 u32 blocksize, i; 182 unsigned long *p = (unsigned long *)data->dest; 183 184 if ((unsigned long)p & 0x00000001) { 185 printf("%s: The data pointer is unaligned.", __func__); 186 return -EIO; 187 } 188 189 host->wait_int = 0; 190 191 /* buf read enable */ 192 sh_mmcif_bitset(MASK_MBUFREN, &host->regs->ce_int_mask); 193 time = mmcif_wait_interrupt_flag(host); 194 if (time == 0 || host->sd_error != 0) 195 return sh_mmcif_error_manage(host); 196 197 host->wait_int = 0; 198 blocksize = (BLOCK_SIZE_MASK & 199 sh_mmcif_read(&host->regs->ce_block_set)) + 3; 200 for (i = 0; i < blocksize / 4; i++) 201 *p++ = sh_mmcif_read(&host->regs->ce_data); 202 203 /* buffer read end */ 204 sh_mmcif_bitset(MASK_MBUFRE, &host->regs->ce_int_mask); 205 time = mmcif_wait_interrupt_flag(host); 206 if (time == 0 || host->sd_error != 0) 207 return sh_mmcif_error_manage(host); 208 209 host->wait_int = 0; 210 return 0; 211 } 212 213 static int sh_mmcif_multi_read(struct sh_mmcif_host *host, 214 struct mmc_data *data) 215 { 216 long time; 217 u32 blocksize, i, j; 218 unsigned long *p = (unsigned long *)data->dest; 219 220 if ((unsigned long)p & 0x00000001) { 221 printf("%s: The data pointer is unaligned.", __func__); 222 return -EIO; 223 } 224 225 host->wait_int = 0; 226 blocksize = BLOCK_SIZE_MASK & sh_mmcif_read(&host->regs->ce_block_set); 227 for (j = 0; j < data->blocks; j++) { 228 sh_mmcif_bitset(MASK_MBUFREN, &host->regs->ce_int_mask); 229 time = mmcif_wait_interrupt_flag(host); 230 if (time == 0 || host->sd_error != 0) 231 return sh_mmcif_error_manage(host); 232 233 host->wait_int = 0; 234 for (i = 0; i < blocksize / 4; i++) 235 *p++ = sh_mmcif_read(&host->regs->ce_data); 236 237 WATCHDOG_RESET(); 238 } 239 return 0; 240 } 241 242 static int sh_mmcif_single_write(struct sh_mmcif_host *host, 243 struct mmc_data *data) 244 { 245 long time; 246 u32 blocksize, i; 247 const unsigned long *p = (unsigned long *)data->dest; 248 249 if ((unsigned long)p & 0x00000001) { 250 printf("%s: The data pointer is unaligned.", __func__); 251 return -EIO; 252 } 253 254 host->wait_int = 0; 255 sh_mmcif_bitset(MASK_MBUFWEN, &host->regs->ce_int_mask); 256 257 time = mmcif_wait_interrupt_flag(host); 258 if (time == 0 || host->sd_error != 0) 259 return sh_mmcif_error_manage(host); 260 261 host->wait_int = 0; 262 blocksize = (BLOCK_SIZE_MASK & 263 sh_mmcif_read(&host->regs->ce_block_set)) + 3; 264 for (i = 0; i < blocksize / 4; i++) 265 sh_mmcif_write(*p++, &host->regs->ce_data); 266 267 /* buffer write end */ 268 sh_mmcif_bitset(MASK_MDTRANE, &host->regs->ce_int_mask); 269 270 time = mmcif_wait_interrupt_flag(host); 271 if (time == 0 || host->sd_error != 0) 272 return sh_mmcif_error_manage(host); 273 274 host->wait_int = 0; 275 return 0; 276 } 277 278 static int sh_mmcif_multi_write(struct sh_mmcif_host *host, 279 struct mmc_data *data) 280 { 281 long time; 282 u32 i, j, blocksize; 283 const unsigned long *p = (unsigned long *)data->dest; 284 285 if ((unsigned long)p & 0x00000001) { 286 printf("%s: The data pointer is unaligned.", __func__); 287 return -EIO; 288 } 289 290 host->wait_int = 0; 291 blocksize = BLOCK_SIZE_MASK & sh_mmcif_read(&host->regs->ce_block_set); 292 for (j = 0; j < data->blocks; j++) { 293 sh_mmcif_bitset(MASK_MBUFWEN, &host->regs->ce_int_mask); 294 295 time = mmcif_wait_interrupt_flag(host); 296 297 if (time == 0 || host->sd_error != 0) 298 return sh_mmcif_error_manage(host); 299 300 host->wait_int = 0; 301 for (i = 0; i < blocksize / 4; i++) 302 sh_mmcif_write(*p++, &host->regs->ce_data); 303 304 WATCHDOG_RESET(); 305 } 306 return 0; 307 } 308 309 static void sh_mmcif_get_response(struct sh_mmcif_host *host, 310 struct mmc_cmd *cmd) 311 { 312 if (cmd->resp_type & MMC_RSP_136) { 313 cmd->response[0] = sh_mmcif_read(&host->regs->ce_resp3); 314 cmd->response[1] = sh_mmcif_read(&host->regs->ce_resp2); 315 cmd->response[2] = sh_mmcif_read(&host->regs->ce_resp1); 316 cmd->response[3] = sh_mmcif_read(&host->regs->ce_resp0); 317 debug(" RESP %08x, %08x, %08x, %08x\n", cmd->response[0], 318 cmd->response[1], cmd->response[2], cmd->response[3]); 319 } else { 320 cmd->response[0] = sh_mmcif_read(&host->regs->ce_resp0); 321 } 322 } 323 324 static void sh_mmcif_get_cmd12response(struct sh_mmcif_host *host, 325 struct mmc_cmd *cmd) 326 { 327 cmd->response[0] = sh_mmcif_read(&host->regs->ce_resp_cmd12); 328 } 329 330 static u32 sh_mmcif_set_cmd(struct sh_mmcif_host *host, 331 struct mmc_data *data, struct mmc_cmd *cmd) 332 { 333 u32 tmp = 0; 334 u32 opc = cmd->cmdidx; 335 336 /* Response Type check */ 337 switch (cmd->resp_type) { 338 case MMC_RSP_NONE: 339 tmp |= CMD_SET_RTYP_NO; 340 break; 341 case MMC_RSP_R1: 342 case MMC_RSP_R1b: 343 case MMC_RSP_R3: 344 tmp |= CMD_SET_RTYP_6B; 345 break; 346 case MMC_RSP_R2: 347 tmp |= CMD_SET_RTYP_17B; 348 break; 349 default: 350 printf(DRIVER_NAME": Not support type response.\n"); 351 break; 352 } 353 354 /* RBSY */ 355 if (opc == MMC_CMD_SWITCH) 356 tmp |= CMD_SET_RBSY; 357 358 /* WDAT / DATW */ 359 if (host->data) { 360 tmp |= CMD_SET_WDAT; 361 switch (host->bus_width) { 362 case MMC_BUS_WIDTH_1: 363 tmp |= CMD_SET_DATW_1; 364 break; 365 case MMC_BUS_WIDTH_4: 366 tmp |= CMD_SET_DATW_4; 367 break; 368 case MMC_BUS_WIDTH_8: 369 tmp |= CMD_SET_DATW_8; 370 break; 371 default: 372 printf(DRIVER_NAME": Not support bus width.\n"); 373 break; 374 } 375 } 376 /* DWEN */ 377 if (opc == MMC_CMD_WRITE_SINGLE_BLOCK || 378 opc == MMC_CMD_WRITE_MULTIPLE_BLOCK) 379 tmp |= CMD_SET_DWEN; 380 /* CMLTE/CMD12EN */ 381 if (opc == MMC_CMD_READ_MULTIPLE_BLOCK || 382 opc == MMC_CMD_WRITE_MULTIPLE_BLOCK) { 383 tmp |= CMD_SET_CMLTE | CMD_SET_CMD12EN; 384 sh_mmcif_bitset(data->blocks << 16, &host->regs->ce_block_set); 385 } 386 /* RIDXC[1:0] check bits */ 387 if (opc == MMC_CMD_SEND_OP_COND || opc == MMC_CMD_ALL_SEND_CID || 388 opc == MMC_CMD_SEND_CSD || opc == MMC_CMD_SEND_CID) 389 tmp |= CMD_SET_RIDXC_BITS; 390 /* RCRC7C[1:0] check bits */ 391 if (opc == MMC_CMD_SEND_OP_COND) 392 tmp |= CMD_SET_CRC7C_BITS; 393 /* RCRC7C[1:0] internal CRC7 */ 394 if (opc == MMC_CMD_ALL_SEND_CID || 395 opc == MMC_CMD_SEND_CSD || opc == MMC_CMD_SEND_CID) 396 tmp |= CMD_SET_CRC7C_INTERNAL; 397 398 return opc = ((opc << 24) | tmp); 399 } 400 401 static u32 sh_mmcif_data_trans(struct sh_mmcif_host *host, 402 struct mmc_data *data, u16 opc) 403 { 404 u32 ret; 405 406 switch (opc) { 407 case MMC_CMD_READ_MULTIPLE_BLOCK: 408 ret = sh_mmcif_multi_read(host, data); 409 break; 410 case MMC_CMD_WRITE_MULTIPLE_BLOCK: 411 ret = sh_mmcif_multi_write(host, data); 412 break; 413 case MMC_CMD_WRITE_SINGLE_BLOCK: 414 ret = sh_mmcif_single_write(host, data); 415 break; 416 case MMC_CMD_READ_SINGLE_BLOCK: 417 case MMC_CMD_SEND_EXT_CSD: 418 ret = sh_mmcif_single_read(host, data); 419 break; 420 default: 421 printf(DRIVER_NAME": NOT SUPPORT CMD = d'%08d\n", opc); 422 ret = -EINVAL; 423 break; 424 } 425 return ret; 426 } 427 428 static int sh_mmcif_start_cmd(struct sh_mmcif_host *host, 429 struct mmc_data *data, struct mmc_cmd *cmd) 430 { 431 long time; 432 int ret = 0, mask = 0; 433 u32 opc = cmd->cmdidx; 434 435 if (opc == MMC_CMD_STOP_TRANSMISSION) { 436 /* MMCIF sends the STOP command automatically */ 437 if (host->last_cmd == MMC_CMD_READ_MULTIPLE_BLOCK) 438 sh_mmcif_bitset(MASK_MCMD12DRE, 439 &host->regs->ce_int_mask); 440 else 441 sh_mmcif_bitset(MASK_MCMD12RBE, 442 &host->regs->ce_int_mask); 443 444 time = mmcif_wait_interrupt_flag(host); 445 if (time == 0 || host->sd_error != 0) 446 return sh_mmcif_error_manage(host); 447 448 sh_mmcif_get_cmd12response(host, cmd); 449 return 0; 450 } 451 if (opc == MMC_CMD_SWITCH) 452 mask = MASK_MRBSYE; 453 else 454 mask = MASK_MCRSPE; 455 456 mask |= MASK_MCMDVIO | MASK_MBUFVIO | MASK_MWDATERR | 457 MASK_MRDATERR | MASK_MRIDXERR | MASK_MRSPERR | 458 MASK_MCCSTO | MASK_MCRCSTO | MASK_MWDATTO | 459 MASK_MRDATTO | MASK_MRBSYTO | MASK_MRSPTO; 460 461 if (host->data) { 462 sh_mmcif_write(0, &host->regs->ce_block_set); 463 sh_mmcif_write(data->blocksize, &host->regs->ce_block_set); 464 } 465 opc = sh_mmcif_set_cmd(host, data, cmd); 466 467 sh_mmcif_write(INT_START_MAGIC, &host->regs->ce_int); 468 sh_mmcif_write(mask, &host->regs->ce_int_mask); 469 470 debug("CMD%d ARG:%08x\n", cmd->cmdidx, cmd->cmdarg); 471 /* set arg */ 472 sh_mmcif_write(cmd->cmdarg, &host->regs->ce_arg); 473 host->wait_int = 0; 474 /* set cmd */ 475 sh_mmcif_write(opc, &host->regs->ce_cmd_set); 476 477 time = mmcif_wait_interrupt_flag(host); 478 if (time == 0) 479 return sh_mmcif_error_manage(host); 480 481 if (host->sd_error) { 482 switch (cmd->cmdidx) { 483 case MMC_CMD_ALL_SEND_CID: 484 case MMC_CMD_SELECT_CARD: 485 case MMC_CMD_APP_CMD: 486 ret = -ETIMEDOUT; 487 break; 488 default: 489 printf(DRIVER_NAME": Cmd(d'%d) err\n", cmd->cmdidx); 490 ret = sh_mmcif_error_manage(host); 491 break; 492 } 493 host->sd_error = 0; 494 host->wait_int = 0; 495 return ret; 496 } 497 498 /* if no response */ 499 if (!(opc & 0x00C00000)) 500 return 0; 501 502 if (host->wait_int == 1) { 503 sh_mmcif_get_response(host, cmd); 504 host->wait_int = 0; 505 } 506 if (host->data) 507 ret = sh_mmcif_data_trans(host, data, cmd->cmdidx); 508 host->last_cmd = cmd->cmdidx; 509 510 return ret; 511 } 512 513 static int sh_mmcif_request(struct mmc *mmc, struct mmc_cmd *cmd, 514 struct mmc_data *data) 515 { 516 struct sh_mmcif_host *host = mmc->priv; 517 int ret; 518 519 WATCHDOG_RESET(); 520 521 switch (cmd->cmdidx) { 522 case MMC_CMD_APP_CMD: 523 return -ETIMEDOUT; 524 case MMC_CMD_SEND_EXT_CSD: /* = SD_SEND_IF_COND (8) */ 525 if (data) 526 /* ext_csd */ 527 break; 528 else 529 /* send_if_cond cmd (not support) */ 530 return -ETIMEDOUT; 531 default: 532 break; 533 } 534 host->sd_error = 0; 535 host->data = data; 536 ret = sh_mmcif_start_cmd(host, data, cmd); 537 host->data = NULL; 538 539 return ret; 540 } 541 542 static int sh_mmcif_set_ios(struct mmc *mmc) 543 { 544 struct sh_mmcif_host *host = mmc->priv; 545 546 if (mmc->clock) 547 sh_mmcif_clock_control(host, mmc->clock); 548 549 if (mmc->bus_width == 8) 550 host->bus_width = MMC_BUS_WIDTH_8; 551 else if (mmc->bus_width == 4) 552 host->bus_width = MMC_BUS_WIDTH_4; 553 else 554 host->bus_width = MMC_BUS_WIDTH_1; 555 556 debug("clock = %d, buswidth = %d\n", mmc->clock, mmc->bus_width); 557 558 return 0; 559 } 560 561 static int sh_mmcif_init(struct mmc *mmc) 562 { 563 struct sh_mmcif_host *host = mmc->priv; 564 565 sh_mmcif_sync_reset(host); 566 sh_mmcif_write(MASK_ALL, &host->regs->ce_int_mask); 567 return 0; 568 } 569 570 static const struct mmc_ops sh_mmcif_ops = { 571 .send_cmd = sh_mmcif_request, 572 .set_ios = sh_mmcif_set_ios, 573 .init = sh_mmcif_init, 574 }; 575 576 static struct mmc_config sh_mmcif_cfg = { 577 .name = DRIVER_NAME, 578 .ops = &sh_mmcif_ops, 579 .host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_4BIT | 580 MMC_MODE_8BIT, 581 .voltages = MMC_VDD_32_33 | MMC_VDD_33_34, 582 .b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT, 583 }; 584 585 int mmcif_mmc_init(void) 586 { 587 struct mmc *mmc; 588 struct sh_mmcif_host *host = NULL; 589 590 host = malloc(sizeof(struct sh_mmcif_host)); 591 if (!host) 592 return -ENOMEM; 593 memset(host, 0, sizeof(*host)); 594 595 host->regs = (struct sh_mmcif_regs *)CONFIG_SH_MMCIF_ADDR; 596 host->clk = CONFIG_SH_MMCIF_CLK; 597 598 sh_mmcif_cfg.f_min = MMC_CLK_DIV_MIN(host->clk); 599 sh_mmcif_cfg.f_max = MMC_CLK_DIV_MAX(host->clk); 600 601 mmc = mmc_create(&sh_mmcif_cfg, host); 602 if (mmc == NULL) { 603 free(host); 604 return -ENOMEM; 605 } 606 607 return 0; 608 } 609