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 <dm.h> 17 #include <linux/errno.h> 18 #include <linux/compat.h> 19 #include <linux/io.h> 20 #include <linux/sizes.h> 21 #include <asm/arch/rmobile.h> 22 #include <asm/arch/sh_sdhi.h> 23 #include <clk.h> 24 25 #define DRIVER_NAME "sh-sdhi" 26 27 struct sh_sdhi_host { 28 void __iomem *addr; 29 int ch; 30 int bus_shift; 31 unsigned long quirks; 32 unsigned char wait_int; 33 unsigned char sd_error; 34 unsigned char detect_waiting; 35 unsigned char app_cmd; 36 }; 37 38 static inline void sh_sdhi_writeq(struct sh_sdhi_host *host, int reg, u64 val) 39 { 40 writeq(val, host->addr + (reg << host->bus_shift)); 41 } 42 43 static inline u64 sh_sdhi_readq(struct sh_sdhi_host *host, int reg) 44 { 45 return readq(host->addr + (reg << host->bus_shift)); 46 } 47 48 static inline void sh_sdhi_writew(struct sh_sdhi_host *host, int reg, u16 val) 49 { 50 writew(val, host->addr + (reg << host->bus_shift)); 51 } 52 53 static inline u16 sh_sdhi_readw(struct sh_sdhi_host *host, int reg) 54 { 55 return readw(host->addr + (reg << host->bus_shift)); 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 if (host->app_cmd) { 481 if (!data) 482 host->app_cmd = 0; 483 return opc | BIT(6); 484 } 485 486 switch (opc) { 487 case MMC_CMD_SWITCH: 488 return opc | (data ? 0x1c00 : 0x40); 489 case MMC_CMD_SEND_EXT_CSD: 490 return opc | (data ? 0x1c00 : 0); 491 case MMC_CMD_SEND_OP_COND: 492 return opc | 0x0700; 493 case MMC_CMD_APP_CMD: 494 host->app_cmd = 1; 495 default: 496 return opc; 497 } 498 } 499 500 static unsigned short sh_sdhi_data_trans(struct sh_sdhi_host *host, 501 struct mmc_data *data, unsigned short opc) 502 { 503 if (host->app_cmd) { 504 host->app_cmd = 0; 505 switch (opc) { 506 case SD_CMD_APP_SEND_SCR: 507 case SD_CMD_APP_SD_STATUS: 508 return sh_sdhi_single_read(host, data); 509 default: 510 printf(DRIVER_NAME": SD: NOT SUPPORT APP CMD = d'%04d\n", 511 opc); 512 return -EINVAL; 513 } 514 } else { 515 switch (opc) { 516 case MMC_CMD_WRITE_MULTIPLE_BLOCK: 517 return sh_sdhi_multi_write(host, data); 518 case MMC_CMD_READ_MULTIPLE_BLOCK: 519 return sh_sdhi_multi_read(host, data); 520 case MMC_CMD_WRITE_SINGLE_BLOCK: 521 return sh_sdhi_single_write(host, data); 522 case MMC_CMD_READ_SINGLE_BLOCK: 523 case MMC_CMD_SWITCH: 524 case MMC_CMD_SEND_EXT_CSD:; 525 return sh_sdhi_single_read(host, data); 526 default: 527 printf(DRIVER_NAME": SD: NOT SUPPORT CMD = d'%04d\n", opc); 528 return -EINVAL; 529 } 530 } 531 } 532 533 static int sh_sdhi_start_cmd(struct sh_sdhi_host *host, 534 struct mmc_data *data, struct mmc_cmd *cmd) 535 { 536 long time; 537 unsigned short shcmd, opc = cmd->cmdidx; 538 int ret = 0; 539 unsigned long timeout; 540 541 debug("opc = %d, arg = %x, resp_type = %x\n", 542 opc, cmd->cmdarg, cmd->resp_type); 543 544 if (opc == MMC_CMD_STOP_TRANSMISSION) { 545 /* SDHI sends the STOP command automatically by STOP reg */ 546 sh_sdhi_writew(host, SDHI_INFO1_MASK, ~INFO1M_ACCESS_END & 547 sh_sdhi_readw(host, SDHI_INFO1_MASK)); 548 549 time = sh_sdhi_wait_interrupt_flag(host); 550 if (time == 0 || host->sd_error != 0) 551 return sh_sdhi_error_manage(host); 552 553 sh_sdhi_get_response(host, cmd); 554 return 0; 555 } 556 557 if (data) { 558 if ((opc == MMC_CMD_READ_MULTIPLE_BLOCK) || 559 opc == MMC_CMD_WRITE_MULTIPLE_BLOCK) { 560 sh_sdhi_writew(host, SDHI_STOP, STOP_SEC_ENABLE); 561 sh_sdhi_writew(host, SDHI_SECCNT, data->blocks); 562 } 563 sh_sdhi_writew(host, SDHI_SIZE, data->blocksize); 564 } 565 566 shcmd = 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)(shcmd & CMD_MASK)); 598 time = sh_sdhi_wait_interrupt_flag(host); 599 if (!time) { 600 host->app_cmd = 0; 601 return sh_sdhi_error_manage(host); 602 } 603 604 if (host->sd_error) { 605 switch (cmd->cmdidx) { 606 case MMC_CMD_ALL_SEND_CID: 607 case MMC_CMD_SELECT_CARD: 608 case SD_CMD_SEND_IF_COND: 609 case MMC_CMD_APP_CMD: 610 ret = -ETIMEDOUT; 611 break; 612 default: 613 debug(DRIVER_NAME": Cmd(d'%d) err\n", opc); 614 debug(DRIVER_NAME": cmdidx = %d\n", cmd->cmdidx); 615 ret = sh_sdhi_error_manage(host); 616 break; 617 } 618 host->sd_error = 0; 619 host->wait_int = 0; 620 host->app_cmd = 0; 621 return ret; 622 } 623 624 if (sh_sdhi_readw(host, SDHI_INFO1) & INFO1_RESP_END) { 625 host->app_cmd = 0; 626 return -EINVAL; 627 } 628 629 if (host->wait_int) { 630 sh_sdhi_get_response(host, cmd); 631 host->wait_int = 0; 632 } 633 634 if (data) 635 ret = sh_sdhi_data_trans(host, data, opc); 636 637 debug("ret = %d, resp = %08x, %08x, %08x, %08x\n", 638 ret, cmd->response[0], cmd->response[1], 639 cmd->response[2], cmd->response[3]); 640 return ret; 641 } 642 643 static int sh_sdhi_send_cmd_common(struct sh_sdhi_host *host, 644 struct mmc_cmd *cmd, struct mmc_data *data) 645 { 646 host->sd_error = 0; 647 648 return sh_sdhi_start_cmd(host, data, cmd); 649 } 650 651 static int sh_sdhi_set_ios_common(struct sh_sdhi_host *host, struct mmc *mmc) 652 { 653 int ret; 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_common(struct sh_sdhi_host *host) 678 { 679 int ret = sh_sdhi_sync_reset(host); 680 681 sh_sdhi_writew(host, SDHI_PORTSEL, USE_1PORT); 682 683 #if defined(__BIG_ENDIAN_BITFIELD) 684 sh_sdhi_writew(host, SDHI_EXT_SWAP, SET_SWAP); 685 #endif 686 687 sh_sdhi_writew(host, SDHI_INFO1_MASK, INFO1M_RESP_END | 688 INFO1M_ACCESS_END | INFO1M_CARD_RE | 689 INFO1M_DATA3_CARD_RE | INFO1M_DATA3_CARD_IN); 690 691 return ret; 692 } 693 694 #ifndef CONFIG_DM_MMC 695 static void *mmc_priv(struct mmc *mmc) 696 { 697 return (void *)mmc->priv; 698 } 699 700 static int sh_sdhi_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, 701 struct mmc_data *data) 702 { 703 struct sh_sdhi_host *host = mmc_priv(mmc); 704 705 return sh_sdhi_send_cmd_common(host, cmd, data); 706 } 707 708 static int sh_sdhi_set_ios(struct mmc *mmc) 709 { 710 struct sh_sdhi_host *host = mmc_priv(mmc); 711 712 return sh_sdhi_set_ios_common(host, mmc); 713 } 714 715 static int sh_sdhi_initialize(struct mmc *mmc) 716 { 717 struct sh_sdhi_host *host = mmc_priv(mmc); 718 719 return sh_sdhi_initialize_common(host); 720 } 721 722 static const struct mmc_ops sh_sdhi_ops = { 723 .send_cmd = sh_sdhi_send_cmd, 724 .set_ios = sh_sdhi_set_ios, 725 .init = sh_sdhi_initialize, 726 }; 727 728 #ifdef CONFIG_RCAR_GEN3 729 static struct mmc_config sh_sdhi_cfg = { 730 .name = DRIVER_NAME, 731 .ops = &sh_sdhi_ops, 732 .f_min = CLKDEV_INIT, 733 .f_max = CLKDEV_HS_DATA, 734 .voltages = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34, 735 .host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT | MMC_MODE_HS | 736 MMC_MODE_HS_52MHz, 737 .part_type = PART_TYPE_DOS, 738 .b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT, 739 }; 740 #else 741 static struct mmc_config sh_sdhi_cfg = { 742 .name = DRIVER_NAME, 743 .ops = &sh_sdhi_ops, 744 .f_min = CLKDEV_INIT, 745 .f_max = CLKDEV_HS_DATA, 746 .voltages = MMC_VDD_32_33 | MMC_VDD_33_34, 747 .host_caps = MMC_MODE_4BIT | MMC_MODE_HS, 748 .part_type = PART_TYPE_DOS, 749 .b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT, 750 }; 751 #endif 752 753 int sh_sdhi_init(unsigned long addr, int ch, unsigned long quirks) 754 { 755 int ret = 0; 756 struct mmc *mmc; 757 struct sh_sdhi_host *host = NULL; 758 759 if (ch >= CONFIG_SYS_SH_SDHI_NR_CHANNEL) 760 return -ENODEV; 761 762 host = malloc(sizeof(struct sh_sdhi_host)); 763 if (!host) 764 return -ENOMEM; 765 766 mmc = mmc_create(&sh_sdhi_cfg, host); 767 if (!mmc) { 768 ret = -1; 769 goto error; 770 } 771 772 host->ch = ch; 773 host->addr = (void __iomem *)addr; 774 host->quirks = quirks; 775 776 if (host->quirks & SH_SDHI_QUIRK_64BIT_BUF) 777 host->bus_shift = 2; 778 else if (host->quirks & SH_SDHI_QUIRK_16BIT_BUF) 779 host->bus_shift = 1; 780 781 return ret; 782 error: 783 if (host) 784 free(host); 785 return ret; 786 } 787 788 #else 789 790 struct sh_sdhi_plat { 791 struct mmc_config cfg; 792 struct mmc mmc; 793 }; 794 795 int sh_sdhi_dm_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, 796 struct mmc_data *data) 797 { 798 struct sh_sdhi_host *host = dev_get_priv(dev); 799 800 return sh_sdhi_send_cmd_common(host, cmd, data); 801 } 802 803 int sh_sdhi_dm_set_ios(struct udevice *dev) 804 { 805 struct sh_sdhi_host *host = dev_get_priv(dev); 806 struct mmc *mmc = mmc_get_mmc_dev(dev); 807 808 return sh_sdhi_set_ios_common(host, mmc); 809 } 810 811 static const struct dm_mmc_ops sh_sdhi_dm_ops = { 812 .send_cmd = sh_sdhi_dm_send_cmd, 813 .set_ios = sh_sdhi_dm_set_ios, 814 }; 815 816 static int sh_sdhi_dm_bind(struct udevice *dev) 817 { 818 struct sh_sdhi_plat *plat = dev_get_platdata(dev); 819 820 return mmc_bind(dev, &plat->mmc, &plat->cfg); 821 } 822 823 static int sh_sdhi_dm_probe(struct udevice *dev) 824 { 825 struct sh_sdhi_plat *plat = dev_get_platdata(dev); 826 struct sh_sdhi_host *host = dev_get_priv(dev); 827 struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); 828 struct clk sh_sdhi_clk; 829 const u32 quirks = dev_get_driver_data(dev); 830 fdt_addr_t base; 831 int ret; 832 833 base = devfdt_get_addr(dev); 834 if (base == FDT_ADDR_T_NONE) 835 return -EINVAL; 836 837 host->addr = devm_ioremap(dev, base, SZ_2K); 838 if (!host->addr) 839 return -ENOMEM; 840 841 ret = clk_get_by_index(dev, 0, &sh_sdhi_clk); 842 if (ret) { 843 debug("failed to get clock, ret=%d\n", ret); 844 return ret; 845 } 846 847 ret = clk_enable(&sh_sdhi_clk); 848 if (ret) { 849 debug("failed to enable clock, ret=%d\n", ret); 850 return ret; 851 } 852 853 host->quirks = quirks; 854 855 if (host->quirks & SH_SDHI_QUIRK_64BIT_BUF) 856 host->bus_shift = 2; 857 else if (host->quirks & SH_SDHI_QUIRK_16BIT_BUF) 858 host->bus_shift = 1; 859 860 plat->cfg.name = dev->name; 861 plat->cfg.host_caps = MMC_MODE_HS_52MHz | MMC_MODE_HS; 862 863 switch (fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), "bus-width", 864 1)) { 865 case 8: 866 plat->cfg.host_caps |= MMC_MODE_8BIT; 867 break; 868 case 4: 869 plat->cfg.host_caps |= MMC_MODE_4BIT; 870 break; 871 case 1: 872 break; 873 default: 874 dev_err(dev, "Invalid \"bus-width\" value\n"); 875 return -EINVAL; 876 } 877 878 sh_sdhi_initialize_common(host); 879 880 plat->cfg.voltages = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34; 881 plat->cfg.f_min = CLKDEV_INIT; 882 plat->cfg.f_max = CLKDEV_HS_DATA; 883 plat->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; 884 885 upriv->mmc = &plat->mmc; 886 887 return 0; 888 } 889 890 static const struct udevice_id sh_sdhi_sd_match[] = { 891 { .compatible = "renesas,sdhi-r8a7795", .data = SH_SDHI_QUIRK_64BIT_BUF }, 892 { .compatible = "renesas,sdhi-r8a7796", .data = SH_SDHI_QUIRK_64BIT_BUF }, 893 { /* sentinel */ } 894 }; 895 896 U_BOOT_DRIVER(sh_sdhi_mmc) = { 897 .name = "sh-sdhi-mmc", 898 .id = UCLASS_MMC, 899 .of_match = sh_sdhi_sd_match, 900 .bind = sh_sdhi_dm_bind, 901 .probe = sh_sdhi_dm_probe, 902 .priv_auto_alloc_size = sizeof(struct sh_sdhi_host), 903 .platdata_auto_alloc_size = sizeof(struct sh_sdhi_plat), 904 .ops = &sh_sdhi_dm_ops, 905 }; 906 #endif 907