All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] mmc: dw_mmc: add support for RK3288.
@ 2014-07-05 12:59 ` addy ke
  0 siblings, 0 replies; 22+ messages in thread
From: addy ke @ 2014-07-05 12:59 UTC (permalink / raw)
  To: robh+dt, pawel.moll, mark.rutland, ijc+devicetree, galak,
	rdunlap, tgih.jun, jh80.chung, chris, ulf.hansson, dinguyen,
	heiko, olof
  Cc: devicetree, linux-doc, linux-kernel, linux-mmc, hj, kever.yang,
	xjq, huangtao, zyw, yzq, zhenfu.fang, cf, zhangqing, hl, lintao,
	chenfen, zyf, addy ke

This patch focuses on clock setting for RK3288 mmc controller.

In RK3288 mmc controller, CLKDIV register can only be set 0 or 1,
and if DDR 8bit mode, CLKDIV register must be set 1.

Signed-off-by: addy ke <addy.ke@rock-chips.com>
---
 .../devicetree/bindings/mmc/rockchip-dw-mshc.txt   |  4 +-
 drivers/mmc/host/dw_mmc-pltfm.c                    | 50 +++++++++++++++++++++-
 2 files changed, 51 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt
index c559f3f..e3f95cd 100644
--- a/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt
+++ b/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt
@@ -10,7 +10,9 @@ extensions to the Synopsys Designware Mobile Storage Host Controller.
 Required Properties:
 
 * compatible: should be
-	- "rockchip,rk2928-dw-mshc": for Rockchip RK2928 and following
+	- "rockchip,rk2928-dw-mshc": for Rockchip RK2928 and following,
+							before RK3288
+	- "rockchip,rk3288-dw-mshc": for Rockchip RK3288
 
 Example:
 
diff --git a/drivers/mmc/host/dw_mmc-pltfm.c b/drivers/mmc/host/dw_mmc-pltfm.c
index d4a47a9..15d796e 100644
--- a/drivers/mmc/host/dw_mmc-pltfm.c
+++ b/drivers/mmc/host/dw_mmc-pltfm.c
@@ -21,17 +21,61 @@
 #include <linux/mmc/mmc.h>
 #include <linux/mmc/dw_mmc.h>
 #include <linux/of.h>
+#include <linux/clk.h>
 
 #include "dw_mmc.h"
 #include "dw_mmc-pltfm.h"
 
+#define RK3288_CLKGEN_DIV	2
+
 static void dw_mci_pltfm_prepare_command(struct dw_mci *host, u32 *cmdr)
 {
 	*cmdr |= SDMMC_CMD_USE_HOLD_REG;
 }
 
-static const struct dw_mci_drv_data rockchip_drv_data = {
+static int dw_mci_rk3288_setup_clock(struct dw_mci *host)
+{
+	host->bus_hz = clk_get_rate(host->ciu_clk) / RK3288_CLKGEN_DIV;
+
+	return 0;
+}
+
+static void dw_mci_rk3288_set_ios(struct dw_mci *host, struct mmc_ios *ios)
+{
+	int ret;
+	unsigned int cclkin;
+
+	/*
+	 * cclkin: source clock of mmc controller.
+	 * bus_hz: card interface clock generated by CLKGEN.
+	 * bus_hz = cclkin / RK3288_CLKGEN_DIV;
+	 * ios->clock = (div == 0) ? bus_hz : (bus_hz / (2 * div))
+	 *
+	 * Note: div can only be 0 or 1
+	 *       if DDR50 8bit mode, div must be set 1
+	 */
+	if ((ios->bus_width == MMC_BUS_WIDTH_8) &&
+	    (ios->timing == MMC_TIMING_UHS_DDR50 ||
+	     ios->timing == MMC_TIMING_MMC_DDR52))
+		cclkin = 2 * ios->clock * RK3288_CLKGEN_DIV;
+	else
+		cclkin = ios->clock * RK3288_CLKGEN_DIV;
+
+	ret = clk_set_rate(host->ciu_clk, cclkin);
+	if (ret)
+		dev_warn(host->dev, "failed to set rate %uHz\n", ios->clock);
+
+	host->bus_hz = clk_get_rate(host->ciu_clk) / RK3288_CLKGEN_DIV;
+}
+
+static const struct dw_mci_drv_data rk2928_drv_data = {
+	.prepare_command	= dw_mci_pltfm_prepare_command,
+};
+
+static const struct dw_mci_drv_data rk3288_drv_data = {
 	.prepare_command	= dw_mci_pltfm_prepare_command,
+	.set_ios	= dw_mci_rk3288_set_ios,
+	.setup_clock	= dw_mci_rk3288_setup_clock,
 };
 
 static const struct dw_mci_drv_data socfpga_drv_data = {
@@ -95,7 +139,9 @@ EXPORT_SYMBOL_GPL(dw_mci_pltfm_pmops);
 static const struct of_device_id dw_mci_pltfm_match[] = {
 	{ .compatible = "snps,dw-mshc", },
 	{ .compatible = "rockchip,rk2928-dw-mshc",
-		.data = &rockchip_drv_data },
+		.data = &rk2928_drv_data },
+	{ .compatible = "rockchip,rk3288-dw-mshc",
+		.data = &rk3288_drv_data },
 	{ .compatible = "altr,socfpga-dw-mshc",
 		.data = &socfpga_drv_data },
 	{},
-- 
1.8.3.2



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

* [PATCH] mmc: dw_mmc: add support for RK3288.
@ 2014-07-05 12:59 ` addy ke
  0 siblings, 0 replies; 22+ messages in thread
From: addy ke @ 2014-07-05 12:59 UTC (permalink / raw)
  To: robh+dt-DgEjT+Ai2ygdnm+yROfE0A, pawel.moll-5wv7dgnIgG8,
	mark.rutland-5wv7dgnIgG8, ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	galak-sgV2jX0FEOL9JmXXK+q4OQ, rdunlap-wEGCiKHe2LqWVfeAwA7xHQ,
	tgih.jun-Sze3O3UU22JBDgjK7y7TUQ,
	jh80.chung-Sze3O3UU22JBDgjK7y7TUQ, chris-OsFVWbfNK3isTnJN9+BGXg,
	ulf.hansson-QSEj5FYQhm4dnm+yROfE0A,
	dinguyen-EIB2kfCEclfQT0dZR+AlfA, heiko-4mtYJXux2i+zQB+pC5nmwQ,
	olof-nZhT3qVonbNeoWH0uzbU5w
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-doc-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-mmc-u79uwXL29TY76Z2rM5mHXA, hj-TNX95d0MmH7DzftRWevZcw,
	kever.yang-TNX95d0MmH7DzftRWevZcw, xjq-TNX95d0MmH7DzftRWevZcw,
	huangtao-TNX95d0MmH7DzftRWevZcw, zyw-TNX95d0MmH7DzftRWevZcw,
	yzq-TNX95d0MmH7DzftRWevZcw, zhenfu.fang-TNX95d0MmH7DzftRWevZcw,
	cf-TNX95d0MmH7DzftRWevZcw, zhangqing-TNX95d0MmH7DzftRWevZcw,
	hl-TNX95d0MmH7DzftRWevZcw, lintao-TNX95d0MmH7DzftRWevZcw,
	chenfen-TNX95d0MmH7DzftRWevZcw, zyf-TNX95d0MmH7DzftRWevZcw,
	addy ke

This patch focuses on clock setting for RK3288 mmc controller.

In RK3288 mmc controller, CLKDIV register can only be set 0 or 1,
and if DDR 8bit mode, CLKDIV register must be set 1.

Signed-off-by: addy ke <addy.ke-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
---
 .../devicetree/bindings/mmc/rockchip-dw-mshc.txt   |  4 +-
 drivers/mmc/host/dw_mmc-pltfm.c                    | 50 +++++++++++++++++++++-
 2 files changed, 51 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt
index c559f3f..e3f95cd 100644
--- a/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt
+++ b/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt
@@ -10,7 +10,9 @@ extensions to the Synopsys Designware Mobile Storage Host Controller.
 Required Properties:
 
 * compatible: should be
-	- "rockchip,rk2928-dw-mshc": for Rockchip RK2928 and following
+	- "rockchip,rk2928-dw-mshc": for Rockchip RK2928 and following,
+							before RK3288
+	- "rockchip,rk3288-dw-mshc": for Rockchip RK3288
 
 Example:
 
diff --git a/drivers/mmc/host/dw_mmc-pltfm.c b/drivers/mmc/host/dw_mmc-pltfm.c
index d4a47a9..15d796e 100644
--- a/drivers/mmc/host/dw_mmc-pltfm.c
+++ b/drivers/mmc/host/dw_mmc-pltfm.c
@@ -21,17 +21,61 @@
 #include <linux/mmc/mmc.h>
 #include <linux/mmc/dw_mmc.h>
 #include <linux/of.h>
+#include <linux/clk.h>
 
 #include "dw_mmc.h"
 #include "dw_mmc-pltfm.h"
 
+#define RK3288_CLKGEN_DIV	2
+
 static void dw_mci_pltfm_prepare_command(struct dw_mci *host, u32 *cmdr)
 {
 	*cmdr |= SDMMC_CMD_USE_HOLD_REG;
 }
 
-static const struct dw_mci_drv_data rockchip_drv_data = {
+static int dw_mci_rk3288_setup_clock(struct dw_mci *host)
+{
+	host->bus_hz = clk_get_rate(host->ciu_clk) / RK3288_CLKGEN_DIV;
+
+	return 0;
+}
+
+static void dw_mci_rk3288_set_ios(struct dw_mci *host, struct mmc_ios *ios)
+{
+	int ret;
+	unsigned int cclkin;
+
+	/*
+	 * cclkin: source clock of mmc controller.
+	 * bus_hz: card interface clock generated by CLKGEN.
+	 * bus_hz = cclkin / RK3288_CLKGEN_DIV;
+	 * ios->clock = (div == 0) ? bus_hz : (bus_hz / (2 * div))
+	 *
+	 * Note: div can only be 0 or 1
+	 *       if DDR50 8bit mode, div must be set 1
+	 */
+	if ((ios->bus_width == MMC_BUS_WIDTH_8) &&
+	    (ios->timing == MMC_TIMING_UHS_DDR50 ||
+	     ios->timing == MMC_TIMING_MMC_DDR52))
+		cclkin = 2 * ios->clock * RK3288_CLKGEN_DIV;
+	else
+		cclkin = ios->clock * RK3288_CLKGEN_DIV;
+
+	ret = clk_set_rate(host->ciu_clk, cclkin);
+	if (ret)
+		dev_warn(host->dev, "failed to set rate %uHz\n", ios->clock);
+
+	host->bus_hz = clk_get_rate(host->ciu_clk) / RK3288_CLKGEN_DIV;
+}
+
+static const struct dw_mci_drv_data rk2928_drv_data = {
+	.prepare_command	= dw_mci_pltfm_prepare_command,
+};
+
+static const struct dw_mci_drv_data rk3288_drv_data = {
 	.prepare_command	= dw_mci_pltfm_prepare_command,
+	.set_ios	= dw_mci_rk3288_set_ios,
+	.setup_clock	= dw_mci_rk3288_setup_clock,
 };
 
 static const struct dw_mci_drv_data socfpga_drv_data = {
@@ -95,7 +139,9 @@ EXPORT_SYMBOL_GPL(dw_mci_pltfm_pmops);
 static const struct of_device_id dw_mci_pltfm_match[] = {
 	{ .compatible = "snps,dw-mshc", },
 	{ .compatible = "rockchip,rk2928-dw-mshc",
-		.data = &rockchip_drv_data },
+		.data = &rk2928_drv_data },
+	{ .compatible = "rockchip,rk3288-dw-mshc",
+		.data = &rk3288_drv_data },
 	{ .compatible = "altr,socfpga-dw-mshc",
 		.data = &socfpga_drv_data },
 	{},
-- 
1.8.3.2


--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH] mmc: dw_mmc: add support for RK3288.
  2014-07-05 12:59 ` addy ke
  (?)
@ 2014-07-07  2:07 ` Jaehoon Chung
  2014-07-07  2:42   ` addy ke
  -1 siblings, 1 reply; 22+ messages in thread
From: Jaehoon Chung @ 2014-07-07  2:07 UTC (permalink / raw)
  To: addy ke, robh+dt, pawel.moll, mark.rutland, ijc+devicetree,
	galak, rdunlap, tgih.jun, chris, ulf.hansson, dinguyen, heiko,
	olof
  Cc: devicetree, linux-doc, linux-kernel, linux-mmc, hj, kever.yang,
	xjq, huangtao, zyw, yzq, zhenfu.fang, cf, zhangqing, hl, lintao,
	chenfen, zyf

Hi, Addy,

On 07/05/2014 09:59 PM, addy ke wrote:
> This patch focuses on clock setting for RK3288 mmc controller.
> 
> In RK3288 mmc controller, CLKDIV register can only be set 0 or 1,
> and if DDR 8bit mode, CLKDIV register must be set 1.
> 
> Signed-off-by: addy ke <addy.ke@rock-chips.com>
> ---
>  .../devicetree/bindings/mmc/rockchip-dw-mshc.txt   |  4 +-
>  drivers/mmc/host/dw_mmc-pltfm.c                    | 50 +++++++++++++++++++++-
>  2 files changed, 51 insertions(+), 3 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt
> index c559f3f..e3f95cd 100644
> --- a/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt
> +++ b/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt
> @@ -10,7 +10,9 @@ extensions to the Synopsys Designware Mobile Storage Host Controller.
>  Required Properties:
>  
>  * compatible: should be
> -	- "rockchip,rk2928-dw-mshc": for Rockchip RK2928 and following
> +	- "rockchip,rk2928-dw-mshc": for Rockchip RK2928 and following,
> +							before RK3288
> +	- "rockchip,rk3288-dw-mshc": for Rockchip RK3288
>  
>  Example:
>  
> diff --git a/drivers/mmc/host/dw_mmc-pltfm.c b/drivers/mmc/host/dw_mmc-pltfm.c
> index d4a47a9..15d796e 100644
> --- a/drivers/mmc/host/dw_mmc-pltfm.c
> +++ b/drivers/mmc/host/dw_mmc-pltfm.c
> @@ -21,17 +21,61 @@
>  #include <linux/mmc/mmc.h>
>  #include <linux/mmc/dw_mmc.h>
>  #include <linux/of.h>
> +#include <linux/clk.h>
>  
>  #include "dw_mmc.h"
>  #include "dw_mmc-pltfm.h"
>  
> +#define RK3288_CLKGEN_DIV	2
"2" is used to the general div value at rockchip?

> +
>  static void dw_mci_pltfm_prepare_command(struct dw_mci *host, u32 *cmdr)
>  {
>  	*cmdr |= SDMMC_CMD_USE_HOLD_REG;
>  }
>  
> -static const struct dw_mci_drv_data rockchip_drv_data = {
> +static int dw_mci_rk3288_setup_clock(struct dw_mci *host)
> +{
> +	host->bus_hz = clk_get_rate(host->ciu_clk) / RK3288_CLKGEN_DIV;
I knew that you need not to call clk_get_rate(). In dw-mmc.c, it's already called.
So you can just use the host->bus_hz.

host->bus_hz /= RK3288_CLKGEN_DIV;

Best Regards,
Jaehoon Chung

> +
> +	return 0;
> +}
> +
> +static void dw_mci_rk3288_set_ios(struct dw_mci *host, struct mmc_ios *ios)
> +{
> +	int ret;
> +	unsigned int cclkin;
> +
> +	/*
> +	 * cclkin: source clock of mmc controller.
> +	 * bus_hz: card interface clock generated by CLKGEN.
> +	 * bus_hz = cclkin / RK3288_CLKGEN_DIV;
> +	 * ios->clock = (div == 0) ? bus_hz : (bus_hz / (2 * div))
> +	 *
> +	 * Note: div can only be 0 or 1
> +	 *       if DDR50 8bit mode, div must be set 1
> +	 */
> +	if ((ios->bus_width == MMC_BUS_WIDTH_8) &&
> +	    (ios->timing == MMC_TIMING_UHS_DDR50 ||
> +	     ios->timing == MMC_TIMING_MMC_DDR52))
> +		cclkin = 2 * ios->clock * RK3288_CLKGEN_DIV;
> +	else
> +		cclkin = ios->clock * RK3288_CLKGEN_DIV;
> +
> +	ret = clk_set_rate(host->ciu_clk, cclkin);
> +	if (ret)
> +		dev_warn(host->dev, "failed to set rate %uHz\n", ios->clock);
> +
> +	host->bus_hz = clk_get_rate(host->ciu_clk) / RK3288_CLKGEN_DIV;
> +}
> +
> +static const struct dw_mci_drv_data rk2928_drv_data = {
> +	.prepare_command	= dw_mci_pltfm_prepare_command,
> +};
> +
> +static const struct dw_mci_drv_data rk3288_drv_data = {
>  	.prepare_command	= dw_mci_pltfm_prepare_command,
> +	.set_ios	= dw_mci_rk3288_set_ios,
> +	.setup_clock	= dw_mci_rk3288_setup_clock,
>  };
>  
>  static const struct dw_mci_drv_data socfpga_drv_data = {
> @@ -95,7 +139,9 @@ EXPORT_SYMBOL_GPL(dw_mci_pltfm_pmops);
>  static const struct of_device_id dw_mci_pltfm_match[] = {
>  	{ .compatible = "snps,dw-mshc", },
>  	{ .compatible = "rockchip,rk2928-dw-mshc",
> -		.data = &rockchip_drv_data },
> +		.data = &rk2928_drv_data },
> +	{ .compatible = "rockchip,rk3288-dw-mshc",
> +		.data = &rk3288_drv_data },
>  	{ .compatible = "altr,socfpga-dw-mshc",
>  		.data = &socfpga_drv_data },
>  	{},
> 


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

* Re: [PATCH] mmc: dw_mmc: add support for RK3288.
  2014-07-07  2:07 ` Jaehoon Chung
@ 2014-07-07  2:42   ` addy ke
  0 siblings, 0 replies; 22+ messages in thread
From: addy ke @ 2014-07-07  2:42 UTC (permalink / raw)
  To: jh80.chung, robh+dt, pawel.moll, mark.rutland, ijc+devicetree,
	galak, rdunlap, tgih.jun, chris, ulf.hansson, dinguyen, heiko,
	olof
  Cc: devicetree, linux-doc, linux-kernel, linux-mmc, hj, kever.yang,
	xjq, huangtao, zyw, yzq, zhenfu.fang, cf, zhangqing, hl, lintao,
	chenfen, zyf

> Hi, Addy,
> 
> On 07/05/2014 09:59 PM, addy ke wrote:
>> This patch focuses on clock setting for RK3288 mmc controller.
>>
>> In RK3288 mmc controller, CLKDIV register can only be set 0 or 1,
>> and if DDR 8bit mode, CLKDIV register must be set 1.
>>
>> Signed-off-by: addy ke <addy.ke@rock-chips.com>
>> ---
>>  .../devicetree/bindings/mmc/rockchip-dw-mshc.txt   |  4 +-
>>  drivers/mmc/host/dw_mmc-pltfm.c                    | 50 +++++++++++++++++++++-
>>  2 files changed, 51 insertions(+), 3 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt
>> index c559f3f..e3f95cd 100644
>> --- a/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt
>> +++ b/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt
>> @@ -10,7 +10,9 @@ extensions to the Synopsys Designware Mobile Storage Host Controller.
>>  Required Properties:
>>  
>>  * compatible: should be
>> -	- "rockchip,rk2928-dw-mshc": for Rockchip RK2928 and following
>> +	- "rockchip,rk2928-dw-mshc": for Rockchip RK2928 and following,
>> +							before RK3288
>> +	- "rockchip,rk3288-dw-mshc": for Rockchip RK3288
>>  
>>  Example:
>>  
>> diff --git a/drivers/mmc/host/dw_mmc-pltfm.c b/drivers/mmc/host/dw_mmc-pltfm.c
>> index d4a47a9..15d796e 100644
>> --- a/drivers/mmc/host/dw_mmc-pltfm.c
>> +++ b/drivers/mmc/host/dw_mmc-pltfm.c
>> @@ -21,17 +21,61 @@
>>  #include <linux/mmc/mmc.h>
>>  #include <linux/mmc/dw_mmc.h>
>>  #include <linux/of.h>
>> +#include <linux/clk.h>
>>  
>>  #include "dw_mmc.h"
>>  #include "dw_mmc-pltfm.h"
>>  
>> +#define RK3288_CLKGEN_DIV	2
> "2" is used to the general div value at rockchip?
> 
Yes, In RK3288, the div generated by CLKGEN is 2 and can not be changed by software.
>> +
>>  static void dw_mci_pltfm_prepare_command(struct dw_mci *host, u32 *cmdr)
>>  {
>>  	*cmdr |= SDMMC_CMD_USE_HOLD_REG;
>>  }
>>  
>> -static const struct dw_mci_drv_data rockchip_drv_data = {
>> +static int dw_mci_rk3288_setup_clock(struct dw_mci *host)
>> +{
>> +	host->bus_hz = clk_get_rate(host->ciu_clk) / RK3288_CLKGEN_DIV;
> I knew that you need not to call clk_get_rate(). In dw-mmc.c, it's already called.
> So you can just use the host->bus_hz.
> 
> host->bus_hz /= RK3288_CLKGEN_DIV;
> 
> Best Regards,
> Jaehoon Chung
> 
>> +
>> +	return 0;
>> +}
>> +
>> +static void dw_mci_rk3288_set_ios(struct dw_mci *host, struct mmc_ios *ios)
>> +{
>> +	int ret;
>> +	unsigned int cclkin;
>> +
>> +	/*
>> +	 * cclkin: source clock of mmc controller.
>> +	 * bus_hz: card interface clock generated by CLKGEN.
>> +	 * bus_hz = cclkin / RK3288_CLKGEN_DIV;
>> +	 * ios->clock = (div == 0) ? bus_hz : (bus_hz / (2 * div))
>> +	 *
>> +	 * Note: div can only be 0 or 1
>> +	 *       if DDR50 8bit mode, div must be set 1
>> +	 */
>> +	if ((ios->bus_width == MMC_BUS_WIDTH_8) &&
>> +	    (ios->timing == MMC_TIMING_UHS_DDR50 ||
>> +	     ios->timing == MMC_TIMING_MMC_DDR52))
>> +		cclkin = 2 * ios->clock * RK3288_CLKGEN_DIV;
>> +	else
>> +		cclkin = ios->clock * RK3288_CLKGEN_DIV;
>> +
>> +	ret = clk_set_rate(host->ciu_clk, cclkin);
>> +	if (ret)
>> +		dev_warn(host->dev, "failed to set rate %uHz\n", ios->clock);
>> +
>> +	host->bus_hz = clk_get_rate(host->ciu_clk) / RK3288_CLKGEN_DIV;
>> +}
>> +
>> +static const struct dw_mci_drv_data rk2928_drv_data = {
>> +	.prepare_command	= dw_mci_pltfm_prepare_command,
>> +};
>> +
>> +static const struct dw_mci_drv_data rk3288_drv_data = {
>>  	.prepare_command	= dw_mci_pltfm_prepare_command,
>> +	.set_ios	= dw_mci_rk3288_set_ios,
>> +	.setup_clock	= dw_mci_rk3288_setup_clock,
>>  };
>>  
>>  static const struct dw_mci_drv_data socfpga_drv_data = {
>> @@ -95,7 +139,9 @@ EXPORT_SYMBOL_GPL(dw_mci_pltfm_pmops);
>>  static const struct of_device_id dw_mci_pltfm_match[] = {
>>  	{ .compatible = "snps,dw-mshc", },
>>  	{ .compatible = "rockchip,rk2928-dw-mshc",
>> -		.data = &rockchip_drv_data },
>> +		.data = &rk2928_drv_data },
>> +	{ .compatible = "rockchip,rk3288-dw-mshc",
>> +		.data = &rk3288_drv_data },
>>  	{ .compatible = "altr,socfpga-dw-mshc",
>>  		.data = &socfpga_drv_data },
>>  	{},
>>
> 
> 
> 
> 


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

* [PATCH v2] mmc: dw_mmc: add support for RK3288
  2014-07-05 12:59 ` addy ke
  (?)
  (?)
@ 2014-07-10  3:31 ` Addy Ke
  2014-07-29  4:52   ` Doug Anderson
  2014-07-31  6:01   ` [PATCH] " Addy Ke
  -1 siblings, 2 replies; 22+ messages in thread
From: Addy Ke @ 2014-07-10  3:31 UTC (permalink / raw)
  To: robh+dt, pawel.moll, mark.rutland, ijc+devicetree, galak,
	rdunlap, tgih.jun, jh80.chung, chris, ulf.hansson, dinguyen,
	heiko, olof
  Cc: devicetree, linux-doc, linux-kernel, linux-mmc, zyf, Addy Ke

This patch focuses on clock setting for RK3288 mmc controller.

In RK3288 mmc controller, CLKDIV register can only be set 0 or 1,
and if DDR 8bit mode, CLKDIV register must be set 1.

Signed-off-by: Addy Ke <addy.ke@rock-chips.com>
---
changes since v1:
- dw_mci_rk3288_setup_clock: do not call clk_get_rate(), just use the
  host->bus_hz which is already called by dw_mmc.c, suggested by Jaehoon Chung

 .../devicetree/bindings/mmc/rockchip-dw-mshc.txt   |  4 +-
 drivers/mmc/host/dw_mmc-pltfm.c                    | 50 +++++++++++++++++++++-
 2 files changed, 51 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt
index c559f3f..e3f95cd 100644
--- a/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt
+++ b/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt
@@ -10,7 +10,9 @@ extensions to the Synopsys Designware Mobile Storage Host Controller.
 Required Properties:
 
 * compatible: should be
-	- "rockchip,rk2928-dw-mshc": for Rockchip RK2928 and following
+	- "rockchip,rk2928-dw-mshc": for Rockchip RK2928 and following,
+							before RK3288
+	- "rockchip,rk3288-dw-mshc": for Rockchip RK3288
 
 Example:
 
diff --git a/drivers/mmc/host/dw_mmc-pltfm.c b/drivers/mmc/host/dw_mmc-pltfm.c
index d4a47a9..809c28b 100644
--- a/drivers/mmc/host/dw_mmc-pltfm.c
+++ b/drivers/mmc/host/dw_mmc-pltfm.c
@@ -21,17 +21,61 @@
 #include <linux/mmc/mmc.h>
 #include <linux/mmc/dw_mmc.h>
 #include <linux/of.h>
+#include <linux/clk.h>
 
 #include "dw_mmc.h"
 #include "dw_mmc-pltfm.h"
 
+#define RK3288_CLKGEN_DIV	2
+
 static void dw_mci_pltfm_prepare_command(struct dw_mci *host, u32 *cmdr)
 {
 	*cmdr |= SDMMC_CMD_USE_HOLD_REG;
 }
 
-static const struct dw_mci_drv_data rockchip_drv_data = {
+static int dw_mci_rk3288_setup_clock(struct dw_mci *host)
+{
+	host->bus_hz /= RK3288_CLKGEN_DIV;
+
+	return 0;
+}
+
+static void dw_mci_rk3288_set_ios(struct dw_mci *host, struct mmc_ios *ios)
+{
+	int ret;
+	unsigned int cclkin;
+
+	/*
+	 * cclkin: source clock of mmc controller.
+	 * bus_hz: card interface clock generated by CLKGEN.
+	 * bus_hz = cclkin / RK3288_CLKGEN_DIV;
+	 * ios->clock = (div == 0) ? bus_hz : (bus_hz / (2 * div))
+	 *
+	 * Note: div can only be 0 or 1
+	 *       if DDR50 8bit mode, div must be set 1
+	 */
+	if ((ios->bus_width == MMC_BUS_WIDTH_8) &&
+	    (ios->timing == MMC_TIMING_UHS_DDR50 ||
+	     ios->timing == MMC_TIMING_MMC_DDR52))
+		cclkin = 2 * ios->clock * RK3288_CLKGEN_DIV;
+	else
+		cclkin = ios->clock * RK3288_CLKGEN_DIV;
+
+	ret = clk_set_rate(host->ciu_clk, cclkin);
+	if (ret)
+		dev_warn(host->dev, "failed to set rate %uHz\n", ios->clock);
+
+	host->bus_hz = clk_get_rate(host->ciu_clk) / RK3288_CLKGEN_DIV;
+}
+
+static const struct dw_mci_drv_data rk2928_drv_data = {
+	.prepare_command	= dw_mci_pltfm_prepare_command,
+};
+
+static const struct dw_mci_drv_data rk3288_drv_data = {
 	.prepare_command	= dw_mci_pltfm_prepare_command,
+	.set_ios	= dw_mci_rk3288_set_ios,
+	.setup_clock	= dw_mci_rk3288_setup_clock,
 };
 
 static const struct dw_mci_drv_data socfpga_drv_data = {
@@ -95,7 +139,9 @@ EXPORT_SYMBOL_GPL(dw_mci_pltfm_pmops);
 static const struct of_device_id dw_mci_pltfm_match[] = {
 	{ .compatible = "snps,dw-mshc", },
 	{ .compatible = "rockchip,rk2928-dw-mshc",
-		.data = &rockchip_drv_data },
+		.data = &rk2928_drv_data },
+	{ .compatible = "rockchip,rk3288-dw-mshc",
+		.data = &rk3288_drv_data },
 	{ .compatible = "altr,socfpga-dw-mshc",
 		.data = &socfpga_drv_data },
 	{},
-- 
1.8.3.2



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

* Re: [PATCH v2] mmc: dw_mmc: add support for RK3288
  2014-07-10  3:31 ` [PATCH v2] " Addy Ke
@ 2014-07-29  4:52   ` Doug Anderson
  2014-07-29 16:38     ` Doug Anderson
  2014-07-31  6:01   ` [PATCH] " Addy Ke
  1 sibling, 1 reply; 22+ messages in thread
From: Doug Anderson @ 2014-07-29  4:52 UTC (permalink / raw)
  To: Addy Ke
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Randy Dunlap, Seungwon Jeon, Jaehoon Chung, Chris Ball,
	Ulf Hansson, Dinh Nguyen, Heiko Stübner, Olof Johansson,
	devicetree, linux-doc, linux-kernel, linux-mmc, zyf

Addy,

On Wed, Jul 9, 2014 at 8:31 PM, Addy Ke <addy.ke@rock-chips.com> wrote:
> This patch focuses on clock setting for RK3288 mmc controller.
>
> In RK3288 mmc controller, CLKDIV register can only be set 0 or 1,
> and if DDR 8bit mode, CLKDIV register must be set 1.
>
> Signed-off-by: Addy Ke <addy.ke@rock-chips.com>
> ---
> changes since v1:
> - dw_mci_rk3288_setup_clock: do not call clk_get_rate(), just use the
>   host->bus_hz which is already called by dw_mmc.c, suggested by Jaehoon Chung
>
>  .../devicetree/bindings/mmc/rockchip-dw-mshc.txt   |  4 +-
>  drivers/mmc/host/dw_mmc-pltfm.c                    | 50 +++++++++++++++++++++-
>  2 files changed, 51 insertions(+), 3 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt
> index c559f3f..e3f95cd 100644
> --- a/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt
> +++ b/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt
> @@ -10,7 +10,9 @@ extensions to the Synopsys Designware Mobile Storage Host Controller.
>  Required Properties:
>
>  * compatible: should be
> -       - "rockchip,rk2928-dw-mshc": for Rockchip RK2928 and following
> +       - "rockchip,rk2928-dw-mshc": for Rockchip RK2928 and following,
> +                                                       before RK3288
> +       - "rockchip,rk3288-dw-mshc": for Rockchip RK3288
>
>  Example:
>
> diff --git a/drivers/mmc/host/dw_mmc-pltfm.c b/drivers/mmc/host/dw_mmc-pltfm.c
> index d4a47a9..809c28b 100644
> --- a/drivers/mmc/host/dw_mmc-pltfm.c
> +++ b/drivers/mmc/host/dw_mmc-pltfm.c
> @@ -21,17 +21,61 @@
>  #include <linux/mmc/mmc.h>
>  #include <linux/mmc/dw_mmc.h>
>  #include <linux/of.h>
> +#include <linux/clk.h>
>
>  #include "dw_mmc.h"
>  #include "dw_mmc-pltfm.h"
>
> +#define RK3288_CLKGEN_DIV      2

Yup, this matches what I see in the TRM.  It will always divide by 2
to allow for 4 phases (picking the phases not supported yet).  Default
phase looks to be 180 degrees which is why we've (currently) got
USE_HOLD_REG hardcoded.  :)

> +
>  static void dw_mci_pltfm_prepare_command(struct dw_mci *host, u32 *cmdr)
>  {
>         *cmdr |= SDMMC_CMD_USE_HOLD_REG;
>  }
>
> -static const struct dw_mci_drv_data rockchip_drv_data = {
> +static int dw_mci_rk3288_setup_clock(struct dw_mci *host)
> +{
> +       host->bus_hz /= RK3288_CLKGEN_DIV;
> +
> +       return 0;
> +}
> +
> +static void dw_mci_rk3288_set_ios(struct dw_mci *host, struct mmc_ios *ios)
> +{
> +       int ret;
> +       unsigned int cclkin;
> +
> +       /*
> +        * cclkin: source clock of mmc controller.
> +        * bus_hz: card interface clock generated by CLKGEN.
> +        * bus_hz = cclkin / RK3288_CLKGEN_DIV;
> +        * ios->clock = (div == 0) ? bus_hz : (bus_hz / (2 * div))
> +        *
> +        * Note: div can only be 0 or 1
> +        *       if DDR50 8bit mode, div must be set 1

Makes sense.  So this function is essentially reversing the logic in
dw_mmc and making sure that we'll get the right DIV (0 or 1) in
dw_mci_setup_bus().


> +        */
> +       if ((ios->bus_width == MMC_BUS_WIDTH_8) &&
> +           (ios->timing == MMC_TIMING_UHS_DDR50 ||

Probably don't need UHS_DDR50 since (I think) you can't have an 8-bit
SD card--only MMC, right?  ...but it doesn't hurt.


> +            ios->timing == MMC_TIMING_MMC_DDR52))
> +               cclkin = 2 * ios->clock * RK3288_CLKGEN_DIV;
> +       else
> +               cclkin = ios->clock * RK3288_CLKGEN_DIV;
> +
> +       ret = clk_set_rate(host->ciu_clk, cclkin);
> +       if (ret)
> +               dev_warn(host->dev, "failed to set rate %uHz\n", ios->clock);
> +
> +       host->bus_hz = clk_get_rate(host->ciu_clk) / RK3288_CLKGEN_DIV;
> +}
> +
> +static const struct dw_mci_drv_data rk2928_drv_data = {
> +       .prepare_command        = dw_mci_pltfm_prepare_command,
> +};
> +
> +static const struct dw_mci_drv_data rk3288_drv_data = {
>         .prepare_command        = dw_mci_pltfm_prepare_command,
> +       .set_ios        = dw_mci_rk3288_set_ios,
> +       .setup_clock    = dw_mci_rk3288_setup_clock,
>  };
>
>  static const struct dw_mci_drv_data socfpga_drv_data = {
> @@ -95,7 +139,9 @@ EXPORT_SYMBOL_GPL(dw_mci_pltfm_pmops);
>  static const struct of_device_id dw_mci_pltfm_match[] = {
>         { .compatible = "snps,dw-mshc", },
>         { .compatible = "rockchip,rk2928-dw-mshc",
> -               .data = &rockchip_drv_data },
> +               .data = &rk2928_drv_data },
> +       { .compatible = "rockchip,rk3288-dw-mshc",
> +               .data = &rk3288_drv_data },
>         { .compatible = "altr,socfpga-dw-mshc",
>                 .data = &socfpga_drv_data },
>         {},

Reviewed-by: Doug Anderson <dianders@chromium.org>
Tested-by: Doug Anderson <dianders@chromium.org>

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

* Re: [PATCH v2] mmc: dw_mmc: add support for RK3288
  2014-07-29  4:52   ` Doug Anderson
@ 2014-07-29 16:38     ` Doug Anderson
  0 siblings, 0 replies; 22+ messages in thread
From: Doug Anderson @ 2014-07-29 16:38 UTC (permalink / raw)
  To: Addy Ke
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Randy Dunlap, Seungwon Jeon, Jaehoon Chung, Chris Ball,
	Ulf Hansson, Dinh Nguyen, Heiko Stübner, Olof Johansson,
	devicetree, linux-doc, linux-kernel, linux-mmc, zyf, Sonny Rao

Addy,

On Mon, Jul 28, 2014 at 9:52 PM, Doug Anderson <dianders@chromium.org> wrote:
> Addy,
>
> On Wed, Jul 9, 2014 at 8:31 PM, Addy Ke <addy.ke@rock-chips.com> wrote:
>> This patch focuses on clock setting for RK3288 mmc controller.
>>
>> In RK3288 mmc controller, CLKDIV register can only be set 0 or 1,
>> and if DDR 8bit mode, CLKDIV register must be set 1.
>>
>> Signed-off-by: Addy Ke <addy.ke@rock-chips.com>
>> ---
>> changes since v1:
>> - dw_mci_rk3288_setup_clock: do not call clk_get_rate(), just use the
>>   host->bus_hz which is already called by dw_mmc.c, suggested by Jaehoon Chung
>>
>>  .../devicetree/bindings/mmc/rockchip-dw-mshc.txt   |  4 +-
>>  drivers/mmc/host/dw_mmc-pltfm.c                    | 50 +++++++++++++++++++++-
>>  2 files changed, 51 insertions(+), 3 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt
>> index c559f3f..e3f95cd 100644
>> --- a/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt
>> +++ b/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt
>> @@ -10,7 +10,9 @@ extensions to the Synopsys Designware Mobile Storage Host Controller.
>>  Required Properties:
>>
>>  * compatible: should be
>> -       - "rockchip,rk2928-dw-mshc": for Rockchip RK2928 and following
>> +       - "rockchip,rk2928-dw-mshc": for Rockchip RK2928 and following,
>> +                                                       before RK3288
>> +       - "rockchip,rk3288-dw-mshc": for Rockchip RK3288
>>
>>  Example:
>>
>> diff --git a/drivers/mmc/host/dw_mmc-pltfm.c b/drivers/mmc/host/dw_mmc-pltfm.c
>> index d4a47a9..809c28b 100644
>> --- a/drivers/mmc/host/dw_mmc-pltfm.c
>> +++ b/drivers/mmc/host/dw_mmc-pltfm.c
>> @@ -21,17 +21,61 @@
>>  #include <linux/mmc/mmc.h>
>>  #include <linux/mmc/dw_mmc.h>
>>  #include <linux/of.h>
>> +#include <linux/clk.h>
>>
>>  #include "dw_mmc.h"
>>  #include "dw_mmc-pltfm.h"
>>
>> +#define RK3288_CLKGEN_DIV      2
>
> Yup, this matches what I see in the TRM.  It will always divide by 2
> to allow for 4 phases (picking the phases not supported yet).  Default
> phase looks to be 180 degrees which is why we've (currently) got
> USE_HOLD_REG hardcoded.  :)
>
>> +
>>  static void dw_mci_pltfm_prepare_command(struct dw_mci *host, u32 *cmdr)
>>  {
>>         *cmdr |= SDMMC_CMD_USE_HOLD_REG;
>>  }
>>
>> -static const struct dw_mci_drv_data rockchip_drv_data = {
>> +static int dw_mci_rk3288_setup_clock(struct dw_mci *host)
>> +{
>> +       host->bus_hz /= RK3288_CLKGEN_DIV;
>> +
>> +       return 0;
>> +}
>> +
>> +static void dw_mci_rk3288_set_ios(struct dw_mci *host, struct mmc_ios *ios)
>> +{
>> +       int ret;
>> +       unsigned int cclkin;
>> +
>> +       /*
>> +        * cclkin: source clock of mmc controller.
>> +        * bus_hz: card interface clock generated by CLKGEN.
>> +        * bus_hz = cclkin / RK3288_CLKGEN_DIV;
>> +        * ios->clock = (div == 0) ? bus_hz : (bus_hz / (2 * div))
>> +        *
>> +        * Note: div can only be 0 or 1
>> +        *       if DDR50 8bit mode, div must be set 1
>
> Makes sense.  So this function is essentially reversing the logic in
> dw_mmc and making sure that we'll get the right DIV (0 or 1) in
> dw_mci_setup_bus().
>
>
>> +        */
>> +       if ((ios->bus_width == MMC_BUS_WIDTH_8) &&
>> +           (ios->timing == MMC_TIMING_UHS_DDR50 ||
>
> Probably don't need UHS_DDR50 since (I think) you can't have an 8-bit
> SD card--only MMC, right?  ...but it doesn't hurt.
>
>
>> +            ios->timing == MMC_TIMING_MMC_DDR52))
>> +               cclkin = 2 * ios->clock * RK3288_CLKGEN_DIV;
>> +       else
>> +               cclkin = ios->clock * RK3288_CLKGEN_DIV;
>> +
>> +       ret = clk_set_rate(host->ciu_clk, cclkin);
>> +       if (ret)
>> +               dev_warn(host->dev, "failed to set rate %uHz\n", ios->clock);
>> +
>> +       host->bus_hz = clk_get_rate(host->ciu_clk) / RK3288_CLKGEN_DIV;
>> +}
>> +
>> +static const struct dw_mci_drv_data rk2928_drv_data = {
>> +       .prepare_command        = dw_mci_pltfm_prepare_command,
>> +};
>> +
>> +static const struct dw_mci_drv_data rk3288_drv_data = {
>>         .prepare_command        = dw_mci_pltfm_prepare_command,
>> +       .set_ios        = dw_mci_rk3288_set_ios,
>> +       .setup_clock    = dw_mci_rk3288_setup_clock,
>>  };
>>
>>  static const struct dw_mci_drv_data socfpga_drv_data = {
>> @@ -95,7 +139,9 @@ EXPORT_SYMBOL_GPL(dw_mci_pltfm_pmops);
>>  static const struct of_device_id dw_mci_pltfm_match[] = {
>>         { .compatible = "snps,dw-mshc", },
>>         { .compatible = "rockchip,rk2928-dw-mshc",
>> -               .data = &rockchip_drv_data },
>> +               .data = &rk2928_drv_data },
>> +       { .compatible = "rockchip,rk3288-dw-mshc",
>> +               .data = &rk3288_drv_data },
>>         { .compatible = "altr,socfpga-dw-mshc",
>>                 .data = &socfpga_drv_data },
>>         {},
>
> Reviewed-by: Doug Anderson <dianders@chromium.org>
> Tested-by: Doug Anderson <dianders@chromium.org>

It turns out that I spoke too soon.  I realized that in my testing I
didn't have "DDR" mode enabled for my eMMC card.  When I did that then
your patch didn't work.

The problem is that dw_mci_setup_bus() doesn't realize that you've
changed "bus_hz" so it needs to re-run.  You can fix it like this:


diff --git a/drivers/mmc/host/dw_mmc-pltfm.c b/drivers/mmc/host/dw_mmc-pltfm.c
index 809c28b..bcc96d0 100644
--- a/drivers/mmc/host/dw_mmc-pltfm.c
+++ b/drivers/mmc/host/dw_mmc-pltfm.c
@@ -44,6 +44,7 @@ static void dw_mci_rk3288_set_ios(struct dw_mci
*host, struct mmc_ios *ios)
 {
        int ret;
        unsigned int cclkin;
+       u32 bus_hz;

        /*
         * cclkin: source clock of mmc controller.
@@ -65,7 +66,11 @@ static void dw_mci_rk3288_set_ios(struct dw_mci
*host, struct mmc_ios *ios)
        if (ret)
                dev_warn(host->dev, "failed to set rate %uHz\n", ios->clock);

-       host->bus_hz = clk_get_rate(host->ciu_clk) / RK3288_CLKGEN_DIV;
+       bus_hz = clk_get_rate(host->ciu_clk) / RK3288_CLKGEN_DIV;
+       if (bus_hz != host->bus_hz) {
+               host->bus_hz = bus_hz;
+               host->current_speed = 0;        /* force dw_mci_setup_bus() */
+       }
 }

 static const struct dw_mci_drv_data rk2928_drv_data = {


Do you want to spin the patch for this?

-Doug

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

* [PATCH] mmc: dw_mmc: add support for RK3288
  2014-07-10  3:31 ` [PATCH v2] " Addy Ke
  2014-07-29  4:52   ` Doug Anderson
@ 2014-07-31  6:01   ` Addy Ke
  2014-07-31 15:40     ` Doug Anderson
                       ` (2 more replies)
  1 sibling, 3 replies; 22+ messages in thread
From: Addy Ke @ 2014-07-31  6:01 UTC (permalink / raw)
  To: robh+dt, pawel.moll, mark.rutland, ijc+devicetree, galak,
	rdunlap, tgih.jun, jh80.chung, chris, ulf.hansson, dinguyen,
	heiko, olof, dianders
  Cc: devicetree, linux-doc, linux-kernel, linux-mmc, zhenfu.fang, cf,
	lintao, chenfen, zyf, xjq, huangtao, zyw, yzq, hj, kever.yang,
	zhangqing, hl, Addy Ke

This patch focuses on clock setting for RK3288 mmc controller.

In RK3288 mmc controller, CLKDIV register can only be set 0 or 1,
and if DDR 8bit mode, CLKDIV register must be set 1.

Reported-by Doug Anderson <dianders@chromium.org>
Suggested-by: Jaehoon Chung <jh80.chung@samsung.com>
Suggested-by: Doug Anderson <dianders@chromium.org>
Signed-off-by: Addy Ke <addy.ke@rock-chips.com>
---
changes since v1:
- dw_mci_rk3288_setup_clock: do not call clk_get_rate(), just use the
  host->bus_hz which is already called by dw_mmc.c, suggested by Jaehoon Chung

changes since v2:
- merge from ChromiumOS tree, fix up clock settting bug, 
  which cause DDR50 mode for emmc not to work, reported by Doug Anderson
- remove MMC_TIMING_UHS_DDR50 condition, because on RK3288 only emmc can work
  in 8bit mode, suggested by Doug Anderson

 .../devicetree/bindings/mmc/rockchip-dw-mshc.txt   |  6 ++-
 drivers/mmc/host/dw_mmc-pltfm.c                    | 56 +++++++++++++++++++++-
 2 files changed, 58 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt
index c559f3f..c327c2d 100644
--- a/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt
+++ b/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt
@@ -10,12 +10,14 @@ extensions to the Synopsys Designware Mobile Storage Host Controller.
 Required Properties:
 
 * compatible: should be
-	- "rockchip,rk2928-dw-mshc": for Rockchip RK2928 and following
+	- "rockchip,rk2928-dw-mshc": for Rockchip RK2928 and following,
+							before RK3288
+	- "rockchip,rk3288-dw-mshc": for Rockchip RK3288
 
 Example:
 
 	rkdwmmc0@12200000 {
-		compatible = "rockchip,rk2928-dw-mshc";
+		compatible = "rockchip,rk3288-dw-mshc";
 		reg = <0x12200000 0x1000>;
 		interrupts = <0 75 0>;
 		#address-cells = <1>;
diff --git a/drivers/mmc/host/dw_mmc-pltfm.c b/drivers/mmc/host/dw_mmc-pltfm.c
index d4a47a9..b547f7a 100644
--- a/drivers/mmc/host/dw_mmc-pltfm.c
+++ b/drivers/mmc/host/dw_mmc-pltfm.c
@@ -21,17 +21,67 @@
 #include <linux/mmc/mmc.h>
 #include <linux/mmc/dw_mmc.h>
 #include <linux/of.h>
+#include <linux/clk.h>
 
 #include "dw_mmc.h"
 #include "dw_mmc-pltfm.h"
 
+#define RK3288_CLKGEN_DIV	2
+
 static void dw_mci_pltfm_prepare_command(struct dw_mci *host, u32 *cmdr)
 {
 	*cmdr |= SDMMC_CMD_USE_HOLD_REG;
 }
 
-static const struct dw_mci_drv_data rockchip_drv_data = {
+static int dw_mci_rk3288_setup_clock(struct dw_mci *host)
+{
+	host->bus_hz /= RK3288_CLKGEN_DIV;
+
+	return 0;
+}
+
+static void dw_mci_rk3288_set_ios(struct dw_mci *host, struct mmc_ios *ios)
+{
+	int ret;
+	unsigned int cclkin;
+	u32 bus_hz;
+
+	/*
+	 * cclkin: source clock of mmc controller.
+	 * bus_hz: card interface clock generated by CLKGEN.
+	 * bus_hz = cclkin / RK3288_CLKGEN_DIV;
+	 * ios->clock = (div == 0) ? bus_hz : (bus_hz / (2 * div))
+	 *
+	 * Note: div can only be 0 or 1
+	 *       if DDR50 8bit mode(only emmc work in 8bit mode),
+	 *       div must be set 1
+	 */
+	if ((ios->bus_width == MMC_BUS_WIDTH_8) &&
+	    (ios->timing == MMC_TIMING_MMC_DDR52))
+		cclkin = 2 * ios->clock * RK3288_CLKGEN_DIV;
+	else
+		cclkin = ios->clock * RK3288_CLKGEN_DIV;
+
+	ret = clk_set_rate(host->ciu_clk, cclkin);
+	if (ret)
+		dev_warn(host->dev, "failed to set rate %uHz\n", ios->clock);
+
+	bus_hz = clk_get_rate(host->ciu_clk) / RK3288_CLKGEN_DIV;
+	if (bus_hz != host->bus_hz) {
+		host->bus_hz = bus_hz;
+		/* force dw_mci_setup_bus() */
+		host->current_speed = 0;
+	}
+}
+
+static const struct dw_mci_drv_data rk2928_drv_data = {
+	.prepare_command	= dw_mci_pltfm_prepare_command,
+};
+
+static const struct dw_mci_drv_data rk3288_drv_data = {
 	.prepare_command	= dw_mci_pltfm_prepare_command,
+	.set_ios	= dw_mci_rk3288_set_ios,
+	.setup_clock	= dw_mci_rk3288_setup_clock,
 };
 
 static const struct dw_mci_drv_data socfpga_drv_data = {
@@ -95,7 +145,9 @@ EXPORT_SYMBOL_GPL(dw_mci_pltfm_pmops);
 static const struct of_device_id dw_mci_pltfm_match[] = {
 	{ .compatible = "snps,dw-mshc", },
 	{ .compatible = "rockchip,rk2928-dw-mshc",
-		.data = &rockchip_drv_data },
+		.data = &rk2928_drv_data },
+	{ .compatible = "rockchip,rk3288-dw-mshc",
+		.data = &rk3288_drv_data },
 	{ .compatible = "altr,socfpga-dw-mshc",
 		.data = &socfpga_drv_data },
 	{},
-- 
1.8.3.2



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

* Re: [PATCH] mmc: dw_mmc: add support for RK3288
  2014-07-31  6:01   ` [PATCH] " Addy Ke
@ 2014-07-31 15:40     ` Doug Anderson
  2014-08-12 12:17       ` Ulf Hansson
  2014-08-07  8:47     ` Jaehoon Chung
  2014-08-14  8:01       ` Addy Ke
  2 siblings, 1 reply; 22+ messages in thread
From: Doug Anderson @ 2014-07-31 15:40 UTC (permalink / raw)
  To: Addy Ke, Chris Ball, Ulf Hansson, Jaehoon Chung, Seungwon Jeon
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Randy Dunlap, Dinh Nguyen, Heiko Stübner, Olof Johansson,
	devicetree, linux-doc, linux-kernel, linux-mmc, zhenfu.fang,
	Eddie Cai, lintao, chenfen, zyf, Jianqun Xu, Tao Huang, Chris,
	姚智情,
	han jiang, Kever Yang, zhangqing, Lin Huang

Addy,

On Wed, Jul 30, 2014 at 11:01 PM, Addy Ke <addy.ke@rock-chips.com> wrote:
> This patch focuses on clock setting for RK3288 mmc controller.
>
> In RK3288 mmc controller, CLKDIV register can only be set 0 or 1,
> and if DDR 8bit mode, CLKDIV register must be set 1.
>
> Reported-by Doug Anderson <dianders@chromium.org>
> Suggested-by: Jaehoon Chung <jh80.chung@samsung.com>
> Suggested-by: Doug Anderson <dianders@chromium.org>

You don't need "Suggested-by" and "Reported-by" for people who
reviewed your patch.  Suggested-by is usually when someone suggested
an overall feature and Reported-by is usually when someone reported a
bug in code that already landed.

You could add me as a Signed-off-by, though, since you folded in some
code that I wrote.

I think whoever applies this could fixup the tags, so:

Reviewed-by: Doug Anderson <dianders@chromium.org>
Tested-by: Doug Anderson <dianders@chromium.org>
Signed-off-by: Doug Anderson <dianders@chromium.org>


It would be great to see this applied unless there are other objections.  :)

-Doug

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

* Re: [PATCH] mmc: dw_mmc: add support for RK3288
  2014-07-31  6:01   ` [PATCH] " Addy Ke
  2014-07-31 15:40     ` Doug Anderson
@ 2014-08-07  8:47     ` Jaehoon Chung
  2014-08-14  8:01       ` Addy Ke
  2 siblings, 0 replies; 22+ messages in thread
From: Jaehoon Chung @ 2014-08-07  8:47 UTC (permalink / raw)
  To: Addy Ke, robh+dt, pawel.moll, mark.rutland, ijc+devicetree,
	galak, rdunlap, tgih.jun, jh80.chung, chris, ulf.hansson,
	dinguyen, heiko, olof, dianders
  Cc: devicetree, linux-doc, linux-kernel, linux-mmc, zhenfu.fang, cf,
	lintao, chenfen, zyf, xjq, huangtao, zyw, yzq, hj, kever.yang,
	zhangqing, hl

Acked-by: Jaehoon Chung <jh80.chung@samsung.com>

Best Regards,
Jaehoon Chung

On 07/31/2014 03:01 PM, Addy Ke wrote:
> This patch focuses on clock setting for RK3288 mmc controller.
> 
> In RK3288 mmc controller, CLKDIV register can only be set 0 or 1,
> and if DDR 8bit mode, CLKDIV register must be set 1.
> 
> Reported-by Doug Anderson <dianders@chromium.org>
> Suggested-by: Jaehoon Chung <jh80.chung@samsung.com>
> Suggested-by: Doug Anderson <dianders@chromium.org>
> Signed-off-by: Addy Ke <addy.ke@rock-chips.com>
> ---
> changes since v1:
> - dw_mci_rk3288_setup_clock: do not call clk_get_rate(), just use the
>   host->bus_hz which is already called by dw_mmc.c, suggested by Jaehoon Chung
> 
> changes since v2:
> - merge from ChromiumOS tree, fix up clock settting bug, 
>   which cause DDR50 mode for emmc not to work, reported by Doug Anderson
> - remove MMC_TIMING_UHS_DDR50 condition, because on RK3288 only emmc can work
>   in 8bit mode, suggested by Doug Anderson
> 
>  .../devicetree/bindings/mmc/rockchip-dw-mshc.txt   |  6 ++-
>  drivers/mmc/host/dw_mmc-pltfm.c                    | 56 +++++++++++++++++++++-
>  2 files changed, 58 insertions(+), 4 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt
> index c559f3f..c327c2d 100644
> --- a/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt
> +++ b/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt
> @@ -10,12 +10,14 @@ extensions to the Synopsys Designware Mobile Storage Host Controller.
>  Required Properties:
>  
>  * compatible: should be
> -	- "rockchip,rk2928-dw-mshc": for Rockchip RK2928 and following
> +	- "rockchip,rk2928-dw-mshc": for Rockchip RK2928 and following,
> +							before RK3288
> +	- "rockchip,rk3288-dw-mshc": for Rockchip RK3288
>  
>  Example:
>  
>  	rkdwmmc0@12200000 {
> -		compatible = "rockchip,rk2928-dw-mshc";
> +		compatible = "rockchip,rk3288-dw-mshc";
>  		reg = <0x12200000 0x1000>;
>  		interrupts = <0 75 0>;
>  		#address-cells = <1>;
> diff --git a/drivers/mmc/host/dw_mmc-pltfm.c b/drivers/mmc/host/dw_mmc-pltfm.c
> index d4a47a9..b547f7a 100644
> --- a/drivers/mmc/host/dw_mmc-pltfm.c
> +++ b/drivers/mmc/host/dw_mmc-pltfm.c
> @@ -21,17 +21,67 @@
>  #include <linux/mmc/mmc.h>
>  #include <linux/mmc/dw_mmc.h>
>  #include <linux/of.h>
> +#include <linux/clk.h>
>  
>  #include "dw_mmc.h"
>  #include "dw_mmc-pltfm.h"
>  
> +#define RK3288_CLKGEN_DIV	2
> +
>  static void dw_mci_pltfm_prepare_command(struct dw_mci *host, u32 *cmdr)
>  {
>  	*cmdr |= SDMMC_CMD_USE_HOLD_REG;
>  }
>  
> -static const struct dw_mci_drv_data rockchip_drv_data = {
> +static int dw_mci_rk3288_setup_clock(struct dw_mci *host)
> +{
> +	host->bus_hz /= RK3288_CLKGEN_DIV;
> +
> +	return 0;
> +}
> +
> +static void dw_mci_rk3288_set_ios(struct dw_mci *host, struct mmc_ios *ios)
> +{
> +	int ret;
> +	unsigned int cclkin;
> +	u32 bus_hz;
> +
> +	/*
> +	 * cclkin: source clock of mmc controller.
> +	 * bus_hz: card interface clock generated by CLKGEN.
> +	 * bus_hz = cclkin / RK3288_CLKGEN_DIV;
> +	 * ios->clock = (div == 0) ? bus_hz : (bus_hz / (2 * div))
> +	 *
> +	 * Note: div can only be 0 or 1
> +	 *       if DDR50 8bit mode(only emmc work in 8bit mode),
> +	 *       div must be set 1
> +	 */
> +	if ((ios->bus_width == MMC_BUS_WIDTH_8) &&
> +	    (ios->timing == MMC_TIMING_MMC_DDR52))
> +		cclkin = 2 * ios->clock * RK3288_CLKGEN_DIV;
> +	else
> +		cclkin = ios->clock * RK3288_CLKGEN_DIV;
> +
> +	ret = clk_set_rate(host->ciu_clk, cclkin);
> +	if (ret)
> +		dev_warn(host->dev, "failed to set rate %uHz\n", ios->clock);
> +
> +	bus_hz = clk_get_rate(host->ciu_clk) / RK3288_CLKGEN_DIV;
> +	if (bus_hz != host->bus_hz) {
> +		host->bus_hz = bus_hz;
> +		/* force dw_mci_setup_bus() */
> +		host->current_speed = 0;
> +	}
> +}
> +
> +static const struct dw_mci_drv_data rk2928_drv_data = {
> +	.prepare_command	= dw_mci_pltfm_prepare_command,
> +};
> +
> +static const struct dw_mci_drv_data rk3288_drv_data = {
>  	.prepare_command	= dw_mci_pltfm_prepare_command,
> +	.set_ios	= dw_mci_rk3288_set_ios,
> +	.setup_clock	= dw_mci_rk3288_setup_clock,
>  };
>  
>  static const struct dw_mci_drv_data socfpga_drv_data = {
> @@ -95,7 +145,9 @@ EXPORT_SYMBOL_GPL(dw_mci_pltfm_pmops);
>  static const struct of_device_id dw_mci_pltfm_match[] = {
>  	{ .compatible = "snps,dw-mshc", },
>  	{ .compatible = "rockchip,rk2928-dw-mshc",
> -		.data = &rockchip_drv_data },
> +		.data = &rk2928_drv_data },
> +	{ .compatible = "rockchip,rk3288-dw-mshc",
> +		.data = &rk3288_drv_data },
>  	{ .compatible = "altr,socfpga-dw-mshc",
>  		.data = &socfpga_drv_data },
>  	{},
> 


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

* Re: [PATCH] mmc: dw_mmc: add support for RK3288
  2014-07-31 15:40     ` Doug Anderson
@ 2014-08-12 12:17       ` Ulf Hansson
  0 siblings, 0 replies; 22+ messages in thread
From: Ulf Hansson @ 2014-08-12 12:17 UTC (permalink / raw)
  To: Doug Anderson, Addy Ke
  Cc: Chris Ball, Jaehoon Chung, Seungwon Jeon, Rob Herring,
	Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala, Randy Dunlap,
	Dinh Nguyen, Heiko Stübner, Olof Johansson, devicetree,
	linux-doc, linux-kernel, linux-mmc, zhenfu.fang, Eddie Cai,
	lintao, chenfen, zyf, Jianqun Xu, Tao Huang, Chris,
	姚智情,
	han jiang, Kever Yang, zhangqing, Lin Huang

On 31 July 2014 17:40, Doug Anderson <dianders@chromium.org> wrote:
> Addy,
>
> On Wed, Jul 30, 2014 at 11:01 PM, Addy Ke <addy.ke@rock-chips.com> wrote:
>> This patch focuses on clock setting for RK3288 mmc controller.
>>
>> In RK3288 mmc controller, CLKDIV register can only be set 0 or 1,
>> and if DDR 8bit mode, CLKDIV register must be set 1.
>>
>> Reported-by Doug Anderson <dianders@chromium.org>
>> Suggested-by: Jaehoon Chung <jh80.chung@samsung.com>
>> Suggested-by: Doug Anderson <dianders@chromium.org>
>
> You don't need "Suggested-by" and "Reported-by" for people who
> reviewed your patch.  Suggested-by is usually when someone suggested
> an overall feature and Reported-by is usually when someone reported a
> bug in code that already landed.
>
> You could add me as a Signed-off-by, though, since you folded in some
> code that I wrote.
>
> I think whoever applies this could fixup the tags, so:
>
> Reviewed-by: Doug Anderson <dianders@chromium.org>
> Tested-by: Doug Anderson <dianders@chromium.org>
> Signed-off-by: Doug Anderson <dianders@chromium.org>
>

Thanks! Queued for 3.18, with corrected tags.

Kind regards
Uffe

>
> It would be great to see this applied unless there are other objections.  :)
>
> -Doug

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

* [PATCH] mmc: dw_mmc: move rockchip related code to a separate file
@ 2014-08-14  8:01       ` Addy Ke
  0 siblings, 0 replies; 22+ messages in thread
From: Addy Ke @ 2014-08-14  8:01 UTC (permalink / raw)
  To: robh+dt, pawel.moll, mark.rutland, ijc+devicetree, galak,
	rdunlap, tgih.jun, jh80.chung, chris, ulf.hansson, dinguyen,
	heiko, olof, dianders
  Cc: devicetree, linux-doc, linux-kernel, linux-mmc, zhenfu.fang, cf,
	lintao, chenfen, zyf, xjq, huangtao, zyw, yzq, hj, kever.yang,
	zhangqing, hl, Addy Ke

To support HS200 and UHS-1, we need add a big hunk of code,
as shown in the following patches. So a separate file for
rockchip SOCs is suitable.

Signed-off-by: Addy Ke <addy.ke@rock-chips.com>
---
 drivers/mmc/host/Kconfig           |   9 +++
 drivers/mmc/host/Makefile          |   1 +
 drivers/mmc/host/dw_mmc-pltfm.c    |  57 ---------------
 drivers/mmc/host/dw_mmc-rockchip.c | 146 +++++++++++++++++++++++++++++++++++++
 4 files changed, 156 insertions(+), 57 deletions(-)
 create mode 100644 drivers/mmc/host/dw_mmc-rockchip.c

diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index a565254..ae61df6 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -621,6 +621,15 @@ config MMC_DW_PCI
 
 	  If unsure, say N.
 
+config MMC_DW_ROCKCHIP
+	tristate "Rockchip specific extensions for Synopsys DW Memory Card Interface"
+	depends on MMC_DW
+	select MMC_DW_PLTFM
+	help
+	  This selects support for Rockchip SoC specific extensions to the
+	  Synopsys DesignWare Memory Card Interface driver. Select this option
+	  for platforms based on RK3066, RK3188 and RK3288 SoC's.
+
 config MMC_SH_MMCIF
 	tristate "SuperH Internal MMCIF support"
 	depends on MMC_BLOCK
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index 7f81ddf..5fce465 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_MMC_DW_PLTFM)	+= dw_mmc-pltfm.o
 obj-$(CONFIG_MMC_DW_EXYNOS)	+= dw_mmc-exynos.o
 obj-$(CONFIG_MMC_DW_K3)		+= dw_mmc-k3.o
 obj-$(CONFIG_MMC_DW_PCI)	+= dw_mmc-pci.o
+obj-$(CONFIG_MMC_DW_ROCKCHIP)	+= dw_mmc-rockchip.o
 obj-$(CONFIG_MMC_SH_MMCIF)	+= sh_mmcif.o
 obj-$(CONFIG_MMC_JZ4740)	+= jz4740_mmc.o
 obj-$(CONFIG_MMC_VUB300)	+= vub300.o
diff --git a/drivers/mmc/host/dw_mmc-pltfm.c b/drivers/mmc/host/dw_mmc-pltfm.c
index b547f7a..0c56c41 100644
--- a/drivers/mmc/host/dw_mmc-pltfm.c
+++ b/drivers/mmc/host/dw_mmc-pltfm.c
@@ -26,64 +26,11 @@
 #include "dw_mmc.h"
 #include "dw_mmc-pltfm.h"
 
-#define RK3288_CLKGEN_DIV	2
-
 static void dw_mci_pltfm_prepare_command(struct dw_mci *host, u32 *cmdr)
 {
 	*cmdr |= SDMMC_CMD_USE_HOLD_REG;
 }
 
-static int dw_mci_rk3288_setup_clock(struct dw_mci *host)
-{
-	host->bus_hz /= RK3288_CLKGEN_DIV;
-
-	return 0;
-}
-
-static void dw_mci_rk3288_set_ios(struct dw_mci *host, struct mmc_ios *ios)
-{
-	int ret;
-	unsigned int cclkin;
-	u32 bus_hz;
-
-	/*
-	 * cclkin: source clock of mmc controller.
-	 * bus_hz: card interface clock generated by CLKGEN.
-	 * bus_hz = cclkin / RK3288_CLKGEN_DIV;
-	 * ios->clock = (div == 0) ? bus_hz : (bus_hz / (2 * div))
-	 *
-	 * Note: div can only be 0 or 1
-	 *       if DDR50 8bit mode(only emmc work in 8bit mode),
-	 *       div must be set 1
-	 */
-	if ((ios->bus_width == MMC_BUS_WIDTH_8) &&
-	    (ios->timing == MMC_TIMING_MMC_DDR52))
-		cclkin = 2 * ios->clock * RK3288_CLKGEN_DIV;
-	else
-		cclkin = ios->clock * RK3288_CLKGEN_DIV;
-
-	ret = clk_set_rate(host->ciu_clk, cclkin);
-	if (ret)
-		dev_warn(host->dev, "failed to set rate %uHz\n", ios->clock);
-
-	bus_hz = clk_get_rate(host->ciu_clk) / RK3288_CLKGEN_DIV;
-	if (bus_hz != host->bus_hz) {
-		host->bus_hz = bus_hz;
-		/* force dw_mci_setup_bus() */
-		host->current_speed = 0;
-	}
-}
-
-static const struct dw_mci_drv_data rk2928_drv_data = {
-	.prepare_command	= dw_mci_pltfm_prepare_command,
-};
-
-static const struct dw_mci_drv_data rk3288_drv_data = {
-	.prepare_command	= dw_mci_pltfm_prepare_command,
-	.set_ios	= dw_mci_rk3288_set_ios,
-	.setup_clock	= dw_mci_rk3288_setup_clock,
-};
-
 static const struct dw_mci_drv_data socfpga_drv_data = {
 	.prepare_command	= dw_mci_pltfm_prepare_command,
 };
@@ -144,10 +91,6 @@ EXPORT_SYMBOL_GPL(dw_mci_pltfm_pmops);
 
 static const struct of_device_id dw_mci_pltfm_match[] = {
 	{ .compatible = "snps,dw-mshc", },
-	{ .compatible = "rockchip,rk2928-dw-mshc",
-		.data = &rk2928_drv_data },
-	{ .compatible = "rockchip,rk3288-dw-mshc",
-		.data = &rk3288_drv_data },
 	{ .compatible = "altr,socfpga-dw-mshc",
 		.data = &socfpga_drv_data },
 	{},
diff --git a/drivers/mmc/host/dw_mmc-rockchip.c b/drivers/mmc/host/dw_mmc-rockchip.c
new file mode 100644
index 0000000..3d86ef3
--- /dev/null
+++ b/drivers/mmc/host/dw_mmc-rockchip.c
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
+ * Author: addy ke <addy.ke@rock-chips.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/dw_mmc.h>
+#include <linux/of_address.h>
+
+#include "dw_mmc.h"
+#include "dw_mmc-pltfm.h"
+
+#define RK3288_CLKGEN_DIV       2
+
+static void dw_mci_rockchip_prepare_command(struct dw_mci *host, u32 *cmdr)
+{
+	*cmdr |= SDMMC_CMD_USE_HOLD_REG;
+}
+
+static int dw_mci_rk3288_setup_clock(struct dw_mci *host)
+{
+	host->bus_hz /= RK3288_CLKGEN_DIV;
+
+	return 0;
+}
+
+static void dw_mci_rk3288_set_ios(struct dw_mci *host, struct mmc_ios *ios)
+{
+	int ret;
+	unsigned int cclkin;
+	u32 bus_hz;
+
+	/*
+	 * cclkin: source clock of mmc controller
+	 * bus_hz: card interface clock generated by CLKGEN
+	 * bus_hz = cclkin / RK3288_CLKGEN_DIV
+	 * os->clock = (div == 0) ? bus_hz : (bus_hz / (2 * div))
+	 *
+	 * Note: div can only be 0 or 1
+	 *       if DDR50 8bit mode(only emmc work in 8bit mode),
+	 *       div must be set 1
+	 */
+	if (ios->bus_width == MMC_BUS_WIDTH_8 &&
+	    ios->timing == MMC_TIMING_MMC_DDR52)
+		cclkin = 2 * ios->clock * RK3288_CLKGEN_DIV;
+	else
+		cclkin = ios->clock * RK3288_CLKGEN_DIV;
+
+	ret = clk_set_rate(host->ciu_clk, cclkin);
+	if (ret)
+		dev_warn(host->dev, "failed to set rate %uHz\n", ios->clock);
+
+	bus_hz = clk_get_rate(host->ciu_clk) / RK3288_CLKGEN_DIV;
+	if (bus_hz != host->bus_hz) {
+		host->bus_hz = bus_hz;
+		/* force dw_mci_setup_bus() */
+		host->current_speed = 0;
+	}
+}
+
+static const struct dw_mci_drv_data rk2928_drv_data = {
+	.prepare_command        = dw_mci_rockchip_prepare_command,
+};
+
+static const struct dw_mci_drv_data rk3288_drv_data = {
+	.prepare_command        = dw_mci_rockchip_prepare_command,
+	.set_ios		= dw_mci_rk3288_set_ios,
+	.setup_clock    = dw_mci_rk3288_setup_clock,
+};
+
+static const struct of_device_id dw_mci_rockchip_match[] = {
+	{ .compatible = "rockchip,rk2928-dw-mshc",
+		.data = &rk2928_drv_data },
+	{ .compatible = "rockchip,rk3288-dw-mshc",
+		.data = &rk3288_drv_data },
+	{},
+};
+MODULE_DEVICE_TABLE(of, dw_mci_rockchip_match);
+
+static int dw_mci_rockchip_probe(struct platform_device *pdev)
+{
+	const struct dw_mci_drv_data *drv_data;
+	const struct of_device_id *match;
+
+	match = of_match_node(dw_mci_rockchip_match, pdev->dev.of_node);
+	drv_data = match->data;
+
+	return dw_mci_pltfm_register(pdev, drv_data);
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int dw_mci_rockchip_suspend(struct device *dev)
+{
+	struct dw_mci *host = dev_get_drvdata(dev);
+	int ret;
+
+	ret = dw_mci_suspend(host);
+	if (!ret)
+		clk_disable_unprepare(host->ciu_clk);
+
+	return ret;
+}
+
+static int dw_mci_rockchip_resume(struct device *dev)
+{
+	struct dw_mci *host = dev_get_drvdata(dev);
+	int ret;
+
+	ret = clk_prepare_enable(host->ciu_clk);
+	if (ret) {
+		dev_err(host->dev, "failed to enable ciu clock\n");
+		return ret;
+	}
+
+	return dw_mci_resume(host);
+}
+#endif /* CONFIG_PM_SLEEP */
+
+static SIMPLE_DEV_PM_OPS(dw_mci_rockchip_pmops,
+			 dw_mci_rockchip_suspend,
+			 dw_mci_rockchip_resume);
+
+static struct platform_driver dw_mci_rockchip_pltfm_driver = {
+	.probe		= dw_mci_rockchip_probe,
+	.remove		= dw_mci_pltfm_remove,
+	.driver		= {
+		.name		= "dwmmc_rockchip",
+		.of_match_table	= dw_mci_rockchip_match,
+		.pm		= &dw_mci_rockchip_pmops,
+	},
+};
+
+module_platform_driver(dw_mci_rockchip_pltfm_driver);
+
+MODULE_AUTHOR("Addy Ke <addy.ke@rock-chips.com>");
+MODULE_DESCRIPTION("Rockchip Specific DW-MSHC Driver Extension");
+MODULE_ALIAS("platform:dwmmc-rockchip");
+MODULE_LICENSE("GPL v2");
-- 
1.8.3.2



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

* [PATCH] mmc: dw_mmc: move rockchip related code to a separate file
@ 2014-08-14  8:01       ` Addy Ke
  0 siblings, 0 replies; 22+ messages in thread
From: Addy Ke @ 2014-08-14  8:01 UTC (permalink / raw)
  To: robh+dt-DgEjT+Ai2ygdnm+yROfE0A, pawel.moll-5wv7dgnIgG8,
	mark.rutland-5wv7dgnIgG8, ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	galak-sgV2jX0FEOL9JmXXK+q4OQ, rdunlap-wEGCiKHe2LqWVfeAwA7xHQ,
	tgih.jun-Sze3O3UU22JBDgjK7y7TUQ,
	jh80.chung-Sze3O3UU22JBDgjK7y7TUQ, chris-OsFVWbfNK3isTnJN9+BGXg,
	ulf.hansson-QSEj5FYQhm4dnm+yROfE0A,
	dinguyen-EIB2kfCEclfQT0dZR+AlfA, heiko-4mtYJXux2i+zQB+pC5nmwQ,
	olof-nZhT3qVonbNeoWH0uzbU5w, dianders-F7+t8E8rja9g9hUCZPvPmw
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-doc-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-mmc-u79uwXL29TY76Z2rM5mHXA,
	zhenfu.fang-TNX95d0MmH7DzftRWevZcw, cf-TNX95d0MmH7DzftRWevZcw,
	lintao-TNX95d0MmH7DzftRWevZcw, chenfen-TNX95d0MmH7DzftRWevZcw,
	zyf-TNX95d0MmH7DzftRWevZcw, xjq-TNX95d0MmH7DzftRWevZcw,
	huangtao-TNX95d0MmH7DzftRWevZcw, zyw-TNX95d0MmH7DzftRWevZcw,
	yzq-TNX95d0MmH7DzftRWevZcw, hj-TNX95d0MmH7DzftRWevZcw,
	kever.yang-TNX95d0MmH7DzftRWevZcw,
	zhangqing-TNX95d0MmH7DzftRWevZcw, hl-TNX95d0MmH7DzftRWevZcw,
	Addy Ke

To support HS200 and UHS-1, we need add a big hunk of code,
as shown in the following patches. So a separate file for
rockchip SOCs is suitable.

Signed-off-by: Addy Ke <addy.ke-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
---
 drivers/mmc/host/Kconfig           |   9 +++
 drivers/mmc/host/Makefile          |   1 +
 drivers/mmc/host/dw_mmc-pltfm.c    |  57 ---------------
 drivers/mmc/host/dw_mmc-rockchip.c | 146 +++++++++++++++++++++++++++++++++++++
 4 files changed, 156 insertions(+), 57 deletions(-)
 create mode 100644 drivers/mmc/host/dw_mmc-rockchip.c

diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index a565254..ae61df6 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -621,6 +621,15 @@ config MMC_DW_PCI
 
 	  If unsure, say N.
 
+config MMC_DW_ROCKCHIP
+	tristate "Rockchip specific extensions for Synopsys DW Memory Card Interface"
+	depends on MMC_DW
+	select MMC_DW_PLTFM
+	help
+	  This selects support for Rockchip SoC specific extensions to the
+	  Synopsys DesignWare Memory Card Interface driver. Select this option
+	  for platforms based on RK3066, RK3188 and RK3288 SoC's.
+
 config MMC_SH_MMCIF
 	tristate "SuperH Internal MMCIF support"
 	depends on MMC_BLOCK
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index 7f81ddf..5fce465 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_MMC_DW_PLTFM)	+= dw_mmc-pltfm.o
 obj-$(CONFIG_MMC_DW_EXYNOS)	+= dw_mmc-exynos.o
 obj-$(CONFIG_MMC_DW_K3)		+= dw_mmc-k3.o
 obj-$(CONFIG_MMC_DW_PCI)	+= dw_mmc-pci.o
+obj-$(CONFIG_MMC_DW_ROCKCHIP)	+= dw_mmc-rockchip.o
 obj-$(CONFIG_MMC_SH_MMCIF)	+= sh_mmcif.o
 obj-$(CONFIG_MMC_JZ4740)	+= jz4740_mmc.o
 obj-$(CONFIG_MMC_VUB300)	+= vub300.o
diff --git a/drivers/mmc/host/dw_mmc-pltfm.c b/drivers/mmc/host/dw_mmc-pltfm.c
index b547f7a..0c56c41 100644
--- a/drivers/mmc/host/dw_mmc-pltfm.c
+++ b/drivers/mmc/host/dw_mmc-pltfm.c
@@ -26,64 +26,11 @@
 #include "dw_mmc.h"
 #include "dw_mmc-pltfm.h"
 
-#define RK3288_CLKGEN_DIV	2
-
 static void dw_mci_pltfm_prepare_command(struct dw_mci *host, u32 *cmdr)
 {
 	*cmdr |= SDMMC_CMD_USE_HOLD_REG;
 }
 
-static int dw_mci_rk3288_setup_clock(struct dw_mci *host)
-{
-	host->bus_hz /= RK3288_CLKGEN_DIV;
-
-	return 0;
-}
-
-static void dw_mci_rk3288_set_ios(struct dw_mci *host, struct mmc_ios *ios)
-{
-	int ret;
-	unsigned int cclkin;
-	u32 bus_hz;
-
-	/*
-	 * cclkin: source clock of mmc controller.
-	 * bus_hz: card interface clock generated by CLKGEN.
-	 * bus_hz = cclkin / RK3288_CLKGEN_DIV;
-	 * ios->clock = (div == 0) ? bus_hz : (bus_hz / (2 * div))
-	 *
-	 * Note: div can only be 0 or 1
-	 *       if DDR50 8bit mode(only emmc work in 8bit mode),
-	 *       div must be set 1
-	 */
-	if ((ios->bus_width == MMC_BUS_WIDTH_8) &&
-	    (ios->timing == MMC_TIMING_MMC_DDR52))
-		cclkin = 2 * ios->clock * RK3288_CLKGEN_DIV;
-	else
-		cclkin = ios->clock * RK3288_CLKGEN_DIV;
-
-	ret = clk_set_rate(host->ciu_clk, cclkin);
-	if (ret)
-		dev_warn(host->dev, "failed to set rate %uHz\n", ios->clock);
-
-	bus_hz = clk_get_rate(host->ciu_clk) / RK3288_CLKGEN_DIV;
-	if (bus_hz != host->bus_hz) {
-		host->bus_hz = bus_hz;
-		/* force dw_mci_setup_bus() */
-		host->current_speed = 0;
-	}
-}
-
-static const struct dw_mci_drv_data rk2928_drv_data = {
-	.prepare_command	= dw_mci_pltfm_prepare_command,
-};
-
-static const struct dw_mci_drv_data rk3288_drv_data = {
-	.prepare_command	= dw_mci_pltfm_prepare_command,
-	.set_ios	= dw_mci_rk3288_set_ios,
-	.setup_clock	= dw_mci_rk3288_setup_clock,
-};
-
 static const struct dw_mci_drv_data socfpga_drv_data = {
 	.prepare_command	= dw_mci_pltfm_prepare_command,
 };
@@ -144,10 +91,6 @@ EXPORT_SYMBOL_GPL(dw_mci_pltfm_pmops);
 
 static const struct of_device_id dw_mci_pltfm_match[] = {
 	{ .compatible = "snps,dw-mshc", },
-	{ .compatible = "rockchip,rk2928-dw-mshc",
-		.data = &rk2928_drv_data },
-	{ .compatible = "rockchip,rk3288-dw-mshc",
-		.data = &rk3288_drv_data },
 	{ .compatible = "altr,socfpga-dw-mshc",
 		.data = &socfpga_drv_data },
 	{},
diff --git a/drivers/mmc/host/dw_mmc-rockchip.c b/drivers/mmc/host/dw_mmc-rockchip.c
new file mode 100644
index 0000000..3d86ef3
--- /dev/null
+++ b/drivers/mmc/host/dw_mmc-rockchip.c
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
+ * Author: addy ke <addy.ke-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/dw_mmc.h>
+#include <linux/of_address.h>
+
+#include "dw_mmc.h"
+#include "dw_mmc-pltfm.h"
+
+#define RK3288_CLKGEN_DIV       2
+
+static void dw_mci_rockchip_prepare_command(struct dw_mci *host, u32 *cmdr)
+{
+	*cmdr |= SDMMC_CMD_USE_HOLD_REG;
+}
+
+static int dw_mci_rk3288_setup_clock(struct dw_mci *host)
+{
+	host->bus_hz /= RK3288_CLKGEN_DIV;
+
+	return 0;
+}
+
+static void dw_mci_rk3288_set_ios(struct dw_mci *host, struct mmc_ios *ios)
+{
+	int ret;
+	unsigned int cclkin;
+	u32 bus_hz;
+
+	/*
+	 * cclkin: source clock of mmc controller
+	 * bus_hz: card interface clock generated by CLKGEN
+	 * bus_hz = cclkin / RK3288_CLKGEN_DIV
+	 * os->clock = (div == 0) ? bus_hz : (bus_hz / (2 * div))
+	 *
+	 * Note: div can only be 0 or 1
+	 *       if DDR50 8bit mode(only emmc work in 8bit mode),
+	 *       div must be set 1
+	 */
+	if (ios->bus_width == MMC_BUS_WIDTH_8 &&
+	    ios->timing == MMC_TIMING_MMC_DDR52)
+		cclkin = 2 * ios->clock * RK3288_CLKGEN_DIV;
+	else
+		cclkin = ios->clock * RK3288_CLKGEN_DIV;
+
+	ret = clk_set_rate(host->ciu_clk, cclkin);
+	if (ret)
+		dev_warn(host->dev, "failed to set rate %uHz\n", ios->clock);
+
+	bus_hz = clk_get_rate(host->ciu_clk) / RK3288_CLKGEN_DIV;
+	if (bus_hz != host->bus_hz) {
+		host->bus_hz = bus_hz;
+		/* force dw_mci_setup_bus() */
+		host->current_speed = 0;
+	}
+}
+
+static const struct dw_mci_drv_data rk2928_drv_data = {
+	.prepare_command        = dw_mci_rockchip_prepare_command,
+};
+
+static const struct dw_mci_drv_data rk3288_drv_data = {
+	.prepare_command        = dw_mci_rockchip_prepare_command,
+	.set_ios		= dw_mci_rk3288_set_ios,
+	.setup_clock    = dw_mci_rk3288_setup_clock,
+};
+
+static const struct of_device_id dw_mci_rockchip_match[] = {
+	{ .compatible = "rockchip,rk2928-dw-mshc",
+		.data = &rk2928_drv_data },
+	{ .compatible = "rockchip,rk3288-dw-mshc",
+		.data = &rk3288_drv_data },
+	{},
+};
+MODULE_DEVICE_TABLE(of, dw_mci_rockchip_match);
+
+static int dw_mci_rockchip_probe(struct platform_device *pdev)
+{
+	const struct dw_mci_drv_data *drv_data;
+	const struct of_device_id *match;
+
+	match = of_match_node(dw_mci_rockchip_match, pdev->dev.of_node);
+	drv_data = match->data;
+
+	return dw_mci_pltfm_register(pdev, drv_data);
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int dw_mci_rockchip_suspend(struct device *dev)
+{
+	struct dw_mci *host = dev_get_drvdata(dev);
+	int ret;
+
+	ret = dw_mci_suspend(host);
+	if (!ret)
+		clk_disable_unprepare(host->ciu_clk);
+
+	return ret;
+}
+
+static int dw_mci_rockchip_resume(struct device *dev)
+{
+	struct dw_mci *host = dev_get_drvdata(dev);
+	int ret;
+
+	ret = clk_prepare_enable(host->ciu_clk);
+	if (ret) {
+		dev_err(host->dev, "failed to enable ciu clock\n");
+		return ret;
+	}
+
+	return dw_mci_resume(host);
+}
+#endif /* CONFIG_PM_SLEEP */
+
+static SIMPLE_DEV_PM_OPS(dw_mci_rockchip_pmops,
+			 dw_mci_rockchip_suspend,
+			 dw_mci_rockchip_resume);
+
+static struct platform_driver dw_mci_rockchip_pltfm_driver = {
+	.probe		= dw_mci_rockchip_probe,
+	.remove		= dw_mci_pltfm_remove,
+	.driver		= {
+		.name		= "dwmmc_rockchip",
+		.of_match_table	= dw_mci_rockchip_match,
+		.pm		= &dw_mci_rockchip_pmops,
+	},
+};
+
+module_platform_driver(dw_mci_rockchip_pltfm_driver);
+
+MODULE_AUTHOR("Addy Ke <addy.ke-TNX95d0MmH7DzftRWevZcw@public.gmane.org>");
+MODULE_DESCRIPTION("Rockchip Specific DW-MSHC Driver Extension");
+MODULE_ALIAS("platform:dwmmc-rockchip");
+MODULE_LICENSE("GPL v2");
-- 
1.8.3.2


--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH] mmc: dw_mmc: move rockchip related code to a separate file
  2014-08-14  8:01       ` Addy Ke
  (?)
@ 2014-08-14 12:16       ` Bartlomiej Zolnierkiewicz
  -1 siblings, 0 replies; 22+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2014-08-14 12:16 UTC (permalink / raw)
  To: Addy Ke
  Cc: robh+dt, pawel.moll, mark.rutland, ijc+devicetree, galak,
	rdunlap, tgih.jun, jh80.chung, chris, ulf.hansson, dinguyen,
	heiko, olof, dianders, devicetree, linux-doc, linux-kernel,
	linux-mmc, zhenfu.fang, cf, lintao, chenfen, zyf, xjq, huangtao,
	zyw, yzq, hj, kever.yang, zhangqing, hl


Hi,

On Thursday, August 14, 2014 04:01:33 PM Addy Ke wrote:
> To support HS200 and UHS-1, we need add a big hunk of code,
> as shown in the following patches. So a separate file for
> rockchip SOCs is suitable.
> 
> Signed-off-by: Addy Ke <addy.ke@rock-chips.com>
> ---
>  drivers/mmc/host/Kconfig           |   9 +++
>  drivers/mmc/host/Makefile          |   1 +
>  drivers/mmc/host/dw_mmc-pltfm.c    |  57 ---------------
>  drivers/mmc/host/dw_mmc-rockchip.c | 146 +++++++++++++++++++++++++++++++++++++
>  4 files changed, 156 insertions(+), 57 deletions(-)
>  create mode 100644 drivers/mmc/host/dw_mmc-rockchip.c
> 
> diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
> index a565254..ae61df6 100644
> --- a/drivers/mmc/host/Kconfig
> +++ b/drivers/mmc/host/Kconfig
> @@ -621,6 +621,15 @@ config MMC_DW_PCI
>  
>  	  If unsure, say N.
>  
> +config MMC_DW_ROCKCHIP
> +	tristate "Rockchip specific extensions for Synopsys DW Memory Card Interface"
> +	depends on MMC_DW

While you are at it you may also add (in this or in incremental patch)
dependency on ARCH_ROCKCHIP so this driver becomes limited to Rockchip
architecture.

> +	select MMC_DW_PLTFM
> +	help
> +	  This selects support for Rockchip SoC specific extensions to the
> +	  Synopsys DesignWare Memory Card Interface driver. Select this option
> +	  for platforms based on RK3066, RK3188 and RK3288 SoC's.
> +
>  config MMC_SH_MMCIF
>  	tristate "SuperH Internal MMCIF support"
>  	depends on MMC_BLOCK

Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics


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

* Re: [PATCH] mmc: dw_mmc: move rockchip related code to a separate file
  2014-08-14  8:01       ` Addy Ke
  (?)
  (?)
@ 2014-08-14 17:09       ` Doug Anderson
  2014-08-15 19:52         ` Heiko Stübner
  -1 siblings, 1 reply; 22+ messages in thread
From: Doug Anderson @ 2014-08-14 17:09 UTC (permalink / raw)
  To: Addy Ke
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Randy Dunlap, Seungwon Jeon, Jaehoon Chung, Chris Ball,
	Ulf Hansson, Dinh Nguyen, Heiko Stübner, Olof Johansson,
	devicetree, linux-doc, linux-kernel, linux-mmc, zhenfu.fang,
	Eddie Cai, lintao, chenfen, zyf, Jianqun Xu, Tao Huang, Chris,
	姚智情,
	han jiang, Kever Yang, zhangqing, Lin Huang

Addy,

On Thu, Aug 14, 2014 at 1:01 AM, Addy Ke <addy.ke@rock-chips.com> wrote:
> diff --git a/drivers/mmc/host/dw_mmc-rockchip.c b/drivers/mmc/host/dw_mmc-rockchip.c
> new file mode 100644
> index 0000000..3d86ef3
> --- /dev/null
> +++ b/drivers/mmc/host/dw_mmc-rockchip.c
> @@ -0,0 +1,146 @@
> +/*
> + * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
> + * Author: addy ke <addy.ke@rock-chips.com>

nit: You've already got the author below.  Do you need it here too?

> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/clk.h>
> +#include <linux/mmc/host.h>
> +#include <linux/mmc/dw_mmc.h>
> +#include <linux/of_address.h>
> +
> +#include "dw_mmc.h"
> +#include "dw_mmc-pltfm.h"
> +
> +#define RK3288_CLKGEN_DIV       2
> +
> +static void dw_mci_rockchip_prepare_command(struct dw_mci *host, u32 *cmdr)
> +{
> +       *cmdr |= SDMMC_CMD_USE_HOLD_REG;
> +}
> +
> +static int dw_mci_rk3288_setup_clock(struct dw_mci *host)
> +{
> +       host->bus_hz /= RK3288_CLKGEN_DIV;
> +
> +       return 0;
> +}
> +
> +static void dw_mci_rk3288_set_ios(struct dw_mci *host, struct mmc_ios *ios)
> +{
> +       int ret;
> +       unsigned int cclkin;
> +       u32 bus_hz;
> +
> +       /*
> +        * cclkin: source clock of mmc controller
> +        * bus_hz: card interface clock generated by CLKGEN
> +        * bus_hz = cclkin / RK3288_CLKGEN_DIV
> +        * os->clock = (div == 0) ? bus_hz : (bus_hz / (2 * div))

nit: why did you change "ios->clock" to "os->clock" in the comment?

> +        *
> +        * Note: div can only be 0 or 1
> +        *       if DDR50 8bit mode(only emmc work in 8bit mode),
> +        *       div must be set 1
> +        */
> +       if (ios->bus_width == MMC_BUS_WIDTH_8 &&
> +           ios->timing == MMC_TIMING_MMC_DDR52)
> +               cclkin = 2 * ios->clock * RK3288_CLKGEN_DIV;
> +       else
> +               cclkin = ios->clock * RK3288_CLKGEN_DIV;
> +
> +       ret = clk_set_rate(host->ciu_clk, cclkin);
> +       if (ret)
> +               dev_warn(host->dev, "failed to set rate %uHz\n", ios->clock);
> +
> +       bus_hz = clk_get_rate(host->ciu_clk) / RK3288_CLKGEN_DIV;
> +       if (bus_hz != host->bus_hz) {
> +               host->bus_hz = bus_hz;
> +               /* force dw_mci_setup_bus() */
> +               host->current_speed = 0;
> +       }
> +}
> +
> +static const struct dw_mci_drv_data rk2928_drv_data = {
> +       .prepare_command        = dw_mci_rockchip_prepare_command,
> +};
> +
> +static const struct dw_mci_drv_data rk3288_drv_data = {
> +       .prepare_command        = dw_mci_rockchip_prepare_command,
> +       .set_ios                = dw_mci_rk3288_set_ios,
> +       .setup_clock    = dw_mci_rk3288_setup_clock,
> +};
> +
> +static const struct of_device_id dw_mci_rockchip_match[] = {
> +       { .compatible = "rockchip,rk2928-dw-mshc",
> +               .data = &rk2928_drv_data },
> +       { .compatible = "rockchip,rk3288-dw-mshc",
> +               .data = &rk3288_drv_data },
> +       {},
> +};
> +MODULE_DEVICE_TABLE(of, dw_mci_rockchip_match);
> +
> +static int dw_mci_rockchip_probe(struct platform_device *pdev)
> +{
> +       const struct dw_mci_drv_data *drv_data;
> +       const struct of_device_id *match;
> +
> +       match = of_match_node(dw_mci_rockchip_match, pdev->dev.of_node);

Your code doesn't have "if (pdev->dev.of_node)".  That's OK (I think)
but it means that your KConfig needs a "depends on OF", right?


> +       drv_data = match->data;
> +
> +       return dw_mci_pltfm_register(pdev, drv_data);
> +}
> +
> +#ifdef CONFIG_PM_SLEEP
> +static int dw_mci_rockchip_suspend(struct device *dev)
> +{
> +       struct dw_mci *host = dev_get_drvdata(dev);
> +       int ret;
> +
> +       ret = dw_mci_suspend(host);
> +       if (!ret)
> +               clk_disable_unprepare(host->ciu_clk);
> +
> +       return ret;
> +}
> +
> +static int dw_mci_rockchip_resume(struct device *dev)
> +{
> +       struct dw_mci *host = dev_get_drvdata(dev);
> +       int ret;
> +
> +       ret = clk_prepare_enable(host->ciu_clk);
> +       if (ret) {
> +               dev_err(host->dev, "failed to enable ciu clock\n");
> +               return ret;
> +       }
> +
> +       return dw_mci_resume(host);

Your suspend/resume are different than the platform suspend/resume.
You should change that in a separate change.  This change should just
move code and not change functionality.


> +}
> +#endif /* CONFIG_PM_SLEEP */
> +
> +static SIMPLE_DEV_PM_OPS(dw_mci_rockchip_pmops,
> +                        dw_mci_rockchip_suspend,
> +                        dw_mci_rockchip_resume);
> +
> +static struct platform_driver dw_mci_rockchip_pltfm_driver = {
> +       .probe          = dw_mci_rockchip_probe,
> +       .remove         = dw_mci_pltfm_remove,

On exynos I see the remove wrapped by __exit_p.  Should you do that here, too?


> +       .driver         = {
> +               .name           = "dwmmc_rockchip",
> +               .of_match_table = dw_mci_rockchip_match,
> +               .pm             = &dw_mci_rockchip_pmops,
> +       },
> +};
> +
> +module_platform_driver(dw_mci_rockchip_pltfm_driver);
> +
> +MODULE_AUTHOR("Addy Ke <addy.ke@rock-chips.com>");
> +MODULE_DESCRIPTION("Rockchip Specific DW-MSHC Driver Extension");
> +MODULE_ALIAS("platform:dwmmc-rockchip");
> +MODULE_LICENSE("GPL v2");

-Doug

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

* Re: [PATCH] mmc: dw_mmc: move rockchip related code to a separate file
  2014-08-14 17:09       ` Doug Anderson
@ 2014-08-15 19:52         ` Heiko Stübner
  0 siblings, 0 replies; 22+ messages in thread
From: Heiko Stübner @ 2014-08-15 19:52 UTC (permalink / raw)
  To: Doug Anderson
  Cc: Addy Ke, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell,
	Kumar Gala, Randy Dunlap, Seungwon Jeon, Jaehoon Chung,
	Chris Ball, Ulf Hansson, Dinh Nguyen, Olof Johansson, devicetree,
	linux-doc, linux-kernel, linux-mmc, zhenfu.fang, Eddie Cai,
	lintao, chenfen, zyf, Jianqun Xu, Tao Huang, Chris,
	姚智情,
	han jiang, Kever Yang, zhangqing, Lin Huang

Am Donnerstag, 14. August 2014, 10:09:55 schrieb Doug Anderson:
> Addy,
> 
> On Thu, Aug 14, 2014 at 1:01 AM, Addy Ke <addy.ke@rock-chips.com> wrote:
> > diff --git a/drivers/mmc/host/dw_mmc-rockchip.c
> > b/drivers/mmc/host/dw_mmc-rockchip.c new file mode 100644
> > index 0000000..3d86ef3
> > --- /dev/null
> > +++ b/drivers/mmc/host/dw_mmc-rockchip.c

[...]

> > +static int dw_mci_rockchip_probe(struct platform_device *pdev)
> > +{
> > +       const struct dw_mci_drv_data *drv_data;
> > +       const struct of_device_id *match;
> > +
> > +       match = of_match_node(dw_mci_rockchip_match, pdev->dev.of_node);
> 
> Your code doesn't have "if (pdev->dev.of_node)".  That's OK (I think)
> but it means that your KConfig needs a "depends on OF", right?

Almost all of_* functions have stubs for the !CONFIG_OF case [0].
Instead I guess this simply needs a

if (!pdev->dev.of_node)
	return -ENODEV;

to handle the case when there is no of_node.


Heiko


[0] http://lxr.free-electrons.com/source/include/linux/of.h#L585

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

* [PATCH v2] mmc: dw_mmc: move rockchip related code to a separate file
  2014-08-14  8:01       ` Addy Ke
                         ` (2 preceding siblings ...)
  (?)
@ 2014-08-19  4:36       ` Addy Ke
  2014-08-19  5:08         ` Jaehoon Chung
  2014-08-19 17:28           ` Doug Anderson
  -1 siblings, 2 replies; 22+ messages in thread
From: Addy Ke @ 2014-08-19  4:36 UTC (permalink / raw)
  To: robh+dt, pawel.moll, mark.rutland, ijc+devicetree, galak,
	rdunlap, tgih.jun, jh80.chung, chris, ulf.hansson, dinguyen,
	heiko, olof, dianders
  Cc: devicetree, linux-doc, linux-kernel, linux-mmc, zhenfu.fang, cf,
	lintao, chenfen, zyf, xjq, huangtao, zyw, yzq, hj, kever.yang,
	zhangqing, hl, Addy Ke

To support HS200 and UHS-1, we need add a big hunk of code,
as shown in the following patches. So a separate file for
rockchip SOCs is suitable.

Signed-off-by: Addy Ke <addy.ke@rock-chips.com>
---
Changes in v2:
- Kconfig: depend on ARCH_ROCKCHIP, suggested by Bartlomiej Zolnierkiewicz
- Kconfig: depend on OF, suggested by Doug Anderson
- Not change suspend/resume code, suggested by Doug Anderson
- If pdev->dev.of_node is NULL, then return -ENODEV, suggested by Heiko Stübner

 drivers/mmc/host/Kconfig           |   9 +++
 drivers/mmc/host/Makefile          |   1 +
 drivers/mmc/host/dw_mmc-pltfm.c    |  57 ----------------
 drivers/mmc/host/dw_mmc-rockchip.c | 136 +++++++++++++++++++++++++++++++++++++
 4 files changed, 146 insertions(+), 57 deletions(-)
 create mode 100644 drivers/mmc/host/dw_mmc-rockchip.c

diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index a565254..f6095f6 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -621,6 +621,15 @@ config MMC_DW_PCI
 
 	  If unsure, say N.
 
+config MMC_DW_ROCKCHIP
+	tristate "Rockchip specific extensions for Synopsys DW Memory Card Interface"
+	depends on MMC_DW && ARCH_ROCKCHIP && OF
+	select MMC_DW_PLTFM
+	help
+	  This selects support for Rockchip SoC specific extensions to the
+	  Synopsys DesignWare Memory Card Interface driver. Select this option
+	  for platforms based on RK3066, RK3188 and RK3288 SoC's.
+
 config MMC_SH_MMCIF
 	tristate "SuperH Internal MMCIF support"
 	depends on MMC_BLOCK
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index 7f81ddf..5fce465 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_MMC_DW_PLTFM)	+= dw_mmc-pltfm.o
 obj-$(CONFIG_MMC_DW_EXYNOS)	+= dw_mmc-exynos.o
 obj-$(CONFIG_MMC_DW_K3)		+= dw_mmc-k3.o
 obj-$(CONFIG_MMC_DW_PCI)	+= dw_mmc-pci.o
+obj-$(CONFIG_MMC_DW_ROCKCHIP)	+= dw_mmc-rockchip.o
 obj-$(CONFIG_MMC_SH_MMCIF)	+= sh_mmcif.o
 obj-$(CONFIG_MMC_JZ4740)	+= jz4740_mmc.o
 obj-$(CONFIG_MMC_VUB300)	+= vub300.o
diff --git a/drivers/mmc/host/dw_mmc-pltfm.c b/drivers/mmc/host/dw_mmc-pltfm.c
index b547f7a..0c56c41 100644
--- a/drivers/mmc/host/dw_mmc-pltfm.c
+++ b/drivers/mmc/host/dw_mmc-pltfm.c
@@ -26,64 +26,11 @@
 #include "dw_mmc.h"
 #include "dw_mmc-pltfm.h"
 
-#define RK3288_CLKGEN_DIV	2
-
 static void dw_mci_pltfm_prepare_command(struct dw_mci *host, u32 *cmdr)
 {
 	*cmdr |= SDMMC_CMD_USE_HOLD_REG;
 }
 
-static int dw_mci_rk3288_setup_clock(struct dw_mci *host)
-{
-	host->bus_hz /= RK3288_CLKGEN_DIV;
-
-	return 0;
-}
-
-static void dw_mci_rk3288_set_ios(struct dw_mci *host, struct mmc_ios *ios)
-{
-	int ret;
-	unsigned int cclkin;
-	u32 bus_hz;
-
-	/*
-	 * cclkin: source clock of mmc controller.
-	 * bus_hz: card interface clock generated by CLKGEN.
-	 * bus_hz = cclkin / RK3288_CLKGEN_DIV;
-	 * ios->clock = (div == 0) ? bus_hz : (bus_hz / (2 * div))
-	 *
-	 * Note: div can only be 0 or 1
-	 *       if DDR50 8bit mode(only emmc work in 8bit mode),
-	 *       div must be set 1
-	 */
-	if ((ios->bus_width == MMC_BUS_WIDTH_8) &&
-	    (ios->timing == MMC_TIMING_MMC_DDR52))
-		cclkin = 2 * ios->clock * RK3288_CLKGEN_DIV;
-	else
-		cclkin = ios->clock * RK3288_CLKGEN_DIV;
-
-	ret = clk_set_rate(host->ciu_clk, cclkin);
-	if (ret)
-		dev_warn(host->dev, "failed to set rate %uHz\n", ios->clock);
-
-	bus_hz = clk_get_rate(host->ciu_clk) / RK3288_CLKGEN_DIV;
-	if (bus_hz != host->bus_hz) {
-		host->bus_hz = bus_hz;
-		/* force dw_mci_setup_bus() */
-		host->current_speed = 0;
-	}
-}
-
-static const struct dw_mci_drv_data rk2928_drv_data = {
-	.prepare_command	= dw_mci_pltfm_prepare_command,
-};
-
-static const struct dw_mci_drv_data rk3288_drv_data = {
-	.prepare_command	= dw_mci_pltfm_prepare_command,
-	.set_ios	= dw_mci_rk3288_set_ios,
-	.setup_clock	= dw_mci_rk3288_setup_clock,
-};
-
 static const struct dw_mci_drv_data socfpga_drv_data = {
 	.prepare_command	= dw_mci_pltfm_prepare_command,
 };
@@ -144,10 +91,6 @@ EXPORT_SYMBOL_GPL(dw_mci_pltfm_pmops);
 
 static const struct of_device_id dw_mci_pltfm_match[] = {
 	{ .compatible = "snps,dw-mshc", },
-	{ .compatible = "rockchip,rk2928-dw-mshc",
-		.data = &rk2928_drv_data },
-	{ .compatible = "rockchip,rk3288-dw-mshc",
-		.data = &rk3288_drv_data },
 	{ .compatible = "altr,socfpga-dw-mshc",
 		.data = &socfpga_drv_data },
 	{},
diff --git a/drivers/mmc/host/dw_mmc-rockchip.c b/drivers/mmc/host/dw_mmc-rockchip.c
new file mode 100644
index 0000000..f0c2cb1
--- /dev/null
+++ b/drivers/mmc/host/dw_mmc-rockchip.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/dw_mmc.h>
+#include <linux/of_address.h>
+
+#include "dw_mmc.h"
+#include "dw_mmc-pltfm.h"
+
+#define RK3288_CLKGEN_DIV       2
+
+static void dw_mci_rockchip_prepare_command(struct dw_mci *host, u32 *cmdr)
+{
+	*cmdr |= SDMMC_CMD_USE_HOLD_REG;
+}
+
+static int dw_mci_rk3288_setup_clock(struct dw_mci *host)
+{
+	host->bus_hz /= RK3288_CLKGEN_DIV;
+
+	return 0;
+}
+
+static void dw_mci_rk3288_set_ios(struct dw_mci *host, struct mmc_ios *ios)
+{
+	int ret;
+	unsigned int cclkin;
+	u32 bus_hz;
+
+	/*
+	 * cclkin: source clock of mmc controller
+	 * bus_hz: card interface clock generated by CLKGEN
+	 * bus_hz = cclkin / RK3288_CLKGEN_DIV
+	 * ios->clock = (div == 0) ? bus_hz : (bus_hz / (2 * div))
+	 *
+	 * Note: div can only be 0 or 1
+	 *       if DDR50 8bit mode(only emmc work in 8bit mode),
+	 *       div must be set 1
+	 */
+	if (ios->bus_width == MMC_BUS_WIDTH_8 &&
+	    ios->timing == MMC_TIMING_MMC_DDR52)
+		cclkin = 2 * ios->clock * RK3288_CLKGEN_DIV;
+	else
+		cclkin = ios->clock * RK3288_CLKGEN_DIV;
+
+	ret = clk_set_rate(host->ciu_clk, cclkin);
+	if (ret)
+		dev_warn(host->dev, "failed to set rate %uHz\n", ios->clock);
+
+	bus_hz = clk_get_rate(host->ciu_clk) / RK3288_CLKGEN_DIV;
+	if (bus_hz != host->bus_hz) {
+		host->bus_hz = bus_hz;
+		/* force dw_mci_setup_bus() */
+		host->current_speed = 0;
+	}
+}
+
+static const struct dw_mci_drv_data rk2928_drv_data = {
+	.prepare_command        = dw_mci_rockchip_prepare_command,
+};
+
+static const struct dw_mci_drv_data rk3288_drv_data = {
+	.prepare_command        = dw_mci_rockchip_prepare_command,
+	.set_ios		= dw_mci_rk3288_set_ios,
+	.setup_clock    = dw_mci_rk3288_setup_clock,
+};
+
+static const struct of_device_id dw_mci_rockchip_match[] = {
+	{ .compatible = "rockchip,rk2928-dw-mshc",
+		.data = &rk2928_drv_data },
+	{ .compatible = "rockchip,rk3288-dw-mshc",
+		.data = &rk3288_drv_data },
+	{},
+};
+MODULE_DEVICE_TABLE(of, dw_mci_rockchip_match);
+
+static int dw_mci_rockchip_probe(struct platform_device *pdev)
+{
+	const struct dw_mci_drv_data *drv_data;
+	const struct of_device_id *match;
+
+	if (!pdev->dev.of_node)
+		return -ENODEV;
+
+	match = of_match_node(dw_mci_rockchip_match, pdev->dev.of_node);
+	drv_data = match->data;
+
+	return dw_mci_pltfm_register(pdev, drv_data);
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int dw_mci_rockchip_suspend(struct device *dev)
+{
+	struct dw_mci *host = dev_get_drvdata(dev);
+
+	return dw_mci_suspend(host);
+}
+
+static int dw_mci_rockchip_resume(struct device *dev)
+{
+	struct dw_mci *host = dev_get_drvdata(dev);
+
+	return dw_mci_resume(host);
+}
+#endif /* CONFIG_PM_SLEEP */
+
+static SIMPLE_DEV_PM_OPS(dw_mci_rockchip_pmops,
+			 dw_mci_rockchip_suspend,
+			 dw_mci_rockchip_resume);
+
+static struct platform_driver dw_mci_rockchip_pltfm_driver = {
+	.probe		= dw_mci_rockchip_probe,
+	.remove		= __exit_p(dw_mci_pltfm_remove),
+	.driver		= {
+		.name		= "dwmmc_rockchip",
+		.of_match_table	= dw_mci_rockchip_match,
+		.pm		= &dw_mci_rockchip_pmops,
+	},
+};
+
+module_platform_driver(dw_mci_rockchip_pltfm_driver);
+
+MODULE_AUTHOR("Addy Ke <addy.ke@rock-chips.com>");
+MODULE_DESCRIPTION("Rockchip Specific DW-MSHC Driver Extension");
+MODULE_ALIAS("platform:dwmmc-rockchip");
+MODULE_LICENSE("GPL v2");
-- 
1.8.3.2



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

* Re: [PATCH v2] mmc: dw_mmc: move rockchip related code to a separate file
  2014-08-19  4:36       ` [PATCH v2] " Addy Ke
@ 2014-08-19  5:08         ` Jaehoon Chung
  2014-08-19 17:28           ` Doug Anderson
  1 sibling, 0 replies; 22+ messages in thread
From: Jaehoon Chung @ 2014-08-19  5:08 UTC (permalink / raw)
  To: Addy Ke, robh+dt, pawel.moll, mark.rutland, ijc+devicetree,
	galak, rdunlap, tgih.jun, chris, ulf.hansson, dinguyen, heiko,
	olof, dianders
  Cc: devicetree, linux-doc, linux-kernel, linux-mmc, zhenfu.fang, cf,
	lintao, chenfen, zyf, xjq, huangtao, zyw, yzq, hj, kever.yang,
	zhangqing, hl

Acked-by: Jaehoon Chung <jh80.chung@samsung.com>

Best Regards,
Jaehoon Chung

On 08/19/2014 01:36 PM, Addy Ke wrote:
> To support HS200 and UHS-1, we need add a big hunk of code,
> as shown in the following patches. So a separate file for
> rockchip SOCs is suitable.
> 
> Signed-off-by: Addy Ke <addy.ke@rock-chips.com>
> ---
> Changes in v2:
> - Kconfig: depend on ARCH_ROCKCHIP, suggested by Bartlomiej Zolnierkiewicz
> - Kconfig: depend on OF, suggested by Doug Anderson
> - Not change suspend/resume code, suggested by Doug Anderson
> - If pdev->dev.of_node is NULL, then return -ENODEV, suggested by Heiko Stübner
> 
>  drivers/mmc/host/Kconfig           |   9 +++
>  drivers/mmc/host/Makefile          |   1 +
>  drivers/mmc/host/dw_mmc-pltfm.c    |  57 ----------------
>  drivers/mmc/host/dw_mmc-rockchip.c | 136 +++++++++++++++++++++++++++++++++++++
>  4 files changed, 146 insertions(+), 57 deletions(-)
>  create mode 100644 drivers/mmc/host/dw_mmc-rockchip.c
> 
> diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
> index a565254..f6095f6 100644
> --- a/drivers/mmc/host/Kconfig
> +++ b/drivers/mmc/host/Kconfig
> @@ -621,6 +621,15 @@ config MMC_DW_PCI
>  
>  	  If unsure, say N.
>  
> +config MMC_DW_ROCKCHIP
> +	tristate "Rockchip specific extensions for Synopsys DW Memory Card Interface"
> +	depends on MMC_DW && ARCH_ROCKCHIP && OF
> +	select MMC_DW_PLTFM
> +	help
> +	  This selects support for Rockchip SoC specific extensions to the
> +	  Synopsys DesignWare Memory Card Interface driver. Select this option
> +	  for platforms based on RK3066, RK3188 and RK3288 SoC's.
> +
>  config MMC_SH_MMCIF
>  	tristate "SuperH Internal MMCIF support"
>  	depends on MMC_BLOCK
> diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
> index 7f81ddf..5fce465 100644
> --- a/drivers/mmc/host/Makefile
> +++ b/drivers/mmc/host/Makefile
> @@ -45,6 +45,7 @@ obj-$(CONFIG_MMC_DW_PLTFM)	+= dw_mmc-pltfm.o
>  obj-$(CONFIG_MMC_DW_EXYNOS)	+= dw_mmc-exynos.o
>  obj-$(CONFIG_MMC_DW_K3)		+= dw_mmc-k3.o
>  obj-$(CONFIG_MMC_DW_PCI)	+= dw_mmc-pci.o
> +obj-$(CONFIG_MMC_DW_ROCKCHIP)	+= dw_mmc-rockchip.o
>  obj-$(CONFIG_MMC_SH_MMCIF)	+= sh_mmcif.o
>  obj-$(CONFIG_MMC_JZ4740)	+= jz4740_mmc.o
>  obj-$(CONFIG_MMC_VUB300)	+= vub300.o
> diff --git a/drivers/mmc/host/dw_mmc-pltfm.c b/drivers/mmc/host/dw_mmc-pltfm.c
> index b547f7a..0c56c41 100644
> --- a/drivers/mmc/host/dw_mmc-pltfm.c
> +++ b/drivers/mmc/host/dw_mmc-pltfm.c
> @@ -26,64 +26,11 @@
>  #include "dw_mmc.h"
>  #include "dw_mmc-pltfm.h"
>  
> -#define RK3288_CLKGEN_DIV	2
> -
>  static void dw_mci_pltfm_prepare_command(struct dw_mci *host, u32 *cmdr)
>  {
>  	*cmdr |= SDMMC_CMD_USE_HOLD_REG;
>  }
>  
> -static int dw_mci_rk3288_setup_clock(struct dw_mci *host)
> -{
> -	host->bus_hz /= RK3288_CLKGEN_DIV;
> -
> -	return 0;
> -}
> -
> -static void dw_mci_rk3288_set_ios(struct dw_mci *host, struct mmc_ios *ios)
> -{
> -	int ret;
> -	unsigned int cclkin;
> -	u32 bus_hz;
> -
> -	/*
> -	 * cclkin: source clock of mmc controller.
> -	 * bus_hz: card interface clock generated by CLKGEN.
> -	 * bus_hz = cclkin / RK3288_CLKGEN_DIV;
> -	 * ios->clock = (div == 0) ? bus_hz : (bus_hz / (2 * div))
> -	 *
> -	 * Note: div can only be 0 or 1
> -	 *       if DDR50 8bit mode(only emmc work in 8bit mode),
> -	 *       div must be set 1
> -	 */
> -	if ((ios->bus_width == MMC_BUS_WIDTH_8) &&
> -	    (ios->timing == MMC_TIMING_MMC_DDR52))
> -		cclkin = 2 * ios->clock * RK3288_CLKGEN_DIV;
> -	else
> -		cclkin = ios->clock * RK3288_CLKGEN_DIV;
> -
> -	ret = clk_set_rate(host->ciu_clk, cclkin);
> -	if (ret)
> -		dev_warn(host->dev, "failed to set rate %uHz\n", ios->clock);
> -
> -	bus_hz = clk_get_rate(host->ciu_clk) / RK3288_CLKGEN_DIV;
> -	if (bus_hz != host->bus_hz) {
> -		host->bus_hz = bus_hz;
> -		/* force dw_mci_setup_bus() */
> -		host->current_speed = 0;
> -	}
> -}
> -
> -static const struct dw_mci_drv_data rk2928_drv_data = {
> -	.prepare_command	= dw_mci_pltfm_prepare_command,
> -};
> -
> -static const struct dw_mci_drv_data rk3288_drv_data = {
> -	.prepare_command	= dw_mci_pltfm_prepare_command,
> -	.set_ios	= dw_mci_rk3288_set_ios,
> -	.setup_clock	= dw_mci_rk3288_setup_clock,
> -};
> -
>  static const struct dw_mci_drv_data socfpga_drv_data = {
>  	.prepare_command	= dw_mci_pltfm_prepare_command,
>  };
> @@ -144,10 +91,6 @@ EXPORT_SYMBOL_GPL(dw_mci_pltfm_pmops);
>  
>  static const struct of_device_id dw_mci_pltfm_match[] = {
>  	{ .compatible = "snps,dw-mshc", },
> -	{ .compatible = "rockchip,rk2928-dw-mshc",
> -		.data = &rk2928_drv_data },
> -	{ .compatible = "rockchip,rk3288-dw-mshc",
> -		.data = &rk3288_drv_data },
>  	{ .compatible = "altr,socfpga-dw-mshc",
>  		.data = &socfpga_drv_data },
>  	{},
> diff --git a/drivers/mmc/host/dw_mmc-rockchip.c b/drivers/mmc/host/dw_mmc-rockchip.c
> new file mode 100644
> index 0000000..f0c2cb1
> --- /dev/null
> +++ b/drivers/mmc/host/dw_mmc-rockchip.c
> @@ -0,0 +1,136 @@
> +/*
> + * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/clk.h>
> +#include <linux/mmc/host.h>
> +#include <linux/mmc/dw_mmc.h>
> +#include <linux/of_address.h>
> +
> +#include "dw_mmc.h"
> +#include "dw_mmc-pltfm.h"
> +
> +#define RK3288_CLKGEN_DIV       2
> +
> +static void dw_mci_rockchip_prepare_command(struct dw_mci *host, u32 *cmdr)
> +{
> +	*cmdr |= SDMMC_CMD_USE_HOLD_REG;
> +}
> +
> +static int dw_mci_rk3288_setup_clock(struct dw_mci *host)
> +{
> +	host->bus_hz /= RK3288_CLKGEN_DIV;
> +
> +	return 0;
> +}
> +
> +static void dw_mci_rk3288_set_ios(struct dw_mci *host, struct mmc_ios *ios)
> +{
> +	int ret;
> +	unsigned int cclkin;
> +	u32 bus_hz;
> +
> +	/*
> +	 * cclkin: source clock of mmc controller
> +	 * bus_hz: card interface clock generated by CLKGEN
> +	 * bus_hz = cclkin / RK3288_CLKGEN_DIV
> +	 * ios->clock = (div == 0) ? bus_hz : (bus_hz / (2 * div))
> +	 *
> +	 * Note: div can only be 0 or 1
> +	 *       if DDR50 8bit mode(only emmc work in 8bit mode),
> +	 *       div must be set 1
> +	 */
> +	if (ios->bus_width == MMC_BUS_WIDTH_8 &&
> +	    ios->timing == MMC_TIMING_MMC_DDR52)
> +		cclkin = 2 * ios->clock * RK3288_CLKGEN_DIV;
> +	else
> +		cclkin = ios->clock * RK3288_CLKGEN_DIV;
> +
> +	ret = clk_set_rate(host->ciu_clk, cclkin);
> +	if (ret)
> +		dev_warn(host->dev, "failed to set rate %uHz\n", ios->clock);
> +
> +	bus_hz = clk_get_rate(host->ciu_clk) / RK3288_CLKGEN_DIV;
> +	if (bus_hz != host->bus_hz) {
> +		host->bus_hz = bus_hz;
> +		/* force dw_mci_setup_bus() */
> +		host->current_speed = 0;
> +	}
> +}
> +
> +static const struct dw_mci_drv_data rk2928_drv_data = {
> +	.prepare_command        = dw_mci_rockchip_prepare_command,
> +};
> +
> +static const struct dw_mci_drv_data rk3288_drv_data = {
> +	.prepare_command        = dw_mci_rockchip_prepare_command,
> +	.set_ios		= dw_mci_rk3288_set_ios,
> +	.setup_clock    = dw_mci_rk3288_setup_clock,
> +};
> +
> +static const struct of_device_id dw_mci_rockchip_match[] = {
> +	{ .compatible = "rockchip,rk2928-dw-mshc",
> +		.data = &rk2928_drv_data },
> +	{ .compatible = "rockchip,rk3288-dw-mshc",
> +		.data = &rk3288_drv_data },
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, dw_mci_rockchip_match);
> +
> +static int dw_mci_rockchip_probe(struct platform_device *pdev)
> +{
> +	const struct dw_mci_drv_data *drv_data;
> +	const struct of_device_id *match;
> +
> +	if (!pdev->dev.of_node)
> +		return -ENODEV;
> +
> +	match = of_match_node(dw_mci_rockchip_match, pdev->dev.of_node);
> +	drv_data = match->data;
> +
> +	return dw_mci_pltfm_register(pdev, drv_data);
> +}
> +
> +#ifdef CONFIG_PM_SLEEP
> +static int dw_mci_rockchip_suspend(struct device *dev)
> +{
> +	struct dw_mci *host = dev_get_drvdata(dev);
> +
> +	return dw_mci_suspend(host);
> +}
> +
> +static int dw_mci_rockchip_resume(struct device *dev)
> +{
> +	struct dw_mci *host = dev_get_drvdata(dev);
> +
> +	return dw_mci_resume(host);
> +}
> +#endif /* CONFIG_PM_SLEEP */
> +
> +static SIMPLE_DEV_PM_OPS(dw_mci_rockchip_pmops,
> +			 dw_mci_rockchip_suspend,
> +			 dw_mci_rockchip_resume);
> +
> +static struct platform_driver dw_mci_rockchip_pltfm_driver = {
> +	.probe		= dw_mci_rockchip_probe,
> +	.remove		= __exit_p(dw_mci_pltfm_remove),
> +	.driver		= {
> +		.name		= "dwmmc_rockchip",
> +		.of_match_table	= dw_mci_rockchip_match,
> +		.pm		= &dw_mci_rockchip_pmops,
> +	},
> +};
> +
> +module_platform_driver(dw_mci_rockchip_pltfm_driver);
> +
> +MODULE_AUTHOR("Addy Ke <addy.ke@rock-chips.com>");
> +MODULE_DESCRIPTION("Rockchip Specific DW-MSHC Driver Extension");
> +MODULE_ALIAS("platform:dwmmc-rockchip");
> +MODULE_LICENSE("GPL v2");
> 


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

* Re: [PATCH v2] mmc: dw_mmc: move rockchip related code to a separate file
  2014-08-19  4:36       ` [PATCH v2] " Addy Ke
@ 2014-08-19 17:28           ` Doug Anderson
  2014-08-19 17:28           ` Doug Anderson
  1 sibling, 0 replies; 22+ messages in thread
From: Doug Anderson @ 2014-08-19 17:28 UTC (permalink / raw)
  To: Addy Ke, Ulf Hansson
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Randy Dunlap, Seungwon Jeon, Jaehoon Chung, Chris Ball,
	Dinh Nguyen, Heiko Stübner, Olof Johansson, devicetree,
	linux-doc, linux-kernel, linux-mmc, zhenfu.fang, Eddie Cai,
	lintao, chenfen, zyf, Jianqun Xu, Tao Huang, Chris,
	姚智情,
	han jiang, Kever Yang, zhangqing, Lin Huang

Hi,

On Mon, Aug 18, 2014 at 9:36 PM, Addy Ke <addy.ke@rock-chips.com> wrote:
> To support HS200 and UHS-1, we need add a big hunk of code,
> as shown in the following patches. So a separate file for
> rockchip SOCs is suitable.
>
> Signed-off-by: Addy Ke <addy.ke@rock-chips.com>
> ---
> Changes in v2:
> - Kconfig: depend on ARCH_ROCKCHIP, suggested by Bartlomiej Zolnierkiewicz
> - Kconfig: depend on OF, suggested by Doug Anderson
> - Not change suspend/resume code, suggested by Doug Anderson
> - If pdev->dev.of_node is NULL, then return -ENODEV, suggested by Heiko Stübner
>
>  drivers/mmc/host/Kconfig           |   9 +++
>  drivers/mmc/host/Makefile          |   1 +
>  drivers/mmc/host/dw_mmc-pltfm.c    |  57 ----------------
>  drivers/mmc/host/dw_mmc-rockchip.c | 136 +++++++++++++++++++++++++++++++++++++
>  4 files changed, 146 insertions(+), 57 deletions(-)
>  create mode 100644 drivers/mmc/host/dw_mmc-rockchip.c
>
> diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
> index a565254..f6095f6 100644
> --- a/drivers/mmc/host/Kconfig
> +++ b/drivers/mmc/host/Kconfig
> @@ -621,6 +621,15 @@ config MMC_DW_PCI
>
>           If unsure, say N.
>
> +config MMC_DW_ROCKCHIP
> +       tristate "Rockchip specific extensions for Synopsys DW Memory Card Interface"
> +       depends on MMC_DW && ARCH_ROCKCHIP && OF

Actually, Heiko's change to check if pdev->dev.of_node is NULL means
that you don't need to depend on OF anymore.

Ulf: do you want Addy to spin again, or do you want to just remove
this "&& OF" when applying the patch?

...I've tested this both with and without the "&& OF", and the "&& OF"
won't really hurt anything, so:

Tested-by: Doug Anderson <dianders@chromium.org>
Reviewed-by: Doug Anderson <dianders@chromium.org>

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

* Re: [PATCH v2] mmc: dw_mmc: move rockchip related code to a separate file
@ 2014-08-19 17:28           ` Doug Anderson
  0 siblings, 0 replies; 22+ messages in thread
From: Doug Anderson @ 2014-08-19 17:28 UTC (permalink / raw)
  To: Addy Ke, Ulf Hansson
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Randy Dunlap, Seungwon Jeon, Jaehoon Chung, Chris Ball,
	Dinh Nguyen, Heiko Stübner, Olof Johansson, devicetree,
	linux-doc, linux-kernel, linux-mmc, zhenfu.fang, Eddie Cai,
	lintao, chenfen, zyf, Jianqun Xu

Hi,

On Mon, Aug 18, 2014 at 9:36 PM, Addy Ke <addy.ke@rock-chips.com> wrote:
> To support HS200 and UHS-1, we need add a big hunk of code,
> as shown in the following patches. So a separate file for
> rockchip SOCs is suitable.
>
> Signed-off-by: Addy Ke <addy.ke@rock-chips.com>
> ---
> Changes in v2:
> - Kconfig: depend on ARCH_ROCKCHIP, suggested by Bartlomiej Zolnierkiewicz
> - Kconfig: depend on OF, suggested by Doug Anderson
> - Not change suspend/resume code, suggested by Doug Anderson
> - If pdev->dev.of_node is NULL, then return -ENODEV, suggested by Heiko Stübner
>
>  drivers/mmc/host/Kconfig           |   9 +++
>  drivers/mmc/host/Makefile          |   1 +
>  drivers/mmc/host/dw_mmc-pltfm.c    |  57 ----------------
>  drivers/mmc/host/dw_mmc-rockchip.c | 136 +++++++++++++++++++++++++++++++++++++
>  4 files changed, 146 insertions(+), 57 deletions(-)
>  create mode 100644 drivers/mmc/host/dw_mmc-rockchip.c
>
> diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
> index a565254..f6095f6 100644
> --- a/drivers/mmc/host/Kconfig
> +++ b/drivers/mmc/host/Kconfig
> @@ -621,6 +621,15 @@ config MMC_DW_PCI
>
>           If unsure, say N.
>
> +config MMC_DW_ROCKCHIP
> +       tristate "Rockchip specific extensions for Synopsys DW Memory Card Interface"
> +       depends on MMC_DW && ARCH_ROCKCHIP && OF

Actually, Heiko's change to check if pdev->dev.of_node is NULL means
that you don't need to depend on OF anymore.

Ulf: do you want Addy to spin again, or do you want to just remove
this "&& OF" when applying the patch?

...I've tested this both with and without the "&& OF", and the "&& OF"
won't really hurt anything, so:

Tested-by: Doug Anderson <dianders@chromium.org>
Reviewed-by: Doug Anderson <dianders@chromium.org>

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

* Re: [PATCH v2] mmc: dw_mmc: move rockchip related code to a separate file
  2014-08-19 17:28           ` Doug Anderson
@ 2014-08-29 11:05             ` Ulf Hansson
  -1 siblings, 0 replies; 22+ messages in thread
From: Ulf Hansson @ 2014-08-29 11:05 UTC (permalink / raw)
  To: Doug Anderson, Addy Ke
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Randy Dunlap, Seungwon Jeon, Jaehoon Chung, Chris Ball,
	Dinh Nguyen, Heiko Stübner, Olof Johansson, devicetree,
	linux-doc, linux-kernel, linux-mmc, zhenfu.fang, Eddie Cai,
	lintao, chenfen, zyf, Jianqun Xu, Tao Huang, Chris,
	姚智情,
	han jiang, Kever Yang, zhangqing, Lin Huang

On 19 August 2014 19:28, Doug Anderson <dianders@chromium.org> wrote:
> Hi,
>
> On Mon, Aug 18, 2014 at 9:36 PM, Addy Ke <addy.ke@rock-chips.com> wrote:
>> To support HS200 and UHS-1, we need add a big hunk of code,
>> as shown in the following patches. So a separate file for
>> rockchip SOCs is suitable.
>>
>> Signed-off-by: Addy Ke <addy.ke@rock-chips.com>
>> ---
>> Changes in v2:
>> - Kconfig: depend on ARCH_ROCKCHIP, suggested by Bartlomiej Zolnierkiewicz
>> - Kconfig: depend on OF, suggested by Doug Anderson
>> - Not change suspend/resume code, suggested by Doug Anderson
>> - If pdev->dev.of_node is NULL, then return -ENODEV, suggested by Heiko Stübner
>>
>>  drivers/mmc/host/Kconfig           |   9 +++
>>  drivers/mmc/host/Makefile          |   1 +
>>  drivers/mmc/host/dw_mmc-pltfm.c    |  57 ----------------
>>  drivers/mmc/host/dw_mmc-rockchip.c | 136 +++++++++++++++++++++++++++++++++++++
>>  4 files changed, 146 insertions(+), 57 deletions(-)
>>  create mode 100644 drivers/mmc/host/dw_mmc-rockchip.c
>>
>> diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
>> index a565254..f6095f6 100644
>> --- a/drivers/mmc/host/Kconfig
>> +++ b/drivers/mmc/host/Kconfig
>> @@ -621,6 +621,15 @@ config MMC_DW_PCI
>>
>>           If unsure, say N.
>>
>> +config MMC_DW_ROCKCHIP
>> +       tristate "Rockchip specific extensions for Synopsys DW Memory Card Interface"
>> +       depends on MMC_DW && ARCH_ROCKCHIP && OF
>
> Actually, Heiko's change to check if pdev->dev.of_node is NULL means
> that you don't need to depend on OF anymore.
>
> Ulf: do you want Addy to spin again, or do you want to just remove
> this "&& OF" when applying the patch?
>
> ...I've tested this both with and without the "&& OF", and the "&& OF"
> won't really hurt anything, so:
>
> Tested-by: Doug Anderson <dianders@chromium.org>
> Reviewed-by: Doug Anderson <dianders@chromium.org>

Thanks! Applied for next and by removing the dependency to "OF".

Kind regards
Uffe

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

* Re: [PATCH v2] mmc: dw_mmc: move rockchip related code to a separate file
@ 2014-08-29 11:05             ` Ulf Hansson
  0 siblings, 0 replies; 22+ messages in thread
From: Ulf Hansson @ 2014-08-29 11:05 UTC (permalink / raw)
  To: Doug Anderson, Addy Ke
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Randy Dunlap, Seungwon Jeon, Jaehoon Chung, Chris Ball,
	Dinh Nguyen, Heiko Stübner, Olof Johansson, devicetree,
	linux-doc, linux-kernel, linux-mmc, zhenfu.fang, Eddie Cai,
	lintao, chenfen, zyf, Jianqun Xu

On 19 August 2014 19:28, Doug Anderson <dianders@chromium.org> wrote:
> Hi,
>
> On Mon, Aug 18, 2014 at 9:36 PM, Addy Ke <addy.ke@rock-chips.com> wrote:
>> To support HS200 and UHS-1, we need add a big hunk of code,
>> as shown in the following patches. So a separate file for
>> rockchip SOCs is suitable.
>>
>> Signed-off-by: Addy Ke <addy.ke@rock-chips.com>
>> ---
>> Changes in v2:
>> - Kconfig: depend on ARCH_ROCKCHIP, suggested by Bartlomiej Zolnierkiewicz
>> - Kconfig: depend on OF, suggested by Doug Anderson
>> - Not change suspend/resume code, suggested by Doug Anderson
>> - If pdev->dev.of_node is NULL, then return -ENODEV, suggested by Heiko Stübner
>>
>>  drivers/mmc/host/Kconfig           |   9 +++
>>  drivers/mmc/host/Makefile          |   1 +
>>  drivers/mmc/host/dw_mmc-pltfm.c    |  57 ----------------
>>  drivers/mmc/host/dw_mmc-rockchip.c | 136 +++++++++++++++++++++++++++++++++++++
>>  4 files changed, 146 insertions(+), 57 deletions(-)
>>  create mode 100644 drivers/mmc/host/dw_mmc-rockchip.c
>>
>> diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
>> index a565254..f6095f6 100644
>> --- a/drivers/mmc/host/Kconfig
>> +++ b/drivers/mmc/host/Kconfig
>> @@ -621,6 +621,15 @@ config MMC_DW_PCI
>>
>>           If unsure, say N.
>>
>> +config MMC_DW_ROCKCHIP
>> +       tristate "Rockchip specific extensions for Synopsys DW Memory Card Interface"
>> +       depends on MMC_DW && ARCH_ROCKCHIP && OF
>
> Actually, Heiko's change to check if pdev->dev.of_node is NULL means
> that you don't need to depend on OF anymore.
>
> Ulf: do you want Addy to spin again, or do you want to just remove
> this "&& OF" when applying the patch?
>
> ...I've tested this both with and without the "&& OF", and the "&& OF"
> won't really hurt anything, so:
>
> Tested-by: Doug Anderson <dianders@chromium.org>
> Reviewed-by: Doug Anderson <dianders@chromium.org>

Thanks! Applied for next and by removing the dependency to "OF".

Kind regards
Uffe

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

end of thread, other threads:[~2014-08-29 11:05 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-07-05 12:59 [PATCH] mmc: dw_mmc: add support for RK3288 addy ke
2014-07-05 12:59 ` addy ke
2014-07-07  2:07 ` Jaehoon Chung
2014-07-07  2:42   ` addy ke
2014-07-10  3:31 ` [PATCH v2] " Addy Ke
2014-07-29  4:52   ` Doug Anderson
2014-07-29 16:38     ` Doug Anderson
2014-07-31  6:01   ` [PATCH] " Addy Ke
2014-07-31 15:40     ` Doug Anderson
2014-08-12 12:17       ` Ulf Hansson
2014-08-07  8:47     ` Jaehoon Chung
2014-08-14  8:01     ` [PATCH] mmc: dw_mmc: move rockchip related code to a separate file Addy Ke
2014-08-14  8:01       ` Addy Ke
2014-08-14 12:16       ` Bartlomiej Zolnierkiewicz
2014-08-14 17:09       ` Doug Anderson
2014-08-15 19:52         ` Heiko Stübner
2014-08-19  4:36       ` [PATCH v2] " Addy Ke
2014-08-19  5:08         ` Jaehoon Chung
2014-08-19 17:28         ` Doug Anderson
2014-08-19 17:28           ` Doug Anderson
2014-08-29 11:05           ` Ulf Hansson
2014-08-29 11:05             ` Ulf Hansson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.