Re: [PATCH v4 2/2] sdhci-s3c: Add support no internal clock divider in host controller
Hi Chris, Unfortunately it's not merged your tree. It's required for s5pc210 board. can you merge it for 37-rc6 or later? Thank you, Kyungmin Park On Mon, Oct 11, 2010 at 2:47 PM, Kukjin Kim kgene@samsung.com wrote: From: Jeongbae Seo jeongbae@samsung.com 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. If external clock divider type is selected, some functions related with clock control will be overridened by other functions. The current clock control index is added to let you know which clock bus is used for SDHCI when using overriding functions. The checking functions is added into sdhci_s3c_consider_clock, because clock divider step is different from that of host controller. Signed-off-by: Jeongbae Seo jeongbae@samsung.com Cc: Jaehoon Chung jh80.ch...@samsung.com Cc: Kyungmin Park kyungmin.p...@samsung.com Cc: Ben Dooks ben-li...@fluff.org Signed-off-by: Kukjin Kim kgene@samsung.com --- Changes since v3: - Modified comparision condition as per Kyungmin Park's suggestion Changes since v2: - Changed clock control method to overriding from using quirk - This patch is referred from that of Jaehoon Chung's support non-standard clock setting Changes since v1: - Separated to each topic NOTE : - This patch depends on following. [PATCH 4/5] ARM: SAMSUNG : Add clock types into platform data drivers/mmc/host/sdhci-s3c.c | 62 ++ 1 files changed, 62 insertions(+), 0 deletions(-) diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c index a7710f5..e7208f6 100644 --- a/drivers/mmc/host/sdhci-s3c.c +++ b/drivers/mmc/host/sdhci-s3c.c @@ -130,6 +130,15 @@ static unsigned int sdhci_s3c_consider_clock(struct sdhci_s3c *ourhost, if (!clksrc) return UINT_MAX; + /* + * Clock divider's step is different as 1 from that of host controller + * when 'clk_type' is S3C_SDHCI_CLK_DIV_EXTERNAL. + */ + if (ourhost-pdata-clk_type == S3C_SDHCI_CLK_DIV_EXTERNAL) { + rate = clk_round_rate(clksrc, wanted); + return wanted - rate; + } + rate = clk_get_rate(clksrc); for (div = 1; div 256; div *= 2) { @@ -232,6 +241,42 @@ static unsigned int sdhci_s3c_get_min_clock(struct sdhci_host *host) return min; } +/* sdhci_cmu_get_max_clk - callback to get maximum clock frequency.*/ +static unsigned int sdhci_cmu_get_max_clock(struct sdhci_host *host) +{ + struct sdhci_s3c *ourhost = to_s3c(host); + + return clk_round_rate(ourhost-clk_bus[ourhost-cur_clk], UINT_MAX); +} + +/* sdhci_cmu_get_min_clock - callback to get minimal supported clock value. */ +static unsigned int sdhci_cmu_get_min_clock(struct sdhci_host *host) +{ + struct sdhci_s3c *ourhost = to_s3c(host); + + /* + * initial clock can be in the frequency range of + * 100KHz-400KHz, so we set it as max value. + */ + return clk_round_rate(ourhost-clk_bus[ourhost-cur_clk], 40); +} + +/* sdhci_cmu_set_clock - callback on clock change.*/ +static void sdhci_cmu_set_clock(struct sdhci_host *host, unsigned int clock) +{ + struct sdhci_s3c *ourhost = to_s3c(host); + + /* don't bother if the clock is going off */ + if (clock == 0) + return; + + sdhci_s3c_set_clock(host, clock); + + clk_set_rate(ourhost-clk_bus[ourhost-cur_clk], clock); + + host-clock = clock; +} + static struct sdhci_ops sdhci_s3c_ops = { .get_max_clock = sdhci_s3c_get_max_clk, .set_clock = sdhci_s3c_set_clock, @@ -361,6 +406,13 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) clks++; sc-clk_bus[ptr] = clk; + + /* + * save current clock index to know which clock bus + * is used later in overriding functions. + */ + sc-cur_clk = ptr; + clk_enable(clk); dev_info(dev, clock source %d: %s (%ld Hz)\n, @@ -427,6 +479,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 can use overriding functions instead of default. + */ + if (pdata-clk_type) { + sdhci_s3c_ops.set_clock = sdhci_cmu_set_clock; + sdhci_s3c_ops.get_min_clock = sdhci_cmu_get_min_clock; + sdhci_s3c_ops.get_max_clock = sdhci_cmu_get_max_clock; + } + /* It supports additional host capabilities if needed */ if
Re: [PATCH v4 2/2] sdhci-s3c: Add support no internal clock divider in host controller
Hi Kyungmin, Ben, On Mon, Dec 20, 2010 at 11:08:00AM +0900, Kyungmin Park wrote: Hi Chris, Unfortunately it's not merged your tree. It's required for s5pc210 board. can you merge it for 37-rc6 or later? I'm not comfortable slipping this into .37 (-rc6 has already been released) without an ACK from Ben, but I will accept it into mmc-next for the .38 merge window, and Ben can yell sometime before the merge if he doesn't agree. Does that work okay for you? Thanks, -- Chris Ball c...@laptop.org http://printf.net/ One Laptop Per Child -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 2/2] sdhci-s3c: Add support no internal clock divider in host controller
From: Jeongbae Seo jeongbae@samsung.com 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. If external clock divider type is selected, some functions related with clock control will be overridened by other functions. The current clock control index is added to let you know which clock bus is used for SDHCI when using overriding functions. The checking functions is added into sdhci_s3c_consider_clock, because clock divider step is different from that of host controller. Signed-off-by: Jeongbae Seo jeongbae@samsung.com Cc: Jaehoon Chung jh80.ch...@samsung.com Cc: Kyungmin Park kyungmin.p...@samsung.com Cc: Ben Dooks ben-li...@fluff.org Signed-off-by: Kukjin Kim kgene@samsung.com --- Changes since v3: - Modified comparision condition as per Kyungmin Park's suggestion Changes since v2: - Changed clock control method to overriding from using quirk - This patch is referred from that of Jaehoon Chung's support non-standard clock setting Changes since v1: - Separated to each topic NOTE : - This patch depends on following. [PATCH 4/5] ARM: SAMSUNG : Add clock types into platform data drivers/mmc/host/sdhci-s3c.c | 62 ++ 1 files changed, 62 insertions(+), 0 deletions(-) diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c index a7710f5..e7208f6 100644 --- a/drivers/mmc/host/sdhci-s3c.c +++ b/drivers/mmc/host/sdhci-s3c.c @@ -130,6 +130,15 @@ static unsigned int sdhci_s3c_consider_clock(struct sdhci_s3c *ourhost, if (!clksrc) return UINT_MAX; + /* +* Clock divider's step is different as 1 from that of host controller +* when 'clk_type' is S3C_SDHCI_CLK_DIV_EXTERNAL. +*/ + if (ourhost-pdata-clk_type == S3C_SDHCI_CLK_DIV_EXTERNAL) { + rate = clk_round_rate(clksrc, wanted); + return wanted - rate; + } + rate = clk_get_rate(clksrc); for (div = 1; div 256; div *= 2) { @@ -232,6 +241,42 @@ static unsigned int sdhci_s3c_get_min_clock(struct sdhci_host *host) return min; } +/* sdhci_cmu_get_max_clk - callback to get maximum clock frequency.*/ +static unsigned int sdhci_cmu_get_max_clock(struct sdhci_host *host) +{ + struct sdhci_s3c *ourhost = to_s3c(host); + + return clk_round_rate(ourhost-clk_bus[ourhost-cur_clk], UINT_MAX); +} + +/* sdhci_cmu_get_min_clock - callback to get minimal supported clock value. */ +static unsigned int sdhci_cmu_get_min_clock(struct sdhci_host *host) +{ + struct sdhci_s3c *ourhost = to_s3c(host); + + /* +* initial clock can be in the frequency range of +* 100KHz-400KHz, so we set it as max value. +*/ + return clk_round_rate(ourhost-clk_bus[ourhost-cur_clk], 40); +} + +/* sdhci_cmu_set_clock - callback on clock change.*/ +static void sdhci_cmu_set_clock(struct sdhci_host *host, unsigned int clock) +{ + struct sdhci_s3c *ourhost = to_s3c(host); + + /* don't bother if the clock is going off */ + if (clock == 0) + return; + + sdhci_s3c_set_clock(host, clock); + + clk_set_rate(ourhost-clk_bus[ourhost-cur_clk], clock); + + host-clock = clock; +} + static struct sdhci_ops sdhci_s3c_ops = { .get_max_clock = sdhci_s3c_get_max_clk, .set_clock = sdhci_s3c_set_clock, @@ -361,6 +406,13 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) clks++; sc-clk_bus[ptr] = clk; + + /* +* save current clock index to know which clock bus +* is used later in overriding functions. +*/ + sc-cur_clk = ptr; + clk_enable(clk); dev_info(dev, clock source %d: %s (%ld Hz)\n, @@ -427,6 +479,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 can use overriding functions instead of default. +*/ + if (pdata-clk_type) { + sdhci_s3c_ops.set_clock = sdhci_cmu_set_clock; + sdhci_s3c_ops.get_min_clock = sdhci_cmu_get_min_clock; + sdhci_s3c_ops.get_max_clock = sdhci_cmu_get_max_clock; + } + /* It supports additional host capabilities if needed */ if (pdata-host_caps) host-mmc-caps |= pdata-host_caps; -- 1.6.2.5 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html