1 /* 2 * ARM PrimeCell MultiMedia Card Interface - PL180 3 * 4 * Copyright (C) ST-Ericsson SA 2010 5 * 6 * Author: Ulf Hansson <ulf.hansson@stericsson.com> 7 * Author: Martin Lundholm <martin.xa.lundholm@stericsson.com> 8 * Ported to drivers/mmc/ by: Matt Waddel <matt.waddel@linaro.org> 9 * 10 * This program is free software; you can redistribute it and/or 11 * modify it under the terms of the GNU General Public License as 12 * published by the Free Software Foundation; either version 2 of 13 * the License, or (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software 22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 23 * MA 02111-1307 USA 24 */ 25 26 /* #define DEBUG */ 27 28 #include <asm/io.h> 29 #include "common.h" 30 #include <errno.h> 31 #include <mmc.h> 32 #include "arm_pl180_mmci.h" 33 #include <malloc.h> 34 35 struct mmc_host { 36 struct sdi_registers *base; 37 }; 38 39 static int wait_for_command_end(struct mmc *dev, struct mmc_cmd *cmd) 40 { 41 u32 hoststatus, statusmask; 42 struct mmc_host *host = dev->priv; 43 44 statusmask = SDI_STA_CTIMEOUT | SDI_STA_CCRCFAIL; 45 if ((cmd->resp_type & MMC_RSP_PRESENT)) 46 statusmask |= SDI_STA_CMDREND; 47 else 48 statusmask |= SDI_STA_CMDSENT; 49 50 do 51 hoststatus = readl(&host->base->status) & statusmask; 52 while (!hoststatus); 53 54 writel(statusmask, &host->base->status_clear); 55 if (hoststatus & SDI_STA_CTIMEOUT) { 56 printf("CMD%d time out\n", cmd->cmdidx); 57 return -ETIMEDOUT; 58 } else if ((hoststatus & SDI_STA_CCRCFAIL) && 59 (cmd->flags & MMC_RSP_CRC)) { 60 printf("CMD%d CRC error\n", cmd->cmdidx); 61 return -EILSEQ; 62 } 63 64 if (cmd->resp_type & MMC_RSP_PRESENT) { 65 cmd->response[0] = readl(&host->base->response0); 66 cmd->response[1] = readl(&host->base->response1); 67 cmd->response[2] = readl(&host->base->response2); 68 cmd->response[3] = readl(&host->base->response3); 69 debug("CMD%d response[0]:0x%08X, response[1]:0x%08X, " 70 "response[2]:0x%08X, response[3]:0x%08X\n", 71 cmd->cmdidx, cmd->response[0], cmd->response[1], 72 cmd->response[2], cmd->response[3]); 73 } 74 75 return 0; 76 } 77 78 /* send command to the mmc card and wait for results */ 79 static int do_command(struct mmc *dev, struct mmc_cmd *cmd) 80 { 81 int result; 82 u32 sdi_cmd = 0; 83 struct mmc_host *host = dev->priv; 84 85 sdi_cmd = ((cmd->cmdidx & SDI_CMD_CMDINDEX_MASK) | SDI_CMD_CPSMEN); 86 87 if (cmd->resp_type) { 88 sdi_cmd |= SDI_CMD_WAITRESP; 89 if (cmd->resp_type & MMC_RSP_136) 90 sdi_cmd |= SDI_CMD_LONGRESP; 91 } 92 93 writel((u32)cmd->cmdarg, &host->base->argument); 94 udelay(COMMAND_REG_DELAY); 95 writel(sdi_cmd, &host->base->command); 96 result = wait_for_command_end(dev, cmd); 97 98 /* After CMD2 set RCA to a none zero value. */ 99 if ((result == 0) && (cmd->cmdidx == MMC_CMD_ALL_SEND_CID)) 100 dev->rca = 10; 101 102 /* After CMD3 open drain is switched off and push pull is used. */ 103 if ((result == 0) && (cmd->cmdidx == MMC_CMD_SET_RELATIVE_ADDR)) { 104 u32 sdi_pwr = readl(&host->base->power) & ~SDI_PWR_OPD; 105 writel(sdi_pwr, &host->base->power); 106 } 107 108 return result; 109 } 110 111 static int read_bytes(struct mmc *dev, u32 *dest, u32 blkcount, u32 blksize) 112 { 113 u32 *tempbuff = dest; 114 u64 xfercount = blkcount * blksize; 115 struct mmc_host *host = dev->priv; 116 u32 status, status_err; 117 118 debug("read_bytes: blkcount=%u blksize=%u\n", blkcount, blksize); 119 120 status = readl(&host->base->status); 121 status_err = status & (SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT | 122 SDI_STA_RXOVERR); 123 while ((!status_err) && (xfercount >= sizeof(u32))) { 124 if (status & SDI_STA_RXDAVL) { 125 *(tempbuff) = readl(&host->base->fifo); 126 tempbuff++; 127 xfercount -= sizeof(u32); 128 } 129 status = readl(&host->base->status); 130 status_err = status & (SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT | 131 SDI_STA_RXOVERR); 132 } 133 134 status_err = status & 135 (SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT | SDI_STA_DBCKEND | 136 SDI_STA_RXOVERR); 137 while (!status_err) { 138 status = readl(&host->base->status); 139 status_err = status & 140 (SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT | SDI_STA_DBCKEND | 141 SDI_STA_RXOVERR); 142 } 143 144 if (status & SDI_STA_DTIMEOUT) { 145 printf("Read data timed out, xfercount: %llu, status: 0x%08X\n", 146 xfercount, status); 147 return -ETIMEDOUT; 148 } else if (status & SDI_STA_DCRCFAIL) { 149 printf("Read data bytes CRC error: 0x%x\n", status); 150 return -EILSEQ; 151 } else if (status & SDI_STA_RXOVERR) { 152 printf("Read data RX overflow error\n"); 153 return -EIO; 154 } 155 156 writel(SDI_ICR_MASK, &host->base->status_clear); 157 158 if (xfercount) { 159 printf("Read data error, xfercount: %llu\n", xfercount); 160 return -ENOBUFS; 161 } 162 163 return 0; 164 } 165 166 static int write_bytes(struct mmc *dev, u32 *src, u32 blkcount, u32 blksize) 167 { 168 u32 *tempbuff = src; 169 int i; 170 u64 xfercount = blkcount * blksize; 171 struct mmc_host *host = dev->priv; 172 u32 status, status_err; 173 174 debug("write_bytes: blkcount=%u blksize=%u\n", blkcount, blksize); 175 176 status = readl(&host->base->status); 177 status_err = status & (SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT); 178 while (!status_err && xfercount) { 179 if (status & SDI_STA_TXFIFOBW) { 180 if (xfercount >= SDI_FIFO_BURST_SIZE * sizeof(u32)) { 181 for (i = 0; i < SDI_FIFO_BURST_SIZE; i++) 182 writel(*(tempbuff + i), 183 &host->base->fifo); 184 tempbuff += SDI_FIFO_BURST_SIZE; 185 xfercount -= SDI_FIFO_BURST_SIZE * sizeof(u32); 186 } else { 187 while (xfercount >= sizeof(u32)) { 188 writel(*(tempbuff), &host->base->fifo); 189 tempbuff++; 190 xfercount -= sizeof(u32); 191 } 192 } 193 } 194 status = readl(&host->base->status); 195 status_err = status & (SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT); 196 } 197 198 status_err = status & 199 (SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT | SDI_STA_DBCKEND); 200 while (!status_err) { 201 status = readl(&host->base->status); 202 status_err = status & 203 (SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT | SDI_STA_DBCKEND); 204 } 205 206 if (status & SDI_STA_DTIMEOUT) { 207 printf("Write data timed out, xfercount:%llu,status:0x%08X\n", 208 xfercount, status); 209 return -ETIMEDOUT; 210 } else if (status & SDI_STA_DCRCFAIL) { 211 printf("Write data CRC error\n"); 212 return -EILSEQ; 213 } 214 215 writel(SDI_ICR_MASK, &host->base->status_clear); 216 217 if (xfercount) { 218 printf("Write data error, xfercount:%llu", xfercount); 219 return -ENOBUFS; 220 } 221 222 return 0; 223 } 224 225 static int do_data_transfer(struct mmc *dev, 226 struct mmc_cmd *cmd, 227 struct mmc_data *data) 228 { 229 int error = -ETIMEDOUT; 230 struct mmc_host *host = dev->priv; 231 u32 blksz = 0; 232 u32 data_ctrl = 0; 233 u32 data_len = (u32) (data->blocks * data->blocksize); 234 235 blksz = (ffs(data->blocksize) - 1); 236 data_ctrl |= ((blksz << 4) & SDI_DCTRL_DBLKSIZE_MASK); 237 data_ctrl |= SDI_DCTRL_DTEN; 238 239 writel(SDI_DTIMER_DEFAULT, &host->base->datatimer); 240 writel(data_len, &host->base->datalength); 241 udelay(DATA_REG_DELAY); 242 243 if (data->flags & MMC_DATA_READ) { 244 data_ctrl |= SDI_DCTRL_DTDIR_IN; 245 writel(data_ctrl, &host->base->datactrl); 246 247 error = do_command(dev, cmd); 248 if (error) 249 return error; 250 251 error = read_bytes(dev, (u32 *)data->dest, (u32)data->blocks, 252 (u32)data->blocksize); 253 } else if (data->flags & MMC_DATA_WRITE) { 254 error = do_command(dev, cmd); 255 if (error) 256 return error; 257 258 writel(data_ctrl, &host->base->datactrl); 259 error = write_bytes(dev, (u32 *)data->src, (u32)data->blocks, 260 (u32)data->blocksize); 261 } 262 263 return error; 264 } 265 266 static int host_request(struct mmc *dev, 267 struct mmc_cmd *cmd, 268 struct mmc_data *data) 269 { 270 int result; 271 272 if (data) 273 result = do_data_transfer(dev, cmd, data); 274 else 275 result = do_command(dev, cmd); 276 277 return result; 278 } 279 280 /* MMC uses open drain drivers in the enumeration phase */ 281 static int mmc_host_reset(struct mmc *dev) 282 { 283 struct mmc_host *host = dev->priv; 284 u32 sdi_u32 = SDI_PWR_OPD | SDI_PWR_PWRCTRL_ON; 285 286 writel(sdi_u32, &host->base->power); 287 288 return 0; 289 } 290 291 static void host_set_ios(struct mmc *dev) 292 { 293 struct mmc_host *host = dev->priv; 294 u32 sdi_clkcr; 295 296 sdi_clkcr = readl(&host->base->clock); 297 298 /* Ramp up the clock rate */ 299 if (dev->clock) { 300 u32 clkdiv = 0; 301 302 if (dev->clock >= dev->f_max) 303 dev->clock = dev->f_max; 304 305 clkdiv = ((ARM_MCLK / dev->clock) / 2) - 1; 306 307 if (clkdiv > SDI_CLKCR_CLKDIV_MASK) 308 clkdiv = SDI_CLKCR_CLKDIV_MASK; 309 310 sdi_clkcr &= ~(SDI_CLKCR_CLKDIV_MASK); 311 sdi_clkcr |= clkdiv; 312 } 313 314 /* Set the bus width */ 315 if (dev->bus_width) { 316 u32 buswidth = 0; 317 318 switch (dev->bus_width) { 319 case 1: 320 buswidth |= SDI_CLKCR_WIDBUS_1; 321 break; 322 case 4: 323 buswidth |= SDI_CLKCR_WIDBUS_4; 324 break; 325 default: 326 printf("Invalid bus width\n"); 327 break; 328 } 329 sdi_clkcr &= ~(SDI_CLKCR_WIDBUS_MASK); 330 sdi_clkcr |= buswidth; 331 } 332 333 writel(sdi_clkcr, &host->base->clock); 334 udelay(CLK_CHANGE_DELAY); 335 } 336 337 struct mmc *alloc_mmc_struct(void) 338 { 339 struct mmc_host *host = NULL; 340 struct mmc *mmc_device = NULL; 341 342 host = malloc(sizeof(struct mmc_host)); 343 if (!host) 344 return NULL; 345 346 mmc_device = malloc(sizeof(struct mmc)); 347 if (!mmc_device) 348 goto err; 349 350 mmc_device->priv = host; 351 return mmc_device; 352 353 err: 354 free(host); 355 return NULL; 356 } 357 358 /* 359 * mmc_host_init - initialize the mmc controller. 360 * Set initial clock and power for mmc slot. 361 * Initialize mmc struct and register with mmc framework. 362 */ 363 static int arm_pl180_mmci_host_init(struct mmc *dev) 364 { 365 struct mmc_host *host = dev->priv; 366 u32 sdi_u32; 367 368 host->base = (struct sdi_registers *)CONFIG_ARM_PL180_MMCI_BASE; 369 370 /* Initially set power-on, full voltage & MMCI read */ 371 sdi_u32 = INIT_PWR; 372 writel(sdi_u32, &host->base->power); 373 374 /* setting clk freq 505KHz */ 375 sdi_u32 = SDI_CLKCR_CLKDIV_INIT | SDI_CLKCR_CLKEN; 376 writel(sdi_u32, &host->base->clock); 377 udelay(CLK_CHANGE_DELAY); 378 379 /* Disable mmc interrupts */ 380 sdi_u32 = readl(&host->base->mask0) & ~SDI_MASK0_MASK; 381 writel(sdi_u32, &host->base->mask0); 382 383 sprintf(dev->name, "MMC"); 384 dev->clock = ARM_MCLK / (2 * (SDI_CLKCR_CLKDIV_INIT + 1)); 385 dev->send_cmd = host_request; 386 dev->set_ios = host_set_ios; 387 dev->init = mmc_host_reset; 388 dev->host_caps = 0; 389 dev->voltages = VOLTAGE_WINDOW_MMC; 390 dev->f_min = dev->clock; 391 dev->f_max = CONFIG_ARM_PL180_MMCI_CLOCK_FREQ; 392 393 return 0; 394 } 395 396 int arm_pl180_mmci_init(void) 397 { 398 int error; 399 struct mmc *dev; 400 401 dev = alloc_mmc_struct(); 402 if (!dev) 403 return -1; 404 405 error = arm_pl180_mmci_host_init(dev); 406 if (error) { 407 printf("mmci_host_init error - %d\n", error); 408 return -1; 409 } 410 411 dev->b_max = 0; 412 413 mmc_register(dev); 414 debug("registered mmc interface number is:%d\n", dev->block_dev.dev); 415 416 return 0; 417 } 418