Jeongbae Seo wrote: > > From: Hyuk Lee <hyuk1.lee@xxxxxxxxxxx> > > This patch adds to support no internal clock divider in SDHCI. > The external clock divider can be used to make a proper clock > because SDHCI doesn't support internal clock divider by itself. > Hi, Please add Chris Ball <cjb@xxxxxxxxxx> who is a maintainer of MMC subsystem in Cc later. > Signed-off-by: Hyuk Lee <hyuk1.lee@xxxxxxxxxxx> > Signed-off-by: Jeongbae Seo <jeongbae.seo@xxxxxxxxxxx> > --- > drivers/mmc/host/sdhci-s3c.c | 63 > ++++++++++++++++++++++++++++++++++++++++++ > 1 files changed, 63 insertions(+), 0 deletions(-) > > diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c > index 71ad416..6160960 100644 > --- a/drivers/mmc/host/sdhci-s3c.c > +++ b/drivers/mmc/host/sdhci-s3c.c > @@ -96,6 +96,13 @@ static unsigned int sdhci_s3c_get_max_clk(struct > sdhci_host *host) > unsigned int rate, max; > int clk; > > + /* > + * There is only one clock source(sclk) if there is no clock divider > + * in the host controller > + */ > + if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK) > + return clk_round_rate(ourhost->clk_bus[2], UINT_MAX); > + > /* note, a reset will reset the clock source */ > > sdhci_s3c_check_sclk(host); > @@ -130,6 +137,15 @@ static unsigned int sdhci_s3c_consider_clock(struct > sdhci_s3c *ourhost, > if (!clksrc) > return UINT_MAX; > > + /* > + * There is only one clock source(sclk) if there is no clock divider > + * in the host controller > + */ > + if (ourhost->host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK) { > + rate = clk_round_rate(clksrc, wanted); > + return wanted - rate; > + } > + > rate = clk_get_rate(clksrc); > > for (div = 1; div < 256; div *= 2) { > @@ -159,6 +175,7 @@ static void sdhci_s3c_set_clock(struct sdhci_host *host, > unsigned int clock) > int best_src = 0; > int src; > u32 ctrl; > + unsigned int timeout; > > /* don't bother if the clock is going off. */ > if (clock == 0) > @@ -204,6 +221,35 @@ static void sdhci_s3c_set_clock(struct sdhci_host *host, > unsigned int clock) > (ourhost->pdata->cfg_card)(ourhost->pdev, host- > >ioaddr, > &ios, NULL); > } > + > + /* > + * There is only one clock source(sclk) if there is no clock divider > + * in the host controller > + */ > + if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK) { > + writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL); > + clk_set_rate(ourhost->clk_bus[ourhost->cur_clk], clock); > + > + writew(SDHCI_CLOCK_INT_EN, host->ioaddr + > SDHCI_CLOCK_CONTROL); > + > + /* Wait max 20 ms */ > + timeout = 20; > + while (!((sdhci_readw(host, SDHCI_CLOCK_CONTROL)) > + & SDHCI_CLOCK_INT_STABLE)) { > + if (timeout == 0) { > + printk(KERN_ERR "%s: clock never > stabilised.\n" > + , mmc_hostname(host- > >mmc)); > + return; > + } > + timeout--; > + mdelay(1); > + } > + > + writew(SDHCI_CLOCK_INT_EN | SDHCI_CLOCK_CARD_EN, > + host->ioaddr + SDHCI_CLOCK_CONTROL); > + > + host->clock = clock; > + } > } > > /** > @@ -221,6 +267,13 @@ static unsigned int sdhci_s3c_get_min_clock(struct > sdhci_host *host) > unsigned int delta, min = UINT_MAX; > int src; > > + /* > + * There is only one clock source(sclk) if there is no clock divider > + * in the host controller > + */ > + if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK) > + return clk_round_rate(ourhost->clk_bus[2], 400000); > + > for (src = 0; src < MAX_BUS_CLK; src++) { > delta = sdhci_s3c_consider_clock(ourhost, src, 0); > if (delta == UINT_MAX) > @@ -425,6 +478,16 @@ static int __devinit sdhci_s3c_probe(struct > platform_device *pdev) > /* HSMMC on Samsung SoCs uses SDCLK as timeout clock */ > host->quirks |= SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK; > > + /* > + * If controller does not have internal clock divider, > + * we need to use another method with setup a quirk. > + */ > + if (pdata->clk_type) > + host->quirks |= SDHCI_QUIRK_NONSTANDARD_CLOCK; > + > + if (pdata->host_caps) > + host->mmc->caps |= pdata->host_caps; > + If you want to add above feature, please separate it... (snip) Thanks. Best regards, Kgene. -- Kukjin Kim <kgene.kim@xxxxxxxxxxx>, Senior Engineer, SW Solution Development Team, Samsung Electronics Co., Ltd. -- To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html