aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mmc/host/mmci.c29
-rw-r--r--drivers/mmc/host/mmci.h2
2 files changed, 28 insertions, 3 deletions
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index b588810fd1a4..2e6075fdce46 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -72,6 +72,7 @@ static unsigned int fmax = 515633;
72 * @pwrreg_clkgate: MMCIPOWER register must be used to gate the clock 72 * @pwrreg_clkgate: MMCIPOWER register must be used to gate the clock
73 * @busy_detect: true if busy detection on dat0 is supported 73 * @busy_detect: true if busy detection on dat0 is supported
74 * @pwrreg_nopower: bits in MMCIPOWER don't controls ext. power supply 74 * @pwrreg_nopower: bits in MMCIPOWER don't controls ext. power supply
75 * @explicit_mclk_control: enable explicit mclk control in driver.
75 */ 76 */
76struct variant_data { 77struct variant_data {
77 unsigned int clkreg; 78 unsigned int clkreg;
@@ -93,6 +94,7 @@ struct variant_data {
93 bool pwrreg_clkgate; 94 bool pwrreg_clkgate;
94 bool busy_detect; 95 bool busy_detect;
95 bool pwrreg_nopower; 96 bool pwrreg_nopower;
97 bool explicit_mclk_control;
96}; 98};
97 99
98static struct variant_data variant_arm = { 100static struct variant_data variant_arm = {
@@ -286,7 +288,9 @@ static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired)
286 host->cclk = 0; 288 host->cclk = 0;
287 289
288 if (desired) { 290 if (desired) {
289 if (desired >= host->mclk) { 291 if (variant->explicit_mclk_control) {
292 host->cclk = host->mclk;
293 } else if (desired >= host->mclk) {
290 clk = MCI_CLK_BYPASS; 294 clk = MCI_CLK_BYPASS;
291 if (variant->st_clkdiv) 295 if (variant->st_clkdiv)
292 clk |= MCI_ST_UX500_NEG_EDGE; 296 clk |= MCI_ST_UX500_NEG_EDGE;
@@ -1327,6 +1331,17 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
1327 if (!ios->clock && variant->pwrreg_clkgate) 1331 if (!ios->clock && variant->pwrreg_clkgate)
1328 pwr &= ~MCI_PWR_ON; 1332 pwr &= ~MCI_PWR_ON;
1329 1333
1334 if (host->variant->explicit_mclk_control &&
1335 ios->clock != host->clock_cache) {
1336 ret = clk_set_rate(host->clk, ios->clock);
1337 if (ret < 0)
1338 dev_err(mmc_dev(host->mmc),
1339 "Error setting clock rate (%d)\n", ret);
1340 else
1341 host->mclk = clk_get_rate(host->clk);
1342 }
1343 host->clock_cache = ios->clock;
1344
1330 spin_lock_irqsave(&host->lock, flags); 1345 spin_lock_irqsave(&host->lock, flags);
1331 1346
1332 mmci_set_clkreg(host, ios->clock); 1347 mmci_set_clkreg(host, ios->clock);
@@ -1502,9 +1517,12 @@ static int mmci_probe(struct amba_device *dev,
1502 * The ARM and ST versions of the block have slightly different 1517 * The ARM and ST versions of the block have slightly different
1503 * clock divider equations which means that the minimum divider 1518 * clock divider equations which means that the minimum divider
1504 * differs too. 1519 * differs too.
1520 * on Qualcomm like controllers get the nearest minimum clock to 100Khz
1505 */ 1521 */
1506 if (variant->st_clkdiv) 1522 if (variant->st_clkdiv)
1507 mmc->f_min = DIV_ROUND_UP(host->mclk, 257); 1523 mmc->f_min = DIV_ROUND_UP(host->mclk, 257);
1524 else if (variant->explicit_mclk_control)
1525 mmc->f_min = clk_round_rate(host->clk, 100000);
1508 else 1526 else
1509 mmc->f_min = DIV_ROUND_UP(host->mclk, 512); 1527 mmc->f_min = DIV_ROUND_UP(host->mclk, 512);
1510 /* 1528 /*
@@ -1514,9 +1532,14 @@ static int mmci_probe(struct amba_device *dev,
1514 * the block, of course. 1532 * the block, of course.
1515 */ 1533 */
1516 if (mmc->f_max) 1534 if (mmc->f_max)
1517 mmc->f_max = min(host->mclk, mmc->f_max); 1535 mmc->f_max = variant->explicit_mclk_control ?
1536 min(variant->f_max, mmc->f_max) :
1537 min(host->mclk, mmc->f_max);
1518 else 1538 else
1519 mmc->f_max = min(host->mclk, fmax); 1539 mmc->f_max = variant->explicit_mclk_control ?
1540 fmax : min(host->mclk, fmax);
1541
1542
1520 dev_dbg(mmc_dev(mmc), "clocking block at %u Hz\n", mmc->f_max); 1543 dev_dbg(mmc_dev(mmc), "clocking block at %u Hz\n", mmc->f_max);
1521 1544
1522 /* Get regulators and the supported OCR mask */ 1545 /* Get regulators and the supported OCR mask */
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h
index d38a99df1820..ef346170b241 100644
--- a/drivers/mmc/host/mmci.h
+++ b/drivers/mmc/host/mmci.h
@@ -208,6 +208,8 @@ struct mmci_host {
208 spinlock_t lock; 208 spinlock_t lock;
209 209
210 unsigned int mclk; 210 unsigned int mclk;
211 /* cached value of requested clk in set_ios */
212 unsigned int clock_cache;
211 unsigned int cclk; 213 unsigned int cclk;
212 u32 pwr_reg; 214 u32 pwr_reg;
213 u32 pwr_reg_add; 215 u32 pwr_reg_add;