Skip to contentSkip to conversation

mmc: dw_mmc: k3 remove clk_table

PATCH New Zhangfei Gao 8 participants 22 messages Jan 13, 2014 – Feb 27, 2014

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

cover mmc: dw_mmc: k3 remove clk_table

clk_table is used to set clock source in each mode, as well as limitation, max_rate and init rate. It concerned many experts though, and Seungwon recommended some limitation can be hide in clk.c. Also soc is updated as the limitation now same as max_rate, so directly using ios->clock.

Zhangfei Gao (2):
clk: hisilicon: add hi3620_mmc_clks
mmc: dw_mmc: k3: remove clk_table

 .../bindings/arm/hisilicon/hisilicon.txt           |   14 +
 .../devicetree/bindings/clock/hi3620-clock.txt     |    1 +
 .../devicetree/bindings/mmc/k3-dw-mshc.txt         |   14 -
 drivers/clk/hisilicon/clk-hi3620.c                 |  267 ++++++++++++++++++++
 drivers/mmc/host/dw_mmc-k3.c                       |   41 +--
 include/dt-bindings/clock/hi3620-clock.h           |    5 +
 6 files changed, 289 insertions(+), 53 deletions(-)
Signature · 1 line
1.7.9.5
#1 lore raw

PATCH 1/2 clk: hisilicon: add hi3620_mmc_clks

Suggest by Arnd: abstract mmc tuning as clock behavior, also because different soc have different tuning method and registers. hi3620_mmc_clks is added to handle mmc clock specifically on hi3620.

---
 .../bindings/arm/hisilicon/hisilicon.txt           |   14 +
 .../devicetree/bindings/clock/hi3620-clock.txt     |    1 +
 drivers/clk/hisilicon/clk-hi3620.c                 |  267 ++++++++++++++++++++
 include/dt-bindings/clock/hi3620-clock.h           |    5 +
 4 files changed, 287 insertions(+)
Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt +14 -0
index 8c7a4653508d..df0a452b8526 100644
@@ -30,3 +30,17 @@ Example:
 		resume-offset = <0x308>;
 		reboot-offset = <0x4>;
 	};
+
+PCTRL: Peripheral misc control register
+
+Required Properties:
+- compatible: "hisilicon,pctrl"
+- reg: Address and size of pctrl.
+
+Example:
+
+	/* for Hi3620 */
+	pctrl: pctrl at fca09000 {
+		compatible = "hisilicon,pctrl";
+		reg = <0xfca09000 0x1000>;
+	};
Documentation/devicetree/bindings/clock/hi3620-clock.txt +1 -0
index 4b71ab41be53..dad6269f52c5 100644
@@ -7,6 +7,7 @@ Required Properties:
 
 - compatible: should be one of the following.
   - "hisilicon,hi3620-clock" - controller compatible with Hi3620 SoC.
+  - "hisilicon,hi3620-mmc-clock" - controller specific for Hi3620 mmc.
 
 - reg: physical base address of the controller and length of memory mapped
   region.
drivers/clk/hisilicon/clk-hi3620.c +267 -0

270 lines not on this page · raw message

include/dt-bindings/clock/hi3620-clock.h +5 -0
index 6eaa6a45e110..21b9d0e2eb0c 100644
@@ -147,6 +147,11 @@
 #define HI3620_MMC_CLK3		217
 #define HI3620_MCU_CLK		218
 
+#define HI3620_SD_CIUCLK	0
+#define HI3620_MMC_CIUCLK1	1
+#define HI3620_MMC_CIUCLK2	2
+#define HI3620_MMC_CIUCLK3	3
+
 #define HI3620_NR_CLKS		219
 
 #endif	/* __DTS_HI3620_CLOCK_H */
Signature · 1 line
1.7.9.5
#2 lore raw

PATCH 1/1 clk: hisilicon: add hi3620_mmc_clks

Suggest by Arnd: abstract mmc tuning as clock behavior, also because different soc have different tuning method and registers. hi3620_mmc_clks is added to handle mmc clock specifically on hi3620.

---
 .../bindings/arm/hisilicon/hisilicon.txt           |   14 +
 .../devicetree/bindings/clock/hi3620-clock.txt     |    1 +
 drivers/clk/hisilicon/clk-hi3620.c                 |  274 ++++++++++++++++++++
 include/dt-bindings/clock/hi3620-clock.h           |    5 +
 4 files changed, 294 insertions(+)
Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt +14 -0
index 8c7a4653508d..df0a452b8526 100644
@@ -30,3 +30,17 @@ Example:
 		resume-offset = <0x308>;
 		reboot-offset = <0x4>;
 	};
+
+PCTRL: Peripheral misc control register
+
+Required Properties:
+- compatible: "hisilicon,pctrl"
+- reg: Address and size of pctrl.
+
+Example:
+
+	/* for Hi3620 */
+	pctrl: pctrl at fca09000 {
+		compatible = "hisilicon,pctrl";
+		reg = <0xfca09000 0x1000>;
+	};
Documentation/devicetree/bindings/clock/hi3620-clock.txt +1 -0
index 4b71ab41be53..dad6269f52c5 100644
@@ -7,6 +7,7 @@ Required Properties:
 
 - compatible: should be one of the following.
   - "hisilicon,hi3620-clock" - controller compatible with Hi3620 SoC.
+  - "hisilicon,hi3620-mmc-clock" - controller specific for Hi3620 mmc.
 
 - reg: physical base address of the controller and length of memory mapped
   region.
drivers/clk/hisilicon/clk-hi3620.c +274 -0

277 lines not on this page · raw message

include/dt-bindings/clock/hi3620-clock.h +5 -0
index 6eaa6a45e110..21b9d0e2eb0c 100644
@@ -147,6 +147,11 @@
 #define HI3620_MMC_CLK3		217
 #define HI3620_MCU_CLK		218
 
+#define HI3620_SD_CIUCLK	0
+#define HI3620_MMC_CIUCLK1	1
+#define HI3620_MMC_CIUCLK2	2
+#define HI3620_MMC_CIUCLK3	3
+
 #define HI3620_NR_CLKS		219
 
 #endif	/* __DTS_HI3620_CLOCK_H */
Signature · 1 line
1.7.9.5
#3 lore raw

PATCH 1/1 clk: hisilicon: add hi3620_mmc_clks

Quoting Zhangfei Gao (2014-01-13 01:37:32)

Quoted 7 lines

Suggest by Arnd: abstract mmc tuning as clock behavior, also because different soc have different tuning method and registers. hi3620_mmc_clks is added to handle mmc clock specifically on hi3620.

Taken into clk-next (again! This one got lost when migrating my early branch from 3.14-rcX to the new clk-next)

Regards,
Mike

Quoted 342 lines
---
 .../bindings/arm/hisilicon/hisilicon.txt           |   14 +
 .../devicetree/bindings/clock/hi3620-clock.txt     |    1 +
 drivers/clk/hisilicon/clk-hi3620.c                 |  274 ++++++++++++++++++++
 include/dt-bindings/clock/hi3620-clock.h           |    5 +
 4 files changed, 294 insertions(+)
Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt +14 -0
index 8c7a4653508d..df0a452b8526 100644
@@ -30,3 +30,17 @@ Example:
                resume-offset = <0x308>;
                reboot-offset = <0x4>;
        };
+
+PCTRL: Peripheral misc control register
+
+Required Properties:
+- compatible: "hisilicon,pctrl"
+- reg: Address and size of pctrl.
+
+Example:
+
+       /* for Hi3620 */
+       pctrl: pctrl at fca09000 {
+               compatible = "hisilicon,pctrl";
+               reg = <0xfca09000 0x1000>;
+       };
Documentation/devicetree/bindings/clock/hi3620-clock.txt +1 -0
index 4b71ab41be53..dad6269f52c5 100644
@@ -7,6 +7,7 @@ Required Properties:
 
 - compatible: should be one of the following.
   - "hisilicon,hi3620-clock" - controller compatible with Hi3620 SoC.
+  - "hisilicon,hi3620-mmc-clock" - controller specific for Hi3620 mmc.
 
 - reg: physical base address of the controller and length of memory mapped
   region.
drivers/clk/hisilicon/clk-hi3620.c +274 -0
index f24ad6a3a797..38faa469d288 100644
@@ -240,3 +240,277 @@ static void __init hi3620_clk_init(struct device_node *np)
                                   base);
 }
 CLK_OF_DECLARE(hi3620_clk, "hisilicon,hi3620-clock", hi3620_clk_init);
+
+struct hisi_mmc_clock {
+       unsigned int            id;
+       const char              *name;
+       const char              *parent_name;
+       unsigned long           flags;
+       u32                     clken_reg;
+       u32                     clken_bit;
+       u32                     div_reg;
+       u32                     div_off;
+       u32                     div_bits;
+       u32                     drv_reg;
+       u32                     drv_off;
+       u32                     drv_bits;
+       u32                     sam_reg;
+       u32                     sam_off;
+       u32                     sam_bits;
+};
+
+struct clk_mmc {
+       struct clk_hw   hw;
+       u32             id;
+       void __iomem    *clken_reg;
+       u32             clken_bit;
+       void __iomem    *div_reg;
+       u32             div_off;
+       u32             div_bits;
+       void __iomem    *drv_reg;
+       u32             drv_off;
+       u32             drv_bits;
+       void __iomem    *sam_reg;
+       u32             sam_off;
+       u32             sam_bits;
+};
+
+#define to_mmc(_hw) container_of(_hw, struct clk_mmc, hw)
+
+static struct hisi_mmc_clock hi3620_mmc_clks[] __initdata = {
+       { HI3620_SD_CIUCLK,     "sd_bclk1", "sd_clk", CLK_SET_RATE_PARENT, 0x1f8, 0, 0x1f8, 1, 3, 0x1f8, 4, 4, 0x1f8, 8, 4},
+       { HI3620_MMC_CIUCLK1,   "mmc_bclk1", "mmc_clk1", CLK_SET_RATE_PARENT, 0x1f8, 12, 0x1f8, 13, 3, 0x1f8, 16, 4, 0x1f8, 20, 4},
+       { HI3620_MMC_CIUCLK2,   "mmc_bclk2", "mmc_clk2", CLK_SET_RATE_PARENT, 0x1f8, 24, 0x1f8, 25, 3, 0x1f8, 28, 4, 0x1fc, 0, 4},
+       { HI3620_MMC_CIUCLK3,   "mmc_bclk3", "mmc_clk3", CLK_SET_RATE_PARENT, 0x1fc, 4, 0x1fc, 5, 3, 0x1fc, 8, 4, 0x1fc, 12, 4},
+};
+
+static unsigned long mmc_clk_recalc_rate(struct clk_hw *hw,
+                      unsigned long parent_rate)
+{
+       switch (parent_rate) {
+       case 26000000:
+               return 13000000;
+       case 180000000:
+               return 25000000;
+       case 360000000:
+               return 50000000;
+       case 720000000:
+               return 100000000;
+       case 1440000000:
+               return 180000000;
+       default:
+               return parent_rate;
+       }
+}
+
+static long mmc_clk_determine_rate(struct clk_hw *hw, unsigned long rate,
+                             unsigned long *best_parent_rate,
+                             struct clk **best_parent_p)
+{
+       struct clk_mmc *mclk = to_mmc(hw);
+       unsigned long best = 0;
+
+       if ((rate <= 13000000) && (mclk->id == HI3620_MMC_CIUCLK1)) {
+               rate = 13000000;
+               best = 26000000;
+       } else if (rate <= 26000000) {
+               rate = 25000000;
+               best = 180000000;
+       } else if (rate <= 52000000) {
+               rate = 50000000;
+               best = 360000000;
+       } else if (rate <= 100000000) {
+               rate = 100000000;
+               best = 720000000;
+       } else {
+               /* max is 180M */
+               rate = 180000000;
+               best = 1440000000;
+       }
+       *best_parent_rate = best;
+       return rate;
+}
+
+static u32 mmc_clk_delay(u32 val, u32 para, u32 off, u32 len)
+{
+       u32 i;
+
+       if (para >= 0) {
+               for (i = 0; i < len; i++) {
+                       if (para % 2)
+                               val |= 1 << (off + i);
+                       else
+                               val &= ~(1 << (off + i));
+                       para = para >> 1;
+               }
+       }
+       return val;
+}
+
+static int mmc_clk_set_timing(struct clk_hw *hw, unsigned long rate)
+{
+       struct clk_mmc *mclk = to_mmc(hw);
+       unsigned long flags;
+       u32 sam, drv, div, val;
+       static DEFINE_SPINLOCK(mmc_clk_lock);
+
+       switch (rate) {
+       case 13000000:
+               sam = 3;
+               drv = 1;
+               div = 1;
+               break;
+       case 25000000:
+               sam = 13;
+               drv = 6;
+               div = 6;
+               break;
+       case 50000000:
+               sam = 3;
+               drv = 6;
+               div = 6;
+               break;
+       case 100000000:
+               sam = 6;
+               drv = 4;
+               div = 6;
+               break;
+       case 180000000:
+               sam = 6;
+               drv = 4;
+               div = 7;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       spin_lock_irqsave(&mmc_clk_lock, flags);
+
+       val = readl_relaxed(mclk->clken_reg);
+       val &= ~(1 << mclk->clken_bit);
+       writel_relaxed(val, mclk->clken_reg);
+
+       val = readl_relaxed(mclk->sam_reg);
+       val = mmc_clk_delay(val, sam, mclk->sam_off, mclk->sam_bits);
+       writel_relaxed(val, mclk->sam_reg);
+
+       val = readl_relaxed(mclk->drv_reg);
+       val = mmc_clk_delay(val, drv, mclk->drv_off, mclk->drv_bits);
+       writel_relaxed(val, mclk->drv_reg);
+
+       val = readl_relaxed(mclk->div_reg);
+       val = mmc_clk_delay(val, div, mclk->div_off, mclk->div_bits);
+       writel_relaxed(val, mclk->div_reg);
+
+       val = readl_relaxed(mclk->clken_reg);
+       val |= 1 << mclk->clken_bit;
+       writel_relaxed(val, mclk->clken_reg);
+
+       spin_unlock_irqrestore(&mmc_clk_lock, flags);
+
+       return 0;
+}
+
+static int mmc_clk_prepare(struct clk_hw *hw)
+{
+       struct clk_mmc *mclk = to_mmc(hw);
+       unsigned long rate;
+
+       if (mclk->id == HI3620_MMC_CIUCLK1)
+               rate = 13000000;
+       else
+               rate = 25000000;
+
+       return mmc_clk_set_timing(hw, rate);
+}
+
+static int mmc_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+                            unsigned long parent_rate)
+{
+       return mmc_clk_set_timing(hw, rate);
+}
+
+static struct clk_ops clk_mmc_ops = {
+       .prepare = mmc_clk_prepare,
+       .determine_rate = mmc_clk_determine_rate,
+       .set_rate = mmc_clk_set_rate,
+       .recalc_rate = mmc_clk_recalc_rate,
+};
+
+static struct clk *hisi_register_clk_mmc(struct hisi_mmc_clock *mmc_clk,
+                       void __iomem *base, struct device_node *np)
+{
+       struct clk_mmc *mclk;
+       struct clk *clk;
+       struct clk_init_data init;
+
+       mclk = kzalloc(sizeof(*mclk), GFP_KERNEL);
+       if (!mclk) {
+               pr_err("%s: fail to allocate mmc clk\n", __func__);
+               return ERR_PTR(-ENOMEM);
+       }
+
+       init.name = mmc_clk->name;
+       init.ops = &clk_mmc_ops;
+       init.flags = mmc_clk->flags | CLK_IS_BASIC;
+       init.parent_names = (mmc_clk->parent_name ? &mmc_clk->parent_name : NULL);
+       init.num_parents = (mmc_clk->parent_name ? 1 : 0);
+       mclk->hw.init = &init;
+
+       mclk->id = mmc_clk->id;
+       mclk->clken_reg = base + mmc_clk->clken_reg;
+       mclk->clken_bit = mmc_clk->clken_bit;
+       mclk->div_reg = base + mmc_clk->div_reg;
+       mclk->div_off = mmc_clk->div_off;
+       mclk->div_bits = mmc_clk->div_bits;
+       mclk->drv_reg = base + mmc_clk->drv_reg;
+       mclk->drv_off = mmc_clk->drv_off;
+       mclk->drv_bits = mmc_clk->drv_bits;
+       mclk->sam_reg = base + mmc_clk->sam_reg;
+       mclk->sam_off = mmc_clk->sam_off;
+       mclk->sam_bits = mmc_clk->sam_bits;
+
+       clk = clk_register(NULL, &mclk->hw);
+       if (WARN_ON(IS_ERR(clk)))
+               kfree(mclk);
+       return clk;
+}
+
+static void __init hi3620_mmc_clk_init(struct device_node *node)
+{
+       void __iomem *base;
+       int i, num = ARRAY_SIZE(hi3620_mmc_clks);
+       struct clk_onecell_data *clk_data;
+
+       if (!node) {
+               pr_err("failed to find pctrl node in DTS\n");
+               return;
+       }
+
+       base = of_iomap(node, 0);
+       if (!base) {
+               pr_err("failed to map pctrl\n");
+               return;
+       }
+
+       clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
+       if (WARN_ON(!clk_data))
+               return;
+
+       clk_data->clks = kzalloc(sizeof(struct clk *) * num, GFP_KERNEL);
+       if (!clk_data->clks) {
+               pr_err("%s: fail to allocate mmc clk\n", __func__);
+               return;
+       }
+
+       for (i = 0; i < num; i++) {
+               struct hisi_mmc_clock *mmc_clk = &hi3620_mmc_clks[i];
+               clk_data->clks[mmc_clk->id] =
+                       hisi_register_clk_mmc(mmc_clk, base, node);
+       }
+
+       clk_data->clk_num = num;
+       of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+}
+
+CLK_OF_DECLARE(hi3620_mmc_clk, "hisilicon,hi3620-mmc-clock", hi3620_mmc_clk_init);
include/dt-bindings/clock/hi3620-clock.h +5 -0
index 6eaa6a45e110..21b9d0e2eb0c 100644
@@ -147,6 +147,11 @@
 #define HI3620_MMC_CLK3                217
 #define HI3620_MCU_CLK         218
 
+#define HI3620_SD_CIUCLK       0
+#define HI3620_MMC_CIUCLK1     1
+#define HI3620_MMC_CIUCLK2     2
+#define HI3620_MMC_CIUCLK3     3
+
 #define HI3620_NR_CLKS         219
 
 #endif /* __DTS_HI3620_CLOCK_H */
Signature · 1 line
1.7.9.5
#4 lore raw

PATCH 1/2 clk: hisilicon: add hi3620_mmc_clks

In reply to Zhangfei Gao
Quoted 121 lines · Zhangfei Gao

Suggest by Arnd: abstract mmc tuning as clock behavior, also because different soc have different tuning method and registers. hi3620_mmc_clks is added to handle mmc clock specifically on hi3620.

---
 .../bindings/arm/hisilicon/hisilicon.txt           |   14 +
 .../devicetree/bindings/clock/hi3620-clock.txt     |    1 +
 drivers/clk/hisilicon/clk-hi3620.c                 |  267 ++++++++++++++++++++
 include/dt-bindings/clock/hi3620-clock.h           |    5 +
 4 files changed, 287 insertions(+)
Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt +14 -0
index 8c7a4653508d..df0a452b8526 100644
@@ -30,3 +30,17 @@ Example:
 		resume-offset = <0x308>;
 		reboot-offset = <0x4>;
 	};
+
+PCTRL: Peripheral misc control register
+
+Required Properties:
+- compatible: "hisilicon,pctrl"
+- reg: Address and size of pctrl.
+
+Example:
+
+	/* for Hi3620 */
+	pctrl: pctrl at fca09000 {
+		compatible = "hisilicon,pctrl";
+		reg = <0xfca09000 0x1000>;
+	};
Documentation/devicetree/bindings/clock/hi3620-clock.txt +1 -0
index 4b71ab41be53..dad6269f52c5 100644
@@ -7,6 +7,7 @@ Required Properties:
 
 - compatible: should be one of the following.
   - "hisilicon,hi3620-clock" - controller compatible with Hi3620 SoC.
+  - "hisilicon,hi3620-mmc-clock" - controller specific for Hi3620 mmc.
 
 - reg: physical base address of the controller and length of memory mapped
   region.
drivers/clk/hisilicon/clk-hi3620.c +39 -0
index f24ad6a3a797..54cc3475ec36 100644
@@ -240,3 +240,270 @@ static void __init hi3620_clk_init(struct device_node *np)
 				   base);
 }
 CLK_OF_DECLARE(hi3620_clk, "hisilicon,hi3620-clock", hi3620_clk_init);
+
+struct hisi_mmc_clock {
+	unsigned int		id;
+	const char		*name;
+	const char		*parent_name;
+	unsigned long		flags;
+	u32			clken_reg;
+	u32			clken_bit;
+	u32			div_reg;
+	u32			div_off;
+	u32			div_bits;
+	u32			drv_reg;
+	u32			drv_off;
+	u32			drv_bits;
+	u32			sam_reg;
+	u32			sam_off;
+	u32			sam_bits;
+};
+
+struct clk_mmc {
+	struct clk_hw	hw;
+	u32		id;
+	void __iomem	*clken_reg;
+	u32		clken_bit;
+	void __iomem	*div_reg;
+	u32		div_off;
+	u32		div_bits;
+	void __iomem	*drv_reg;
+	u32		drv_off;
+	u32		drv_bits;
+	void __iomem	*sam_reg;
+	u32		sam_off;
+	u32		sam_bits;
+};
+
+#define to_mmc(_hw) container_of(_hw, struct clk_mmc, hw)
+
+static struct hisi_mmc_clock hi3620_mmc_clks[] __initdata = {
+	{ HI3620_SD_CIUCLK,	"sd_bclk1", "sd_clk", CLK_SET_RATE_PARENT, 0x1f8, 0, 0x1f8, 1, 3, 0x1f8, 4,

4, 0x1f8, 8, 4},

drivers/clk/hisilicon/clk-hi3620.c +1 -0
+	{ HI3620_MMC_CIUCLK1,   "mmc_bclk1", "mmc_clk1", CLK_SET_RATE_PARENT, 0x1f8, 12, 0x1f8, 13, 3,

0x1f8, 16, 4, 0x1f8, 20, 4},

drivers/clk/hisilicon/clk-hi3620.c +1 -0
+	{ HI3620_MMC_CIUCLK2,   "mmc_bclk2", "mmc_clk2", CLK_SET_RATE_PARENT, 0x1f8, 24, 0x1f8, 25, 3,

0x1f8, 28, 4, 0x1fc, 0, 4},

drivers/clk/hisilicon/clk-hi3620.c +1 -0
+	{ HI3620_MMC_CIUCLK3,   "mmc_bclk3", "mmc_clk3", CLK_SET_RATE_PARENT, 0x1fc, 4, 0x1fc, 5, 3,

0x1fc, 8, 4, 0x1fc, 12, 4},

drivers/clk/hisilicon/clk-hi3620.c +17 -0
+};
+
+static unsigned long mmc_clk_recalc_rate(struct clk_hw *hw,
+		       unsigned long parent_rate)
+{
+	switch (parent_rate) {
+	case 26000000:
+		return 13000000;
+	case 180000000:
+		return 25000000;
+	case 360000000:
+		return 50000000;
+	case 720000000:
+		return 100000000;
+	default:
+		return parent_rate;
+	}

drivers/clk/hisilicon/clk-hi3620.c static void __init hi3620_clk_init(struct device_node *np) · line 311

Quoted 10 lines
drivers/clk/hisilicon/clk-hi3620.c +10 -0
+}
+
+static long mmc_clk_determine_rate(struct clk_hw *hw, unsigned long rate,
+			      unsigned long *best_parent_rate,
+			      struct clk **best_parent_p)
+{
+	struct clk_mmc *mclk = to_mmc(hw);
+	unsigned long best = 0;
+
+	if ((rate <= 13000000) && (mclk->id == HI3620_MMC_CIUCLK1)) {

No need to check HI3620_MMC_CIUCLK2 and HI3620_MMC_CIUCLK3?

Quoted 91 lines
drivers/clk/hisilicon/clk-hi3620.c +91 -0
+		rate = 13000000;
+		best = 26000000;
+	} else if (rate <= 26000000) {
+		rate = 25000000;
+		best = 180000000;
+	} else if (rate <= 52000000) {
+		rate = 50000000;
+		best = 360000000;
+	} else if (rate <= 100000000) {
+		rate = 100000000;
+		best = 720000000;
+	} else {
+		/* max is 180M */
+		rate = 180000000;
+		best = 1440000000;
+	}
+	*best_parent_rate = best;
+	return rate;
+}
+
+static u32 mmc_clk_delay(u32 val, u32 para, u32 off, u32 len)
+{
+	u32 i;
+
+	if (para >= 0) {
+		for (i = 0; i < len; i++) {
+			if (para % 2)
+				val |= 1 << (off + i);
+			else
+				val &= ~(1 << (off + i));
+			para = para >> 1;
+		}
+	}
+	return val;
+}
+
+static int mmc_clk_set_timing(struct clk_hw *hw, unsigned long rate)
+{
+	struct clk_mmc *mclk = to_mmc(hw);
+	unsigned long flags;
+	u32 sam, drv, div, val;
+	static DEFINE_SPINLOCK(mmc_clk_lock);
+
+	switch (rate) {
+	case 13000000:
+		sam = 3;
+		drv = 1;
+		div = 1;
+		break;
+	case 25000000:
+		sam = 13;
+		drv = 6;
+		div = 6;
+		break;
+	case 50000000:
+		sam = 3;
+		drv = 6;
+		div = 6;
+		break;
+	case 100000000:
+		sam = 6;
+		drv = 4;
+		div = 6;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	spin_lock_irqsave(&mmc_clk_lock, flags);
+
+	val = readl_relaxed(mclk->clken_reg);
+	val &= ~(1 << mclk->clken_bit);
+	writel_relaxed(val, mclk->clken_reg);
+
+	val = readl_relaxed(mclk->sam_reg);
+	val = mmc_clk_delay(val, sam, mclk->sam_off, mclk->sam_bits);
+	writel_relaxed(val, mclk->sam_reg);
+
+	val = readl_relaxed(mclk->drv_reg);
+	val = mmc_clk_delay(val, drv, mclk->drv_off, mclk->drv_bits);
+	writel_relaxed(val, mclk->drv_reg);
+
+	val = readl_relaxed(mclk->div_reg);
+	val = mmc_clk_delay(val, div, mclk->div_off, mclk->div_bits);
+	writel_relaxed(val, mclk->div_reg);
+
+	val = readl_relaxed(mclk->clken_reg);
+	val |= 1 << mclk->clken_bit;
+	writel_relaxed(val, mclk->clken_reg);
+
+	spin_unlock_irqrestore(&mmc_clk_lock, flags);

drivers/clk/hisilicon/clk-hi3620.c static void __init hi3620_clk_init(struct device_node *np) · line 412

Quoted 10 lines
drivers/clk/hisilicon/clk-hi3620.c +10 -0
+
+	return 0;
+}
+
+static int mmc_clk_prepare(struct clk_hw *hw)
+{
+	struct clk_mmc *mclk = to_mmc(hw);
+	unsigned long rate;
+
+	if (mclk->id == HI3620_MMC_CIUCLK1)

HI3620_SD_CIUCLK was used in previous version.
Is it fixed with HI3620_MMC_CIUCLK1?
And, please clarify in case of HI3620_MMC_CIUCLK2 and HI3620_MMC_CIUCLK3 as well.

Thanks,
Seungwon Jeon

Quoted 120 lines
drivers/clk/hisilicon/clk-hi3620.c +97 -0
+		rate = 13000000;
+	else
+		rate = 25000000;
+
+	return mmc_clk_set_timing(hw, rate);
+}
+
+static int mmc_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+			     unsigned long parent_rate)
+{
+	return mmc_clk_set_timing(hw, rate);
+}
+
+static struct clk_ops clk_mmc_ops = {
+	.prepare = mmc_clk_prepare,
+	.determine_rate = mmc_clk_determine_rate,
+	.set_rate = mmc_clk_set_rate,
+	.recalc_rate = mmc_clk_recalc_rate,
+};
+
+static struct clk *hisi_register_clk_mmc(struct hisi_mmc_clock *mmc_clk,
+			void __iomem *base, struct device_node *np)
+{
+	struct clk_mmc *mclk;
+	struct clk *clk;
+	struct clk_init_data init;
+
+	mclk = kzalloc(sizeof(*mclk), GFP_KERNEL);
+	if (!mclk) {
+		pr_err("%s: fail to allocate mmc clk\n", __func__);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	init.name = mmc_clk->name;
+	init.ops = &clk_mmc_ops;
+	init.flags = mmc_clk->flags | CLK_IS_BASIC;
+	init.parent_names = (mmc_clk->parent_name ? &mmc_clk->parent_name : NULL);
+	init.num_parents = (mmc_clk->parent_name ? 1 : 0);
+	mclk->hw.init = &init;
+
+	mclk->id = mmc_clk->id;
+	mclk->clken_reg = base + mmc_clk->clken_reg;
+	mclk->clken_bit = mmc_clk->clken_bit;
+	mclk->div_reg = base + mmc_clk->div_reg;
+	mclk->div_off = mmc_clk->div_off;
+	mclk->div_bits = mmc_clk->div_bits;
+	mclk->drv_reg = base + mmc_clk->drv_reg;
+	mclk->drv_off = mmc_clk->drv_off;
+	mclk->drv_bits = mmc_clk->drv_bits;
+	mclk->sam_reg = base + mmc_clk->sam_reg;
+	mclk->sam_off = mmc_clk->sam_off;
+	mclk->sam_bits = mmc_clk->sam_bits;
+
+	clk = clk_register(NULL, &mclk->hw);
+	if (WARN_ON(IS_ERR(clk)))
+		kfree(mclk);
+	return clk;
+}
+
+static void __init hi3620_mmc_clk_init(struct device_node *node)
+{
+	void __iomem *base;
+	int i, num = ARRAY_SIZE(hi3620_mmc_clks);
+	struct clk_onecell_data *clk_data;
+
+	if (!node) {
+		pr_err("failed to find pctrl node in DTS\n");
+		return;
+	}
+
+	base = of_iomap(node, 0);
+	if (!base) {
+		pr_err("failed to map pctrl\n");
+		return;
+	}
+
+	clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
+	if (WARN_ON(!clk_data))
+		return;
+
+	clk_data->clks = kzalloc(sizeof(struct clk *) * num, GFP_KERNEL);
+	if (!clk_data->clks) {
+		pr_err("%s: fail to allocate mmc clk\n", __func__);
+		return;
+	}
+
+	for (i = 0; i < num; i++) {
+		struct hisi_mmc_clock *mmc_clk = &hi3620_mmc_clks[i];
+		clk_data->clks[mmc_clk->id] =
+			hisi_register_clk_mmc(mmc_clk, base, node);
+	}
+
+	clk_data->clk_num = num;
+	of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+}
+
+CLK_OF_DECLARE(hi3620_mmc_clk, "hisilicon,hi3620-mmc-clock", hi3620_mmc_clk_init);
include/dt-bindings/clock/hi3620-clock.h +5 -1
index 6eaa6a45e110..21b9d0e2eb0c 100644
@@ -147,6 +147,11 @@
 #define HI3620_MMC_CLK3		217
 #define HI3620_MCU_CLK		218
 
+#define HI3620_SD_CIUCLK	0
+#define HI3620_MMC_CIUCLK1	1
+#define HI3620_MMC_CIUCLK2	2
+#define HI3620_MMC_CIUCLK3	3
+
 #define HI3620_NR_CLKS		219
 
 #endif	/* __DTS_HI3620_CLOCK_H */
--

1.7.9.5

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

#5 lore raw

PATCH 1/2 clk: hisilicon: add hi3620_mmc_clks

Quoted 9 lines

drivers/clk/hisilicon/clk-hi3620.c static void __init hi3620_clk_init(struct device_node *np) · line 311

Quoted 8 lines
drivers/clk/hisilicon/clk-hi3620.c +8 -0
+static long mmc_clk_determine_rate(struct clk_hw *hw, unsigned long rate,
+                           unsigned long *best_parent_rate,
+                           struct clk **best_parent_p)
+{
+     struct clk_mmc *mclk = to_mmc(hw);
+     unsigned long best = 0;
+
+     if ((rate <= 13000000) && (mclk->id == HI3620_MMC_CIUCLK1)) {

No need to check HI3620_MMC_CIUCLK2 and HI3620_MMC_CIUCLK3?

Yes, only emmc, id=HI3620_MMC_CIUCLK1, using init clk 13M, while others use init clock 25M.
Add this to handle init mmc init clk 400K and return source clock rate 13M, from your suggestion in fact.

Quoted 21 lines
Quoted 20 lines
drivers/clk/hisilicon/clk-hi3620.c +19 -0
+             rate = 13000000;
+             best = 26000000;
+     } else if (rate <= 26000000) {
+             rate = 25000000;
+             best = 180000000;
+     } else if (rate <= 52000000) {
+             rate = 50000000;
+             best = 360000000;
+     } else if (rate <= 100000000) {
+             rate = 100000000;
+             best = 720000000;
+     } else {
+             /* max is 180M */
+             rate = 180000000;
+             best = 1440000000;
+     }
+     *best_parent_rate = best;
+     return rate;
+}
Quoted 7 lines

drivers/clk/hisilicon/clk-hi3620.c static void __init hi3620_clk_init(struct device_node *np) · line 412

Quoted 6 lines
drivers/clk/hisilicon/clk-hi3620.c +6 -0
+static int mmc_clk_prepare(struct clk_hw *hw)
+{
+     struct clk_mmc *mclk = to_mmc(hw);
+     unsigned long rate;
+
+     if (mclk->id == HI3620_MMC_CIUCLK1)

HI3620_SD_CIUCLK was used in previous version.

Yes, fixed, though it can work on the dev board.

Quoted 2 lines

Is it fixed with HI3620_MMC_CIUCLK1?
And, please clarify in case of HI3620_MMC_CIUCLK2 and HI3620_MMC_CIUCLK3 as well.

Only HI3620_MMC_CIUCLK1 use 13M for init, all others use 25M on hi3620.

Quoted 11 lines

Thanks,
Seungwon Jeon

drivers/clk/hisilicon/clk-hi3620.c static void __init hi3620_clk_init(struct device_node *np) · line 419

Quoted 7 lines
drivers/clk/hisilicon/clk-hi3620.c +7 -0
+             rate = 13000000;
+     else
+             rate = 25000000;
+
+     return mmc_clk_set_timing(hw, rate);
+}
+

Thanks

#6 lore raw

PATCH 1/2 clk: hisilicon: add hi3620_mmc_clks

In reply to Zhangfei Gao
Quoted 7 lines · Zhangfei Gao

Suggest by Arnd: abstract mmc tuning as clock behavior, also because different soc have different tuning method and registers. hi3620_mmc_clks is added to handle mmc clock specifically on hi3620.

I add my ack.
Please run 'checkpatch' and remove some warnings.

Thanks,
Seungwon Jeon

Quoted 345 lines
---
 .../bindings/arm/hisilicon/hisilicon.txt           |   14 +
 .../devicetree/bindings/clock/hi3620-clock.txt     |    1 +
 drivers/clk/hisilicon/clk-hi3620.c                 |  267 ++++++++++++++++++++
 include/dt-bindings/clock/hi3620-clock.h           |    5 +
 4 files changed, 287 insertions(+)
Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt +14 -0
index 8c7a4653508d..df0a452b8526 100644
@@ -30,3 +30,17 @@ Example:
 		resume-offset = <0x308>;
 		reboot-offset = <0x4>;
 	};
+
+PCTRL: Peripheral misc control register
+
+Required Properties:
+- compatible: "hisilicon,pctrl"
+- reg: Address and size of pctrl.
+
+Example:
+
+	/* for Hi3620 */
+	pctrl: pctrl at fca09000 {
+		compatible = "hisilicon,pctrl";
+		reg = <0xfca09000 0x1000>;
+	};
Documentation/devicetree/bindings/clock/hi3620-clock.txt +1 -0
index 4b71ab41be53..dad6269f52c5 100644
@@ -7,6 +7,7 @@ Required Properties:
 
 - compatible: should be one of the following.
   - "hisilicon,hi3620-clock" - controller compatible with Hi3620 SoC.
+  - "hisilicon,hi3620-mmc-clock" - controller specific for Hi3620 mmc.
 
 - reg: physical base address of the controller and length of memory mapped
   region.
drivers/clk/hisilicon/clk-hi3620.c +39 -0
index f24ad6a3a797..54cc3475ec36 100644
@@ -240,3 +240,270 @@ static void __init hi3620_clk_init(struct device_node *np)
 				   base);
 }
 CLK_OF_DECLARE(hi3620_clk, "hisilicon,hi3620-clock", hi3620_clk_init);
+
+struct hisi_mmc_clock {
+	unsigned int		id;
+	const char		*name;
+	const char		*parent_name;
+	unsigned long		flags;
+	u32			clken_reg;
+	u32			clken_bit;
+	u32			div_reg;
+	u32			div_off;
+	u32			div_bits;
+	u32			drv_reg;
+	u32			drv_off;
+	u32			drv_bits;
+	u32			sam_reg;
+	u32			sam_off;
+	u32			sam_bits;
+};
+
+struct clk_mmc {
+	struct clk_hw	hw;
+	u32		id;
+	void __iomem	*clken_reg;
+	u32		clken_bit;
+	void __iomem	*div_reg;
+	u32		div_off;
+	u32		div_bits;
+	void __iomem	*drv_reg;
+	u32		drv_off;
+	u32		drv_bits;
+	void __iomem	*sam_reg;
+	u32		sam_off;
+	u32		sam_bits;
+};
+
+#define to_mmc(_hw) container_of(_hw, struct clk_mmc, hw)
+
+static struct hisi_mmc_clock hi3620_mmc_clks[] __initdata = {
+	{ HI3620_SD_CIUCLK,	"sd_bclk1", "sd_clk", CLK_SET_RATE_PARENT, 0x1f8, 0, 0x1f8, 1, 3, 0x1f8, 4,

4, 0x1f8, 8, 4},

drivers/clk/hisilicon/clk-hi3620.c +1 -0
+	{ HI3620_MMC_CIUCLK1,   "mmc_bclk1", "mmc_clk1", CLK_SET_RATE_PARENT, 0x1f8, 12, 0x1f8, 13, 3,

0x1f8, 16, 4, 0x1f8, 20, 4},

drivers/clk/hisilicon/clk-hi3620.c +1 -0
+	{ HI3620_MMC_CIUCLK2,   "mmc_bclk2", "mmc_clk2", CLK_SET_RATE_PARENT, 0x1f8, 24, 0x1f8, 25, 3,

0x1f8, 28, 4, 0x1fc, 0, 4},

drivers/clk/hisilicon/clk-hi3620.c +1 -0
+	{ HI3620_MMC_CIUCLK3,   "mmc_bclk3", "mmc_clk3", CLK_SET_RATE_PARENT, 0x1fc, 4, 0x1fc, 5, 3,

0x1fc, 8, 4, 0x1fc, 12, 4},

drivers/clk/hisilicon/clk-hi3620.c +225 -0
+};
+
+static unsigned long mmc_clk_recalc_rate(struct clk_hw *hw,
+		       unsigned long parent_rate)
+{
+	switch (parent_rate) {
+	case 26000000:
+		return 13000000;
+	case 180000000:
+		return 25000000;
+	case 360000000:
+		return 50000000;
+	case 720000000:
+		return 100000000;
+	default:
+		return parent_rate;
+	}
+}
+
+static long mmc_clk_determine_rate(struct clk_hw *hw, unsigned long rate,
+			      unsigned long *best_parent_rate,
+			      struct clk **best_parent_p)
+{
+	struct clk_mmc *mclk = to_mmc(hw);
+	unsigned long best = 0;
+
+	if ((rate <= 13000000) && (mclk->id == HI3620_MMC_CIUCLK1)) {
+		rate = 13000000;
+		best = 26000000;
+	} else if (rate <= 26000000) {
+		rate = 25000000;
+		best = 180000000;
+	} else if (rate <= 52000000) {
+		rate = 50000000;
+		best = 360000000;
+	} else if (rate <= 100000000) {
+		rate = 100000000;
+		best = 720000000;
+	} else {
+		/* max is 180M */
+		rate = 180000000;
+		best = 1440000000;
+	}
+	*best_parent_rate = best;
+	return rate;
+}
+
+static u32 mmc_clk_delay(u32 val, u32 para, u32 off, u32 len)
+{
+	u32 i;
+
+	if (para >= 0) {
+		for (i = 0; i < len; i++) {
+			if (para % 2)
+				val |= 1 << (off + i);
+			else
+				val &= ~(1 << (off + i));
+			para = para >> 1;
+		}
+	}
+	return val;
+}
+
+static int mmc_clk_set_timing(struct clk_hw *hw, unsigned long rate)
+{
+	struct clk_mmc *mclk = to_mmc(hw);
+	unsigned long flags;
+	u32 sam, drv, div, val;
+	static DEFINE_SPINLOCK(mmc_clk_lock);
+
+	switch (rate) {
+	case 13000000:
+		sam = 3;
+		drv = 1;
+		div = 1;
+		break;
+	case 25000000:
+		sam = 13;
+		drv = 6;
+		div = 6;
+		break;
+	case 50000000:
+		sam = 3;
+		drv = 6;
+		div = 6;
+		break;
+	case 100000000:
+		sam = 6;
+		drv = 4;
+		div = 6;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	spin_lock_irqsave(&mmc_clk_lock, flags);
+
+	val = readl_relaxed(mclk->clken_reg);
+	val &= ~(1 << mclk->clken_bit);
+	writel_relaxed(val, mclk->clken_reg);
+
+	val = readl_relaxed(mclk->sam_reg);
+	val = mmc_clk_delay(val, sam, mclk->sam_off, mclk->sam_bits);
+	writel_relaxed(val, mclk->sam_reg);
+
+	val = readl_relaxed(mclk->drv_reg);
+	val = mmc_clk_delay(val, drv, mclk->drv_off, mclk->drv_bits);
+	writel_relaxed(val, mclk->drv_reg);
+
+	val = readl_relaxed(mclk->div_reg);
+	val = mmc_clk_delay(val, div, mclk->div_off, mclk->div_bits);
+	writel_relaxed(val, mclk->div_reg);
+
+	val = readl_relaxed(mclk->clken_reg);
+	val |= 1 << mclk->clken_bit;
+	writel_relaxed(val, mclk->clken_reg);
+
+	spin_unlock_irqrestore(&mmc_clk_lock, flags);
+
+	return 0;
+}
+
+static int mmc_clk_prepare(struct clk_hw *hw)
+{
+	struct clk_mmc *mclk = to_mmc(hw);
+	unsigned long rate;
+
+	if (mclk->id == HI3620_MMC_CIUCLK1)
+		rate = 13000000;
+	else
+		rate = 25000000;
+
+	return mmc_clk_set_timing(hw, rate);
+}
+
+static int mmc_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+			     unsigned long parent_rate)
+{
+	return mmc_clk_set_timing(hw, rate);
+}
+
+static struct clk_ops clk_mmc_ops = {
+	.prepare = mmc_clk_prepare,
+	.determine_rate = mmc_clk_determine_rate,
+	.set_rate = mmc_clk_set_rate,
+	.recalc_rate = mmc_clk_recalc_rate,
+};
+
+static struct clk *hisi_register_clk_mmc(struct hisi_mmc_clock *mmc_clk,
+			void __iomem *base, struct device_node *np)
+{
+	struct clk_mmc *mclk;
+	struct clk *clk;
+	struct clk_init_data init;
+
+	mclk = kzalloc(sizeof(*mclk), GFP_KERNEL);
+	if (!mclk) {
+		pr_err("%s: fail to allocate mmc clk\n", __func__);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	init.name = mmc_clk->name;
+	init.ops = &clk_mmc_ops;
+	init.flags = mmc_clk->flags | CLK_IS_BASIC;
+	init.parent_names = (mmc_clk->parent_name ? &mmc_clk->parent_name : NULL);
+	init.num_parents = (mmc_clk->parent_name ? 1 : 0);
+	mclk->hw.init = &init;
+
+	mclk->id = mmc_clk->id;
+	mclk->clken_reg = base + mmc_clk->clken_reg;
+	mclk->clken_bit = mmc_clk->clken_bit;
+	mclk->div_reg = base + mmc_clk->div_reg;
+	mclk->div_off = mmc_clk->div_off;
+	mclk->div_bits = mmc_clk->div_bits;
+	mclk->drv_reg = base + mmc_clk->drv_reg;
+	mclk->drv_off = mmc_clk->drv_off;
+	mclk->drv_bits = mmc_clk->drv_bits;
+	mclk->sam_reg = base + mmc_clk->sam_reg;
+	mclk->sam_off = mmc_clk->sam_off;
+	mclk->sam_bits = mmc_clk->sam_bits;
+
+	clk = clk_register(NULL, &mclk->hw);
+	if (WARN_ON(IS_ERR(clk)))
+		kfree(mclk);
+	return clk;
+}
+
+static void __init hi3620_mmc_clk_init(struct device_node *node)
+{
+	void __iomem *base;
+	int i, num = ARRAY_SIZE(hi3620_mmc_clks);
+	struct clk_onecell_data *clk_data;
+
+	if (!node) {
+		pr_err("failed to find pctrl node in DTS\n");
+		return;
+	}
+
+	base = of_iomap(node, 0);
+	if (!base) {
+		pr_err("failed to map pctrl\n");
+		return;
+	}
+
+	clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
+	if (WARN_ON(!clk_data))
+		return;
+
+	clk_data->clks = kzalloc(sizeof(struct clk *) * num, GFP_KERNEL);
+	if (!clk_data->clks) {
+		pr_err("%s: fail to allocate mmc clk\n", __func__);
+		return;
+	}
+
+	for (i = 0; i < num; i++) {
+		struct hisi_mmc_clock *mmc_clk = &hi3620_mmc_clks[i];
+		clk_data->clks[mmc_clk->id] =
+			hisi_register_clk_mmc(mmc_clk, base, node);
+	}
+
+	clk_data->clk_num = num;
+	of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+}
+
+CLK_OF_DECLARE(hi3620_mmc_clk, "hisilicon,hi3620-mmc-clock", hi3620_mmc_clk_init);
include/dt-bindings/clock/hi3620-clock.h +5 -1
index 6eaa6a45e110..21b9d0e2eb0c 100644
@@ -147,6 +147,11 @@
 #define HI3620_MMC_CLK3		217
 #define HI3620_MCU_CLK		218
 
+#define HI3620_SD_CIUCLK	0
+#define HI3620_MMC_CIUCLK1	1
+#define HI3620_MMC_CIUCLK2	2
+#define HI3620_MMC_CIUCLK3	3
+
 #define HI3620_NR_CLKS		219
 
 #endif	/* __DTS_HI3620_CLOCK_H */
--

1.7.9.5

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

author
#7 lore raw

PATCH 1/2 clk: hisilicon: add hi3620_mmc_clks

Quoted 5 lines · Seungwon Jeon
Quoted 4 lines · Zhangfei Gao

Suggest by Arnd: abstract mmc tuning as clock behavior, also because different soc have different tuning method and registers. hi3620_mmc_clks is added to handle mmc clock specifically on hi3620.

Quoted 9 lines
Quoted 3 lines

I add my ack.
Please run 'checkpatch' and remove some warnings.

Thanks Seungwon.

Have checked before, and ignoring warnings of "line over 80 characters" seems more neat.

Thanks

#8 lore raw

PATCH 1/2 clk: hisilicon: add hi3620_mmc_clks

In reply to Zhangfei Gao

Quoting Zhangfei Gao (2014-01-13 01:14:28)

Quoted 7 lines

Suggest by Arnd: abstract mmc tuning as clock behavior, also because different soc have different tuning method and registers. hi3620_mmc_clks is added to handle mmc clock specifically on hi3620.

Patch looks good to me with one exception. I do not have Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt in the clk-next branch. Is there a stable branch I can pull in as a dependency?

Thanks,
Mike

Quoted 335 lines
---
 .../bindings/arm/hisilicon/hisilicon.txt           |   14 +
 .../devicetree/bindings/clock/hi3620-clock.txt     |    1 +
 drivers/clk/hisilicon/clk-hi3620.c                 |  267 ++++++++++++++++++++
 include/dt-bindings/clock/hi3620-clock.h           |    5 +
 4 files changed, 287 insertions(+)
Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt +14 -0
index 8c7a4653508d..df0a452b8526 100644
@@ -30,3 +30,17 @@ Example:
                resume-offset = <0x308>;
                reboot-offset = <0x4>;
        };
+
+PCTRL: Peripheral misc control register
+
+Required Properties:
+- compatible: "hisilicon,pctrl"
+- reg: Address and size of pctrl.
+
+Example:
+
+       /* for Hi3620 */
+       pctrl: pctrl at fca09000 {
+               compatible = "hisilicon,pctrl";
+               reg = <0xfca09000 0x1000>;
+       };
Documentation/devicetree/bindings/clock/hi3620-clock.txt +1 -0
index 4b71ab41be53..dad6269f52c5 100644
@@ -7,6 +7,7 @@ Required Properties:
 
 - compatible: should be one of the following.
   - "hisilicon,hi3620-clock" - controller compatible with Hi3620 SoC.
+  - "hisilicon,hi3620-mmc-clock" - controller specific for Hi3620 mmc.
 
 - reg: physical base address of the controller and length of memory mapped
   region.
drivers/clk/hisilicon/clk-hi3620.c +267 -0
index f24ad6a3a797..54cc3475ec36 100644
@@ -240,3 +240,270 @@ static void __init hi3620_clk_init(struct device_node *np)
                                   base);
 }
 CLK_OF_DECLARE(hi3620_clk, "hisilicon,hi3620-clock", hi3620_clk_init);
+
+struct hisi_mmc_clock {
+       unsigned int            id;
+       const char              *name;
+       const char              *parent_name;
+       unsigned long           flags;
+       u32                     clken_reg;
+       u32                     clken_bit;
+       u32                     div_reg;
+       u32                     div_off;
+       u32                     div_bits;
+       u32                     drv_reg;
+       u32                     drv_off;
+       u32                     drv_bits;
+       u32                     sam_reg;
+       u32                     sam_off;
+       u32                     sam_bits;
+};
+
+struct clk_mmc {
+       struct clk_hw   hw;
+       u32             id;
+       void __iomem    *clken_reg;
+       u32             clken_bit;
+       void __iomem    *div_reg;
+       u32             div_off;
+       u32             div_bits;
+       void __iomem    *drv_reg;
+       u32             drv_off;
+       u32             drv_bits;
+       void __iomem    *sam_reg;
+       u32             sam_off;
+       u32             sam_bits;
+};
+
+#define to_mmc(_hw) container_of(_hw, struct clk_mmc, hw)
+
+static struct hisi_mmc_clock hi3620_mmc_clks[] __initdata = {
+       { HI3620_SD_CIUCLK,     "sd_bclk1", "sd_clk", CLK_SET_RATE_PARENT, 0x1f8, 0, 0x1f8, 1, 3, 0x1f8, 4, 4, 0x1f8, 8, 4},
+       { HI3620_MMC_CIUCLK1,   "mmc_bclk1", "mmc_clk1", CLK_SET_RATE_PARENT, 0x1f8, 12, 0x1f8, 13, 3, 0x1f8, 16, 4, 0x1f8, 20, 4},
+       { HI3620_MMC_CIUCLK2,   "mmc_bclk2", "mmc_clk2", CLK_SET_RATE_PARENT, 0x1f8, 24, 0x1f8, 25, 3, 0x1f8, 28, 4, 0x1fc, 0, 4},
+       { HI3620_MMC_CIUCLK3,   "mmc_bclk3", "mmc_clk3", CLK_SET_RATE_PARENT, 0x1fc, 4, 0x1fc, 5, 3, 0x1fc, 8, 4, 0x1fc, 12, 4},
+};
+
+static unsigned long mmc_clk_recalc_rate(struct clk_hw *hw,
+                      unsigned long parent_rate)
+{
+       switch (parent_rate) {
+       case 26000000:
+               return 13000000;
+       case 180000000:
+               return 25000000;
+       case 360000000:
+               return 50000000;
+       case 720000000:
+               return 100000000;
+       default:
+               return parent_rate;
+       }
+}
+
+static long mmc_clk_determine_rate(struct clk_hw *hw, unsigned long rate,
+                             unsigned long *best_parent_rate,
+                             struct clk **best_parent_p)
+{
+       struct clk_mmc *mclk = to_mmc(hw);
+       unsigned long best = 0;
+
+       if ((rate <= 13000000) && (mclk->id == HI3620_MMC_CIUCLK1)) {
+               rate = 13000000;
+               best = 26000000;
+       } else if (rate <= 26000000) {
+               rate = 25000000;
+               best = 180000000;
+       } else if (rate <= 52000000) {
+               rate = 50000000;
+               best = 360000000;
+       } else if (rate <= 100000000) {
+               rate = 100000000;
+               best = 720000000;
+       } else {
+               /* max is 180M */
+               rate = 180000000;
+               best = 1440000000;
+       }
+       *best_parent_rate = best;
+       return rate;
+}
+
+static u32 mmc_clk_delay(u32 val, u32 para, u32 off, u32 len)
+{
+       u32 i;
+
+       if (para >= 0) {
+               for (i = 0; i < len; i++) {
+                       if (para % 2)
+                               val |= 1 << (off + i);
+                       else
+                               val &= ~(1 << (off + i));
+                       para = para >> 1;
+               }
+       }
+       return val;
+}
+
+static int mmc_clk_set_timing(struct clk_hw *hw, unsigned long rate)
+{
+       struct clk_mmc *mclk = to_mmc(hw);
+       unsigned long flags;
+       u32 sam, drv, div, val;
+       static DEFINE_SPINLOCK(mmc_clk_lock);
+
+       switch (rate) {
+       case 13000000:
+               sam = 3;
+               drv = 1;
+               div = 1;
+               break;
+       case 25000000:
+               sam = 13;
+               drv = 6;
+               div = 6;
+               break;
+       case 50000000:
+               sam = 3;
+               drv = 6;
+               div = 6;
+               break;
+       case 100000000:
+               sam = 6;
+               drv = 4;
+               div = 6;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       spin_lock_irqsave(&mmc_clk_lock, flags);
+
+       val = readl_relaxed(mclk->clken_reg);
+       val &= ~(1 << mclk->clken_bit);
+       writel_relaxed(val, mclk->clken_reg);
+
+       val = readl_relaxed(mclk->sam_reg);
+       val = mmc_clk_delay(val, sam, mclk->sam_off, mclk->sam_bits);
+       writel_relaxed(val, mclk->sam_reg);
+
+       val = readl_relaxed(mclk->drv_reg);
+       val = mmc_clk_delay(val, drv, mclk->drv_off, mclk->drv_bits);
+       writel_relaxed(val, mclk->drv_reg);
+
+       val = readl_relaxed(mclk->div_reg);
+       val = mmc_clk_delay(val, div, mclk->div_off, mclk->div_bits);
+       writel_relaxed(val, mclk->div_reg);
+
+       val = readl_relaxed(mclk->clken_reg);
+       val |= 1 << mclk->clken_bit;
+       writel_relaxed(val, mclk->clken_reg);
+
+       spin_unlock_irqrestore(&mmc_clk_lock, flags);
+
+       return 0;
+}
+
+static int mmc_clk_prepare(struct clk_hw *hw)
+{
+       struct clk_mmc *mclk = to_mmc(hw);
+       unsigned long rate;
+
+       if (mclk->id == HI3620_MMC_CIUCLK1)
+               rate = 13000000;
+       else
+               rate = 25000000;
+
+       return mmc_clk_set_timing(hw, rate);
+}
+
+static int mmc_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+                            unsigned long parent_rate)
+{
+       return mmc_clk_set_timing(hw, rate);
+}
+
+static struct clk_ops clk_mmc_ops = {
+       .prepare = mmc_clk_prepare,
+       .determine_rate = mmc_clk_determine_rate,
+       .set_rate = mmc_clk_set_rate,
+       .recalc_rate = mmc_clk_recalc_rate,
+};
+
+static struct clk *hisi_register_clk_mmc(struct hisi_mmc_clock *mmc_clk,
+                       void __iomem *base, struct device_node *np)
+{
+       struct clk_mmc *mclk;
+       struct clk *clk;
+       struct clk_init_data init;
+
+       mclk = kzalloc(sizeof(*mclk), GFP_KERNEL);
+       if (!mclk) {
+               pr_err("%s: fail to allocate mmc clk\n", __func__);
+               return ERR_PTR(-ENOMEM);
+       }
+
+       init.name = mmc_clk->name;
+       init.ops = &clk_mmc_ops;
+       init.flags = mmc_clk->flags | CLK_IS_BASIC;
+       init.parent_names = (mmc_clk->parent_name ? &mmc_clk->parent_name : NULL);
+       init.num_parents = (mmc_clk->parent_name ? 1 : 0);
+       mclk->hw.init = &init;
+
+       mclk->id = mmc_clk->id;
+       mclk->clken_reg = base + mmc_clk->clken_reg;
+       mclk->clken_bit = mmc_clk->clken_bit;
+       mclk->div_reg = base + mmc_clk->div_reg;
+       mclk->div_off = mmc_clk->div_off;
+       mclk->div_bits = mmc_clk->div_bits;
+       mclk->drv_reg = base + mmc_clk->drv_reg;
+       mclk->drv_off = mmc_clk->drv_off;
+       mclk->drv_bits = mmc_clk->drv_bits;
+       mclk->sam_reg = base + mmc_clk->sam_reg;
+       mclk->sam_off = mmc_clk->sam_off;
+       mclk->sam_bits = mmc_clk->sam_bits;
+
+       clk = clk_register(NULL, &mclk->hw);
+       if (WARN_ON(IS_ERR(clk)))
+               kfree(mclk);
+       return clk;
+}
+
+static void __init hi3620_mmc_clk_init(struct device_node *node)
+{
+       void __iomem *base;
+       int i, num = ARRAY_SIZE(hi3620_mmc_clks);
+       struct clk_onecell_data *clk_data;
+
+       if (!node) {
+               pr_err("failed to find pctrl node in DTS\n");
+               return;
+       }
+
+       base = of_iomap(node, 0);
+       if (!base) {
+               pr_err("failed to map pctrl\n");
+               return;
+       }
+
+       clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
+       if (WARN_ON(!clk_data))
+               return;
+
+       clk_data->clks = kzalloc(sizeof(struct clk *) * num, GFP_KERNEL);
+       if (!clk_data->clks) {
+               pr_err("%s: fail to allocate mmc clk\n", __func__);
+               return;
+       }
+
+       for (i = 0; i < num; i++) {
+               struct hisi_mmc_clock *mmc_clk = &hi3620_mmc_clks[i];
+               clk_data->clks[mmc_clk->id] =
+                       hisi_register_clk_mmc(mmc_clk, base, node);
+       }
+
+       clk_data->clk_num = num;
+       of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+}
+
+CLK_OF_DECLARE(hi3620_mmc_clk, "hisilicon,hi3620-mmc-clock", hi3620_mmc_clk_init);
include/dt-bindings/clock/hi3620-clock.h +5 -0
index 6eaa6a45e110..21b9d0e2eb0c 100644
@@ -147,6 +147,11 @@
 #define HI3620_MMC_CLK3                217
 #define HI3620_MCU_CLK         218
 
+#define HI3620_SD_CIUCLK       0
+#define HI3620_MMC_CIUCLK1     1
+#define HI3620_MMC_CIUCLK2     2
+#define HI3620_MMC_CIUCLK3     3
+
 #define HI3620_NR_CLKS         219
 
 #endif /* __DTS_HI3620_CLOCK_H */
Signature · 1 line
1.7.9.5
author
#9 lore raw

PATCH 1/2 clk: hisilicon: add hi3620_mmc_clks

Dear Mike

Quoted 5 lines · Mike Turquette

Quoting Zhangfei Gao (2014-01-13 01:14:28)

Quoted 4 lines

Suggest by Arnd: abstract mmc tuning as clock behavior, also because different soc have different tuning method and registers. hi3620_mmc_clks is added to handle mmc clock specifically on hi3620.

Quoted 7 lines
Quoted 3 lines

Patch looks good to me with one exception. I do not have Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt in the clk-next branch. Is there a stable branch I can pull in as a dependency?

Mach-hisi just have been uploaeded.
Have tried next-20140114, the patch can be applied successfully. While v3.13-rc8 still can not.

Is this fine?

Thanks

#10 lore raw

PATCH 1/2 clk: hisilicon: add hi3620_mmc_clks

Quoting zhangfei (2014-01-14 17:40:25)

Quoted 16 lines

Dear Mike

Quoted 5 lines · Mike Turquette

Quoting Zhangfei Gao (2014-01-13 01:14:28)

Quoted 4 lines

Suggest by Arnd: abstract mmc tuning as clock behavior, also because different soc have different tuning method and registers. hi3620_mmc_clks is added to handle mmc clock specifically on hi3620.

Quoted 7 lines
Quoted 3 lines

Patch looks good to me with one exception. I do not have Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt in the clk-next branch. Is there a stable branch I can pull in as a dependency?

Quoted 5 lines

Mach-hisi just have been uploaeded.
Have tried next-20140114, the patch can be applied successfully. While v3.13-rc8 still can not.

Is this fine?

Can you give me a link to the branch that introduces Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt?

I guess the patch introducing it is going through arm-soc. Is this going in for 3.14? If so then perhaps the clk tree and the arm-soc tree can share a stable branch that introduces it.

Regards,
Mike

Quoted 2 lines

Thanks

#11 lore raw

PATCH 1/2 clk: hisilicon: add hi3620_mmc_clks

Quoted 23 lines · Mike Turquette

Quoting zhangfei (2014-01-14 17:40:25)

Quoted 11 lines

Dear Mike

Quoted 8 lines · Mike Turquette

Quoting Zhangfei Gao (2014-01-13 01:14:28)

Quoted 7 lines

Suggest by Arnd: abstract mmc tuning as clock behavior, also because different soc have different tuning method and registers. hi3620_mmc_clks is added to handle mmc clock specifically on hi3620.

Quoted 8 lines
Quoted 3 lines

Patch looks good to me with one exception. I do not have Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt in the clk-next branch. Is there a stable branch I can pull in as a dependency?

Mach-hisi just have been uploaeded.
Have tried next-20140114, the patch can be applied successfully. While v3.13-rc8 still can not.

Is this fine?

Can you give me a link to the branch that introduces Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt?

Quoted 7 lines

I guess the patch introducing it is going through arm-soc. Is this going in for 3.14? If so then perhaps the clk tree and the arm-soc tree can share a stable branch that introduces it.

Regards,
Mike

Some patches are merged into arm-soc, and others are in clk tree. If sharing a stable branch between arm-soc and clk tree, it only means that we need to revert all commits that are in arm-soc and clk tree. I think it's too complex.

How about split the patch? The patch on document should enter in arm-soc.

Regards
Haojian

#12 lore raw

PATCH 1/2 clk: hisilicon: add hi3620_mmc_clks

Quoting Haojian Zhuang (2014-01-14 21:59:40)

Quoted 29 lines · Mike Turquette
Quoted 27 lines

Quoting zhangfei (2014-01-14 17:40:25)

Quoted 11 lines

Dear Mike

Quoted 8 lines · Mike Turquette

Quoting Zhangfei Gao (2014-01-13 01:14:28)

Quoted 7 lines

Suggest by Arnd: abstract mmc tuning as clock behavior, also because different soc have different tuning method and registers. hi3620_mmc_clks is added to handle mmc clock specifically on hi3620.

Quoted 8 lines
Quoted 3 lines

Patch looks good to me with one exception. I do not have Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt in the clk-next branch. Is there a stable branch I can pull in as a dependency?

Mach-hisi just have been uploaeded.
Have tried next-20140114, the patch can be applied successfully. While v3.13-rc8 still can not.

Is this fine?

Can you give me a link to the branch that introduces Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt?

I guess the patch introducing it is going through arm-soc. Is this going in for 3.14? If so then perhaps the clk tree and the arm-soc tree can share a stable branch that introduces it.

Quoted 7 lines
Quoted 3 lines

Regards,
Mike

Some patches are merged into arm-soc, and others are in clk tree. If sharing a stable branch between arm-soc and clk tree, it only means that we need to revert all commits that are in arm-soc and clk tree. I think it's too complex.

I'm suggesting reverting any patches that are applied to arm-soc. I'm only suggesting that there might be a common branch that both the clk and arm-soc trees can depend on to fix this problem.

Quoted 2 lines

How about split the patch? The patch on document should enter in arm-soc.

That is one approach. You might want to run it past the arm-soc folks first to see if they will take in the binding definition for 3.14.

Regards,
Mike

Quoted 3 lines

Regards
Haojian

#13 lore raw

PATCH 1/2 clk: hisilicon: add hi3620_mmc_clks

Quoted 40 lines · Mike Turquette

Quoting Haojian Zhuang (2014-01-14 21:59:40)

Quoted 28 lines · Mike Turquette
Quoted 27 lines

Quoting zhangfei (2014-01-14 17:40:25)

Quoted 11 lines

Dear Mike

Quoted 8 lines · Mike Turquette

Quoting Zhangfei Gao (2014-01-13 01:14:28)

Quoted 7 lines

Suggest by Arnd: abstract mmc tuning as clock behavior, also because different soc have different tuning method and registers. hi3620_mmc_clks is added to handle mmc clock specifically on hi3620.

Quoted 8 lines
Quoted 3 lines

Patch looks good to me with one exception. I do not have Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt in the clk-next branch. Is there a stable branch I can pull in as a dependency?

Mach-hisi just have been uploaeded.
Have tried next-20140114, the patch can be applied successfully. While v3.13-rc8 still can not.

Is this fine?

Can you give me a link to the branch that introduces Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt?

I guess the patch introducing it is going through arm-soc. Is this going in for 3.14? If so then perhaps the clk tree and the arm-soc tree can share a stable branch that introduces it.

Quoted 7 lines
Quoted 3 lines

Regards,
Mike

Some patches are merged into arm-soc, and others are in clk tree. If sharing a stable branch between arm-soc and clk tree, it only means that we need to revert all commits that are in arm-soc and clk tree. I think it's too complex.

I'm suggesting reverting any patches that are applied to arm-soc. I'm only suggesting that there might be a common branch that both the clk and arm-soc trees can depend on to fix this problem.

Quoted 7 lines
Quoted 1 line

How about split the patch? The patch on document should enter in arm-soc.

That is one approach. You might want to run it past the arm-soc folks first to see if they will take in the binding definition for 3.14.

Regards,
Mike

Yes, so I already made Kevin in this loop. Let's see whether he has any comments on it.

Regards
Haojian

#14 lore raw

PATCH 1/2 clk: hisilicon: add hi3620_mmc_clks

In reply to Mike Turquette
Quoted 33 lines · Mike Turquette

Quoting Haojian Zhuang (2014-01-14 21:59:40)

Quoted 32 lines · Mike Turquette
Quoted 30 lines

Quoting zhangfei (2014-01-14 17:40:25)

Quoted 11 lines

Dear Mike

Quoted 8 lines · Mike Turquette

Quoting Zhangfei Gao (2014-01-13 01:14:28)

Quoted 7 lines

Suggest by Arnd: abstract mmc tuning as clock behavior, also because different soc have different tuning method and registers. hi3620_mmc_clks is added to handle mmc clock specifically on hi3620.

Quoted 8 lines
Quoted 3 lines

Patch looks good to me with one exception. I do not have Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt in the clk-next branch. Is there a stable branch I can pull in as a dependency?

Mach-hisi just have been uploaeded.
Have tried next-20140114, the patch can be applied successfully. While v3.13-rc8 still can not.

Is this fine?

Can you give me a link to the branch that introduces Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt?

I guess the patch introducing it is going through arm-soc. Is this going in for 3.14? If so then perhaps the clk tree and the arm-soc tree can share a stable branch that introduces it.

Regards,
Mike

Quoted 8 lines
Quoted 4 lines

Some patches are merged into arm-soc, and others are in clk tree. If sharing a stable branch between arm-soc and clk tree, it only means that we need to revert all commits that are in arm-soc and clk tree. I think it's too complex.

I'm suggesting reverting any patches that are applied to arm-soc. I'm only suggesting that there might be a common branch that both the clk and arm-soc trees can depend on to fix this problem.

This one is stable, and is where the binding is introduced:

git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc.git hisi/soc

Quoted 4 lines
Quoted 1 line

How about split the patch? The patch on document should enter in arm-soc.

That is one approach. You might want to run it past the arm-soc folks first to see if they will take in the binding definition for 3.14.

We're not taking anything new for 3.14.

Kevin

#15 lore raw

PATCH 2/2 mmc: dw_mmc: k3: remove clk_table

In reply to Zhangfei Gao

Remove clk_table and directly use ios->clock as clock source rate. Abstract init clock rate and max clock limitation in clk.c

---
 .../devicetree/bindings/mmc/k3-dw-mshc.txt         |   14 -------
 drivers/mmc/host/dw_mmc-k3.c                       |   41 +-------------------
 2 files changed, 2 insertions(+), 53 deletions(-)
Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt +0 -14
index d7e2d7f159bb..b8653ea97957 100644
@@ -14,18 +14,6 @@ Required Properties:
 * compatible: should be one of the following.
   - "hisilicon,hi4511-dw-mshc": for controllers with hi4511 specific extentions.
 
-* clock-freq-table: should be the frequency (in Hz) array of the ciu clock
-	in each	supported mode.
-	0. CIU clock rate in Hz for DS mode
-	1. CIU clock rate in Hz for MMC HS mode
-	2. CIU clock rate in Hz for SD HS mode
-	3. CIU clock rate in Hz for SDR12 mode
-	4. CIU clock rate in Hz for SDR25 mode
-	5. CIU clock rate in Hz for SDR50 mode
-	6. CIU clock rate in Hz for SDR104 mode
-	7. CIU clock rate in Hz for DDR50 mode
-	8. CIU clock rate in Hz for HS200 mode
-
 Example:
 
 	/* for Hi3620 */
@@ -39,8 +27,6 @@ Example:
 		#size-cells = <0>;
 		clocks = <&mmc_clock HI3620_SD_CIUCLK>, <&clock HI3620_DDRC_PER_CLK>;
 		clock-names = "ciu", "biu";
-		clock-freq-table =
-		<25000000 0 50000000 25000000 50000000 100000000 0 50000000>;
 	};
 
 	/* Board portion */
drivers/mmc/host/dw_mmc-k3.c +2 -39

58 lines not on this page · raw message

Signature · 1 line
1.7.9.5
#17 lore raw

PATCH 2/2 mmc: dw_mmc: k3: remove clk_table

Hi,

Quoted 7 lines · Seungwon Jeon
Quoted 4 lines · Zhangfei Gao

Remove clk_table and directly use ios->clock as clock source rate. Abstract init clock rate and max clock limitation in clk.c

It looks like patch 1/2 did not make 3.14. Do you want me to take this patch for 3.14 anyway? (Why?)

Thanks,

- Chris.

Signature · 1 line
Chris Ball   <[email protected]>   <http://printf.net/>
#18 lore raw

PATCH 2/2 mmc: dw_mmc: k3: remove clk_table

Quoted 8 lines · Chris Ball

Hi,

Quoted 4 lines · Seungwon Jeon
Quoted 3 lines · Zhangfei Gao

Remove clk_table and directly use ios->clock as clock source rate. Abstract init clock rate and max clock limitation in clk.c

Quoted 6 lines
Quoted 3 lines
Quoted 1 line

It looks like patch 1/2 did not make 3.14. Do you want me to take this patch for 3.14 anyway? (Why?)

Yes, I hope that it would be merged this time.
I think that this change should have been applied to (036f29: mmc:
dw_mmc: add dw_mmc-k3 for k3 platform) originally.

Thanks,
sw-j

#19 lore raw

PATCH 2/2 mmc: dw_mmc: k3: remove clk_table

Quoting Seungwon Jeon (2014-01-17 08:10:23)

Quoted 11 lines · Chris Ball
Quoted 10 lines

Hi,

Quoted 6 lines · Seungwon Jeon
Quoted 4 lines · Zhangfei Gao

Remove clk_table and directly use ios->clock as clock source rate. Abstract init clock rate and max clock limitation in clk.c

Quoted 7 lines
Quoted 4 lines
Quoted 1 line

It looks like patch 1/2 did not make 3.14. Do you want me to take this patch for 3.14 anyway? (Why?)

Yes, I hope that it would be merged this time.
I think that this change should have been applied to (036f29: mmc:
dw_mmc: add dw_mmc-k3 for k3 platform) originally.

Oops, I just read this mail. I have taken in patch #1 through the clk tree but have not yet pushed it out to my public mirror.

Chris, I'm happy to take it if you haven't yet.

Regards,
Mike

Quoted 3 lines

Thanks,
sw-j

#20 lore raw

PATCH 2/2 mmc: dw_mmc: k3: remove clk_table

Hi Mike,

Quoted 4 lines · Mike Turquette

Oops, I just read this mail. I have taken in patch #1 through the clk tree but have not yet pushed it out to my public mirror.

Chris, I'm happy to take it if you haven't yet.

That's fine. I'd like to take 2/2, just pushed it to mmc-next for 3.14.

Thanks,

- Chris.

Signature · 1 line
Chris Ball   <[email protected]>   <http://printf.net/>