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.c30
1 files changed, 14 insertions, 16 deletions
diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c
index 99d39a6a1032..d513d47364d0 100644
--- a/drivers/mmc/host/mxs-mmc.c
+++ b/drivers/mmc/host/mxs-mmc.c
@@ -564,40 +564,38 @@ static void mxs_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
564 564
565static void mxs_mmc_set_clk_rate(struct mxs_mmc_host *host, unsigned int rate) 565static void mxs_mmc_set_clk_rate(struct mxs_mmc_host *host, unsigned int rate)
566{ 566{
567 unsigned int ssp_rate, bit_rate; 567 unsigned int ssp_clk, ssp_sck;
568 u32 div1, div2; 568 u32 clock_divide, clock_rate;
569 u32 val; 569 u32 val;
570 570
571 ssp_rate = clk_get_rate(host->clk); 571 ssp_clk = clk_get_rate(host->clk);
572 572
573 for (div1 = 2; div1 < 254; div1 += 2) { 573 for (clock_divide = 2; clock_divide <= 254; clock_divide += 2) {
574 div2 = ssp_rate / rate / div1; 574 clock_rate = DIV_ROUND_UP(ssp_clk, rate * clock_divide);
575 if (div2 < 0x100) 575 clock_rate = (clock_rate > 0) ? clock_rate - 1 : 0;
576 if (clock_rate <= 255)
576 break; 577 break;
577 } 578 }
578 579
579 if (div1 >= 254) { 580 if (clock_divide > 254) {
580 dev_err(mmc_dev(host->mmc), 581 dev_err(mmc_dev(host->mmc),
581 "%s: cannot set clock to %d\n", __func__, rate); 582 "%s: cannot set clock to %d\n", __func__, rate);
582 return; 583 return;
583 } 584 }
584 585
585 if (div2 == 0) 586 ssp_sck = ssp_clk / clock_divide / (1 + clock_rate);
586 bit_rate = ssp_rate / div1;
587 else
588 bit_rate = ssp_rate / div1 / div2;
589 587
590 val = readl(host->base + HW_SSP_TIMING); 588 val = readl(host->base + HW_SSP_TIMING);
591 val &= ~(BM_SSP_TIMING_CLOCK_DIVIDE | BM_SSP_TIMING_CLOCK_RATE); 589 val &= ~(BM_SSP_TIMING_CLOCK_DIVIDE | BM_SSP_TIMING_CLOCK_RATE);
592 val |= BF_SSP(div1, TIMING_CLOCK_DIVIDE); 590 val |= BF_SSP(clock_divide, TIMING_CLOCK_DIVIDE);
593 val |= BF_SSP(div2 - 1, TIMING_CLOCK_RATE); 591 val |= BF_SSP(clock_rate, TIMING_CLOCK_RATE);
594 writel(val, host->base + HW_SSP_TIMING); 592 writel(val, host->base + HW_SSP_TIMING);
595 593
596 host->clk_rate = bit_rate; 594 host->clk_rate = ssp_sck;
597 595
598 dev_dbg(mmc_dev(host->mmc), 596 dev_dbg(mmc_dev(host->mmc),
599 "%s: div1 %d, div2 %d, ssp %d, bit %d, rate %d\n", 597 "%s: clock_divide %d, clock_rate %d, ssp_clk %d, rate_actual %d, rate_requested %d\n",
600 __func__, div1, div2, ssp_rate, bit_rate, rate); 598 __func__, clock_divide, clock_rate, ssp_clk, ssp_sck, rate);
601} 599}
602 600
603static void mxs_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) 601static void mxs_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)