* [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.