|
@@ -72,6 +72,7 @@ static unsigned int fmax = 515633;
|
|
|
* @pwrreg_clkgate: MMCIPOWER register must be used to gate the clock
|
|
|
* @busy_detect: true if busy detection on dat0 is supported
|
|
|
* @pwrreg_nopower: bits in MMCIPOWER don't controls ext. power supply
|
|
|
+ * @explicit_mclk_control: enable explicit mclk control in driver.
|
|
|
*/
|
|
|
struct variant_data {
|
|
|
unsigned int clkreg;
|
|
@@ -93,6 +94,7 @@ struct variant_data {
|
|
|
bool pwrreg_clkgate;
|
|
|
bool busy_detect;
|
|
|
bool pwrreg_nopower;
|
|
|
+ bool explicit_mclk_control;
|
|
|
};
|
|
|
|
|
|
static struct variant_data variant_arm = {
|
|
@@ -286,7 +288,9 @@ static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired)
|
|
|
host->cclk = 0;
|
|
|
|
|
|
if (desired) {
|
|
|
- if (desired >= host->mclk) {
|
|
|
+ if (variant->explicit_mclk_control) {
|
|
|
+ host->cclk = host->mclk;
|
|
|
+ } else if (desired >= host->mclk) {
|
|
|
clk = MCI_CLK_BYPASS;
|
|
|
if (variant->st_clkdiv)
|
|
|
clk |= MCI_ST_UX500_NEG_EDGE;
|
|
@@ -1327,6 +1331,17 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
|
|
|
if (!ios->clock && variant->pwrreg_clkgate)
|
|
|
pwr &= ~MCI_PWR_ON;
|
|
|
|
|
|
+ if (host->variant->explicit_mclk_control &&
|
|
|
+ ios->clock != host->clock_cache) {
|
|
|
+ ret = clk_set_rate(host->clk, ios->clock);
|
|
|
+ if (ret < 0)
|
|
|
+ dev_err(mmc_dev(host->mmc),
|
|
|
+ "Error setting clock rate (%d)\n", ret);
|
|
|
+ else
|
|
|
+ host->mclk = clk_get_rate(host->clk);
|
|
|
+ }
|
|
|
+ host->clock_cache = ios->clock;
|
|
|
+
|
|
|
spin_lock_irqsave(&host->lock, flags);
|
|
|
|
|
|
mmci_set_clkreg(host, ios->clock);
|
|
@@ -1502,9 +1517,12 @@ static int mmci_probe(struct amba_device *dev,
|
|
|
* The ARM and ST versions of the block have slightly different
|
|
|
* clock divider equations which means that the minimum divider
|
|
|
* differs too.
|
|
|
+ * on Qualcomm like controllers get the nearest minimum clock to 100Khz
|
|
|
*/
|
|
|
if (variant->st_clkdiv)
|
|
|
mmc->f_min = DIV_ROUND_UP(host->mclk, 257);
|
|
|
+ else if (variant->explicit_mclk_control)
|
|
|
+ mmc->f_min = clk_round_rate(host->clk, 100000);
|
|
|
else
|
|
|
mmc->f_min = DIV_ROUND_UP(host->mclk, 512);
|
|
|
/*
|
|
@@ -1514,9 +1532,14 @@ static int mmci_probe(struct amba_device *dev,
|
|
|
* the block, of course.
|
|
|
*/
|
|
|
if (mmc->f_max)
|
|
|
- mmc->f_max = min(host->mclk, mmc->f_max);
|
|
|
+ mmc->f_max = variant->explicit_mclk_control ?
|
|
|
+ min(variant->f_max, mmc->f_max) :
|
|
|
+ min(host->mclk, mmc->f_max);
|
|
|
else
|
|
|
- mmc->f_max = min(host->mclk, fmax);
|
|
|
+ mmc->f_max = variant->explicit_mclk_control ?
|
|
|
+ fmax : min(host->mclk, fmax);
|
|
|
+
|
|
|
+
|
|
|
dev_dbg(mmc_dev(mmc), "clocking block at %u Hz\n", mmc->f_max);
|
|
|
|
|
|
/* Get regulators and the supported OCR mask */
|