aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/mxs-mmc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/host/mxs-mmc.c')
-rw-r--r--drivers/mmc/host/mxs-mmc.c57
1 files changed, 29 insertions, 28 deletions
diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c
index 2ea53613c794..a699a8673766 100644
--- a/drivers/mmc/host/mxs-mmc.c
+++ b/drivers/mmc/host/mxs-mmc.c
@@ -51,7 +51,7 @@
51#define MXS_MMC_DETECT_TIMEOUT (HZ/2) 51#define MXS_MMC_DETECT_TIMEOUT (HZ/2)
52 52
53#define SSP_VERSION_LATEST 4 53#define SSP_VERSION_LATEST 4
54#define ssp_is_old() (host->version < SSP_VERSION_LATEST) 54#define ssp_is_old(host) ((host)->version < SSP_VERSION_LATEST)
55 55
56/* SSP registers */ 56/* SSP registers */
57#define HW_SSP_CTRL0 0x000 57#define HW_SSP_CTRL0 0x000
@@ -86,14 +86,14 @@
86#define BM_SSP_BLOCK_SIZE_BLOCK_COUNT (0xffffff << 4) 86#define BM_SSP_BLOCK_SIZE_BLOCK_COUNT (0xffffff << 4)
87#define BP_SSP_BLOCK_SIZE_BLOCK_SIZE (0) 87#define BP_SSP_BLOCK_SIZE_BLOCK_SIZE (0)
88#define BM_SSP_BLOCK_SIZE_BLOCK_SIZE (0xf) 88#define BM_SSP_BLOCK_SIZE_BLOCK_SIZE (0xf)
89#define HW_SSP_TIMING (ssp_is_old() ? 0x050 : 0x070) 89#define HW_SSP_TIMING(h) (ssp_is_old(h) ? 0x050 : 0x070)
90#define BP_SSP_TIMING_TIMEOUT (16) 90#define BP_SSP_TIMING_TIMEOUT (16)
91#define BM_SSP_TIMING_TIMEOUT (0xffff << 16) 91#define BM_SSP_TIMING_TIMEOUT (0xffff << 16)
92#define BP_SSP_TIMING_CLOCK_DIVIDE (8) 92#define BP_SSP_TIMING_CLOCK_DIVIDE (8)
93#define BM_SSP_TIMING_CLOCK_DIVIDE (0xff << 8) 93#define BM_SSP_TIMING_CLOCK_DIVIDE (0xff << 8)
94#define BP_SSP_TIMING_CLOCK_RATE (0) 94#define BP_SSP_TIMING_CLOCK_RATE (0)
95#define BM_SSP_TIMING_CLOCK_RATE (0xff) 95#define BM_SSP_TIMING_CLOCK_RATE (0xff)
96#define HW_SSP_CTRL1 (ssp_is_old() ? 0x060 : 0x080) 96#define HW_SSP_CTRL1(h) (ssp_is_old(h) ? 0x060 : 0x080)
97#define BM_SSP_CTRL1_SDIO_IRQ (1 << 31) 97#define BM_SSP_CTRL1_SDIO_IRQ (1 << 31)
98#define BM_SSP_CTRL1_SDIO_IRQ_EN (1 << 30) 98#define BM_SSP_CTRL1_SDIO_IRQ_EN (1 << 30)
99#define BM_SSP_CTRL1_RESP_ERR_IRQ (1 << 29) 99#define BM_SSP_CTRL1_RESP_ERR_IRQ (1 << 29)
@@ -116,11 +116,11 @@
116#define BM_SSP_CTRL1_WORD_LENGTH (0xf << 4) 116#define BM_SSP_CTRL1_WORD_LENGTH (0xf << 4)
117#define BP_SSP_CTRL1_SSP_MODE (0) 117#define BP_SSP_CTRL1_SSP_MODE (0)
118#define BM_SSP_CTRL1_SSP_MODE (0xf) 118#define BM_SSP_CTRL1_SSP_MODE (0xf)
119#define HW_SSP_SDRESP0 (ssp_is_old() ? 0x080 : 0x0a0) 119#define HW_SSP_SDRESP0(h) (ssp_is_old(h) ? 0x080 : 0x0a0)
120#define HW_SSP_SDRESP1 (ssp_is_old() ? 0x090 : 0x0b0) 120#define HW_SSP_SDRESP1(h) (ssp_is_old(h) ? 0x090 : 0x0b0)
121#define HW_SSP_SDRESP2 (ssp_is_old() ? 0x0a0 : 0x0c0) 121#define HW_SSP_SDRESP2(h) (ssp_is_old(h) ? 0x0a0 : 0x0c0)
122#define HW_SSP_SDRESP3 (ssp_is_old() ? 0x0b0 : 0x0d0) 122#define HW_SSP_SDRESP3(h) (ssp_is_old(h) ? 0x0b0 : 0x0d0)
123#define HW_SSP_STATUS (ssp_is_old() ? 0x0c0 : 0x100) 123#define HW_SSP_STATUS(h) (ssp_is_old(h) ? 0x0c0 : 0x100)
124#define BM_SSP_STATUS_CARD_DETECT (1 << 28) 124#define BM_SSP_STATUS_CARD_DETECT (1 << 28)
125#define BM_SSP_STATUS_SDIO_IRQ (1 << 17) 125#define BM_SSP_STATUS_SDIO_IRQ (1 << 17)
126#define HW_SSP_VERSION (cpu_is_mx23() ? 0x110 : 0x130) 126#define HW_SSP_VERSION (cpu_is_mx23() ? 0x110 : 0x130)
@@ -183,7 +183,7 @@ static int mxs_mmc_get_cd(struct mmc_host *mmc)
183{ 183{
184 struct mxs_mmc_host *host = mmc_priv(mmc); 184 struct mxs_mmc_host *host = mmc_priv(mmc);
185 185
186 return !(readl(host->base + HW_SSP_STATUS) & 186 return !(readl(host->base + HW_SSP_STATUS(host)) &
187 BM_SSP_STATUS_CARD_DETECT); 187 BM_SSP_STATUS_CARD_DETECT);
188} 188}
189 189
@@ -207,7 +207,7 @@ static void mxs_mmc_reset(struct mxs_mmc_host *host)
207 writel(BF_SSP(0xffff, TIMING_TIMEOUT) | 207 writel(BF_SSP(0xffff, TIMING_TIMEOUT) |
208 BF_SSP(2, TIMING_CLOCK_DIVIDE) | 208 BF_SSP(2, TIMING_CLOCK_DIVIDE) |
209 BF_SSP(0, TIMING_CLOCK_RATE), 209 BF_SSP(0, TIMING_CLOCK_RATE),
210 host->base + HW_SSP_TIMING); 210 host->base + HW_SSP_TIMING(host));
211 211
212 if (host->sdio_irq_en) { 212 if (host->sdio_irq_en) {
213 ctrl0 |= BM_SSP_CTRL0_SDIO_IRQ_CHECK; 213 ctrl0 |= BM_SSP_CTRL0_SDIO_IRQ_CHECK;
@@ -215,7 +215,7 @@ static void mxs_mmc_reset(struct mxs_mmc_host *host)
215 } 215 }
216 216
217 writel(ctrl0, host->base + HW_SSP_CTRL0); 217 writel(ctrl0, host->base + HW_SSP_CTRL0);
218 writel(ctrl1, host->base + HW_SSP_CTRL1); 218 writel(ctrl1, host->base + HW_SSP_CTRL1(host));
219} 219}
220 220
221static void mxs_mmc_start_cmd(struct mxs_mmc_host *host, 221static void mxs_mmc_start_cmd(struct mxs_mmc_host *host,
@@ -229,12 +229,12 @@ static void mxs_mmc_request_done(struct mxs_mmc_host *host)
229 229
230 if (mmc_resp_type(cmd) & MMC_RSP_PRESENT) { 230 if (mmc_resp_type(cmd) & MMC_RSP_PRESENT) {
231 if (mmc_resp_type(cmd) & MMC_RSP_136) { 231 if (mmc_resp_type(cmd) & MMC_RSP_136) {
232 cmd->resp[3] = readl(host->base + HW_SSP_SDRESP0); 232 cmd->resp[3] = readl(host->base + HW_SSP_SDRESP0(host));
233 cmd->resp[2] = readl(host->base + HW_SSP_SDRESP1); 233 cmd->resp[2] = readl(host->base + HW_SSP_SDRESP1(host));
234 cmd->resp[1] = readl(host->base + HW_SSP_SDRESP2); 234 cmd->resp[1] = readl(host->base + HW_SSP_SDRESP2(host));
235 cmd->resp[0] = readl(host->base + HW_SSP_SDRESP3); 235 cmd->resp[0] = readl(host->base + HW_SSP_SDRESP3(host));
236 } else { 236 } else {
237 cmd->resp[0] = readl(host->base + HW_SSP_SDRESP0); 237 cmd->resp[0] = readl(host->base + HW_SSP_SDRESP0(host));
238 } 238 }
239 } 239 }
240 240
@@ -277,9 +277,9 @@ static irqreturn_t mxs_mmc_irq_handler(int irq, void *dev_id)
277 277
278 spin_lock(&host->lock); 278 spin_lock(&host->lock);
279 279
280 stat = readl(host->base + HW_SSP_CTRL1); 280 stat = readl(host->base + HW_SSP_CTRL1(host));
281 writel(stat & MXS_MMC_IRQ_BITS, 281 writel(stat & MXS_MMC_IRQ_BITS,
282 host->base + HW_SSP_CTRL1 + STMP_OFFSET_REG_CLR); 282 host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_CLR);
283 283
284 if ((stat & BM_SSP_CTRL1_SDIO_IRQ) && (stat & BM_SSP_CTRL1_SDIO_IRQ_EN)) 284 if ((stat & BM_SSP_CTRL1_SDIO_IRQ) && (stat & BM_SSP_CTRL1_SDIO_IRQ_EN))
285 mmc_signal_sdio_irq(host->mmc); 285 mmc_signal_sdio_irq(host->mmc);
@@ -485,7 +485,7 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host)
485 blocks = 1; 485 blocks = 1;
486 486
487 /* xfer count, block size and count need to be set differently */ 487 /* xfer count, block size and count need to be set differently */
488 if (ssp_is_old()) { 488 if (ssp_is_old(host)) {
489 ctrl0 |= BF_SSP(data_size, CTRL0_XFER_COUNT); 489 ctrl0 |= BF_SSP(data_size, CTRL0_XFER_COUNT);
490 cmd0 |= BF_SSP(log2_blksz, CMD0_BLOCK_SIZE) | 490 cmd0 |= BF_SSP(log2_blksz, CMD0_BLOCK_SIZE) |
491 BF_SSP(blocks - 1, CMD0_BLOCK_COUNT); 491 BF_SSP(blocks - 1, CMD0_BLOCK_COUNT);
@@ -509,10 +509,10 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host)
509 509
510 /* set the timeout count */ 510 /* set the timeout count */
511 timeout = mxs_ns_to_ssp_ticks(host->clk_rate, data->timeout_ns); 511 timeout = mxs_ns_to_ssp_ticks(host->clk_rate, data->timeout_ns);
512 val = readl(host->base + HW_SSP_TIMING); 512 val = readl(host->base + HW_SSP_TIMING(host));
513 val &= ~(BM_SSP_TIMING_TIMEOUT); 513 val &= ~(BM_SSP_TIMING_TIMEOUT);
514 val |= BF_SSP(timeout, TIMING_TIMEOUT); 514 val |= BF_SSP(timeout, TIMING_TIMEOUT);
515 writel(val, host->base + HW_SSP_TIMING); 515 writel(val, host->base + HW_SSP_TIMING(host));
516 516
517 /* pio */ 517 /* pio */
518 host->ssp_pio_words[0] = ctrl0; 518 host->ssp_pio_words[0] = ctrl0;
@@ -598,11 +598,11 @@ static void mxs_mmc_set_clk_rate(struct mxs_mmc_host *host, unsigned int rate)
598 598
599 ssp_sck = ssp_clk / clock_divide / (1 + clock_rate); 599 ssp_sck = ssp_clk / clock_divide / (1 + clock_rate);
600 600
601 val = readl(host->base + HW_SSP_TIMING); 601 val = readl(host->base + HW_SSP_TIMING(host));
602 val &= ~(BM_SSP_TIMING_CLOCK_DIVIDE | BM_SSP_TIMING_CLOCK_RATE); 602 val &= ~(BM_SSP_TIMING_CLOCK_DIVIDE | BM_SSP_TIMING_CLOCK_RATE);
603 val |= BF_SSP(clock_divide, TIMING_CLOCK_DIVIDE); 603 val |= BF_SSP(clock_divide, TIMING_CLOCK_DIVIDE);
604 val |= BF_SSP(clock_rate, TIMING_CLOCK_RATE); 604 val |= BF_SSP(clock_rate, TIMING_CLOCK_RATE);
605 writel(val, host->base + HW_SSP_TIMING); 605 writel(val, host->base + HW_SSP_TIMING(host));
606 606
607 host->clk_rate = ssp_sck; 607 host->clk_rate = ssp_sck;
608 608
@@ -639,16 +639,17 @@ static void mxs_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
639 writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK, 639 writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK,
640 host->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET); 640 host->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET);
641 writel(BM_SSP_CTRL1_SDIO_IRQ_EN, 641 writel(BM_SSP_CTRL1_SDIO_IRQ_EN,
642 host->base + HW_SSP_CTRL1 + STMP_OFFSET_REG_SET); 642 host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_SET);
643 643
644 if (readl(host->base + HW_SSP_STATUS) & BM_SSP_STATUS_SDIO_IRQ) 644 if (readl(host->base + HW_SSP_STATUS(host)) &
645 BM_SSP_STATUS_SDIO_IRQ)
645 mmc_signal_sdio_irq(host->mmc); 646 mmc_signal_sdio_irq(host->mmc);
646 647
647 } else { 648 } else {
648 writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK, 649 writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK,
649 host->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR); 650 host->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR);
650 writel(BM_SSP_CTRL1_SDIO_IRQ_EN, 651 writel(BM_SSP_CTRL1_SDIO_IRQ_EN,
651 host->base + HW_SSP_CTRL1 + STMP_OFFSET_REG_CLR); 652 host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_CLR);
652 } 653 }
653 654
654 spin_unlock_irqrestore(&host->lock, flags); 655 spin_unlock_irqrestore(&host->lock, flags);
@@ -765,8 +766,8 @@ static int mxs_mmc_probe(struct platform_device *pdev)
765 766
766 mmc->max_segs = 52; 767 mmc->max_segs = 52;
767 mmc->max_blk_size = 1 << 0xf; 768 mmc->max_blk_size = 1 << 0xf;
768 mmc->max_blk_count = (ssp_is_old()) ? 0xff : 0xffffff; 769 mmc->max_blk_count = (ssp_is_old(host)) ? 0xff : 0xffffff;
769 mmc->max_req_size = (ssp_is_old()) ? 0xffff : 0xffffffff; 770 mmc->max_req_size = (ssp_is_old(host)) ? 0xffff : 0xffffffff;
770 mmc->max_seg_size = dma_get_max_seg_size(host->dmach->device->dev); 771 mmc->max_seg_size = dma_get_max_seg_size(host->dmach->device->dev);
771 772
772 platform_set_drvdata(pdev, mmc); 773 platform_set_drvdata(pdev, mmc);