1 /* 2 * This is a driver for the SDHC controller found in Freescale MX2/MX3 3 * SoCs. It is basically the same hardware as found on MX1 (imxmmc.c). 4 * Unlike the hardware found on MX1, this hardware just works and does 5 * not need all the quirks found in imxmmc.c, hence the seperate driver. 6 * 7 * Copyright (C) 2009 Ilya Yanok, <yanok@emcraft.com> 8 * Copyright (C) 2008 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de> 9 * Copyright (C) 2006 Pavel Pisa, PiKRON <ppisa@pikron.com> 10 * 11 * derived from pxamci.c by Russell King 12 * 13 * This program is free software; you can redistribute it and/or modify 14 * it under the terms of the GNU General Public License version 2 as 15 * published by the Free Software Foundation. 16 * 17 */ 18 19 #include <config.h> 20 #include <common.h> 21 #include <command.h> 22 #include <mmc.h> 23 #include <part.h> 24 #include <malloc.h> 25 #include <mmc.h> 26 #include <asm/errno.h> 27 #include <asm/io.h> 28 #ifdef CONFIG_MX27 29 #include <asm/arch/clock.h> 30 #endif 31 32 #define DRIVER_NAME "mxc-mmc" 33 34 struct mxcmci_regs { 35 u32 str_stp_clk; 36 u32 status; 37 u32 clk_rate; 38 u32 cmd_dat_cont; 39 u32 res_to; 40 u32 read_to; 41 u32 blk_len; 42 u32 nob; 43 u32 rev_no; 44 u32 int_cntr; 45 u32 cmd; 46 u32 arg; 47 u32 pad; 48 u32 res_fifo; 49 u32 buffer_access; 50 }; 51 52 #define STR_STP_CLK_RESET (1 << 3) 53 #define STR_STP_CLK_START_CLK (1 << 1) 54 #define STR_STP_CLK_STOP_CLK (1 << 0) 55 56 #define STATUS_CARD_INSERTION (1 << 31) 57 #define STATUS_CARD_REMOVAL (1 << 30) 58 #define STATUS_YBUF_EMPTY (1 << 29) 59 #define STATUS_XBUF_EMPTY (1 << 28) 60 #define STATUS_YBUF_FULL (1 << 27) 61 #define STATUS_XBUF_FULL (1 << 26) 62 #define STATUS_BUF_UND_RUN (1 << 25) 63 #define STATUS_BUF_OVFL (1 << 24) 64 #define STATUS_SDIO_INT_ACTIVE (1 << 14) 65 #define STATUS_END_CMD_RESP (1 << 13) 66 #define STATUS_WRITE_OP_DONE (1 << 12) 67 #define STATUS_DATA_TRANS_DONE (1 << 11) 68 #define STATUS_READ_OP_DONE (1 << 11) 69 #define STATUS_WR_CRC_ERROR_CODE_MASK (3 << 10) 70 #define STATUS_CARD_BUS_CLK_RUN (1 << 8) 71 #define STATUS_BUF_READ_RDY (1 << 7) 72 #define STATUS_BUF_WRITE_RDY (1 << 6) 73 #define STATUS_RESP_CRC_ERR (1 << 5) 74 #define STATUS_CRC_READ_ERR (1 << 3) 75 #define STATUS_CRC_WRITE_ERR (1 << 2) 76 #define STATUS_TIME_OUT_RESP (1 << 1) 77 #define STATUS_TIME_OUT_READ (1 << 0) 78 #define STATUS_ERR_MASK 0x2f 79 80 #define CMD_DAT_CONT_CMD_RESP_LONG_OFF (1 << 12) 81 #define CMD_DAT_CONT_STOP_READWAIT (1 << 11) 82 #define CMD_DAT_CONT_START_READWAIT (1 << 10) 83 #define CMD_DAT_CONT_BUS_WIDTH_4 (2 << 8) 84 #define CMD_DAT_CONT_INIT (1 << 7) 85 #define CMD_DAT_CONT_WRITE (1 << 4) 86 #define CMD_DAT_CONT_DATA_ENABLE (1 << 3) 87 #define CMD_DAT_CONT_RESPONSE_48BIT_CRC (1 << 0) 88 #define CMD_DAT_CONT_RESPONSE_136BIT (2 << 0) 89 #define CMD_DAT_CONT_RESPONSE_48BIT (3 << 0) 90 91 #define INT_SDIO_INT_WKP_EN (1 << 18) 92 #define INT_CARD_INSERTION_WKP_EN (1 << 17) 93 #define INT_CARD_REMOVAL_WKP_EN (1 << 16) 94 #define INT_CARD_INSERTION_EN (1 << 15) 95 #define INT_CARD_REMOVAL_EN (1 << 14) 96 #define INT_SDIO_IRQ_EN (1 << 13) 97 #define INT_DAT0_EN (1 << 12) 98 #define INT_BUF_READ_EN (1 << 4) 99 #define INT_BUF_WRITE_EN (1 << 3) 100 #define INT_END_CMD_RES_EN (1 << 2) 101 #define INT_WRITE_OP_DONE_EN (1 << 1) 102 #define INT_READ_OP_EN (1 << 0) 103 104 struct mxcmci_host { 105 struct mmc *mmc; 106 struct mxcmci_regs *base; 107 int irq; 108 int detect_irq; 109 int dma; 110 int do_dma; 111 unsigned int power_mode; 112 113 struct mmc_cmd *cmd; 114 struct mmc_data *data; 115 116 unsigned int dma_nents; 117 unsigned int datasize; 118 unsigned int dma_dir; 119 120 u16 rev_no; 121 unsigned int cmdat; 122 123 int clock; 124 }; 125 126 static struct mxcmci_host mxcmci_host; 127 static struct mxcmci_host *host = &mxcmci_host; 128 129 static inline int mxcmci_use_dma(struct mxcmci_host *host) 130 { 131 return host->do_dma; 132 } 133 134 static void mxcmci_softreset(struct mxcmci_host *host) 135 { 136 int i; 137 138 /* reset sequence */ 139 writel(STR_STP_CLK_RESET, &host->base->str_stp_clk); 140 writel(STR_STP_CLK_RESET | STR_STP_CLK_START_CLK, 141 &host->base->str_stp_clk); 142 143 for (i = 0; i < 8; i++) 144 writel(STR_STP_CLK_START_CLK, &host->base->str_stp_clk); 145 146 writel(0xff, &host->base->res_to); 147 } 148 149 static void mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data) 150 { 151 unsigned int nob = data->blocks; 152 unsigned int blksz = data->blocksize; 153 unsigned int datasize = nob * blksz; 154 155 host->data = data; 156 157 writel(nob, &host->base->nob); 158 writel(blksz, &host->base->blk_len); 159 host->datasize = datasize; 160 } 161 162 static int mxcmci_start_cmd(struct mxcmci_host *host, struct mmc_cmd *cmd, 163 unsigned int cmdat) 164 { 165 if (host->cmd != NULL) 166 printf("mxcmci: error!\n"); 167 host->cmd = cmd; 168 169 switch (cmd->resp_type) { 170 case MMC_RSP_R1: /* short CRC, OPCODE */ 171 case MMC_RSP_R1b:/* short CRC, OPCODE, BUSY */ 172 cmdat |= CMD_DAT_CONT_RESPONSE_48BIT_CRC; 173 break; 174 case MMC_RSP_R2: /* long 136 bit + CRC */ 175 cmdat |= CMD_DAT_CONT_RESPONSE_136BIT; 176 break; 177 case MMC_RSP_R3: /* short */ 178 cmdat |= CMD_DAT_CONT_RESPONSE_48BIT; 179 break; 180 case MMC_RSP_NONE: 181 break; 182 default: 183 printf("mxcmci: unhandled response type 0x%x\n", 184 cmd->resp_type); 185 return -EINVAL; 186 } 187 188 writel(cmd->cmdidx, &host->base->cmd); 189 writel(cmd->cmdarg, &host->base->arg); 190 writel(cmdat, &host->base->cmd_dat_cont); 191 192 return 0; 193 } 194 195 static void mxcmci_finish_request(struct mxcmci_host *host, 196 struct mmc_cmd *cmd, struct mmc_data *data) 197 { 198 host->cmd = NULL; 199 host->data = NULL; 200 } 201 202 static int mxcmci_finish_data(struct mxcmci_host *host, unsigned int stat) 203 { 204 int data_error = 0; 205 206 if (stat & STATUS_ERR_MASK) { 207 printf("request failed. status: 0x%08x\n", 208 stat); 209 if (stat & STATUS_CRC_READ_ERR) { 210 data_error = -EILSEQ; 211 } else if (stat & STATUS_CRC_WRITE_ERR) { 212 u32 err_code = (stat >> 9) & 0x3; 213 if (err_code == 2) /* No CRC response */ 214 data_error = TIMEOUT; 215 else 216 data_error = -EILSEQ; 217 } else if (stat & STATUS_TIME_OUT_READ) { 218 data_error = TIMEOUT; 219 } else { 220 data_error = -EIO; 221 } 222 } 223 224 host->data = NULL; 225 226 return data_error; 227 } 228 229 static int mxcmci_read_response(struct mxcmci_host *host, unsigned int stat) 230 { 231 struct mmc_cmd *cmd = host->cmd; 232 int i; 233 u32 a, b, c; 234 u32 *resp = (u32 *)cmd->response; 235 236 if (!cmd) 237 return 0; 238 239 if (stat & STATUS_TIME_OUT_RESP) { 240 printf("CMD TIMEOUT\n"); 241 return TIMEOUT; 242 } else if (stat & STATUS_RESP_CRC_ERR && cmd->resp_type & MMC_RSP_CRC) { 243 printf("cmd crc error\n"); 244 return -EILSEQ; 245 } 246 247 if (cmd->resp_type & MMC_RSP_PRESENT) { 248 if (cmd->resp_type & MMC_RSP_136) { 249 for (i = 0; i < 4; i++) { 250 a = readl(&host->base->res_fifo) & 0xFFFF; 251 b = readl(&host->base->res_fifo) & 0xFFFF; 252 resp[i] = a << 16 | b; 253 } 254 } else { 255 a = readl(&host->base->res_fifo) & 0xFFFF; 256 b = readl(&host->base->res_fifo) & 0xFFFF; 257 c = readl(&host->base->res_fifo) & 0xFFFF; 258 resp[0] = a << 24 | b << 8 | c >> 8; 259 } 260 } 261 return 0; 262 } 263 264 static int mxcmci_poll_status(struct mxcmci_host *host, u32 mask) 265 { 266 u32 stat; 267 unsigned long timeout = get_ticks() + CONFIG_SYS_HZ; 268 269 do { 270 stat = readl(&host->base->status); 271 if (stat & STATUS_ERR_MASK) 272 return stat; 273 if (timeout < get_ticks()) 274 return STATUS_TIME_OUT_READ; 275 if (stat & mask) 276 return 0; 277 } while (1); 278 } 279 280 static int mxcmci_pull(struct mxcmci_host *host, void *_buf, int bytes) 281 { 282 unsigned int stat; 283 u32 *buf = _buf; 284 285 while (bytes > 3) { 286 stat = mxcmci_poll_status(host, 287 STATUS_BUF_READ_RDY | STATUS_READ_OP_DONE); 288 if (stat) 289 return stat; 290 *buf++ = readl(&host->base->buffer_access); 291 bytes -= 4; 292 } 293 294 if (bytes) { 295 u8 *b = (u8 *)buf; 296 u32 tmp; 297 298 stat = mxcmci_poll_status(host, 299 STATUS_BUF_READ_RDY | STATUS_READ_OP_DONE); 300 if (stat) 301 return stat; 302 tmp = readl(&host->base->buffer_access); 303 memcpy(b, &tmp, bytes); 304 } 305 306 return 0; 307 } 308 309 static int mxcmci_push(struct mxcmci_host *host, const void *_buf, int bytes) 310 { 311 unsigned int stat; 312 const u32 *buf = _buf; 313 314 while (bytes > 3) { 315 stat = mxcmci_poll_status(host, STATUS_BUF_WRITE_RDY); 316 if (stat) 317 return stat; 318 writel(*buf++, &host->base->buffer_access); 319 bytes -= 4; 320 } 321 322 if (bytes) { 323 const u8 *b = (u8 *)buf; 324 u32 tmp; 325 326 stat = mxcmci_poll_status(host, STATUS_BUF_WRITE_RDY); 327 if (stat) 328 return stat; 329 330 memcpy(&tmp, b, bytes); 331 writel(tmp, &host->base->buffer_access); 332 } 333 334 stat = mxcmci_poll_status(host, STATUS_BUF_WRITE_RDY); 335 if (stat) 336 return stat; 337 338 return 0; 339 } 340 341 static int mxcmci_transfer_data(struct mxcmci_host *host) 342 { 343 struct mmc_data *data = host->data; 344 int stat; 345 unsigned long length; 346 347 length = data->blocks * data->blocksize; 348 host->datasize = 0; 349 350 if (data->flags & MMC_DATA_READ) { 351 stat = mxcmci_pull(host, data->dest, length); 352 if (stat) 353 return stat; 354 host->datasize += length; 355 } else { 356 stat = mxcmci_push(host, (const void *)(data->src), length); 357 if (stat) 358 return stat; 359 host->datasize += length; 360 stat = mxcmci_poll_status(host, STATUS_WRITE_OP_DONE); 361 if (stat) 362 return stat; 363 } 364 return 0; 365 } 366 367 static int mxcmci_cmd_done(struct mxcmci_host *host, unsigned int stat) 368 { 369 int datastat; 370 int ret; 371 372 ret = mxcmci_read_response(host, stat); 373 374 if (ret) { 375 mxcmci_finish_request(host, host->cmd, host->data); 376 return ret; 377 } 378 379 if (!host->data) { 380 mxcmci_finish_request(host, host->cmd, host->data); 381 return 0; 382 } 383 384 datastat = mxcmci_transfer_data(host); 385 ret = mxcmci_finish_data(host, datastat); 386 mxcmci_finish_request(host, host->cmd, host->data); 387 return ret; 388 } 389 390 static int mxcmci_request(struct mmc *mmc, struct mmc_cmd *cmd, 391 struct mmc_data *data) 392 { 393 struct mxcmci_host *host = mmc->priv; 394 unsigned int cmdat = host->cmdat; 395 u32 stat; 396 int ret; 397 398 host->cmdat &= ~CMD_DAT_CONT_INIT; 399 if (data) { 400 mxcmci_setup_data(host, data); 401 402 cmdat |= CMD_DAT_CONT_DATA_ENABLE; 403 404 if (data->flags & MMC_DATA_WRITE) 405 cmdat |= CMD_DAT_CONT_WRITE; 406 } 407 408 if ((ret = mxcmci_start_cmd(host, cmd, cmdat))) { 409 mxcmci_finish_request(host, cmd, data); 410 return ret; 411 } 412 413 do { 414 stat = readl(&host->base->status); 415 writel(stat, &host->base->status); 416 } while (!(stat & STATUS_END_CMD_RESP)); 417 418 return mxcmci_cmd_done(host, stat); 419 } 420 421 static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios) 422 { 423 unsigned int divider; 424 int prescaler = 0; 425 unsigned long clk_in = imx_get_perclk2(); 426 427 while (prescaler <= 0x800) { 428 for (divider = 1; divider <= 0xF; divider++) { 429 int x; 430 431 x = (clk_in / (divider + 1)); 432 433 if (prescaler) 434 x /= (prescaler * 2); 435 436 if (x <= clk_ios) 437 break; 438 } 439 if (divider < 0x10) 440 break; 441 442 if (prescaler == 0) 443 prescaler = 1; 444 else 445 prescaler <<= 1; 446 } 447 448 writel((prescaler << 4) | divider, &host->base->clk_rate); 449 } 450 451 static void mxcmci_set_ios(struct mmc *mmc) 452 { 453 struct mxcmci_host *host = mmc->priv; 454 if (mmc->bus_width == 4) 455 host->cmdat |= CMD_DAT_CONT_BUS_WIDTH_4; 456 else 457 host->cmdat &= ~CMD_DAT_CONT_BUS_WIDTH_4; 458 459 if (mmc->clock) { 460 mxcmci_set_clk_rate(host, mmc->clock); 461 writel(STR_STP_CLK_START_CLK, &host->base->str_stp_clk); 462 } else { 463 writel(STR_STP_CLK_STOP_CLK, &host->base->str_stp_clk); 464 } 465 466 host->clock = mmc->clock; 467 } 468 469 static int mxcmci_init(struct mmc *mmc) 470 { 471 struct mxcmci_host *host = mmc->priv; 472 473 mxcmci_softreset(host); 474 475 host->rev_no = readl(&host->base->rev_no); 476 if (host->rev_no != 0x400) { 477 printf("wrong rev.no. 0x%08x. aborting.\n", 478 host->rev_no); 479 return -ENODEV; 480 } 481 482 /* recommended in data sheet */ 483 writel(0x2db4, &host->base->read_to); 484 485 writel(0, &host->base->int_cntr); 486 487 return 0; 488 } 489 490 static int mxcmci_initialize(bd_t *bis) 491 { 492 struct mmc *mmc = NULL; 493 494 mmc = malloc(sizeof(struct mmc)); 495 496 if (!mmc) 497 return -ENOMEM; 498 499 sprintf(mmc->name, "MXC MCI"); 500 mmc->send_cmd = mxcmci_request; 501 mmc->set_ios = mxcmci_set_ios; 502 mmc->init = mxcmci_init; 503 mmc->host_caps = MMC_MODE_4BIT; 504 505 host->base = (struct mxcmci_regs *)CONFIG_MXC_MCI_REGS_BASE; 506 mmc->priv = host; 507 host->mmc = mmc; 508 509 mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; 510 511 mmc->f_min = imx_get_perclk2() >> 7; 512 mmc->f_max = imx_get_perclk2() >> 1; 513 514 mmc_register(mmc); 515 516 return 0; 517 } 518 519 int mxc_mmc_init(bd_t *bis) 520 { 521 return mxcmci_initialize(bis); 522 } 523