1 /* 2 * drivers/mmc/sh_sdhi.c 3 * 4 * SD/MMC driver for Renesas rmobile ARM SoCs. 5 * 6 * Copyright (C) 2011,2013-2017 Renesas Electronics Corporation 7 * Copyright (C) 2014 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com> 8 * Copyright (C) 2008-2009 Renesas Solutions Corp. 9 * 10 * SPDX-License-Identifier: GPL-2.0 11 */ 12 13 #include <common.h> 14 #include <malloc.h> 15 #include <mmc.h> 16 #include <linux/errno.h> 17 #include <asm/io.h> 18 #include <asm/arch/rmobile.h> 19 #include <asm/arch/sh_sdhi.h> 20 21 #define DRIVER_NAME "sh-sdhi" 22 23 struct sh_sdhi_host { 24 unsigned long addr; 25 int ch; 26 int bus_shift; 27 unsigned long quirks; 28 unsigned char wait_int; 29 unsigned char sd_error; 30 unsigned char detect_waiting; 31 }; 32 33 static inline void sh_sdhi_writeq(struct sh_sdhi_host *host, int reg, u64 val) 34 { 35 writeq(val, host->addr + (reg << host->bus_shift)); 36 } 37 38 static inline u64 sh_sdhi_readq(struct sh_sdhi_host *host, int reg) 39 { 40 return readq(host->addr + (reg << host->bus_shift)); 41 } 42 43 static inline void sh_sdhi_writew(struct sh_sdhi_host *host, int reg, u16 val) 44 { 45 writew(val, host->addr + (reg << host->bus_shift)); 46 } 47 48 static inline u16 sh_sdhi_readw(struct sh_sdhi_host *host, int reg) 49 { 50 return readw(host->addr + (reg << host->bus_shift)); 51 } 52 53 static void *mmc_priv(struct mmc *mmc) 54 { 55 return (void *)mmc->priv; 56 } 57 58 static void sh_sdhi_detect(struct sh_sdhi_host *host) 59 { 60 sh_sdhi_writew(host, SDHI_OPTION, 61 OPT_BUS_WIDTH_1 | sh_sdhi_readw(host, SDHI_OPTION)); 62 63 host->detect_waiting = 0; 64 } 65 66 static int sh_sdhi_intr(void *dev_id) 67 { 68 struct sh_sdhi_host *host = dev_id; 69 int state1 = 0, state2 = 0; 70 71 state1 = sh_sdhi_readw(host, SDHI_INFO1); 72 state2 = sh_sdhi_readw(host, SDHI_INFO2); 73 74 debug("%s: state1 = %x, state2 = %x\n", __func__, state1, state2); 75 76 /* CARD Insert */ 77 if (state1 & INFO1_CARD_IN) { 78 sh_sdhi_writew(host, SDHI_INFO1, ~INFO1_CARD_IN); 79 if (!host->detect_waiting) { 80 host->detect_waiting = 1; 81 sh_sdhi_detect(host); 82 } 83 sh_sdhi_writew(host, SDHI_INFO1_MASK, INFO1M_RESP_END | 84 INFO1M_ACCESS_END | INFO1M_CARD_IN | 85 INFO1M_DATA3_CARD_RE | INFO1M_DATA3_CARD_IN); 86 return -EAGAIN; 87 } 88 /* CARD Removal */ 89 if (state1 & INFO1_CARD_RE) { 90 sh_sdhi_writew(host, SDHI_INFO1, ~INFO1_CARD_RE); 91 if (!host->detect_waiting) { 92 host->detect_waiting = 1; 93 sh_sdhi_detect(host); 94 } 95 sh_sdhi_writew(host, SDHI_INFO1_MASK, INFO1M_RESP_END | 96 INFO1M_ACCESS_END | INFO1M_CARD_RE | 97 INFO1M_DATA3_CARD_RE | INFO1M_DATA3_CARD_IN); 98 sh_sdhi_writew(host, SDHI_SDIO_INFO1_MASK, SDIO_INFO1M_ON); 99 sh_sdhi_writew(host, SDHI_SDIO_MODE, SDIO_MODE_OFF); 100 return -EAGAIN; 101 } 102 103 if (state2 & INFO2_ALL_ERR) { 104 sh_sdhi_writew(host, SDHI_INFO2, 105 (unsigned short)~(INFO2_ALL_ERR)); 106 sh_sdhi_writew(host, SDHI_INFO2_MASK, 107 INFO2M_ALL_ERR | 108 sh_sdhi_readw(host, SDHI_INFO2_MASK)); 109 host->sd_error = 1; 110 host->wait_int = 1; 111 return 0; 112 } 113 /* Respons End */ 114 if (state1 & INFO1_RESP_END) { 115 sh_sdhi_writew(host, SDHI_INFO1, ~INFO1_RESP_END); 116 sh_sdhi_writew(host, SDHI_INFO1_MASK, 117 INFO1M_RESP_END | 118 sh_sdhi_readw(host, SDHI_INFO1_MASK)); 119 host->wait_int = 1; 120 return 0; 121 } 122 /* SD_BUF Read Enable */ 123 if (state2 & INFO2_BRE_ENABLE) { 124 sh_sdhi_writew(host, SDHI_INFO2, ~INFO2_BRE_ENABLE); 125 sh_sdhi_writew(host, SDHI_INFO2_MASK, 126 INFO2M_BRE_ENABLE | INFO2M_BUF_ILL_READ | 127 sh_sdhi_readw(host, SDHI_INFO2_MASK)); 128 host->wait_int = 1; 129 return 0; 130 } 131 /* SD_BUF Write Enable */ 132 if (state2 & INFO2_BWE_ENABLE) { 133 sh_sdhi_writew(host, SDHI_INFO2, ~INFO2_BWE_ENABLE); 134 sh_sdhi_writew(host, SDHI_INFO2_MASK, 135 INFO2_BWE_ENABLE | INFO2M_BUF_ILL_WRITE | 136 sh_sdhi_readw(host, SDHI_INFO2_MASK)); 137 host->wait_int = 1; 138 return 0; 139 } 140 /* Access End */ 141 if (state1 & INFO1_ACCESS_END) { 142 sh_sdhi_writew(host, SDHI_INFO1, ~INFO1_ACCESS_END); 143 sh_sdhi_writew(host, SDHI_INFO1_MASK, 144 INFO1_ACCESS_END | 145 sh_sdhi_readw(host, SDHI_INFO1_MASK)); 146 host->wait_int = 1; 147 return 0; 148 } 149 return -EAGAIN; 150 } 151 152 static int sh_sdhi_wait_interrupt_flag(struct sh_sdhi_host *host) 153 { 154 int timeout = 10000000; 155 156 while (1) { 157 timeout--; 158 if (timeout < 0) { 159 debug(DRIVER_NAME": %s timeout\n", __func__); 160 return 0; 161 } 162 163 if (!sh_sdhi_intr(host)) 164 break; 165 166 udelay(1); /* 1 usec */ 167 } 168 169 return 1; /* Return value: NOT 0 = complete waiting */ 170 } 171 172 static int sh_sdhi_clock_control(struct sh_sdhi_host *host, unsigned long clk) 173 { 174 u32 clkdiv, i, timeout; 175 176 if (sh_sdhi_readw(host, SDHI_INFO2) & (1 << 14)) { 177 printf(DRIVER_NAME": Busy state ! Cannot change the clock\n"); 178 return -EBUSY; 179 } 180 181 sh_sdhi_writew(host, SDHI_CLK_CTRL, 182 ~CLK_ENABLE & sh_sdhi_readw(host, SDHI_CLK_CTRL)); 183 184 if (clk == 0) 185 return -EIO; 186 187 clkdiv = 0x80; 188 i = CONFIG_SH_SDHI_FREQ >> (0x8 + 1); 189 for (; clkdiv && clk >= (i << 1); (clkdiv >>= 1)) 190 i <<= 1; 191 192 sh_sdhi_writew(host, SDHI_CLK_CTRL, clkdiv); 193 194 timeout = 100000; 195 /* Waiting for SD Bus busy to be cleared */ 196 while (timeout--) { 197 if ((sh_sdhi_readw(host, SDHI_INFO2) & 0x2000)) 198 break; 199 } 200 201 if (timeout) 202 sh_sdhi_writew(host, SDHI_CLK_CTRL, 203 CLK_ENABLE | sh_sdhi_readw(host, SDHI_CLK_CTRL)); 204 else 205 return -EBUSY; 206 207 return 0; 208 } 209 210 static int sh_sdhi_sync_reset(struct sh_sdhi_host *host) 211 { 212 u32 timeout; 213 sh_sdhi_writew(host, SDHI_SOFT_RST, SOFT_RST_ON); 214 sh_sdhi_writew(host, SDHI_SOFT_RST, SOFT_RST_OFF); 215 sh_sdhi_writew(host, SDHI_CLK_CTRL, 216 CLK_ENABLE | sh_sdhi_readw(host, SDHI_CLK_CTRL)); 217 218 timeout = 100000; 219 while (timeout--) { 220 if (!(sh_sdhi_readw(host, SDHI_INFO2) & INFO2_CBUSY)) 221 break; 222 udelay(100); 223 } 224 225 if (!timeout) 226 return -EBUSY; 227 228 if (host->quirks & SH_SDHI_QUIRK_16BIT_BUF) 229 sh_sdhi_writew(host, SDHI_HOST_MODE, 1); 230 231 return 0; 232 } 233 234 static int sh_sdhi_error_manage(struct sh_sdhi_host *host) 235 { 236 unsigned short e_state1, e_state2; 237 int ret; 238 239 host->sd_error = 0; 240 host->wait_int = 0; 241 242 e_state1 = sh_sdhi_readw(host, SDHI_ERR_STS1); 243 e_state2 = sh_sdhi_readw(host, SDHI_ERR_STS2); 244 if (e_state2 & ERR_STS2_SYS_ERROR) { 245 if (e_state2 & ERR_STS2_RES_STOP_TIMEOUT) 246 ret = -ETIMEDOUT; 247 else 248 ret = -EILSEQ; 249 debug("%s: ERR_STS2 = %04x\n", 250 DRIVER_NAME, sh_sdhi_readw(host, SDHI_ERR_STS2)); 251 sh_sdhi_sync_reset(host); 252 253 sh_sdhi_writew(host, SDHI_INFO1_MASK, 254 INFO1M_DATA3_CARD_RE | INFO1M_DATA3_CARD_IN); 255 return ret; 256 } 257 if (e_state1 & ERR_STS1_CRC_ERROR || e_state1 & ERR_STS1_CMD_ERROR) 258 ret = -EILSEQ; 259 else 260 ret = -ETIMEDOUT; 261 262 debug("%s: ERR_STS1 = %04x\n", 263 DRIVER_NAME, sh_sdhi_readw(host, SDHI_ERR_STS1)); 264 sh_sdhi_sync_reset(host); 265 sh_sdhi_writew(host, SDHI_INFO1_MASK, 266 INFO1M_DATA3_CARD_RE | INFO1M_DATA3_CARD_IN); 267 return ret; 268 } 269 270 static int sh_sdhi_single_read(struct sh_sdhi_host *host, struct mmc_data *data) 271 { 272 long time; 273 unsigned short blocksize, i; 274 unsigned short *p = (unsigned short *)data->dest; 275 u64 *q = (u64 *)data->dest; 276 277 if ((unsigned long)p & 0x00000001) { 278 debug(DRIVER_NAME": %s: The data pointer is unaligned.", 279 __func__); 280 return -EIO; 281 } 282 283 host->wait_int = 0; 284 sh_sdhi_writew(host, SDHI_INFO2_MASK, 285 ~(INFO2M_BRE_ENABLE | INFO2M_BUF_ILL_READ) & 286 sh_sdhi_readw(host, SDHI_INFO2_MASK)); 287 sh_sdhi_writew(host, SDHI_INFO1_MASK, 288 ~INFO1M_ACCESS_END & 289 sh_sdhi_readw(host, SDHI_INFO1_MASK)); 290 time = sh_sdhi_wait_interrupt_flag(host); 291 if (time == 0 || host->sd_error != 0) 292 return sh_sdhi_error_manage(host); 293 294 host->wait_int = 0; 295 blocksize = sh_sdhi_readw(host, SDHI_SIZE); 296 if (host->quirks & SH_SDHI_QUIRK_64BIT_BUF) 297 for (i = 0; i < blocksize / 8; i++) 298 *q++ = sh_sdhi_readq(host, SDHI_BUF0); 299 else 300 for (i = 0; i < blocksize / 2; i++) 301 *p++ = sh_sdhi_readw(host, SDHI_BUF0); 302 303 time = sh_sdhi_wait_interrupt_flag(host); 304 if (time == 0 || host->sd_error != 0) 305 return sh_sdhi_error_manage(host); 306 307 host->wait_int = 0; 308 return 0; 309 } 310 311 static int sh_sdhi_multi_read(struct sh_sdhi_host *host, struct mmc_data *data) 312 { 313 long time; 314 unsigned short blocksize, i, sec; 315 unsigned short *p = (unsigned short *)data->dest; 316 u64 *q = (u64 *)data->dest; 317 318 if ((unsigned long)p & 0x00000001) { 319 debug(DRIVER_NAME": %s: The data pointer is unaligned.", 320 __func__); 321 return -EIO; 322 } 323 324 debug("%s: blocks = %d, blocksize = %d\n", 325 __func__, data->blocks, data->blocksize); 326 327 host->wait_int = 0; 328 for (sec = 0; sec < data->blocks; sec++) { 329 sh_sdhi_writew(host, SDHI_INFO2_MASK, 330 ~(INFO2M_BRE_ENABLE | INFO2M_BUF_ILL_READ) & 331 sh_sdhi_readw(host, SDHI_INFO2_MASK)); 332 333 time = sh_sdhi_wait_interrupt_flag(host); 334 if (time == 0 || host->sd_error != 0) 335 return sh_sdhi_error_manage(host); 336 337 host->wait_int = 0; 338 blocksize = sh_sdhi_readw(host, SDHI_SIZE); 339 if (host->quirks & SH_SDHI_QUIRK_64BIT_BUF) 340 for (i = 0; i < blocksize / 8; i++) 341 *q++ = sh_sdhi_readq(host, SDHI_BUF0); 342 else 343 for (i = 0; i < blocksize / 2; i++) 344 *p++ = sh_sdhi_readw(host, SDHI_BUF0); 345 } 346 347 return 0; 348 } 349 350 static int sh_sdhi_single_write(struct sh_sdhi_host *host, 351 struct mmc_data *data) 352 { 353 long time; 354 unsigned short blocksize, i; 355 const unsigned short *p = (const unsigned short *)data->src; 356 const u64 *q = (const u64 *)data->src; 357 358 if ((unsigned long)p & 0x00000001) { 359 debug(DRIVER_NAME": %s: The data pointer is unaligned.", 360 __func__); 361 return -EIO; 362 } 363 364 debug("%s: blocks = %d, blocksize = %d\n", 365 __func__, data->blocks, data->blocksize); 366 367 host->wait_int = 0; 368 sh_sdhi_writew(host, SDHI_INFO2_MASK, 369 ~(INFO2M_BWE_ENABLE | INFO2M_BUF_ILL_WRITE) & 370 sh_sdhi_readw(host, SDHI_INFO2_MASK)); 371 sh_sdhi_writew(host, SDHI_INFO1_MASK, 372 ~INFO1M_ACCESS_END & 373 sh_sdhi_readw(host, SDHI_INFO1_MASK)); 374 375 time = sh_sdhi_wait_interrupt_flag(host); 376 if (time == 0 || host->sd_error != 0) 377 return sh_sdhi_error_manage(host); 378 379 host->wait_int = 0; 380 blocksize = sh_sdhi_readw(host, SDHI_SIZE); 381 if (host->quirks & SH_SDHI_QUIRK_64BIT_BUF) 382 for (i = 0; i < blocksize / 8; i++) 383 sh_sdhi_writeq(host, SDHI_BUF0, *q++); 384 else 385 for (i = 0; i < blocksize / 2; i++) 386 sh_sdhi_writew(host, SDHI_BUF0, *p++); 387 388 time = sh_sdhi_wait_interrupt_flag(host); 389 if (time == 0 || host->sd_error != 0) 390 return sh_sdhi_error_manage(host); 391 392 host->wait_int = 0; 393 return 0; 394 } 395 396 static int sh_sdhi_multi_write(struct sh_sdhi_host *host, struct mmc_data *data) 397 { 398 long time; 399 unsigned short i, sec, blocksize; 400 const unsigned short *p = (const unsigned short *)data->src; 401 const u64 *q = (const u64 *)data->src; 402 403 debug("%s: blocks = %d, blocksize = %d\n", 404 __func__, data->blocks, data->blocksize); 405 406 host->wait_int = 0; 407 for (sec = 0; sec < data->blocks; sec++) { 408 sh_sdhi_writew(host, SDHI_INFO2_MASK, 409 ~(INFO2M_BWE_ENABLE | INFO2M_BUF_ILL_WRITE) & 410 sh_sdhi_readw(host, SDHI_INFO2_MASK)); 411 412 time = sh_sdhi_wait_interrupt_flag(host); 413 if (time == 0 || host->sd_error != 0) 414 return sh_sdhi_error_manage(host); 415 416 host->wait_int = 0; 417 blocksize = sh_sdhi_readw(host, SDHI_SIZE); 418 if (host->quirks & SH_SDHI_QUIRK_64BIT_BUF) 419 for (i = 0; i < blocksize / 8; i++) 420 sh_sdhi_writeq(host, SDHI_BUF0, *q++); 421 else 422 for (i = 0; i < blocksize / 2; i++) 423 sh_sdhi_writew(host, SDHI_BUF0, *p++); 424 } 425 426 return 0; 427 } 428 429 static void sh_sdhi_get_response(struct sh_sdhi_host *host, struct mmc_cmd *cmd) 430 { 431 unsigned short i, j, cnt = 1; 432 unsigned short resp[8]; 433 434 if (cmd->resp_type & MMC_RSP_136) { 435 cnt = 4; 436 resp[0] = sh_sdhi_readw(host, SDHI_RSP00); 437 resp[1] = sh_sdhi_readw(host, SDHI_RSP01); 438 resp[2] = sh_sdhi_readw(host, SDHI_RSP02); 439 resp[3] = sh_sdhi_readw(host, SDHI_RSP03); 440 resp[4] = sh_sdhi_readw(host, SDHI_RSP04); 441 resp[5] = sh_sdhi_readw(host, SDHI_RSP05); 442 resp[6] = sh_sdhi_readw(host, SDHI_RSP06); 443 resp[7] = sh_sdhi_readw(host, SDHI_RSP07); 444 445 /* SDHI REGISTER SPECIFICATION */ 446 for (i = 7, j = 6; i > 0; i--) { 447 resp[i] = (resp[i] << 8) & 0xff00; 448 resp[i] |= (resp[j--] >> 8) & 0x00ff; 449 } 450 resp[0] = (resp[0] << 8) & 0xff00; 451 } else { 452 resp[0] = sh_sdhi_readw(host, SDHI_RSP00); 453 resp[1] = sh_sdhi_readw(host, SDHI_RSP01); 454 } 455 456 #if defined(__BIG_ENDIAN_BITFIELD) 457 if (cnt == 4) { 458 cmd->response[0] = (resp[6] << 16) | resp[7]; 459 cmd->response[1] = (resp[4] << 16) | resp[5]; 460 cmd->response[2] = (resp[2] << 16) | resp[3]; 461 cmd->response[3] = (resp[0] << 16) | resp[1]; 462 } else { 463 cmd->response[0] = (resp[0] << 16) | resp[1]; 464 } 465 #else 466 if (cnt == 4) { 467 cmd->response[0] = (resp[7] << 16) | resp[6]; 468 cmd->response[1] = (resp[5] << 16) | resp[4]; 469 cmd->response[2] = (resp[3] << 16) | resp[2]; 470 cmd->response[3] = (resp[1] << 16) | resp[0]; 471 } else { 472 cmd->response[0] = (resp[1] << 16) | resp[0]; 473 } 474 #endif /* __BIG_ENDIAN_BITFIELD */ 475 } 476 477 static unsigned short sh_sdhi_set_cmd(struct sh_sdhi_host *host, 478 struct mmc_data *data, unsigned short opc) 479 { 480 switch (opc) { 481 case SD_CMD_APP_SEND_OP_COND: 482 case SD_CMD_APP_SEND_SCR: 483 opc |= SDHI_APP; 484 break; 485 case SD_CMD_APP_SET_BUS_WIDTH: 486 /* SD_APP_SET_BUS_WIDTH*/ 487 if (!data) 488 opc |= SDHI_APP; 489 else /* SD_SWITCH */ 490 opc = SDHI_SD_SWITCH; 491 break; 492 case MMC_CMD_SEND_OP_COND: 493 opc = SDHI_MMC_SEND_OP_COND; 494 break; 495 case MMC_CMD_SEND_EXT_CSD: 496 if (data) 497 opc = SDHI_MMC_SEND_EXT_CSD; 498 break; 499 default: 500 break; 501 } 502 return opc; 503 } 504 505 static unsigned short sh_sdhi_data_trans(struct sh_sdhi_host *host, 506 struct mmc_data *data, unsigned short opc) 507 { 508 unsigned short ret; 509 510 switch (opc) { 511 case MMC_CMD_READ_MULTIPLE_BLOCK: 512 ret = sh_sdhi_multi_read(host, data); 513 break; 514 case MMC_CMD_WRITE_MULTIPLE_BLOCK: 515 ret = sh_sdhi_multi_write(host, data); 516 break; 517 case MMC_CMD_WRITE_SINGLE_BLOCK: 518 ret = sh_sdhi_single_write(host, data); 519 break; 520 case MMC_CMD_READ_SINGLE_BLOCK: 521 case SDHI_SD_APP_SEND_SCR: 522 case SDHI_SD_SWITCH: /* SD_SWITCH */ 523 case SDHI_MMC_SEND_EXT_CSD: 524 ret = sh_sdhi_single_read(host, data); 525 break; 526 default: 527 printf(DRIVER_NAME": SD: NOT SUPPORT CMD = d'%04d\n", opc); 528 ret = -EINVAL; 529 break; 530 } 531 return ret; 532 } 533 534 static int sh_sdhi_start_cmd(struct sh_sdhi_host *host, 535 struct mmc_data *data, struct mmc_cmd *cmd) 536 { 537 long time; 538 unsigned short opc = cmd->cmdidx; 539 int ret = 0; 540 unsigned long timeout; 541 542 debug("opc = %d, arg = %x, resp_type = %x\n", 543 opc, cmd->cmdarg, cmd->resp_type); 544 545 if (opc == MMC_CMD_STOP_TRANSMISSION) { 546 /* SDHI sends the STOP command automatically by STOP reg */ 547 sh_sdhi_writew(host, SDHI_INFO1_MASK, ~INFO1M_ACCESS_END & 548 sh_sdhi_readw(host, SDHI_INFO1_MASK)); 549 550 time = sh_sdhi_wait_interrupt_flag(host); 551 if (time == 0 || host->sd_error != 0) 552 return sh_sdhi_error_manage(host); 553 554 sh_sdhi_get_response(host, cmd); 555 return 0; 556 } 557 558 if (data) { 559 if ((opc == MMC_CMD_READ_MULTIPLE_BLOCK) || 560 opc == MMC_CMD_WRITE_MULTIPLE_BLOCK) { 561 sh_sdhi_writew(host, SDHI_STOP, STOP_SEC_ENABLE); 562 sh_sdhi_writew(host, SDHI_SECCNT, data->blocks); 563 } 564 sh_sdhi_writew(host, SDHI_SIZE, data->blocksize); 565 } 566 opc = sh_sdhi_set_cmd(host, data, opc); 567 568 /* 569 * U-Boot cannot use interrupt. 570 * So this flag may not be clear by timing 571 */ 572 sh_sdhi_writew(host, SDHI_INFO1, ~INFO1_RESP_END); 573 574 sh_sdhi_writew(host, SDHI_INFO1_MASK, 575 INFO1M_RESP_END | sh_sdhi_readw(host, SDHI_INFO1_MASK)); 576 sh_sdhi_writew(host, SDHI_ARG0, 577 (unsigned short)(cmd->cmdarg & ARG0_MASK)); 578 sh_sdhi_writew(host, SDHI_ARG1, 579 (unsigned short)((cmd->cmdarg >> 16) & ARG1_MASK)); 580 581 timeout = 100000; 582 /* Waiting for SD Bus busy to be cleared */ 583 while (timeout--) { 584 if ((sh_sdhi_readw(host, SDHI_INFO2) & 0x2000)) 585 break; 586 } 587 588 host->wait_int = 0; 589 sh_sdhi_writew(host, SDHI_INFO1_MASK, 590 ~INFO1M_RESP_END & sh_sdhi_readw(host, SDHI_INFO1_MASK)); 591 sh_sdhi_writew(host, SDHI_INFO2_MASK, 592 ~(INFO2M_CMD_ERROR | INFO2M_CRC_ERROR | 593 INFO2M_END_ERROR | INFO2M_TIMEOUT | 594 INFO2M_RESP_TIMEOUT | INFO2M_ILA) & 595 sh_sdhi_readw(host, SDHI_INFO2_MASK)); 596 597 sh_sdhi_writew(host, SDHI_CMD, (unsigned short)(opc & CMD_MASK)); 598 599 time = sh_sdhi_wait_interrupt_flag(host); 600 if (!time) 601 return sh_sdhi_error_manage(host); 602 603 if (host->sd_error) { 604 switch (cmd->cmdidx) { 605 case MMC_CMD_ALL_SEND_CID: 606 case MMC_CMD_SELECT_CARD: 607 case SD_CMD_SEND_IF_COND: 608 case MMC_CMD_APP_CMD: 609 ret = -ETIMEDOUT; 610 break; 611 default: 612 debug(DRIVER_NAME": Cmd(d'%d) err\n", opc); 613 debug(DRIVER_NAME": cmdidx = %d\n", cmd->cmdidx); 614 ret = sh_sdhi_error_manage(host); 615 break; 616 } 617 host->sd_error = 0; 618 host->wait_int = 0; 619 return ret; 620 } 621 if (sh_sdhi_readw(host, SDHI_INFO1) & INFO1_RESP_END) 622 return -EINVAL; 623 624 if (host->wait_int) { 625 sh_sdhi_get_response(host, cmd); 626 host->wait_int = 0; 627 } 628 if (data) 629 ret = sh_sdhi_data_trans(host, data, opc); 630 631 debug("ret = %d, resp = %08x, %08x, %08x, %08x\n", 632 ret, cmd->response[0], cmd->response[1], 633 cmd->response[2], cmd->response[3]); 634 return ret; 635 } 636 637 static int sh_sdhi_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, 638 struct mmc_data *data) 639 { 640 struct sh_sdhi_host *host = mmc_priv(mmc); 641 int ret; 642 643 host->sd_error = 0; 644 645 ret = sh_sdhi_start_cmd(host, data, cmd); 646 647 return ret; 648 } 649 650 static int sh_sdhi_set_ios(struct mmc *mmc) 651 { 652 int ret; 653 struct sh_sdhi_host *host = mmc_priv(mmc); 654 655 ret = sh_sdhi_clock_control(host, mmc->clock); 656 if (ret) 657 return -EINVAL; 658 659 if (mmc->bus_width == 8) 660 sh_sdhi_writew(host, SDHI_OPTION, 661 OPT_BUS_WIDTH_8 | (~OPT_BUS_WIDTH_M & 662 sh_sdhi_readw(host, SDHI_OPTION))); 663 else if (mmc->bus_width == 4) 664 sh_sdhi_writew(host, SDHI_OPTION, 665 OPT_BUS_WIDTH_4 | (~OPT_BUS_WIDTH_M & 666 sh_sdhi_readw(host, SDHI_OPTION))); 667 else 668 sh_sdhi_writew(host, SDHI_OPTION, 669 OPT_BUS_WIDTH_1 | (~OPT_BUS_WIDTH_M & 670 sh_sdhi_readw(host, SDHI_OPTION))); 671 672 debug("clock = %d, buswidth = %d\n", mmc->clock, mmc->bus_width); 673 674 return 0; 675 } 676 677 static int sh_sdhi_initialize(struct mmc *mmc) 678 { 679 struct sh_sdhi_host *host = mmc_priv(mmc); 680 int ret = sh_sdhi_sync_reset(host); 681 682 sh_sdhi_writew(host, SDHI_PORTSEL, USE_1PORT); 683 684 #if defined(__BIG_ENDIAN_BITFIELD) 685 sh_sdhi_writew(host, SDHI_EXT_SWAP, SET_SWAP); 686 #endif 687 688 sh_sdhi_writew(host, SDHI_INFO1_MASK, INFO1M_RESP_END | 689 INFO1M_ACCESS_END | INFO1M_CARD_RE | 690 INFO1M_DATA3_CARD_RE | INFO1M_DATA3_CARD_IN); 691 692 return ret; 693 } 694 695 static const struct mmc_ops sh_sdhi_ops = { 696 .send_cmd = sh_sdhi_send_cmd, 697 .set_ios = sh_sdhi_set_ios, 698 .init = sh_sdhi_initialize, 699 }; 700 701 #ifdef CONFIG_RCAR_GEN3 702 static struct mmc_config sh_sdhi_cfg = { 703 .name = DRIVER_NAME, 704 .ops = &sh_sdhi_ops, 705 .f_min = CLKDEV_INIT, 706 .f_max = CLKDEV_HS_DATA, 707 .voltages = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34, 708 .host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT | MMC_MODE_HS | 709 MMC_MODE_HS_52MHz, 710 .part_type = PART_TYPE_DOS, 711 .b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT, 712 }; 713 #else 714 static struct mmc_config sh_sdhi_cfg = { 715 .name = DRIVER_NAME, 716 .ops = &sh_sdhi_ops, 717 .f_min = CLKDEV_INIT, 718 .f_max = CLKDEV_HS_DATA, 719 .voltages = MMC_VDD_32_33 | MMC_VDD_33_34, 720 .host_caps = MMC_MODE_4BIT | MMC_MODE_HS, 721 .part_type = PART_TYPE_DOS, 722 .b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT, 723 }; 724 #endif 725 726 int sh_sdhi_init(unsigned long addr, int ch, unsigned long quirks) 727 { 728 int ret = 0; 729 struct mmc *mmc; 730 struct sh_sdhi_host *host = NULL; 731 732 if (ch >= CONFIG_SYS_SH_SDHI_NR_CHANNEL) 733 return -ENODEV; 734 735 host = malloc(sizeof(struct sh_sdhi_host)); 736 if (!host) 737 return -ENOMEM; 738 739 mmc = mmc_create(&sh_sdhi_cfg, host); 740 if (!mmc) { 741 ret = -1; 742 goto error; 743 } 744 745 host->ch = ch; 746 host->addr = addr; 747 host->quirks = quirks; 748 749 if (host->quirks & SH_SDHI_QUIRK_64BIT_BUF) 750 host->bus_shift = 2; 751 else if (host->quirks & SH_SDHI_QUIRK_16BIT_BUF) 752 host->bus_shift = 1; 753 754 return ret; 755 error: 756 if (host) 757 free(host); 758 return ret; 759 } 760