public inbox for linux-arm-kernel@lists.infradead.org
 help / color / mirror / Atom feed
* [PATCH v4 2/2] sdhci-s3c: Add support no internal clock divider in host controller
@ 2010-10-11  5:47 Kukjin Kim
  2010-12-20  2:08 ` Kyungmin Park
  0 siblings, 1 reply; 4+ messages in thread
From: Kukjin Kim @ 2010-10-11  5:47 UTC (permalink / raw)
  To: linux-arm-kernel

From: Jeongbae Seo <jeongbae.seo@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.seo@samsung.com>
Cc: Jaehoon Chung <jh80.chung@samsung.com>
Cc: Kyungmin Park <kyungmin.park@samsung.com>
Cc: Ben Dooks <ben-linux@fluff.org>
Signed-off-by: Kukjin Kim <kgene.kim@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], 400000);
+}
+
+/* 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

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v4 2/2] sdhci-s3c: Add support no internal clock divider in host controller
  2010-10-11  5:47 [PATCH v4 2/2] sdhci-s3c: Add support no internal clock divider in host controller Kukjin Kim
@ 2010-12-20  2:08 ` Kyungmin Park
  2010-12-20  7:06   ` Chris Ball
  0 siblings, 1 reply; 4+ messages in thread
From: Kyungmin Park @ 2010-12-20  2:08 UTC (permalink / raw)
  To: linux-arm-kernel

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.kim@samsung.com> wrote:
> From: Jeongbae Seo <jeongbae.seo@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.seo@samsung.com>
> Cc: Jaehoon Chung <jh80.chung@samsung.com>
> Cc: Kyungmin Park <kyungmin.park@samsung.com>
> Cc: Ben Dooks <ben-linux@fluff.org>
> Signed-off-by: Kukjin Kim <kgene.kim@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], 400000);
> +}
> +
> +/* 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 majordomo at vger.kernel.org
> More majordomo info at ?http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v4 2/2] sdhci-s3c: Add support no internal clock divider in host controller
  2010-12-20  2:08 ` Kyungmin Park
@ 2010-12-20  7:06   ` Chris Ball
  2010-12-20  7:13     ` Kyungmin Park
  0 siblings, 1 reply; 4+ messages in thread
From: Chris Ball @ 2010-12-20  7:06 UTC (permalink / raw)
  To: linux-arm-kernel

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   <cjb@laptop.org>   <http://printf.net/>
One Laptop Per Child

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v4 2/2] sdhci-s3c: Add support no internal clock divider in host controller
  2010-12-20  7:06   ` Chris Ball
@ 2010-12-20  7:13     ` Kyungmin Park
  0 siblings, 0 replies; 4+ messages in thread
From: Kyungmin Park @ 2010-12-20  7:13 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Dec 20, 2010 at 4:06 PM, Chris Ball <cjb@laptop.org> wrote:
> 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?

It's actually bug fix for s5pc210. If there are another rc please
include it if possible. But it's okay to merge .38.

Thank you,
Kyungmin Park

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2010-12-20  7:13 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-10-11  5:47 [PATCH v4 2/2] sdhci-s3c: Add support no internal clock divider in host controller Kukjin Kim
2010-12-20  2:08 ` Kyungmin Park
2010-12-20  7:06   ` Chris Ball
2010-12-20  7:13     ` Kyungmin Park

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox