diff options
| author | Marc Kleine-Budde <mkl@pengutronix.de> | 2008-10-10 06:05:03 -0400 |
|---|---|---|
| committer | Sascha Hauer <s.hauer@pengutronix.de> | 2008-12-16 08:58:17 -0500 |
| commit | df25f9da9fcc12193208e8da135c930924cd56c5 (patch) | |
| tree | fa42d207ed9ffcada3dfe61a8f280bb051703ff3 | |
| parent | 2507b0a33343552d2177b75dc35fe7073349b773 (diff) | |
imxmmc: use readl/writel
Use readl/writel instead of direct pointer deref.
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
| -rw-r--r-- | drivers/mmc/host/imxmmc.c | 190 | ||||
| -rw-r--r-- | drivers/mmc/host/imxmmc.h | 37 |
2 files changed, 134 insertions, 93 deletions
diff --git a/drivers/mmc/host/imxmmc.c b/drivers/mmc/host/imxmmc.c index 5c921b33b10e..eb29b1d933ac 100644 --- a/drivers/mmc/host/imxmmc.c +++ b/drivers/mmc/host/imxmmc.c | |||
| @@ -43,6 +43,7 @@ struct imxmci_host { | |||
| 43 | struct mmc_host *mmc; | 43 | struct mmc_host *mmc; |
| 44 | spinlock_t lock; | 44 | spinlock_t lock; |
| 45 | struct resource *res; | 45 | struct resource *res; |
| 46 | void __iomem *base; | ||
| 46 | int irq; | 47 | int irq; |
| 47 | imx_dmach_t dma; | 48 | imx_dmach_t dma; |
| 48 | volatile unsigned int imask; | 49 | volatile unsigned int imask; |
| @@ -98,14 +99,22 @@ struct imxmci_host { | |||
| 98 | static void imxmci_stop_clock(struct imxmci_host *host) | 99 | static void imxmci_stop_clock(struct imxmci_host *host) |
| 99 | { | 100 | { |
| 100 | int i = 0; | 101 | int i = 0; |
| 101 | MMC_STR_STP_CLK &= ~STR_STP_CLK_START_CLK; | 102 | u16 reg; |
| 103 | |||
| 104 | reg = readw(host->base + MMC_REG_STR_STP_CLK); | ||
| 105 | writew(reg & ~STR_STP_CLK_START_CLK, host->base + MMC_REG_STR_STP_CLK); | ||
| 102 | while (i < 0x1000) { | 106 | while (i < 0x1000) { |
| 103 | if (!(i & 0x7f)) | 107 | if (!(i & 0x7f)) { |
| 104 | MMC_STR_STP_CLK |= STR_STP_CLK_STOP_CLK; | 108 | reg = readw(host->base + MMC_REG_STR_STP_CLK); |
| 109 | writew(reg | STR_STP_CLK_STOP_CLK, | ||
| 110 | host->base + MMC_REG_STR_STP_CLK); | ||
| 111 | } | ||
| 105 | 112 | ||
| 106 | if (!(MMC_STATUS & STATUS_CARD_BUS_CLK_RUN)) { | 113 | reg = readw(host->base + MMC_REG_STATUS); |
| 114 | if (!(reg & STATUS_CARD_BUS_CLK_RUN)) { | ||
| 107 | /* Check twice before cut */ | 115 | /* Check twice before cut */ |
| 108 | if (!(MMC_STATUS & STATUS_CARD_BUS_CLK_RUN)) | 116 | reg = readw(host->base + MMC_REG_STATUS); |
| 117 | if (!(reg & STATUS_CARD_BUS_CLK_RUN)) | ||
| 109 | return; | 118 | return; |
| 110 | } | 119 | } |
| 111 | 120 | ||
| @@ -119,8 +128,10 @@ static int imxmci_start_clock(struct imxmci_host *host) | |||
| 119 | unsigned int trials = 0; | 128 | unsigned int trials = 0; |
| 120 | unsigned int delay_limit = 128; | 129 | unsigned int delay_limit = 128; |
| 121 | unsigned long flags; | 130 | unsigned long flags; |
| 131 | u16 reg; | ||
| 122 | 132 | ||
| 123 | MMC_STR_STP_CLK &= ~STR_STP_CLK_STOP_CLK; | 133 | reg = readw(host->base + MMC_REG_STR_STP_CLK); |
| 134 | writew(reg & ~STR_STP_CLK_STOP_CLK, host->base + MMC_REG_STR_STP_CLK); | ||
| 124 | 135 | ||
| 125 | clear_bit(IMXMCI_PEND_STARTED_b, &host->pending_events); | 136 | clear_bit(IMXMCI_PEND_STARTED_b, &host->pending_events); |
| 126 | 137 | ||
| @@ -129,15 +140,18 @@ static int imxmci_start_clock(struct imxmci_host *host) | |||
| 129 | * then 6 delay loops, but during card detection (low clockrate) | 140 | * then 6 delay loops, but during card detection (low clockrate) |
| 130 | * it takes up to 5000 delay loops and sometimes fails for the first time | 141 | * it takes up to 5000 delay loops and sometimes fails for the first time |
| 131 | */ | 142 | */ |
| 132 | MMC_STR_STP_CLK |= STR_STP_CLK_START_CLK; | 143 | reg = readw(host->base + MMC_REG_STR_STP_CLK); |
| 144 | writew(reg | STR_STP_CLK_START_CLK, host->base + MMC_REG_STR_STP_CLK); | ||
| 133 | 145 | ||
| 134 | do { | 146 | do { |
| 135 | unsigned int delay = delay_limit; | 147 | unsigned int delay = delay_limit; |
| 136 | 148 | ||
| 137 | while (delay--) { | 149 | while (delay--) { |
| 138 | if (MMC_STATUS & STATUS_CARD_BUS_CLK_RUN) | 150 | reg = readw(host->base + MMC_REG_STATUS); |
| 151 | if (reg & STATUS_CARD_BUS_CLK_RUN) | ||
| 139 | /* Check twice before cut */ | 152 | /* Check twice before cut */ |
| 140 | if (MMC_STATUS & STATUS_CARD_BUS_CLK_RUN) | 153 | reg = readw(host->base + MMC_REG_STATUS); |
| 154 | if (reg & STATUS_CARD_BUS_CLK_RUN) | ||
| 141 | return 0; | 155 | return 0; |
| 142 | 156 | ||
| 143 | if (test_bit(IMXMCI_PEND_STARTED_b, &host->pending_events)) | 157 | if (test_bit(IMXMCI_PEND_STARTED_b, &host->pending_events)) |
| @@ -151,8 +165,11 @@ static int imxmci_start_clock(struct imxmci_host *host) | |||
| 151 | * IRQ or schedule delays this function execution and the clocks has | 165 | * IRQ or schedule delays this function execution and the clocks has |
| 152 | * been already stopped by other means (response processing, SDHC HW) | 166 | * been already stopped by other means (response processing, SDHC HW) |
| 153 | */ | 167 | */ |
| 154 | if (!test_bit(IMXMCI_PEND_STARTED_b, &host->pending_events)) | 168 | if (!test_bit(IMXMCI_PEND_STARTED_b, &host->pending_events)) { |
| 155 | MMC_STR_STP_CLK |= STR_STP_CLK_START_CLK; | 169 | reg = readw(host->base + MMC_REG_STR_STP_CLK); |
| 170 | writew(reg | STR_STP_CLK_START_CLK, | ||
| 171 | host->base + MMC_REG_STR_STP_CLK); | ||
| 172 | } | ||
| 156 | local_irq_restore(flags); | 173 | local_irq_restore(flags); |
| 157 | 174 | ||
| 158 | } while (++trials < 256); | 175 | } while (++trials < 256); |
| @@ -162,23 +179,20 @@ static int imxmci_start_clock(struct imxmci_host *host) | |||
| 162 | return -1; | 179 | return -1; |
| 163 | } | 180 | } |
| 164 | 181 | ||
| 165 | static void imxmci_softreset(void) | 182 | static void imxmci_softreset(struct imxmci_host *host) |
| 166 | { | 183 | { |
| 184 | int i; | ||
| 185 | |||
| 167 | /* reset sequence */ | 186 | /* reset sequence */ |
| 168 | MMC_STR_STP_CLK = 0x8; | 187 | writew(0x08, host->base + MMC_REG_STR_STP_CLK); |
| 169 | MMC_STR_STP_CLK = 0xD; | 188 | writew(0x0D, host->base + MMC_REG_STR_STP_CLK); |
| 170 | MMC_STR_STP_CLK = 0x5; | 189 | |
| 171 | MMC_STR_STP_CLK = 0x5; | 190 | for (i = 0; i < 8; i++) |
| 172 | MMC_STR_STP_CLK = 0x5; | 191 | writew(0x05, host->base + MMC_REG_STR_STP_CLK); |
| 173 | MMC_STR_STP_CLK = 0x5; | 192 | |
| 174 | MMC_STR_STP_CLK = 0x5; | 193 | writew(0xff, host->base + MMC_REG_RES_TO); |
| 175 | MMC_STR_STP_CLK = 0x5; | 194 | writew(512, host->base + MMC_REG_BLK_LEN); |
| 176 | MMC_STR_STP_CLK = 0x5; | 195 | writew(1, host->base + MMC_REG_NOB); |
| 177 | MMC_STR_STP_CLK = 0x5; | ||
| 178 | |||
| 179 | MMC_RES_TO = 0xff; | ||
| 180 | MMC_BLK_LEN = 512; | ||
| 181 | MMC_NOB = 1; | ||
| 182 | } | 196 | } |
| 183 | 197 | ||
| 184 | static int imxmci_busy_wait_for_status(struct imxmci_host *host, | 198 | static int imxmci_busy_wait_for_status(struct imxmci_host *host, |
| @@ -195,7 +209,7 @@ static int imxmci_busy_wait_for_status(struct imxmci_host *host, | |||
| 195 | return -1; | 209 | return -1; |
| 196 | } | 210 | } |
| 197 | udelay(2); | 211 | udelay(2); |
| 198 | *pstat |= MMC_STATUS; | 212 | *pstat |= readw(host->base + MMC_REG_STATUS); |
| 199 | } | 213 | } |
| 200 | if (!loops) | 214 | if (!loops) |
| 201 | return 0; | 215 | return 0; |
| @@ -220,8 +234,8 @@ static void imxmci_setup_data(struct imxmci_host *host, struct mmc_data *data) | |||
| 220 | host->data = data; | 234 | host->data = data; |
| 221 | data->bytes_xfered = 0; | 235 | data->bytes_xfered = 0; |
| 222 | 236 | ||
| 223 | MMC_NOB = nob; | 237 | writew(nob, host->base + MMC_REG_NOB); |
| 224 | MMC_BLK_LEN = blksz; | 238 | writew(blksz, host->base + MMC_REG_BLK_LEN); |
| 225 | 239 | ||
| 226 | /* | 240 | /* |
| 227 | * DMA cannot be used for small block sizes, we have to use CPU driven transfers otherwise. | 241 | * DMA cannot be used for small block sizes, we have to use CPU driven transfers otherwise. |
| @@ -237,8 +251,8 @@ static void imxmci_setup_data(struct imxmci_host *host, struct mmc_data *data) | |||
| 237 | host->dma_dir = DMA_FROM_DEVICE; | 251 | host->dma_dir = DMA_FROM_DEVICE; |
| 238 | 252 | ||
| 239 | /* Hack to enable read SCR */ | 253 | /* Hack to enable read SCR */ |
| 240 | MMC_NOB = 1; | 254 | writew(1, host->base + MMC_REG_NOB); |
| 241 | MMC_BLK_LEN = 512; | 255 | writew(512, host->base + MMC_REG_BLK_LEN); |
| 242 | } else { | 256 | } else { |
| 243 | host->dma_dir = DMA_TO_DEVICE; | 257 | host->dma_dir = DMA_TO_DEVICE; |
| 244 | } | 258 | } |
| @@ -259,7 +273,8 @@ static void imxmci_setup_data(struct imxmci_host *host, struct mmc_data *data) | |||
| 259 | data->sg_len, host->dma_dir); | 273 | data->sg_len, host->dma_dir); |
| 260 | 274 | ||
| 261 | imx_dma_setup_sg(host->dma, data->sg, data->sg_len, datasz, | 275 | imx_dma_setup_sg(host->dma, data->sg, data->sg_len, datasz, |
| 262 | host->res->start + MMC_BUFFER_ACCESS_OFS, DMA_MODE_READ); | 276 | host->res->start + MMC_REG_BUFFER_ACCESS, |
| 277 | DMA_MODE_READ); | ||
| 263 | 278 | ||
| 264 | /*imx_dma_setup_mem2dev_ccr(host->dma, DMA_MODE_READ, IMX_DMA_WIDTH_16, CCR_REN);*/ | 279 | /*imx_dma_setup_mem2dev_ccr(host->dma, DMA_MODE_READ, IMX_DMA_WIDTH_16, CCR_REN);*/ |
| 265 | CCR(host->dma) = CCR_DMOD_LINEAR | CCR_DSIZ_32 | CCR_SMOD_FIFO | CCR_SSIZ_16 | CCR_REN; | 280 | CCR(host->dma) = CCR_DMOD_LINEAR | CCR_DSIZ_32 | CCR_SMOD_FIFO | CCR_SSIZ_16 | CCR_REN; |
| @@ -270,7 +285,8 @@ static void imxmci_setup_data(struct imxmci_host *host, struct mmc_data *data) | |||
| 270 | data->sg_len, host->dma_dir); | 285 | data->sg_len, host->dma_dir); |
| 271 | 286 | ||
| 272 | imx_dma_setup_sg(host->dma, data->sg, data->sg_len, datasz, | 287 | imx_dma_setup_sg(host->dma, data->sg, data->sg_len, datasz, |
| 273 | host->res->start + MMC_BUFFER_ACCESS_OFS, DMA_MODE_WRITE); | 288 | host->res->start + MMC_REG_BUFFER_ACCESS, |
| 289 | DMA_MODE_WRITE); | ||
| 274 | 290 | ||
| 275 | /*imx_dma_setup_mem2dev_ccr(host->dma, DMA_MODE_WRITE, IMX_DMA_WIDTH_16, CCR_REN);*/ | 291 | /*imx_dma_setup_mem2dev_ccr(host->dma, DMA_MODE_WRITE, IMX_DMA_WIDTH_16, CCR_REN);*/ |
| 276 | CCR(host->dma) = CCR_SMOD_LINEAR | CCR_SSIZ_32 | CCR_DMOD_FIFO | CCR_DSIZ_16 | CCR_REN; | 292 | CCR(host->dma) = CCR_SMOD_LINEAR | CCR_SSIZ_32 | CCR_DMOD_FIFO | CCR_DSIZ_16 | CCR_REN; |
| @@ -341,10 +357,10 @@ static void imxmci_start_cmd(struct imxmci_host *host, struct mmc_command *cmd, | |||
| 341 | if (host->actual_bus_width == MMC_BUS_WIDTH_4) | 357 | if (host->actual_bus_width == MMC_BUS_WIDTH_4) |
| 342 | cmdat |= CMD_DAT_CONT_BUS_WIDTH_4; | 358 | cmdat |= CMD_DAT_CONT_BUS_WIDTH_4; |
| 343 | 359 | ||
| 344 | MMC_CMD = cmd->opcode; | 360 | writew(cmd->opcode, host->base + MMC_REG_CMD); |
| 345 | MMC_ARGH = cmd->arg >> 16; | 361 | writew(cmd->arg >> 16, host->base + MMC_REG_ARGH); |
| 346 | MMC_ARGL = cmd->arg & 0xffff; | 362 | writew(cmd->arg & 0xffff, host->base + MMC_REG_ARGL); |
| 347 | MMC_CMD_DAT_CONT = cmdat; | 363 | writew(cmdat, host->base + MMC_REG_CMD_DAT_CONT); |
| 348 | 364 | ||
| 349 | atomic_set(&host->stuck_timeout, 0); | 365 | atomic_set(&host->stuck_timeout, 0); |
| 350 | set_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events); | 366 | set_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events); |
| @@ -363,7 +379,7 @@ static void imxmci_start_cmd(struct imxmci_host *host, struct mmc_command *cmd, | |||
| 363 | 379 | ||
| 364 | spin_lock_irqsave(&host->lock, flags); | 380 | spin_lock_irqsave(&host->lock, flags); |
| 365 | host->imask = imask; | 381 | host->imask = imask; |
| 366 | MMC_INT_MASK = host->imask; | 382 | writew(host->imask, host->base + MMC_REG_INT_MASK); |
| 367 | spin_unlock_irqrestore(&host->lock, flags); | 383 | spin_unlock_irqrestore(&host->lock, flags); |
| 368 | 384 | ||
| 369 | dev_dbg(mmc_dev(host->mmc), "CMD%02d (0x%02x) mask set to 0x%04x\n", | 385 | dev_dbg(mmc_dev(host->mmc), "CMD%02d (0x%02x) mask set to 0x%04x\n", |
| @@ -382,7 +398,7 @@ static void imxmci_finish_request(struct imxmci_host *host, struct mmc_request * | |||
| 382 | IMXMCI_PEND_DMA_DATA_m | IMXMCI_PEND_CPU_DATA_m); | 398 | IMXMCI_PEND_DMA_DATA_m | IMXMCI_PEND_CPU_DATA_m); |
| 383 | 399 | ||
| 384 | host->imask = IMXMCI_INT_MASK_DEFAULT; | 400 | host->imask = IMXMCI_INT_MASK_DEFAULT; |
| 385 | MMC_INT_MASK = host->imask; | 401 | writew(host->imask, host->base + MMC_REG_INT_MASK); |
| 386 | 402 | ||
| 387 | spin_unlock_irqrestore(&host->lock, flags); | 403 | spin_unlock_irqrestore(&host->lock, flags); |
| 388 | 404 | ||
| @@ -448,14 +464,14 @@ static int imxmci_cmd_done(struct imxmci_host *host, unsigned int stat) | |||
| 448 | if (cmd->flags & MMC_RSP_PRESENT) { | 464 | if (cmd->flags & MMC_RSP_PRESENT) { |
| 449 | if (cmd->flags & MMC_RSP_136) { | 465 | if (cmd->flags & MMC_RSP_136) { |
| 450 | for (i = 0; i < 4; i++) { | 466 | for (i = 0; i < 4; i++) { |
| 451 | u32 d = MMC_RES_FIFO & 0xffff; | 467 | a = readw(host->base + MMC_REG_RES_FIFO); |
| 452 | u32 e = MMC_RES_FIFO & 0xffff; | 468 | b = readw(host->base + MMC_REG_RES_FIFO); |
| 453 | cmd->resp[i] = d << 16 | e; | 469 | cmd->resp[i] = a << 16 | b; |
| 454 | } | 470 | } |
| 455 | } else { | 471 | } else { |
| 456 | a = MMC_RES_FIFO & 0xffff; | 472 | a = readw(host->base + MMC_REG_RES_FIFO); |
| 457 | b = MMC_RES_FIFO & 0xffff; | 473 | b = readw(host->base + MMC_REG_RES_FIFO); |
| 458 | c = MMC_RES_FIFO & 0xffff; | 474 | c = readw(host->base + MMC_REG_RES_FIFO); |
| 459 | cmd->resp[0] = a << 24 | b << 8 | c >> 8; | 475 | cmd->resp[0] = a << 24 | b << 8 | c >> 8; |
| 460 | } | 476 | } |
| 461 | } | 477 | } |
| @@ -468,7 +484,7 @@ static int imxmci_cmd_done(struct imxmci_host *host, unsigned int stat) | |||
| 468 | 484 | ||
| 469 | /* Wait for FIFO to be empty before starting DMA write */ | 485 | /* Wait for FIFO to be empty before starting DMA write */ |
| 470 | 486 | ||
| 471 | stat = MMC_STATUS; | 487 | stat = readw(host->base + MMC_REG_STATUS); |
| 472 | if (imxmci_busy_wait_for_status(host, &stat, | 488 | if (imxmci_busy_wait_for_status(host, &stat, |
| 473 | STATUS_APPL_BUFF_FE, | 489 | STATUS_APPL_BUFF_FE, |
| 474 | 40, "imxmci_cmd_done DMA WR") < 0) { | 490 | 40, "imxmci_cmd_done DMA WR") < 0) { |
| @@ -558,7 +574,7 @@ static int imxmci_cpu_driven_data(struct imxmci_host *host, unsigned int *pstat) | |||
| 558 | 574 | ||
| 559 | for (i = burst_len; i >= 2 ; i -= 2) { | 575 | for (i = burst_len; i >= 2 ; i -= 2) { |
| 560 | u16 data; | 576 | u16 data; |
| 561 | data = MMC_BUFFER_ACCESS; | 577 | data = readw(host->base + MMC_REG_BUFFER_ACCESS); |
| 562 | udelay(10); /* required for clocks < 8MHz*/ | 578 | udelay(10); /* required for clocks < 8MHz*/ |
| 563 | if (host->data_cnt+2 <= host->dma_size) { | 579 | if (host->data_cnt+2 <= host->dma_size) { |
| 564 | *(host->data_ptr++) = data; | 580 | *(host->data_ptr++) = data; |
| @@ -569,7 +585,7 @@ static int imxmci_cpu_driven_data(struct imxmci_host *host, unsigned int *pstat) | |||
| 569 | host->data_cnt += 2; | 585 | host->data_cnt += 2; |
| 570 | } | 586 | } |
| 571 | 587 | ||
| 572 | stat = MMC_STATUS; | 588 | stat = readw(host->base + MMC_REG_STATUS); |
| 573 | 589 | ||
| 574 | dev_dbg(mmc_dev(host->mmc), "imxmci_cpu_driven_data read %d burst %d STATUS = 0x%x\n", | 590 | dev_dbg(mmc_dev(host->mmc), "imxmci_cpu_driven_data read %d burst %d STATUS = 0x%x\n", |
| 575 | host->data_cnt, burst_len, stat); | 591 | host->data_cnt, burst_len, stat); |
| @@ -603,9 +619,9 @@ static int imxmci_cpu_driven_data(struct imxmci_host *host, unsigned int *pstat) | |||
| 603 | } | 619 | } |
| 604 | 620 | ||
| 605 | for (i = burst_len; i > 0 ; i -= 2) | 621 | for (i = burst_len; i > 0 ; i -= 2) |
| 606 | MMC_BUFFER_ACCESS = *(host->data_ptr++); | 622 | writew(*(host->data_ptr++), host->base + MMC_REG_BUFFER_ACCESS); |
| 607 | 623 | ||
| 608 | stat = MMC_STATUS; | 624 | stat = readw(host->base + MMC_REG_STATUS); |
| 609 | 625 | ||
| 610 | dev_dbg(mmc_dev(host->mmc), "imxmci_cpu_driven_data write burst %d STATUS = 0x%x\n", | 626 | dev_dbg(mmc_dev(host->mmc), "imxmci_cpu_driven_data write burst %d STATUS = 0x%x\n", |
| 611 | burst_len, stat); | 627 | burst_len, stat); |
| @@ -620,7 +636,7 @@ static int imxmci_cpu_driven_data(struct imxmci_host *host, unsigned int *pstat) | |||
| 620 | static void imxmci_dma_irq(int dma, void *devid) | 636 | static void imxmci_dma_irq(int dma, void *devid) |
| 621 | { | 637 | { |
| 622 | struct imxmci_host *host = devid; | 638 | struct imxmci_host *host = devid; |
| 623 | uint32_t stat = MMC_STATUS; | 639 | u32 stat = readw(host->base + MMC_REG_STATUS); |
| 624 | 640 | ||
| 625 | atomic_set(&host->stuck_timeout, 0); | 641 | atomic_set(&host->stuck_timeout, 0); |
| 626 | host->status_reg = stat; | 642 | host->status_reg = stat; |
| @@ -631,10 +647,11 @@ static void imxmci_dma_irq(int dma, void *devid) | |||
| 631 | static irqreturn_t imxmci_irq(int irq, void *devid) | 647 | static irqreturn_t imxmci_irq(int irq, void *devid) |
| 632 | { | 648 | { |
| 633 | struct imxmci_host *host = devid; | 649 | struct imxmci_host *host = devid; |
| 634 | uint32_t stat = MMC_STATUS; | 650 | u32 stat = readw(host->base + MMC_REG_STATUS); |
| 635 | int handled = 1; | 651 | int handled = 1; |
| 636 | 652 | ||
| 637 | MMC_INT_MASK = host->imask | INT_MASK_SDIO | INT_MASK_AUTO_CARD_DETECT; | 653 | writew(host->imask | INT_MASK_SDIO | INT_MASK_AUTO_CARD_DETECT, |
| 654 | host->base + MMC_REG_INT_MASK); | ||
| 638 | 655 | ||
| 639 | atomic_set(&host->stuck_timeout, 0); | 656 | atomic_set(&host->stuck_timeout, 0); |
| 640 | host->status_reg = stat; | 657 | host->status_reg = stat; |
| @@ -655,7 +672,7 @@ static void imxmci_tasklet_fnc(unsigned long data) | |||
| 655 | if (atomic_read(&host->stuck_timeout) > 4) { | 672 | if (atomic_read(&host->stuck_timeout) > 4) { |
| 656 | char *what; | 673 | char *what; |
| 657 | timeout = 1; | 674 | timeout = 1; |
| 658 | stat = MMC_STATUS; | 675 | stat = readw(host->base + MMC_REG_STATUS); |
| 659 | host->status_reg = stat; | 676 | host->status_reg = stat; |
| 660 | if (test_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events)) | 677 | if (test_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events)) |
| 661 | if (test_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events)) | 678 | if (test_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events)) |
| @@ -671,12 +688,20 @@ static void imxmci_tasklet_fnc(unsigned long data) | |||
| 671 | else | 688 | else |
| 672 | what = "???"; | 689 | what = "???"; |
| 673 | 690 | ||
| 674 | dev_err(mmc_dev(host->mmc), "%s TIMEOUT, hardware stucked STATUS = 0x%04x IMASK = 0x%04x\n", | 691 | dev_err(mmc_dev(host->mmc), |
| 675 | what, stat, MMC_INT_MASK); | 692 | "%s TIMEOUT, hardware stucked STATUS = 0x%04x IMASK = 0x%04x\n", |
| 676 | dev_err(mmc_dev(host->mmc), "CMD_DAT_CONT = 0x%04x, MMC_BLK_LEN = 0x%04x, MMC_NOB = 0x%04x, DMA_CCR = 0x%08x\n", | 693 | what, stat, |
| 677 | MMC_CMD_DAT_CONT, MMC_BLK_LEN, MMC_NOB, CCR(host->dma)); | 694 | readw(host->base + MMC_REG_INT_MASK)); |
| 695 | dev_err(mmc_dev(host->mmc), | ||
| 696 | "CMD_DAT_CONT = 0x%04x, MMC_BLK_LEN = 0x%04x, MMC_NOB = 0x%04x, DMA_CCR = 0x%08x\n", | ||
| 697 | readw(host->base + MMC_REG_CMD_DAT_CONT), | ||
| 698 | readw(host->base + MMC_REG_BLK_LEN), | ||
| 699 | readw(host->base + MMC_REG_NOB), | ||
| 700 | CCR(host->dma)); | ||
| 678 | dev_err(mmc_dev(host->mmc), "CMD%d, prevCMD%d, bus %d-bit, dma_size = 0x%x\n", | 701 | dev_err(mmc_dev(host->mmc), "CMD%d, prevCMD%d, bus %d-bit, dma_size = 0x%x\n", |
| 679 | host->cmd?host->cmd->opcode:0, host->prev_cmd_code, 1 << host->actual_bus_width, host->dma_size); | 702 | host->cmd ? host->cmd->opcode : 0, |
| 703 | host->prev_cmd_code, | ||
| 704 | 1 << host->actual_bus_width, host->dma_size); | ||
| 680 | } | 705 | } |
| 681 | 706 | ||
| 682 | if (!host->present || timeout) | 707 | if (!host->present || timeout) |
| @@ -686,7 +711,7 @@ static void imxmci_tasklet_fnc(unsigned long data) | |||
| 686 | if (test_bit(IMXMCI_PEND_IRQ_b, &host->pending_events) || timeout) { | 711 | if (test_bit(IMXMCI_PEND_IRQ_b, &host->pending_events) || timeout) { |
| 687 | clear_bit(IMXMCI_PEND_IRQ_b, &host->pending_events); | 712 | clear_bit(IMXMCI_PEND_IRQ_b, &host->pending_events); |
| 688 | 713 | ||
| 689 | stat = MMC_STATUS; | 714 | stat = readw(host->base + MMC_REG_STATUS); |
| 690 | /* | 715 | /* |
| 691 | * This is not required in theory, but there is chance to miss some flag | 716 | * This is not required in theory, but there is chance to miss some flag |
| 692 | * which clears automatically by mask write, FreeScale original code keeps | 717 | * which clears automatically by mask write, FreeScale original code keeps |
| @@ -711,7 +736,7 @@ static void imxmci_tasklet_fnc(unsigned long data) | |||
| 711 | } | 736 | } |
| 712 | 737 | ||
| 713 | if (test_bit(IMXMCI_PEND_CPU_DATA_b, &host->pending_events)) { | 738 | if (test_bit(IMXMCI_PEND_CPU_DATA_b, &host->pending_events)) { |
| 714 | stat |= MMC_STATUS; | 739 | stat |= readw(host->base + MMC_REG_STATUS); |
| 715 | if (imxmci_cpu_driven_data(host, &stat)) { | 740 | if (imxmci_cpu_driven_data(host, &stat)) { |
| 716 | if (test_and_clear_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events)) | 741 | if (test_and_clear_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events)) |
| 717 | imxmci_cmd_done(host, stat); | 742 | imxmci_cmd_done(host, stat); |
| @@ -725,7 +750,7 @@ static void imxmci_tasklet_fnc(unsigned long data) | |||
| 725 | if (test_bit(IMXMCI_PEND_DMA_END_b, &host->pending_events) && | 750 | if (test_bit(IMXMCI_PEND_DMA_END_b, &host->pending_events) && |
| 726 | !test_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events)) { | 751 | !test_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events)) { |
| 727 | 752 | ||
| 728 | stat = MMC_STATUS; | 753 | stat = readw(host->base + MMC_REG_STATUS); |
| 729 | /* Same as above */ | 754 | /* Same as above */ |
| 730 | stat |= host->status_reg; | 755 | stat |= host->status_reg; |
| 731 | 756 | ||
| @@ -813,6 +838,7 @@ static void imxmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
| 813 | 838 | ||
| 814 | if (ios->clock) { | 839 | if (ios->clock) { |
| 815 | unsigned int clk; | 840 | unsigned int clk; |
| 841 | u16 reg; | ||
| 816 | 842 | ||
| 817 | /* The prescaler is 5 for PERCLK2 equal to 96MHz | 843 | /* The prescaler is 5 for PERCLK2 equal to 96MHz |
| 818 | * then 96MHz / 5 = 19.2 MHz | 844 | * then 96MHz / 5 = 19.2 MHz |
| @@ -844,17 +870,22 @@ static void imxmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
| 844 | break; | 870 | break; |
| 845 | } | 871 | } |
| 846 | 872 | ||
| 847 | MMC_STR_STP_CLK |= STR_STP_CLK_ENABLE; /* enable controller */ | 873 | /* enable controller */ |
| 874 | reg = readw(host->base + MMC_REG_STR_STP_CLK); | ||
| 875 | writew(reg | STR_STP_CLK_ENABLE, | ||
| 876 | host->base + MMC_REG_STR_STP_CLK); | ||
| 848 | 877 | ||
| 849 | imxmci_stop_clock(host); | 878 | imxmci_stop_clock(host); |
| 850 | MMC_CLK_RATE = (prescaler << 3) | clk; | 879 | writew((prescaler << 3) | clk, host->base + MMC_REG_CLK_RATE); |
| 851 | /* | 880 | /* |
| 852 | * Under my understanding, clock should not be started there, because it would | 881 | * Under my understanding, clock should not be started there, because it would |
| 853 | * initiate SDHC sequencer and send last or random command into card | 882 | * initiate SDHC sequencer and send last or random command into card |
| 854 | */ | 883 | */ |
| 855 | /* imxmci_start_clock(host); */ | 884 | /* imxmci_start_clock(host); */ |
| 856 | 885 | ||
| 857 | dev_dbg(mmc_dev(host->mmc), "MMC_CLK_RATE: 0x%08x\n", MMC_CLK_RATE); | 886 | dev_dbg(mmc_dev(host->mmc), |
| 887 | "MMC_CLK_RATE: 0x%08x\n", | ||
| 888 | readw(host->base + MMC_REG_CLK_RATE)); | ||
| 858 | } else { | 889 | } else { |
| 859 | imxmci_stop_clock(host); | 890 | imxmci_stop_clock(host); |
| 860 | } | 891 | } |
| @@ -913,6 +944,7 @@ static int imxmci_probe(struct platform_device *pdev) | |||
| 913 | struct imxmci_host *host = NULL; | 944 | struct imxmci_host *host = NULL; |
| 914 | struct resource *r; | 945 | struct resource *r; |
| 915 | int ret = 0, irq; | 946 | int ret = 0, irq; |
| 947 | u16 rev_no; | ||
| 916 | 948 | ||
| 917 | printk(KERN_INFO "i.MX mmc driver\n"); | 949 | printk(KERN_INFO "i.MX mmc driver\n"); |
| 918 | 950 | ||
| @@ -921,7 +953,8 @@ static int imxmci_probe(struct platform_device *pdev) | |||
| 921 | if (!r || irq < 0) | 953 | if (!r || irq < 0) |
| 922 | return -ENXIO; | 954 | return -ENXIO; |
| 923 | 955 | ||
| 924 | if (!request_mem_region(r->start, 0x100, pdev->name)) | 956 | r = request_mem_region(r->start, resource_size(r), pdev->name); |
| 957 | if (!r) | ||
| 925 | return -EBUSY; | 958 | return -EBUSY; |
| 926 | 959 | ||
| 927 | mmc = mmc_alloc_host(sizeof(struct imxmci_host), &pdev->dev); | 960 | mmc = mmc_alloc_host(sizeof(struct imxmci_host), &pdev->dev); |
| @@ -945,6 +978,12 @@ static int imxmci_probe(struct platform_device *pdev) | |||
| 945 | mmc->max_blk_count = 65535; | 978 | mmc->max_blk_count = 65535; |
| 946 | 979 | ||
| 947 | host = mmc_priv(mmc); | 980 | host = mmc_priv(mmc); |
| 981 | host->base = ioremap(r->start, resource_size(r)); | ||
| 982 | if (!host->base) { | ||
| 983 | ret = -ENOMEM; | ||
| 984 | goto out; | ||
| 985 | } | ||
| 986 | |||
| 948 | host->mmc = mmc; | 987 | host->mmc = mmc; |
| 949 | host->dma_allocated = 0; | 988 | host->dma_allocated = 0; |
| 950 | host->pdata = pdev->dev.platform_data; | 989 | host->pdata = pdev->dev.platform_data; |
| @@ -972,18 +1011,20 @@ static int imxmci_probe(struct platform_device *pdev) | |||
| 972 | imx_gpio_mode(PB12_PF_SD_CLK); | 1011 | imx_gpio_mode(PB12_PF_SD_CLK); |
| 973 | imx_gpio_mode(PB13_PF_SD_CMD); | 1012 | imx_gpio_mode(PB13_PF_SD_CMD); |
| 974 | 1013 | ||
| 975 | imxmci_softreset(); | 1014 | imxmci_softreset(host); |
| 976 | 1015 | ||
| 977 | if (MMC_REV_NO != 0x390) { | 1016 | rev_no = readw(host->base + MMC_REG_REV_NO); |
| 1017 | if (rev_no != 0x390) { | ||
| 978 | dev_err(mmc_dev(host->mmc), "wrong rev.no. 0x%08x. aborting.\n", | 1018 | dev_err(mmc_dev(host->mmc), "wrong rev.no. 0x%08x. aborting.\n", |
| 979 | MMC_REV_NO); | 1019 | readw(host->base + MMC_REG_REV_NO)); |
| 980 | goto out; | 1020 | goto out; |
| 981 | } | 1021 | } |
| 982 | 1022 | ||
| 983 | MMC_READ_TO = 0x2db4; /* recommended in data sheet */ | 1023 | /* recommended in data sheet */ |
| 1024 | writew(0x2db4, host->base + MMC_REG_READ_TO); | ||
| 984 | 1025 | ||
| 985 | host->imask = IMXMCI_INT_MASK_DEFAULT; | 1026 | host->imask = IMXMCI_INT_MASK_DEFAULT; |
| 986 | MMC_INT_MASK = host->imask; | 1027 | writew(host->imask, host->base + MMC_REG_INT_MASK); |
| 987 | 1028 | ||
| 988 | host->dma = imx_dma_request_by_prio(DRIVER_NAME, DMA_PRIO_LOW); | 1029 | host->dma = imx_dma_request_by_prio(DRIVER_NAME, DMA_PRIO_LOW); |
| 989 | if(host->dma < 0) { | 1030 | if(host->dma < 0) { |
| @@ -1029,10 +1070,12 @@ out: | |||
| 1029 | clk_disable(host->clk); | 1070 | clk_disable(host->clk); |
| 1030 | clk_put(host->clk); | 1071 | clk_put(host->clk); |
| 1031 | } | 1072 | } |
| 1073 | if (host->base) | ||
| 1074 | iounmap(host->base); | ||
| 1032 | } | 1075 | } |
| 1033 | if (mmc) | 1076 | if (mmc) |
| 1034 | mmc_free_host(mmc); | 1077 | mmc_free_host(mmc); |
| 1035 | release_mem_region(r->start, 0x100); | 1078 | release_mem_region(r->start, resource_size(r)); |
| 1036 | return ret; | 1079 | return ret; |
| 1037 | } | 1080 | } |
| 1038 | 1081 | ||
| @@ -1051,6 +1094,7 @@ static int imxmci_remove(struct platform_device *pdev) | |||
| 1051 | mmc_remove_host(mmc); | 1094 | mmc_remove_host(mmc); |
| 1052 | 1095 | ||
| 1053 | free_irq(host->irq, host); | 1096 | free_irq(host->irq, host); |
| 1097 | iounmap(host->base); | ||
| 1054 | if (host->dma_allocated) { | 1098 | if (host->dma_allocated) { |
| 1055 | imx_dma_free(host->dma); | 1099 | imx_dma_free(host->dma); |
| 1056 | host->dma_allocated = 0; | 1100 | host->dma_allocated = 0; |
| @@ -1061,7 +1105,7 @@ static int imxmci_remove(struct platform_device *pdev) | |||
| 1061 | clk_disable(host->clk); | 1105 | clk_disable(host->clk); |
| 1062 | clk_put(host->clk); | 1106 | clk_put(host->clk); |
| 1063 | 1107 | ||
| 1064 | release_mem_region(host->res->start, 0x100); | 1108 | release_mem_region(host->res->start, resource_size(host->res)); |
| 1065 | 1109 | ||
| 1066 | mmc_free_host(mmc); | 1110 | mmc_free_host(mmc); |
| 1067 | } | 1111 | } |
diff --git a/drivers/mmc/host/imxmmc.h b/drivers/mmc/host/imxmmc.h index e5339e334dbb..09d5d4ee3a77 100644 --- a/drivers/mmc/host/imxmmc.h +++ b/drivers/mmc/host/imxmmc.h | |||
| @@ -1,24 +1,21 @@ | |||
| 1 | #define MMC_REG_STR_STP_CLK 0x00 | ||
| 2 | #define MMC_REG_STATUS 0x04 | ||
| 3 | #define MMC_REG_CLK_RATE 0x08 | ||
| 4 | #define MMC_REG_CMD_DAT_CONT 0x0C | ||
| 5 | #define MMC_REG_RES_TO 0x10 | ||
| 6 | #define MMC_REG_READ_TO 0x14 | ||
| 7 | #define MMC_REG_BLK_LEN 0x18 | ||
| 8 | #define MMC_REG_NOB 0x1C | ||
| 9 | #define MMC_REG_REV_NO 0x20 | ||
| 10 | #define MMC_REG_INT_MASK 0x24 | ||
| 11 | #define MMC_REG_CMD 0x28 | ||
| 12 | #define MMC_REG_ARGH 0x2C | ||
| 13 | #define MMC_REG_ARGL 0x30 | ||
| 14 | #define MMC_REG_RES_FIFO 0x34 | ||
| 15 | #define MMC_REG_BUFFER_ACCESS 0x38 | ||
| 1 | 16 | ||
| 2 | # define __REG16(x) (*((volatile u16 *)IO_ADDRESS(x))) | 17 | #define STR_STP_CLK_IPG_CLK_GATE_DIS (1<<15) |
| 3 | 18 | #define STR_STP_CLK_IPG_PERCLK_GATE_DIS (1<<14) | |
| 4 | #define MMC_STR_STP_CLK __REG16(IMX_MMC_BASE + 0x00) | ||
| 5 | #define MMC_STATUS __REG16(IMX_MMC_BASE + 0x04) | ||
| 6 | #define MMC_CLK_RATE __REG16(IMX_MMC_BASE + 0x08) | ||
| 7 | #define MMC_CMD_DAT_CONT __REG16(IMX_MMC_BASE + 0x0C) | ||
| 8 | #define MMC_RES_TO __REG16(IMX_MMC_BASE + 0x10) | ||
| 9 | #define MMC_READ_TO __REG16(IMX_MMC_BASE + 0x14) | ||
| 10 | #define MMC_BLK_LEN __REG16(IMX_MMC_BASE + 0x18) | ||
| 11 | #define MMC_NOB __REG16(IMX_MMC_BASE + 0x1C) | ||
| 12 | #define MMC_REV_NO __REG16(IMX_MMC_BASE + 0x20) | ||
| 13 | #define MMC_INT_MASK __REG16(IMX_MMC_BASE + 0x24) | ||
| 14 | #define MMC_CMD __REG16(IMX_MMC_BASE + 0x28) | ||
| 15 | #define MMC_ARGH __REG16(IMX_MMC_BASE + 0x2C) | ||
| 16 | #define MMC_ARGL __REG16(IMX_MMC_BASE + 0x30) | ||
| 17 | #define MMC_RES_FIFO __REG16(IMX_MMC_BASE + 0x34) | ||
| 18 | #define MMC_BUFFER_ACCESS __REG16(IMX_MMC_BASE + 0x38) | ||
| 19 | #define MMC_BUFFER_ACCESS_OFS 0x38 | ||
| 20 | |||
| 21 | |||
| 22 | #define STR_STP_CLK_ENDIAN (1<<5) | 19 | #define STR_STP_CLK_ENDIAN (1<<5) |
| 23 | #define STR_STP_CLK_RESET (1<<3) | 20 | #define STR_STP_CLK_RESET (1<<3) |
| 24 | #define STR_STP_CLK_ENABLE (1<<2) | 21 | #define STR_STP_CLK_ENABLE (1<<2) |
