mmc: dw_mmc: k3 remove clk_table
Subsystems (4)
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
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
@@ -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
@@ -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
@@ -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
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
@@ -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
@@ -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
@@ -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
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_clksis added to handle mmc clock specifically on hi3620.Signed-off-by Zhangfei Gao <[email protected]>Acked-by Arnd Bergmann <[email protected]>Acked-by Jaehoon Chung <[email protected]>
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@@ -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@@ -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@@ -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@@ -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
PATCH 1/2 clk: hisilicon: add hi3620_mmc_clks
In reply to Zhangfei GaoQuoted 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_clksis added to handle mmc clock specifically on hi3620.Signed-off-by Zhangfei Gao <[email protected]>Acked-by Arnd Bergmann <[email protected]>Acked-by Jaehoon Chung <[email protected]>--- .../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@@ -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@@ -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@@ -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@@ -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
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_CIUCLK2andHI3620_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_CIUCLKwas 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 ofHI3620_MMC_CIUCLK2andHI3620_MMC_CIUCLK3as well.
Only HI3620_MMC_CIUCLK1 use 13M for init, all others use 25M on hi3620.
Quoted 11 lines
Thanks,
Seungwon Jeondrivers/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
PATCH 1/2 clk: hisilicon: add hi3620_mmc_clks
In reply to Zhangfei GaoQuoted 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_clksis added to handle mmc clock specifically on hi3620.Signed-off-by Zhangfei Gao <[email protected]>Acked-by Arnd Bergmann <[email protected]>Acked-by Jaehoon Chung <[email protected]>
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@@ -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@@ -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@@ -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@@ -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
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_clksis added to handle mmc clock specifically on hi3620.
Quoted 9 lines
Quoted 3 lines
Signed-off-by Zhangfei Gao <[email protected]>Acked-by Arnd Bergmann <[email protected]>Acked-by Jaehoon Chung <[email protected]>I add my ack.
Please run 'checkpatch' and remove some warnings.Acked-by Seungwon Jeon <[email protected]>
Thanks Seungwon.
Have checked before, and ignoring warnings of "line over 80 characters" seems more neat.
Thanks
PATCH 1/2 clk: hisilicon: add hi3620_mmc_clks
In reply to Zhangfei GaoQuoting 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_clksis added to handle mmc clock specifically on hi3620.Signed-off-by Zhangfei Gao <[email protected]>Acked-by Arnd Bergmann <[email protected]>Acked-by Jaehoon Chung <[email protected]>
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@@ -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@@ -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@@ -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@@ -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
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_clksis added to handle mmc clock specifically on hi3620.
Quoted 7 lines
Quoted 3 lines
Signed-off-by Zhangfei Gao <[email protected]>Acked-by Arnd Bergmann <[email protected]>Acked-by Jaehoon Chung <[email protected]>Patch looks good to me with one exception. I do not have
Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txtin 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
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_clksis added to handle mmc clock specifically on hi3620.Quoted 7 lines
Quoted 3 lines
Signed-off-by Zhangfei Gao <[email protected]>Acked-by Arnd Bergmann <[email protected]>Acked-by Jaehoon Chung <[email protected]>Patch looks good to me with one exception. I do not have
Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txtin 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
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_clksis added to handle mmc clock specifically on hi3620.Signed-off-by Zhangfei Gao <[email protected]>Acked-by Arnd Bergmann <[email protected]>Acked-by Jaehoon Chung <[email protected]>Quoted 8 lines
Quoted 3 lines
Patch looks good to me with one exception. I do not have
Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txtin 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
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_clksis added to handle mmc clock specifically on hi3620.Signed-off-by Zhangfei Gao <[email protected]>Acked-by Arnd Bergmann <[email protected]>Acked-by Jaehoon Chung <[email protected]>Quoted 8 lines
Quoted 3 lines
Patch looks good to me with one exception. I do not have
Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txtin 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,
MikeSome 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
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_clksis added to handle mmc clock specifically on hi3620.Signed-off-by Zhangfei Gao <[email protected]>Acked-by Arnd Bergmann <[email protected]>Acked-by Jaehoon Chung <[email protected]>Quoted 8 lines
Quoted 3 lines
Patch looks good to me with one exception. I do not have
Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txtin 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,
MikeSome 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
PATCH 1/2 clk: hisilicon: add hi3620_mmc_clks
In reply to Mike TurquetteQuoted 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_clksis added to handle mmc clock specifically on hi3620.Signed-off-by Zhangfei Gao <[email protected]>Acked-by Arnd Bergmann <[email protected]>Acked-by Jaehoon Chung <[email protected]>Quoted 8 lines
Quoted 3 lines
Patch looks good to me with one exception. I do not have
Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txtin 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
PATCH 2/2 mmc: dw_mmc: k3: remove clk_table
In reply to Zhangfei GaoRemove 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
@@ -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
PATCH 2/2 mmc: dw_mmc: k3: remove clk_table
Quoted 4 lines · Zhangfei Gao
Remove
clk_tableand directly useios->clockas clock source rate. Abstract init clock rate and max clock limitation inclk.cSigned-off-by Zhangfei Gao <[email protected]>
Thanks,
Seungwon Jeon
PATCH 2/2 mmc: dw_mmc: k3: remove clk_table
Hi,
Quoted 7 lines · Seungwon Jeon
Quoted 4 lines · Zhangfei Gao
Remove
clk_tableand directly useios->clockas clock source rate. Abstract init clock rate and max clock limitation inclk.cSigned-off-by Zhangfei Gao <[email protected]>Acked-by Seungwon Jeon <[email protected]>
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/>
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_tableand directly useios->clockas clock source rate. Abstract init clock rate and max clock limitation inclk.c
Quoted 6 lines
Quoted 3 lines
Quoted 1 line
Signed-off-by Zhangfei Gao <[email protected]>Acked-by Seungwon Jeon <[email protected]>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
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_tableand directly useios->clockas clock source rate. Abstract init clock rate and max clock limitation inclk.cSigned-off-by Zhangfei Gao <[email protected]>
Quoted 7 lines
Quoted 4 lines
Quoted 1 line
Acked-by Seungwon Jeon <[email protected]>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
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/>
PATCH 2/2 mmc: dw_mmc: k3: remove clk_table
In reply to Zhangfei Gao+ Chris Ball (New e-mail)
Quoted 10 lines · Seungwon Jeon
Quoted 4 lines · Zhangfei Gao
Remove
clk_tableand directly useios->clockas clock source rate. Abstract init clock rate and max clock limitation inclk.cSigned-off-by Zhangfei Gao <[email protected]>Acked-by Seungwon Jeon <[email protected]>Thanks,
Seungwon Jeon