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