From f1a2879c1c57eb40747db3ff1b7b80cb9041e11b Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 25 Apr 2017 14:04:35 +0200 Subject: clk: renesas: Stop enabling legacy DT clock support by default Since v4.15-rc1, the DTS files for all R-Car Gen2 SoCs have been converted to the new CPG/MSSR bindings. Hence it is now safe to no longer enable legacy DT clock support by default. Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig index 43b5a89..84b40b9 100644 --- a/drivers/clk/renesas/Kconfig +++ b/drivers/clk/renesas/Kconfig @@ -24,12 +24,13 @@ if CLK_RENESAS config CLK_RENESAS_LEGACY bool "Legacy DT clock support" depends on CLK_R8A7790 || CLK_R8A7791 || CLK_R8A7792 || CLK_R8A7794 - default y help Enable backward compatibility with old device trees describing a hierarchical representation of the various CPG and MSTP clocks. Say Y if you want your kernel to work with old DTBs. + It is safe to say N if you use the DTS that is supplied with the + current kernel source tree. # SoC config CLK_EMEV2 -- cgit v1.1 From 3391891fa9c82fd14bcddec2f422299b57ce8091 Mon Sep 17 00:00:00 2001 From: Takeshi Kihara Date: Mon, 29 Jan 2018 19:01:49 +0100 Subject: clk: renesas: rcar-gen3: Add Z clock divider support This patch adds Z clock divider support for R-Car Gen3 SoC. Signed-off-by: Takeshi Kihara Signed-off-by: Simon Horman Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/rcar-gen3-cpg.c | 133 ++++++++++++++++++++++++++++++++++++ drivers/clk/renesas/rcar-gen3-cpg.h | 1 + 2 files changed, 134 insertions(+) diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c index 0904886..b85918f 100644 --- a/drivers/clk/renesas/rcar-gen3-cpg.c +++ b/drivers/clk/renesas/rcar-gen3-cpg.c @@ -13,6 +13,7 @@ */ #include +#include #include #include #include @@ -62,6 +63,134 @@ static void cpg_simple_notifier_register(struct raw_notifier_head *notifiers, } /* + * Z Clock + * + * Traits of this clock: + * prepare - clk_prepare only ensures that parents are prepared + * enable - clk_enable only ensures that parents are enabled + * rate - rate is adjustable. clk->rate = (parent->rate * mult / 32 ) / 2 + * parent - fixed parent. No clk_set_parent support + */ +#define CPG_FRQCRB 0x00000004 +#define CPG_FRQCRB_KICK BIT(31) +#define CPG_FRQCRC 0x000000e0 +#define CPG_FRQCRC_ZFC_MASK GENMASK(12, 8) + +struct cpg_z_clk { + struct clk_hw hw; + void __iomem *reg; + void __iomem *kick_reg; +}; + +#define to_z_clk(_hw) container_of(_hw, struct cpg_z_clk, hw) + +static unsigned long cpg_z_clk_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct cpg_z_clk *zclk = to_z_clk(hw); + unsigned int mult; + + mult = 32 - FIELD_GET(CPG_FRQCRC_ZFC_MASK, clk_readl(zclk->reg)); + + /* Factor of 2 is for fixed divider */ + return DIV_ROUND_CLOSEST_ULL((u64)parent_rate * mult, 32 * 2); +} + +static long cpg_z_clk_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *parent_rate) +{ + /* Factor of 2 is for fixed divider */ + unsigned long prate = *parent_rate / 2; + unsigned int mult; + + mult = div_u64(rate * 32ULL, prate); + mult = clamp(mult, 1U, 32U); + + return (u64)prate * mult / 32; +} + +static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct cpg_z_clk *zclk = to_z_clk(hw); + unsigned int mult; + unsigned int i; + u32 val, kick; + + /* Factor of 2 is for fixed divider */ + mult = DIV_ROUND_CLOSEST_ULL(rate * 32ULL * 2, parent_rate); + mult = clamp(mult, 1U, 32U); + + if (clk_readl(zclk->kick_reg) & CPG_FRQCRB_KICK) + return -EBUSY; + + val = clk_readl(zclk->reg) & ~CPG_FRQCRC_ZFC_MASK; + val |= FIELD_PREP(CPG_FRQCRC_ZFC_MASK, 32 - mult); + clk_writel(val, zclk->reg); + + /* + * Set KICK bit in FRQCRB to update hardware setting and wait for + * clock change completion. + */ + kick = clk_readl(zclk->kick_reg); + kick |= CPG_FRQCRB_KICK; + clk_writel(kick, zclk->kick_reg); + + /* + * Note: There is no HW information about the worst case latency. + * + * Using experimental measurements, it seems that no more than + * ~10 iterations are needed, independently of the CPU rate. + * Since this value might be dependent of external xtal rate, pll1 + * rate or even the other emulation clocks rate, use 1000 as a + * "super" safe value. + */ + for (i = 1000; i; i--) { + if (!(clk_readl(zclk->kick_reg) & CPG_FRQCRB_KICK)) + return 0; + + cpu_relax(); + } + + return -ETIMEDOUT; +} + +static const struct clk_ops cpg_z_clk_ops = { + .recalc_rate = cpg_z_clk_recalc_rate, + .round_rate = cpg_z_clk_round_rate, + .set_rate = cpg_z_clk_set_rate, +}; + +static struct clk * __init cpg_z_clk_register(const char *name, + const char *parent_name, + void __iomem *reg) +{ + struct clk_init_data init; + struct cpg_z_clk *zclk; + struct clk *clk; + + zclk = kzalloc(sizeof(*zclk), GFP_KERNEL); + if (!zclk) + return ERR_PTR(-ENOMEM); + + init.name = name; + init.ops = &cpg_z_clk_ops; + init.flags = 0; + init.parent_names = &parent_name; + init.num_parents = 1; + + zclk->reg = reg + CPG_FRQCRC; + zclk->kick_reg = reg + CPG_FRQCRB; + zclk->hw.init = &init; + + clk = clk_register(NULL, &zclk->hw); + if (IS_ERR(clk)) + kfree(zclk); + + return clk; +} + +/* * SDn Clock */ #define CPG_SD_STP_HCK BIT(9) @@ -420,6 +549,10 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev, mult = 1; break; + case CLK_TYPE_GEN3_Z: + return cpg_z_clk_register(core->name, __clk_get_name(parent), + base); + default: return ERR_PTR(-EINVAL); } diff --git a/drivers/clk/renesas/rcar-gen3-cpg.h b/drivers/clk/renesas/rcar-gen3-cpg.h index 2e42843..c73d4d6 100644 --- a/drivers/clk/renesas/rcar-gen3-cpg.h +++ b/drivers/clk/renesas/rcar-gen3-cpg.h @@ -21,6 +21,7 @@ enum rcar_gen3_clk_types { CLK_TYPE_GEN3_SD, CLK_TYPE_GEN3_R, CLK_TYPE_GEN3_PE, + CLK_TYPE_GEN3_Z, }; #define DEF_GEN3_SD(_name, _id, _parent, _offset) \ -- cgit v1.1 From 41ceeb5fef7719474a17a5a6052cae5b6c9e37c0 Mon Sep 17 00:00:00 2001 From: Takeshi Kihara Date: Mon, 29 Jan 2018 19:01:50 +0100 Subject: clk: renesas: rcar-gen3: Add Z2 clock divider support This patch adds Z2 clock divider support for R-Car Gen3 SoC. Signed-off-by: Takeshi Kihara Signed-off-by: Simon Horman Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/rcar-gen3-cpg.c | 22 ++++++++++++++++------ drivers/clk/renesas/rcar-gen3-cpg.h | 1 + 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c index b85918f..0c8fe10 100644 --- a/drivers/clk/renesas/rcar-gen3-cpg.c +++ b/drivers/clk/renesas/rcar-gen3-cpg.c @@ -63,7 +63,7 @@ static void cpg_simple_notifier_register(struct raw_notifier_head *notifiers, } /* - * Z Clock + * Z Clock & Z2 Clock * * Traits of this clock: * prepare - clk_prepare only ensures that parents are prepared @@ -75,11 +75,13 @@ static void cpg_simple_notifier_register(struct raw_notifier_head *notifiers, #define CPG_FRQCRB_KICK BIT(31) #define CPG_FRQCRC 0x000000e0 #define CPG_FRQCRC_ZFC_MASK GENMASK(12, 8) +#define CPG_FRQCRC_Z2FC_MASK GENMASK(4, 0) struct cpg_z_clk { struct clk_hw hw; void __iomem *reg; void __iomem *kick_reg; + unsigned long mask; }; #define to_z_clk(_hw) container_of(_hw, struct cpg_z_clk, hw) @@ -89,8 +91,10 @@ static unsigned long cpg_z_clk_recalc_rate(struct clk_hw *hw, { struct cpg_z_clk *zclk = to_z_clk(hw); unsigned int mult; + u32 val; - mult = 32 - FIELD_GET(CPG_FRQCRC_ZFC_MASK, clk_readl(zclk->reg)); + val = clk_readl(zclk->reg) & zclk->mask; + mult = 32 - (val >> __ffs(zclk->mask)); /* Factor of 2 is for fixed divider */ return DIV_ROUND_CLOSEST_ULL((u64)parent_rate * mult, 32 * 2); @@ -124,8 +128,8 @@ static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate, if (clk_readl(zclk->kick_reg) & CPG_FRQCRB_KICK) return -EBUSY; - val = clk_readl(zclk->reg) & ~CPG_FRQCRC_ZFC_MASK; - val |= FIELD_PREP(CPG_FRQCRC_ZFC_MASK, 32 - mult); + val = clk_readl(zclk->reg) & ~zclk->mask; + val |= ((32 - mult) << __ffs(zclk->mask)) & zclk->mask; clk_writel(val, zclk->reg); /* @@ -163,7 +167,8 @@ static const struct clk_ops cpg_z_clk_ops = { static struct clk * __init cpg_z_clk_register(const char *name, const char *parent_name, - void __iomem *reg) + void __iomem *reg, + unsigned long mask) { struct clk_init_data init; struct cpg_z_clk *zclk; @@ -182,6 +187,7 @@ static struct clk * __init cpg_z_clk_register(const char *name, zclk->reg = reg + CPG_FRQCRC; zclk->kick_reg = reg + CPG_FRQCRB; zclk->hw.init = &init; + zclk->mask = mask; clk = clk_register(NULL, &zclk->hw); if (IS_ERR(clk)) @@ -551,7 +557,11 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev, case CLK_TYPE_GEN3_Z: return cpg_z_clk_register(core->name, __clk_get_name(parent), - base); + base, CPG_FRQCRC_ZFC_MASK); + + case CLK_TYPE_GEN3_Z2: + return cpg_z_clk_register(core->name, __clk_get_name(parent), + base, CPG_FRQCRC_Z2FC_MASK); default: return ERR_PTR(-EINVAL); diff --git a/drivers/clk/renesas/rcar-gen3-cpg.h b/drivers/clk/renesas/rcar-gen3-cpg.h index c73d4d6..ea4f8fc 100644 --- a/drivers/clk/renesas/rcar-gen3-cpg.h +++ b/drivers/clk/renesas/rcar-gen3-cpg.h @@ -22,6 +22,7 @@ enum rcar_gen3_clk_types { CLK_TYPE_GEN3_R, CLK_TYPE_GEN3_PE, CLK_TYPE_GEN3_Z, + CLK_TYPE_GEN3_Z2, }; #define DEF_GEN3_SD(_name, _id, _parent, _offset) \ -- cgit v1.1 From 4003508b4f233104a17150463604dc9c36833815 Mon Sep 17 00:00:00 2001 From: Takeshi Kihara Date: Mon, 29 Jan 2018 19:01:51 +0100 Subject: clk: renesas: r8a7795: Add Z clock This patch adds Z clock for R8A7795 SoC. Signed-off-by: Takeshi Kihara Signed-off-by: Simon Horman Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r8a7795-cpg-mssr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/renesas/r8a7795-cpg-mssr.c b/drivers/clk/renesas/r8a7795-cpg-mssr.c index b1d9f48..995a4c4 100644 --- a/drivers/clk/renesas/r8a7795-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7795-cpg-mssr.c @@ -74,6 +74,7 @@ static struct cpg_core_clk r8a7795_core_clks[] __initdata = { DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1_DIV2, 2, 1), /* Core Clock Outputs */ + DEF_BASE("z", R8A7795_CLK_Z, CLK_TYPE_GEN3_Z, CLK_PLL0), DEF_FIXED("ztr", R8A7795_CLK_ZTR, CLK_PLL1_DIV2, 6, 1), DEF_FIXED("ztrd2", R8A7795_CLK_ZTRD2, CLK_PLL1_DIV2, 12, 1), DEF_FIXED("zt", R8A7795_CLK_ZT, CLK_PLL1_DIV2, 4, 1), -- cgit v1.1 From 1eadca3557f77afbb64100e077f48ac338d731dc Mon Sep 17 00:00:00 2001 From: Takeshi Kihara Date: Mon, 29 Jan 2018 19:01:52 +0100 Subject: clk: renesas: r8a7795: Add Z2 clock This patch adds Z2 clock for r8a7795 SoC. Signed-off-by: Takeshi Kihara Signed-off-by: Simon Horman Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r8a7795-cpg-mssr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/renesas/r8a7795-cpg-mssr.c b/drivers/clk/renesas/r8a7795-cpg-mssr.c index 995a4c4..775b0ce 100644 --- a/drivers/clk/renesas/r8a7795-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7795-cpg-mssr.c @@ -75,6 +75,7 @@ static struct cpg_core_clk r8a7795_core_clks[] __initdata = { /* Core Clock Outputs */ DEF_BASE("z", R8A7795_CLK_Z, CLK_TYPE_GEN3_Z, CLK_PLL0), + DEF_BASE("z2", R8A7795_CLK_Z2, CLK_TYPE_GEN3_Z2, CLK_PLL2), DEF_FIXED("ztr", R8A7795_CLK_ZTR, CLK_PLL1_DIV2, 6, 1), DEF_FIXED("ztrd2", R8A7795_CLK_ZTRD2, CLK_PLL1_DIV2, 12, 1), DEF_FIXED("zt", R8A7795_CLK_ZT, CLK_PLL1_DIV2, 4, 1), -- cgit v1.1 From 72f2a6b31544da1978ab9fb032d0e17ded4af4a7 Mon Sep 17 00:00:00 2001 From: Takeshi Kihara Date: Mon, 29 Jan 2018 19:01:53 +0100 Subject: clk: renesas: r8a7796: Add Z clock This patch adds Z clock for R8A7796 SoC. Signed-off-by: Takeshi Kihara Signed-off-by: Simon Horman Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r8a7796-cpg-mssr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/renesas/r8a7796-cpg-mssr.c b/drivers/clk/renesas/r8a7796-cpg-mssr.c index 41e2973..799a9e5 100644 --- a/drivers/clk/renesas/r8a7796-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7796-cpg-mssr.c @@ -74,6 +74,7 @@ static const struct cpg_core_clk r8a7796_core_clks[] __initconst = { DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1_DIV2, 2, 1), /* Core Clock Outputs */ + DEF_BASE("z", R8A7796_CLK_Z, CLK_TYPE_GEN3_Z, CLK_PLL0), DEF_FIXED("ztr", R8A7796_CLK_ZTR, CLK_PLL1_DIV2, 6, 1), DEF_FIXED("ztrd2", R8A7796_CLK_ZTRD2, CLK_PLL1_DIV2, 12, 1), DEF_FIXED("zt", R8A7796_CLK_ZT, CLK_PLL1_DIV2, 4, 1), -- cgit v1.1 From c50378efa9aa16acfe16d7313d29a874c2c86e5e Mon Sep 17 00:00:00 2001 From: Takeshi Kihara Date: Mon, 29 Jan 2018 19:01:54 +0100 Subject: clk: renesas: r8a7796: Add Z2 clock This patch adds Z2 clock for R8A7796 SoC. Signed-off-by: Takeshi Kihara Signed-off-by: Simon Horman Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r8a7796-cpg-mssr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/renesas/r8a7796-cpg-mssr.c b/drivers/clk/renesas/r8a7796-cpg-mssr.c index 799a9e5..dfb267a 100644 --- a/drivers/clk/renesas/r8a7796-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7796-cpg-mssr.c @@ -75,6 +75,7 @@ static const struct cpg_core_clk r8a7796_core_clks[] __initconst = { /* Core Clock Outputs */ DEF_BASE("z", R8A7796_CLK_Z, CLK_TYPE_GEN3_Z, CLK_PLL0), + DEF_BASE("z2", R8A7796_CLK_Z2, CLK_TYPE_GEN3_Z2, CLK_PLL2), DEF_FIXED("ztr", R8A7796_CLK_ZTR, CLK_PLL1_DIV2, 6, 1), DEF_FIXED("ztrd2", R8A7796_CLK_ZTRD2, CLK_PLL1_DIV2, 12, 1), DEF_FIXED("zt", R8A7796_CLK_ZT, CLK_PLL1_DIV2, 4, 1), -- cgit v1.1 From 75af6fa42dc68b730e85f51034512c61e52eb0c0 Mon Sep 17 00:00:00 2001 From: Corentin Labbe Date: Fri, 19 Jan 2018 15:19:06 +0100 Subject: clk: sunxi-ng: remove select on obsolete SUNXI_CCU_X kconfig name The following symbols: SUNXI_CCU_DIV SUNXI_CCU_MULT SUNXI_CCU_NK SUNXI_CCU_NKM SUNXI_CCU_NM SUNXI_CCU_MP SUNXI_CCU_PHASE were removed with the commit 06e226c7fb23 ("clk: sunxi-ng: Move all clock types to a library") So selecting them is useless. Fixes: c84f5683f6e9 ("clk: sunxi-ng: Add sun4i/sun7i CCU driver") Signed-off-by: Corentin Labbe Signed-off-by: Maxime Ripard --- drivers/clk/sunxi-ng/Kconfig | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig index 6427d0e..33168f9 100644 --- a/drivers/clk/sunxi-ng/Kconfig +++ b/drivers/clk/sunxi-ng/Kconfig @@ -13,13 +13,6 @@ config SUN50I_A64_CCU config SUN4I_A10_CCU bool "Support for the Allwinner A10/A20 CCU" - select SUNXI_CCU_DIV - select SUNXI_CCU_MULT - select SUNXI_CCU_NK - select SUNXI_CCU_NKM - select SUNXI_CCU_NM - select SUNXI_CCU_MP - select SUNXI_CCU_PHASE default MACH_SUN4I default MACH_SUN7I depends on MACH_SUN4I || MACH_SUN7I || COMPILE_TEST -- cgit v1.1 From d897ef56faf9bdb36e931251d0b70b10ebb03a14 Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Wed, 14 Feb 2018 21:08:55 +0100 Subject: clk: sunxi-ng: Mask nkmp factors when setting register Currently, if one of the factors isn't present, bit 0 gets always set to 1. For example, A83T has NMP PLLs modelled as NKMP PLL without K. Since K is not specified, it's offset, width and shift is 0. Driver assumes that lowest value possible is 1, otherwise we would get division by 0. That situation causes that bit 0 is always set, which may change wanted clock rate. Fix that by masking every factor according to it's specified width. Factors with width set to 0 won't have any influence to final register value. Acked-by: Maxime Ripard Signed-off-by: Jernej Skrabec Signed-off-by: Maxime Ripard --- drivers/clk/sunxi-ng/ccu_nkmp.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/drivers/clk/sunxi-ng/ccu_nkmp.c b/drivers/clk/sunxi-ng/ccu_nkmp.c index e58c957..a99068a 100644 --- a/drivers/clk/sunxi-ng/ccu_nkmp.c +++ b/drivers/clk/sunxi-ng/ccu_nkmp.c @@ -134,6 +134,7 @@ static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { struct ccu_nkmp *nkmp = hw_to_ccu_nkmp(hw); + u32 n_mask, k_mask, m_mask, p_mask; struct _ccu_nkmp _nkmp; unsigned long flags; u32 reg; @@ -149,18 +150,20 @@ static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate, ccu_nkmp_find_best(parent_rate, rate, &_nkmp); + n_mask = GENMASK(nkmp->n.width + nkmp->n.shift - 1, nkmp->n.shift); + k_mask = GENMASK(nkmp->k.width + nkmp->k.shift - 1, nkmp->k.shift); + m_mask = GENMASK(nkmp->m.width + nkmp->m.shift - 1, nkmp->m.shift); + p_mask = GENMASK(nkmp->p.width + nkmp->p.shift - 1, nkmp->p.shift); + spin_lock_irqsave(nkmp->common.lock, flags); reg = readl(nkmp->common.base + nkmp->common.reg); - reg &= ~GENMASK(nkmp->n.width + nkmp->n.shift - 1, nkmp->n.shift); - reg &= ~GENMASK(nkmp->k.width + nkmp->k.shift - 1, nkmp->k.shift); - reg &= ~GENMASK(nkmp->m.width + nkmp->m.shift - 1, nkmp->m.shift); - reg &= ~GENMASK(nkmp->p.width + nkmp->p.shift - 1, nkmp->p.shift); - - reg |= (_nkmp.n - nkmp->n.offset) << nkmp->n.shift; - reg |= (_nkmp.k - nkmp->k.offset) << nkmp->k.shift; - reg |= (_nkmp.m - nkmp->m.offset) << nkmp->m.shift; - reg |= ilog2(_nkmp.p) << nkmp->p.shift; + reg &= ~(n_mask | k_mask | m_mask | p_mask); + + reg |= ((_nkmp.n - nkmp->n.offset) << nkmp->n.shift) & n_mask; + reg |= ((_nkmp.k - nkmp->k.offset) << nkmp->k.shift) & k_mask; + reg |= ((_nkmp.m - nkmp->m.offset) << nkmp->m.shift) & m_mask; + reg |= (ilog2(_nkmp.p) << nkmp->p.shift) & p_mask; writel(reg, nkmp->common.base + nkmp->common.reg); -- cgit v1.1 From a5ebc3368ef7c77da5a03ad52834520a634a36ef Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Wed, 14 Feb 2018 21:08:56 +0100 Subject: clk: sunxi-ng: Use u64 for calculation of nkmp rate When parent rate is 24MHz and multiplier N >= 180, intermediate clock rate doesn't fit in 32 bit variable anymore. Because of that, introduce function for calculating clock rate which uses 64 bit variable for intermediate result. Acked-by: Maxime Ripard Signed-off-by: Jernej Skrabec Signed-off-by: Maxime Ripard --- drivers/clk/sunxi-ng/ccu_nkmp.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/drivers/clk/sunxi-ng/ccu_nkmp.c b/drivers/clk/sunxi-ng/ccu_nkmp.c index a99068a..c3f6fe7 100644 --- a/drivers/clk/sunxi-ng/ccu_nkmp.c +++ b/drivers/clk/sunxi-ng/ccu_nkmp.c @@ -20,6 +20,18 @@ struct _ccu_nkmp { unsigned long p, min_p, max_p; }; +static unsigned long ccu_nkmp_calc_rate(unsigned long parent, + unsigned long n, unsigned long k, + unsigned long m, unsigned long p) +{ + u64 rate = parent; + + rate *= n * k; + do_div(rate, m * p); + + return rate; +} + static void ccu_nkmp_find_best(unsigned long parent, unsigned long rate, struct _ccu_nkmp *nkmp) { @@ -33,7 +45,9 @@ static void ccu_nkmp_find_best(unsigned long parent, unsigned long rate, for (_p = nkmp->min_p; _p <= nkmp->max_p; _p <<= 1) { unsigned long tmp_rate; - tmp_rate = parent * _n * _k / (_m * _p); + tmp_rate = ccu_nkmp_calc_rate(parent, + _n, _k, + _m, _p); if (tmp_rate > rate) continue; @@ -107,7 +121,7 @@ static unsigned long ccu_nkmp_recalc_rate(struct clk_hw *hw, p = reg >> nkmp->p.shift; p &= (1 << nkmp->p.width) - 1; - return (parent_rate * n * k >> p) / m; + return ccu_nkmp_calc_rate(parent_rate, n, k, m, 1 << p); } static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate, @@ -127,7 +141,8 @@ static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate, ccu_nkmp_find_best(*parent_rate, rate, &_nkmp); - return *parent_rate * _nkmp.n * _nkmp.k / (_nkmp.m * _nkmp.p); + return ccu_nkmp_calc_rate(*parent_rate, _nkmp.n, _nkmp.k, + _nkmp.m, _nkmp.p); } static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate, -- cgit v1.1 From 039738bf986a516a01e96a4874c172dfe7e66892 Mon Sep 17 00:00:00 2001 From: Fabrizio Castro Date: Mon, 12 Feb 2018 17:44:24 +0000 Subject: clk: renesas: r8a7743: Add rwdt clock Add "rwdt" clock to r8a7743_mod_clks. Also, since we may need to access the watchdog registers at any time, declare the clock as critical. Signed-off-by: Fabrizio Castro Signed-off-by: Ramesh Shanmugasundaram Reviewed-by: Wolfram Sang Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r8a7743-cpg-mssr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/clk/renesas/r8a7743-cpg-mssr.c b/drivers/clk/renesas/r8a7743-cpg-mssr.c index 6dc0b30..d3c8b1e 100644 --- a/drivers/clk/renesas/r8a7743-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7743-cpg-mssr.c @@ -117,6 +117,7 @@ static const struct mssr_mod_clk r8a7743_mod_clks[] __initconst = { DEF_MOD("cmt1", 329, R8A7743_CLK_R), DEF_MOD("usbhs-dmac0", 330, R8A7743_CLK_HP), DEF_MOD("usbhs-dmac1", 331, R8A7743_CLK_HP), + DEF_MOD("rwdt", 402, R8A7743_CLK_R), DEF_MOD("irqc", 407, R8A7743_CLK_CP), DEF_MOD("intc-sys", 408, R8A7743_CLK_ZS), DEF_MOD("audio-dmac1", 501, R8A7743_CLK_HP), @@ -195,6 +196,7 @@ static const struct mssr_mod_clk r8a7743_mod_clks[] __initconst = { }; static const unsigned int r8a7743_crit_mod_clks[] __initconst = { + MOD_CLK_ID(402), /* RWDT */ MOD_CLK_ID(408), /* INTC-SYS (GIC) */ }; -- cgit v1.1 From e0c0a2c4a2bc7c2959d19600ccd03eec4b27c4be Mon Sep 17 00:00:00 2001 From: Fabrizio Castro Date: Mon, 12 Feb 2018 17:44:25 +0000 Subject: clk: renesas: r8a7745: Add rwdt clock Add "rwdt" clock to r8a7745_mod_clks. Also, since we may need to access the watchdog registers at any time, declare the clock as critical. Signed-off-by: Fabrizio Castro Signed-off-by: Ramesh Shanmugasundaram Reviewed-by: Wolfram Sang Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r8a7745-cpg-mssr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/clk/renesas/r8a7745-cpg-mssr.c b/drivers/clk/renesas/r8a7745-cpg-mssr.c index 2859504..87f5a36 100644 --- a/drivers/clk/renesas/r8a7745-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7745-cpg-mssr.c @@ -114,6 +114,7 @@ static const struct mssr_mod_clk r8a7745_mod_clks[] __initconst = { DEF_MOD("cmt1", 329, R8A7745_CLK_R), DEF_MOD("usbhs-dmac0", 330, R8A7745_CLK_HP), DEF_MOD("usbhs-dmac1", 331, R8A7745_CLK_HP), + DEF_MOD("rwdt", 402, R8A7745_CLK_R), DEF_MOD("irqc", 407, R8A7745_CLK_CP), DEF_MOD("intc-sys", 408, R8A7745_CLK_ZS), DEF_MOD("audio-dmac0", 502, R8A7745_CLK_HP), @@ -180,6 +181,7 @@ static const struct mssr_mod_clk r8a7745_mod_clks[] __initconst = { }; static const unsigned int r8a7745_crit_mod_clks[] __initconst = { + MOD_CLK_ID(402), /* RWDT */ MOD_CLK_ID(408), /* INTC-SYS (GIC) */ }; -- cgit v1.1 From 30c288bbf55c1356fd939b158a17c8e8612bdc11 Mon Sep 17 00:00:00 2001 From: Fabrizio Castro Date: Mon, 12 Feb 2018 17:44:26 +0000 Subject: clk: renesas: r8a7790: Add rwdt clock Add "rwdt" clock to r8a7790_mod_clks. Also, since we may need to access the watchdog registers at any time, declare the clock as critical. Signed-off-by: Fabrizio Castro Signed-off-by: Ramesh Shanmugasundaram Reviewed-by: Wolfram Sang Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r8a7790-cpg-mssr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/clk/renesas/r8a7790-cpg-mssr.c b/drivers/clk/renesas/r8a7790-cpg-mssr.c index 46bb55b..f936cb7 100644 --- a/drivers/clk/renesas/r8a7790-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7790-cpg-mssr.c @@ -140,6 +140,7 @@ static const struct mssr_mod_clk r8a7790_mod_clks[] __initconst = { DEF_MOD("cmt1", 329, R8A7790_CLK_R), DEF_MOD("usbhs-dmac0", 330, R8A7790_CLK_HP), DEF_MOD("usbhs-dmac1", 331, R8A7790_CLK_HP), + DEF_MOD("rwdt", 402, R8A7790_CLK_R), DEF_MOD("irqc", 407, R8A7790_CLK_CP), DEF_MOD("intc-sys", 408, R8A7790_CLK_ZS), DEF_MOD("audio-dmac1", 501, R8A7790_CLK_HP), @@ -211,6 +212,7 @@ static const struct mssr_mod_clk r8a7790_mod_clks[] __initconst = { }; static const unsigned int r8a7790_crit_mod_clks[] __initconst = { + MOD_CLK_ID(402), /* RWDT */ MOD_CLK_ID(408), /* INTC-SYS (GIC) */ }; -- cgit v1.1 From 5ada6bee8c966bf7bdc23512d1571adaeea22f0b Mon Sep 17 00:00:00 2001 From: Fabrizio Castro Date: Mon, 12 Feb 2018 17:44:27 +0000 Subject: clk: renesas: r8a7791/r8a7793: Add rwdt clock Add "rwdt" clock to r8a7791_mod_clks. Also, since we may need to access the watchdog registers at any time, declare the clock as critical. Signed-off-by: Fabrizio Castro Signed-off-by: Ramesh Shanmugasundaram Reviewed-by: Wolfram Sang Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r8a7791-cpg-mssr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/clk/renesas/r8a7791-cpg-mssr.c b/drivers/clk/renesas/r8a7791-cpg-mssr.c index c0b51f9..820b220 100644 --- a/drivers/clk/renesas/r8a7791-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7791-cpg-mssr.c @@ -128,6 +128,7 @@ static const struct mssr_mod_clk r8a7791_mod_clks[] __initconst = { DEF_MOD("cmt1", 329, R8A7791_CLK_R), DEF_MOD("usbhs-dmac0", 330, R8A7791_CLK_HP), DEF_MOD("usbhs-dmac1", 331, R8A7791_CLK_HP), + DEF_MOD("rwdt", 402, R8A7791_CLK_R), DEF_MOD("irqc", 407, R8A7791_CLK_CP), DEF_MOD("intc-sys", 408, R8A7791_CLK_ZS), DEF_MOD("audio-dmac1", 501, R8A7791_CLK_HP), @@ -209,6 +210,7 @@ static const struct mssr_mod_clk r8a7791_mod_clks[] __initconst = { }; static const unsigned int r8a7791_crit_mod_clks[] __initconst = { + MOD_CLK_ID(402), /* RWDT */ MOD_CLK_ID(408), /* INTC-SYS (GIC) */ }; -- cgit v1.1 From c43d8630fe1a6bb09e005d38793346d989aa4dad Mon Sep 17 00:00:00 2001 From: Fabrizio Castro Date: Mon, 12 Feb 2018 17:44:28 +0000 Subject: clk: renesas: r8a7794: Add rwdt clock Add "rwdt" clock to r8a7794_mod_clks. Also, since we may need to access the watchdog registers at any time, declare the clock as critical. Signed-off-by: Fabrizio Castro Signed-off-by: Ramesh Shanmugasundaram Reviewed-by: Wolfram Sang Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r8a7794-cpg-mssr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/clk/renesas/r8a7794-cpg-mssr.c b/drivers/clk/renesas/r8a7794-cpg-mssr.c index ec091a4..2a40bbe 100644 --- a/drivers/clk/renesas/r8a7794-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7794-cpg-mssr.c @@ -121,6 +121,7 @@ static const struct mssr_mod_clk r8a7794_mod_clks[] __initconst = { DEF_MOD("cmt1", 329, R8A7794_CLK_R), DEF_MOD("usbhs-dmac0", 330, R8A7794_CLK_HP), DEF_MOD("usbhs-dmac1", 331, R8A7794_CLK_HP), + DEF_MOD("rwdt", 402, R8A7794_CLK_R), DEF_MOD("irqc", 407, R8A7794_CLK_CP), DEF_MOD("intc-sys", 408, R8A7794_CLK_ZS), DEF_MOD("audio-dmac0", 502, R8A7794_CLK_HP), @@ -190,6 +191,7 @@ static const struct mssr_mod_clk r8a7794_mod_clks[] __initconst = { }; static const unsigned int r8a7794_crit_mod_clks[] __initconst = { + MOD_CLK_ID(402), /* RWDT */ MOD_CLK_ID(408), /* INTC-SYS (GIC) */ }; -- cgit v1.1 From 20254c7cea447d2ffba17046e3e80da667d742d3 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 7 Feb 2018 16:43:23 +0100 Subject: clk: renesas: r8a7792: Add rwdt clock Add "rwdt" clock to r8a7792_mod_clks. Also, since we may need to access the watchdog registers at any time, declare the clock as critical. Signed-off-by: Geert Uytterhoeven Acked-by: Fabrizio Castro --- drivers/clk/renesas/r8a7792-cpg-mssr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/clk/renesas/r8a7792-cpg-mssr.c b/drivers/clk/renesas/r8a7792-cpg-mssr.c index 7f85bbf..609a540 100644 --- a/drivers/clk/renesas/r8a7792-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7792-cpg-mssr.c @@ -98,6 +98,7 @@ static const struct mssr_mod_clk r8a7792_mod_clks[] __initconst = { DEF_MOD("tpu0", 304, R8A7792_CLK_CP), DEF_MOD("sdhi0", 314, R8A7792_CLK_SD), DEF_MOD("cmt1", 329, R8A7792_CLK_R), + DEF_MOD("rwdt", 402, R8A7792_CLK_R), DEF_MOD("irqc", 407, R8A7792_CLK_CP), DEF_MOD("intc-sys", 408, R8A7792_CLK_ZS), DEF_MOD("audio-dmac0", 502, R8A7792_CLK_HP), @@ -154,6 +155,7 @@ static const struct mssr_mod_clk r8a7792_mod_clks[] __initconst = { }; static const unsigned int r8a7792_crit_mod_clks[] __initconst = { + MOD_CLK_ID(402), /* RWDT */ MOD_CLK_ID(408), /* INTC-SYS (GIC) */ }; -- cgit v1.1 From 35b3c462dae1b451772992d4e43bfef814499b49 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Thu, 15 Feb 2018 14:56:53 +0300 Subject: dt-bindings: clock: add R8A77980 CPG core clock definitions Add macros usable by the device tree sources to reference the R8A77980 CPG core clocks by index. The data come from the table 8.2e of the R-Car Series, 3rd Generation User's Manual: Hardware (Rev. 0.80, Oct, 2017), however I had to add the Z2 clock which is somehow present only on the figure 8.1e... Based on the original (and large) patch by Vladimir Barinov. Signed-off-by: Vladimir Barinov Signed-off-by: Sergei Shtylyov Reviewed-by: Rob Herring Reviewed-by: Simon Horman Signed-off-by: Geert Uytterhoeven --- include/dt-bindings/clock/r8a77980-cpg-mssr.h | 51 +++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 include/dt-bindings/clock/r8a77980-cpg-mssr.h diff --git a/include/dt-bindings/clock/r8a77980-cpg-mssr.h b/include/dt-bindings/clock/r8a77980-cpg-mssr.h new file mode 100644 index 0000000..a4c0d76 --- /dev/null +++ b/include/dt-bindings/clock/r8a77980-cpg-mssr.h @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2018 Renesas Electronics Corp. + * Copyright (C) 2018 Cogent Embedded, Inc. + */ +#ifndef __DT_BINDINGS_CLOCK_R8A77980_CPG_MSSR_H__ +#define __DT_BINDINGS_CLOCK_R8A77980_CPG_MSSR_H__ + +#include + +/* r8a77980 CPG Core Clocks */ +#define R8A77980_CLK_Z2 0 +#define R8A77980_CLK_ZR 1 +#define R8A77980_CLK_ZTR 2 +#define R8A77980_CLK_ZTRD2 3 +#define R8A77980_CLK_ZT 4 +#define R8A77980_CLK_ZX 5 +#define R8A77980_CLK_S0D1 6 +#define R8A77980_CLK_S0D2 7 +#define R8A77980_CLK_S0D3 8 +#define R8A77980_CLK_S0D4 9 +#define R8A77980_CLK_S0D6 10 +#define R8A77980_CLK_S0D12 11 +#define R8A77980_CLK_S0D24 12 +#define R8A77980_CLK_S1D1 13 +#define R8A77980_CLK_S1D2 14 +#define R8A77980_CLK_S1D4 15 +#define R8A77980_CLK_S2D1 16 +#define R8A77980_CLK_S2D2 17 +#define R8A77980_CLK_S2D4 18 +#define R8A77980_CLK_S3D1 19 +#define R8A77980_CLK_S3D2 20 +#define R8A77980_CLK_S3D4 21 +#define R8A77980_CLK_LB 22 +#define R8A77980_CLK_CL 23 +#define R8A77980_CLK_ZB3 24 +#define R8A77980_CLK_ZB3D2 25 +#define R8A77980_CLK_ZB3D4 26 +#define R8A77980_CLK_SD0H 27 +#define R8A77980_CLK_SD0 28 +#define R8A77980_CLK_RPC 29 +#define R8A77980_CLK_RPCD2 30 +#define R8A77980_CLK_MSO 31 +#define R8A77980_CLK_CANFD 32 +#define R8A77980_CLK_CSI0 33 +#define R8A77980_CLK_CP 34 +#define R8A77980_CLK_CPEX 35 +#define R8A77980_CLK_R 36 +#define R8A77980_CLK_OSC 37 + +#endif /* __DT_BINDINGS_CLOCK_R8A77980_CPG_MSSR_H__ */ -- cgit v1.1 From ce15783c510a9905545e7708345454c38b725dd8 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Thu, 15 Feb 2018 14:58:45 +0300 Subject: clk: renesas: cpg-mssr: add R8A77980 support Add R-Car V3H (R8A77980) Clock Pulse Generator / Module Standby and Software Reset support, using the CPG/MSSR driver core and the common R-Car Gen3 code. Based on the original (and large) patch by Vladimir Barinov. Signed-off-by: Vladimir Barinov Signed-off-by: Sergei Shtylyov Reviewed-by: Rob Herring Reviewed-by: Simon Horman Signed-off-by: Geert Uytterhoeven --- .../devicetree/bindings/clock/renesas,cpg-mssr.txt | 5 +- drivers/clk/renesas/Kconfig | 5 + drivers/clk/renesas/Makefile | 1 + drivers/clk/renesas/r8a77980-cpg-mssr.c | 227 +++++++++++++++++++++ drivers/clk/renesas/renesas-cpg-mssr.c | 6 + drivers/clk/renesas/renesas-cpg-mssr.h | 1 + 6 files changed, 243 insertions(+), 2 deletions(-) create mode 100644 drivers/clk/renesas/r8a77980-cpg-mssr.c diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt index f1890d0..bc4ea08 100644 --- a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt +++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt @@ -23,6 +23,7 @@ Required Properties: - "renesas,r8a7795-cpg-mssr" for the r8a7795 SoC (R-Car H3) - "renesas,r8a7796-cpg-mssr" for the r8a7796 SoC (R-Car M3-W) - "renesas,r8a77970-cpg-mssr" for the r8a77970 SoC (R-Car V3M) + - "renesas,r8a77980-cpg-mssr" for the r8a77980 SoC (R-Car V3H) - "renesas,r8a77995-cpg-mssr" for the r8a77995 SoC (R-Car D3) - reg: Base address and length of the memory resource used by the CPG/MSSR @@ -32,8 +33,8 @@ Required Properties: clock-names - clock-names: List of external parent clock names. Valid names are: - "extal" (r8a7743, r8a7745, r8a7790, r8a7791, r8a7792, r8a7793, r8a7794, - r8a7795, r8a7796, r8a77970, r8a77995) - - "extalr" (r8a7795, r8a7796, r8a77970) + r8a7795, r8a7796, r8a77970, r8a77980, r8a77995) + - "extalr" (r8a7795, r8a7796, r8a77970, r8a77980) - "usb_extal" (r8a7743, r8a7745, r8a7790, r8a7791, r8a7793, r8a7794) - #clock-cells: Must be 2 diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig index 84b40b9..43bab4f 100644 --- a/drivers/clk/renesas/Kconfig +++ b/drivers/clk/renesas/Kconfig @@ -16,6 +16,7 @@ config CLK_RENESAS select CLK_R8A7795 if ARCH_R8A7795 select CLK_R8A7796 if ARCH_R8A7796 select CLK_R8A77970 if ARCH_R8A77970 + select CLK_R8A77980 if ARCH_R8A77980 select CLK_R8A77995 if ARCH_R8A77995 select CLK_SH73A0 if ARCH_SH73A0 @@ -101,6 +102,10 @@ config CLK_R8A77970 bool "R-Car V3M clock support" if COMPILE_TEST select CLK_RCAR_GEN3_CPG +config CLK_R8A77980 + bool "R-Car V3H clock support" if COMPILE_TEST + select CLK_RCAR_GEN3_CPG + config CLK_R8A77995 bool "R-Car D3 clock support" if COMPILE_TEST select CLK_RCAR_GEN3_CPG diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile index 34c4e0b..e20fa19 100644 --- a/drivers/clk/renesas/Makefile +++ b/drivers/clk/renesas/Makefile @@ -15,6 +15,7 @@ obj-$(CONFIG_CLK_R8A7794) += r8a7794-cpg-mssr.o obj-$(CONFIG_CLK_R8A7795) += r8a7795-cpg-mssr.o obj-$(CONFIG_CLK_R8A7796) += r8a7796-cpg-mssr.o obj-$(CONFIG_CLK_R8A77970) += r8a77970-cpg-mssr.o +obj-$(CONFIG_CLK_R8A77980) += r8a77980-cpg-mssr.o obj-$(CONFIG_CLK_R8A77995) += r8a77995-cpg-mssr.o obj-$(CONFIG_CLK_SH73A0) += clk-sh73a0.o diff --git a/drivers/clk/renesas/r8a77980-cpg-mssr.c b/drivers/clk/renesas/r8a77980-cpg-mssr.c new file mode 100644 index 0000000..7aaae73 --- /dev/null +++ b/drivers/clk/renesas/r8a77980-cpg-mssr.c @@ -0,0 +1,227 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * r8a77980 Clock Pulse Generator / Module Standby and Software Reset + * + * Copyright (C) 2018 Renesas Electronics Corp. + * Copyright (C) 2018 Cogent Embedded, Inc. + * + * Based on r8a7795-cpg-mssr.c + * + * Copyright (C) 2015 Glider bvba + */ + +#include +#include +#include +#include +#include + +#include + +#include "renesas-cpg-mssr.h" +#include "rcar-gen3-cpg.h" + +enum clk_ids { + /* Core Clock Outputs exported to DT */ + LAST_DT_CORE_CLK = R8A77980_CLK_OSC, + + /* External Input Clocks */ + CLK_EXTAL, + CLK_EXTALR, + + /* Internal Core Clocks */ + CLK_MAIN, + CLK_PLL1, + CLK_PLL2, + CLK_PLL3, + CLK_PLL1_DIV2, + CLK_PLL1_DIV4, + CLK_S0, + CLK_S1, + CLK_S2, + CLK_S3, + CLK_SDSRC, + + /* Module Clocks */ + MOD_CLK_BASE +}; + +static const struct cpg_core_clk r8a77980_core_clks[] __initconst = { + /* External Clock Inputs */ + DEF_INPUT("extal", CLK_EXTAL), + DEF_INPUT("extalr", CLK_EXTALR), + + /* Internal Core Clocks */ + DEF_BASE(".main", CLK_MAIN, CLK_TYPE_GEN3_MAIN, CLK_EXTAL), + DEF_BASE(".pll1", CLK_PLL1, CLK_TYPE_GEN3_PLL1, CLK_MAIN), + DEF_BASE(".pll2", CLK_PLL2, CLK_TYPE_GEN3_PLL2, CLK_MAIN), + DEF_BASE(".pll3", CLK_PLL3, CLK_TYPE_GEN3_PLL3, CLK_MAIN), + + DEF_FIXED(".pll1_div2", CLK_PLL1_DIV2, CLK_PLL1, 2, 1), + DEF_FIXED(".pll1_div4", CLK_PLL1_DIV4, CLK_PLL1_DIV2, 2, 1), + DEF_FIXED(".s0", CLK_S0, CLK_PLL1_DIV2, 2, 1), + DEF_FIXED(".s1", CLK_S1, CLK_PLL1_DIV2, 3, 1), + DEF_FIXED(".s2", CLK_S2, CLK_PLL1_DIV2, 4, 1), + DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 6, 1), + DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1_DIV2, 2, 1), + + /* Core Clock Outputs */ + DEF_FIXED("ztr", R8A77980_CLK_ZTR, CLK_PLL1_DIV2, 6, 1), + DEF_FIXED("ztrd2", R8A77980_CLK_ZTRD2, CLK_PLL1_DIV2, 12, 1), + DEF_FIXED("zt", R8A77980_CLK_ZT, CLK_PLL1_DIV2, 4, 1), + DEF_FIXED("zx", R8A77980_CLK_ZX, CLK_PLL1_DIV2, 2, 1), + DEF_FIXED("s0d1", R8A77980_CLK_S0D1, CLK_S0, 1, 1), + DEF_FIXED("s0d2", R8A77980_CLK_S0D2, CLK_S0, 2, 1), + DEF_FIXED("s0d3", R8A77980_CLK_S0D3, CLK_S0, 3, 1), + DEF_FIXED("s0d4", R8A77980_CLK_S0D4, CLK_S0, 4, 1), + DEF_FIXED("s0d6", R8A77980_CLK_S0D6, CLK_S0, 6, 1), + DEF_FIXED("s0d12", R8A77980_CLK_S0D12, CLK_S0, 12, 1), + DEF_FIXED("s0d24", R8A77980_CLK_S0D24, CLK_S0, 24, 1), + DEF_FIXED("s1d1", R8A77980_CLK_S1D1, CLK_S1, 1, 1), + DEF_FIXED("s1d2", R8A77980_CLK_S1D2, CLK_S1, 2, 1), + DEF_FIXED("s1d4", R8A77980_CLK_S1D4, CLK_S1, 4, 1), + DEF_FIXED("s2d1", R8A77980_CLK_S2D1, CLK_S2, 1, 1), + DEF_FIXED("s2d2", R8A77980_CLK_S2D2, CLK_S2, 2, 1), + DEF_FIXED("s2d4", R8A77980_CLK_S2D4, CLK_S2, 4, 1), + DEF_FIXED("s3d1", R8A77980_CLK_S3D1, CLK_S3, 1, 1), + DEF_FIXED("s3d2", R8A77980_CLK_S3D2, CLK_S3, 2, 1), + DEF_FIXED("s3d4", R8A77980_CLK_S3D4, CLK_S3, 4, 1), + + DEF_GEN3_SD("sd0", R8A77980_CLK_SD0, CLK_SDSRC, 0x0074), + + DEF_FIXED("cl", R8A77980_CLK_CL, CLK_PLL1_DIV2, 48, 1), + DEF_FIXED("cp", R8A77980_CLK_CP, CLK_EXTAL, 2, 1), + DEF_FIXED("cpex", R8A77980_CLK_CPEX, CLK_EXTAL, 2, 1), + + DEF_DIV6P1("canfd", R8A77980_CLK_CANFD, CLK_PLL1_DIV4, 0x244), + DEF_DIV6P1("csi0", R8A77980_CLK_CSI0, CLK_PLL1_DIV4, 0x00c), + DEF_DIV6P1("mso", R8A77980_CLK_MSO, CLK_PLL1_DIV4, 0x014), +}; + +static const struct mssr_mod_clk r8a77980_mod_clks[] __initconst = { + DEF_MOD("tmu4", 121, R8A77980_CLK_S0D6), + DEF_MOD("tmu3", 122, R8A77980_CLK_S0D6), + DEF_MOD("tmu2", 123, R8A77980_CLK_S0D6), + DEF_MOD("tmu1", 124, R8A77980_CLK_S0D6), + DEF_MOD("tmu0", 125, R8A77980_CLK_CP), + DEF_MOD("scif4", 203, R8A77980_CLK_S3D4), + DEF_MOD("scif3", 204, R8A77980_CLK_S3D4), + DEF_MOD("scif1", 206, R8A77980_CLK_S3D4), + DEF_MOD("scif0", 207, R8A77980_CLK_S3D4), + DEF_MOD("msiof3", 208, R8A77980_CLK_MSO), + DEF_MOD("msiof2", 209, R8A77980_CLK_MSO), + DEF_MOD("msiof1", 210, R8A77980_CLK_MSO), + DEF_MOD("msiof0", 211, R8A77980_CLK_MSO), + DEF_MOD("sys-dmac2", 217, R8A77980_CLK_S0D3), + DEF_MOD("sys-dmac1", 218, R8A77980_CLK_S0D3), + DEF_MOD("tpu0", 304, R8A77980_CLK_S3D4), + DEF_MOD("sdif", 314, R8A77980_CLK_SD0), + DEF_MOD("pciec0", 319, R8A77980_CLK_S3D1), + DEF_MOD("intc-ex", 407, R8A77980_CLK_CP), + DEF_MOD("intc-ap", 408, R8A77980_CLK_S0D3), + DEF_MOD("hscif3", 517, R8A77980_CLK_S3D1), + DEF_MOD("hscif2", 518, R8A77980_CLK_S3D1), + DEF_MOD("hscif1", 519, R8A77980_CLK_S3D1), + DEF_MOD("hscif0", 520, R8A77980_CLK_S3D1), + DEF_MOD("imp4", 521, R8A77980_CLK_S1D1), + DEF_MOD("thermal", 522, R8A77980_CLK_CP), + DEF_MOD("pwm", 523, R8A77980_CLK_S0D12), + DEF_MOD("impdma1", 526, R8A77980_CLK_S1D1), + DEF_MOD("impdma0", 527, R8A77980_CLK_S1D1), + DEF_MOD("imp-ocv4", 528, R8A77980_CLK_S1D1), + DEF_MOD("imp-ocv3", 529, R8A77980_CLK_S1D1), + DEF_MOD("imp-ocv2", 531, R8A77980_CLK_S1D1), + DEF_MOD("fcpvd0", 603, R8A77980_CLK_S3D1), + DEF_MOD("vspd0", 623, R8A77980_CLK_S3D1), + DEF_MOD("csi41", 715, R8A77980_CLK_CSI0), + DEF_MOD("csi40", 716, R8A77980_CLK_CSI0), + DEF_MOD("du0", 724, R8A77980_CLK_S2D1), + DEF_MOD("lvds", 727, R8A77980_CLK_S2D1), + DEF_MOD("etheravb", 812, R8A77980_CLK_S3D2), + DEF_MOD("gether", 813, R8A77980_CLK_S3D2), + DEF_MOD("imp3", 824, R8A77980_CLK_S1D1), + DEF_MOD("imp2", 825, R8A77980_CLK_S1D1), + DEF_MOD("imp1", 826, R8A77980_CLK_S1D1), + DEF_MOD("imp0", 827, R8A77980_CLK_S1D1), + DEF_MOD("imp-ocv1", 828, R8A77980_CLK_S1D1), + DEF_MOD("imp-ocv0", 829, R8A77980_CLK_S1D1), + DEF_MOD("impram", 830, R8A77980_CLK_S1D1), + DEF_MOD("impcnn", 831, R8A77980_CLK_S1D1), + DEF_MOD("gpio5", 907, R8A77980_CLK_CP), + DEF_MOD("gpio4", 908, R8A77980_CLK_CP), + DEF_MOD("gpio3", 909, R8A77980_CLK_CP), + DEF_MOD("gpio2", 910, R8A77980_CLK_CP), + DEF_MOD("gpio1", 911, R8A77980_CLK_CP), + DEF_MOD("gpio0", 912, R8A77980_CLK_CP), + DEF_MOD("can-fd", 914, R8A77980_CLK_S3D2), + DEF_MOD("i2c4", 927, R8A77980_CLK_S0D6), + DEF_MOD("i2c3", 928, R8A77980_CLK_S0D6), + DEF_MOD("i2c2", 929, R8A77980_CLK_S3D2), + DEF_MOD("i2c1", 930, R8A77980_CLK_S3D2), + DEF_MOD("i2c0", 931, R8A77980_CLK_S3D2), +}; + +static const unsigned int r8a77980_crit_mod_clks[] __initconst = { + MOD_CLK_ID(408), /* INTC-AP (GIC) */ +}; + + +/* + * CPG Clock Data + */ + +/* + * MD EXTAL PLL2 PLL1 PLL3 + * 14 13 (MHz) + * -------------------------------------------------- + * 0 0 16.66 x 1 x240 x192 x192 + * 0 1 20 x 1 x200 x160 x160 + * 1 0 27 x 1 x148 x118 x118 + * 1 1 33.33 / 2 x240 x192 x192 + */ +#define CPG_PLL_CONFIG_INDEX(md) ((((md) & BIT(14)) >> 13) | \ + (((md) & BIT(13)) >> 13)) + +static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[4] __initconst = { + /* EXTAL div PLL1 mult/div PLL3 mult/div */ + { 1, 192, 1, 192, 1, }, + { 1, 160, 1, 160, 1, }, + { 1, 118, 1, 118, 1, }, + { 2, 192, 1, 192, 1, }, +}; + +static int __init r8a77980_cpg_mssr_init(struct device *dev) +{ + const struct rcar_gen3_cpg_pll_config *cpg_pll_config; + u32 cpg_mode; + int error; + + error = rcar_rst_read_mode_pins(&cpg_mode); + if (error) + return error; + + cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)]; + + return rcar_gen3_cpg_init(cpg_pll_config, CLK_EXTALR, cpg_mode); +} + +const struct cpg_mssr_info r8a77980_cpg_mssr_info __initconst = { + /* Core Clocks */ + .core_clks = r8a77980_core_clks, + .num_core_clks = ARRAY_SIZE(r8a77980_core_clks), + .last_dt_core_clk = LAST_DT_CORE_CLK, + .num_total_core_clks = MOD_CLK_BASE, + + /* Module Clocks */ + .mod_clks = r8a77980_mod_clks, + .num_mod_clks = ARRAY_SIZE(r8a77980_mod_clks), + .num_hw_mod_clks = 12 * 32, + + /* Critical Module Clocks */ + .crit_mod_clks = r8a77980_crit_mod_clks, + .num_crit_mod_clks = ARRAY_SIZE(r8a77980_crit_mod_clks), + + /* Callbacks */ + .init = r8a77980_cpg_mssr_init, + .cpg_clk_register = rcar_gen3_cpg_clk_register, +}; diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index e3cc72c..aadfa6d 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -699,6 +699,12 @@ static const struct of_device_id cpg_mssr_match[] = { .data = &r8a77970_cpg_mssr_info, }, #endif +#ifdef CONFIG_ARCH_R8A77980 + { + .compatible = "renesas,r8a77980-cpg-mssr", + .data = &r8a77980_cpg_mssr_info, + }, +#endif #ifdef CONFIG_CLK_R8A77995 { .compatible = "renesas,r8a77995-cpg-mssr", diff --git a/drivers/clk/renesas/renesas-cpg-mssr.h b/drivers/clk/renesas/renesas-cpg-mssr.h index 0745b09..143293e 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.h +++ b/drivers/clk/renesas/renesas-cpg-mssr.h @@ -140,6 +140,7 @@ extern const struct cpg_mssr_info r8a7794_cpg_mssr_info; extern const struct cpg_mssr_info r8a7795_cpg_mssr_info; extern const struct cpg_mssr_info r8a7796_cpg_mssr_info; extern const struct cpg_mssr_info r8a77970_cpg_mssr_info; +extern const struct cpg_mssr_info r8a77980_cpg_mssr_info; extern const struct cpg_mssr_info r8a77995_cpg_mssr_info; -- cgit v1.1 From 7ce36da900c0a2ff4777d9ba51c4f1cb74205463 Mon Sep 17 00:00:00 2001 From: Jacopo Mondi Date: Tue, 20 Feb 2018 16:12:03 +0100 Subject: clk: renesas: cpg-mssr: Add support for R-Car M3-N Initial support for R-Car M3-N (r8a77965), including core and module clocks. Based on Table 8.2d of "R-Car Series, 3rd Generation User's Manual: Hardware (Rev. 0.80, Oct 31, 2017)". Signed-off-by: Jacopo Mondi Signed-off-by: Geert Uytterhoeven --- .../devicetree/bindings/clock/renesas,cpg-mssr.txt | 5 +- drivers/clk/renesas/Kconfig | 5 + drivers/clk/renesas/Makefile | 1 + drivers/clk/renesas/r8a77965-cpg-mssr.c | 334 +++++++++++++++++++++ drivers/clk/renesas/renesas-cpg-mssr.c | 6 + drivers/clk/renesas/renesas-cpg-mssr.h | 1 + include/dt-bindings/clock/r8a77965-cpg-mssr.h | 62 ++++ 7 files changed, 412 insertions(+), 2 deletions(-) create mode 100644 drivers/clk/renesas/r8a77965-cpg-mssr.c create mode 100644 include/dt-bindings/clock/r8a77965-cpg-mssr.h diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt index bc4ea08..773a522 100644 --- a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt +++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt @@ -22,6 +22,7 @@ Required Properties: - "renesas,r8a7794-cpg-mssr" for the r8a7794 SoC (R-Car E2) - "renesas,r8a7795-cpg-mssr" for the r8a7795 SoC (R-Car H3) - "renesas,r8a7796-cpg-mssr" for the r8a7796 SoC (R-Car M3-W) + - "renesas,r8a77965-cpg-mssr" for the r8a77965 SoC (R-Car M3-N) - "renesas,r8a77970-cpg-mssr" for the r8a77970 SoC (R-Car V3M) - "renesas,r8a77980-cpg-mssr" for the r8a77980 SoC (R-Car V3H) - "renesas,r8a77995-cpg-mssr" for the r8a77995 SoC (R-Car D3) @@ -33,8 +34,8 @@ Required Properties: clock-names - clock-names: List of external parent clock names. Valid names are: - "extal" (r8a7743, r8a7745, r8a7790, r8a7791, r8a7792, r8a7793, r8a7794, - r8a7795, r8a7796, r8a77970, r8a77980, r8a77995) - - "extalr" (r8a7795, r8a7796, r8a77970, r8a77980) + r8a7795, r8a7796, r8a77965, r8a77970, r8a77980, r8a77995) + - "extalr" (r8a7795, r8a7796, r8a77965, r8a77970, r8a77980) - "usb_extal" (r8a7743, r8a7745, r8a7790, r8a7791, r8a7793, r8a7794) - #clock-cells: Must be 2 diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig index 43bab4f..ef76c86 100644 --- a/drivers/clk/renesas/Kconfig +++ b/drivers/clk/renesas/Kconfig @@ -15,6 +15,7 @@ config CLK_RENESAS select CLK_R8A7794 if ARCH_R8A7794 select CLK_R8A7795 if ARCH_R8A7795 select CLK_R8A7796 if ARCH_R8A7796 + select CLK_R8A77965 if ARCH_R8A77965 select CLK_R8A77970 if ARCH_R8A77970 select CLK_R8A77980 if ARCH_R8A77980 select CLK_R8A77995 if ARCH_R8A77995 @@ -98,6 +99,10 @@ config CLK_R8A7796 bool "R-Car M3-W clock support" if COMPILE_TEST select CLK_RCAR_GEN3_CPG +config CLK_R8A77965 + bool "R-Car M3-N clock support" if COMPILE_TEST + select CLK_RCAR_GEN3_CPG + config CLK_R8A77970 bool "R-Car V3M clock support" if COMPILE_TEST select CLK_RCAR_GEN3_CPG diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile index e20fa19..6c0f196 100644 --- a/drivers/clk/renesas/Makefile +++ b/drivers/clk/renesas/Makefile @@ -14,6 +14,7 @@ obj-$(CONFIG_CLK_R8A7792) += r8a7792-cpg-mssr.o obj-$(CONFIG_CLK_R8A7794) += r8a7794-cpg-mssr.o obj-$(CONFIG_CLK_R8A7795) += r8a7795-cpg-mssr.o obj-$(CONFIG_CLK_R8A7796) += r8a7796-cpg-mssr.o +obj-$(CONFIG_CLK_R8A77965) += r8a77965-cpg-mssr.o obj-$(CONFIG_CLK_R8A77970) += r8a77970-cpg-mssr.o obj-$(CONFIG_CLK_R8A77980) += r8a77980-cpg-mssr.o obj-$(CONFIG_CLK_R8A77995) += r8a77995-cpg-mssr.o diff --git a/drivers/clk/renesas/r8a77965-cpg-mssr.c b/drivers/clk/renesas/r8a77965-cpg-mssr.c new file mode 100644 index 0000000..41e506a --- /dev/null +++ b/drivers/clk/renesas/r8a77965-cpg-mssr.c @@ -0,0 +1,334 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * r8a77965 Clock Pulse Generator / Module Standby and Software Reset + * + * Copyright (C) 2018 Jacopo Mondi + * + * Based on r8a7795-cpg-mssr.c + * + * Copyright (C) 2015 Glider bvba + * Copyright (C) 2015 Renesas Electronics Corp. + */ + +#include +#include +#include +#include + +#include + +#include "renesas-cpg-mssr.h" +#include "rcar-gen3-cpg.h" + +enum clk_ids { + /* Core Clock Outputs exported to DT */ + LAST_DT_CORE_CLK = R8A77965_CLK_OSC, + + /* External Input Clocks */ + CLK_EXTAL, + CLK_EXTALR, + + /* Internal Core Clocks */ + CLK_MAIN, + CLK_PLL0, + CLK_PLL1, + CLK_PLL3, + CLK_PLL4, + CLK_PLL1_DIV2, + CLK_PLL1_DIV4, + CLK_S0, + CLK_S1, + CLK_S2, + CLK_S3, + CLK_SDSRC, + CLK_SSPSRC, + CLK_RINT, + + /* Module Clocks */ + MOD_CLK_BASE +}; + +static const struct cpg_core_clk r8a77965_core_clks[] __initconst = { + /* External Clock Inputs */ + DEF_INPUT("extal", CLK_EXTAL), + DEF_INPUT("extalr", CLK_EXTALR), + + /* Internal Core Clocks */ + DEF_BASE(".main", CLK_MAIN, CLK_TYPE_GEN3_MAIN, CLK_EXTAL), + DEF_BASE(".pll0", CLK_PLL0, CLK_TYPE_GEN3_PLL0, CLK_MAIN), + DEF_BASE(".pll1", CLK_PLL1, CLK_TYPE_GEN3_PLL1, CLK_MAIN), + DEF_BASE(".pll3", CLK_PLL3, CLK_TYPE_GEN3_PLL3, CLK_MAIN), + DEF_BASE(".pll4", CLK_PLL4, CLK_TYPE_GEN3_PLL4, CLK_MAIN), + + DEF_FIXED(".pll1_div2", CLK_PLL1_DIV2, CLK_PLL1, 2, 1), + DEF_FIXED(".pll1_div4", CLK_PLL1_DIV4, CLK_PLL1_DIV2, 2, 1), + DEF_FIXED(".s0", CLK_S0, CLK_PLL1_DIV2, 2, 1), + DEF_FIXED(".s1", CLK_S1, CLK_PLL1_DIV2, 3, 1), + DEF_FIXED(".s2", CLK_S2, CLK_PLL1_DIV2, 4, 1), + DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 6, 1), + DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1_DIV2, 2, 1), + + /* Core Clock Outputs */ + DEF_BASE("z", R8A77965_CLK_Z, CLK_TYPE_GEN3_Z, CLK_PLL0), + DEF_FIXED("ztr", R8A77965_CLK_ZTR, CLK_PLL1_DIV2, 6, 1), + DEF_FIXED("ztrd2", R8A77965_CLK_ZTRD2, CLK_PLL1_DIV2, 12, 1), + DEF_FIXED("zt", R8A77965_CLK_ZT, CLK_PLL1_DIV2, 4, 1), + DEF_FIXED("zx", R8A77965_CLK_ZX, CLK_PLL1_DIV2, 2, 1), + DEF_FIXED("s0d1", R8A77965_CLK_S0D1, CLK_S0, 1, 1), + DEF_FIXED("s0d2", R8A77965_CLK_S0D2, CLK_S0, 2, 1), + DEF_FIXED("s0d3", R8A77965_CLK_S0D3, CLK_S0, 3, 1), + DEF_FIXED("s0d4", R8A77965_CLK_S0D4, CLK_S0, 4, 1), + DEF_FIXED("s0d6", R8A77965_CLK_S0D6, CLK_S0, 6, 1), + DEF_FIXED("s0d8", R8A77965_CLK_S0D8, CLK_S0, 8, 1), + DEF_FIXED("s0d12", R8A77965_CLK_S0D12, CLK_S0, 12, 1), + DEF_FIXED("s1d1", R8A77965_CLK_S1D1, CLK_S1, 1, 1), + DEF_FIXED("s1d2", R8A77965_CLK_S1D2, CLK_S1, 2, 1), + DEF_FIXED("s1d4", R8A77965_CLK_S1D4, CLK_S1, 4, 1), + DEF_FIXED("s2d1", R8A77965_CLK_S2D1, CLK_S2, 1, 1), + DEF_FIXED("s2d2", R8A77965_CLK_S2D2, CLK_S2, 2, 1), + DEF_FIXED("s2d4", R8A77965_CLK_S2D4, CLK_S2, 4, 1), + DEF_FIXED("s3d1", R8A77965_CLK_S3D1, CLK_S3, 1, 1), + DEF_FIXED("s3d2", R8A77965_CLK_S3D2, CLK_S3, 2, 1), + DEF_FIXED("s3d4", R8A77965_CLK_S3D4, CLK_S3, 4, 1), + + DEF_GEN3_SD("sd0", R8A77965_CLK_SD0, CLK_SDSRC, 0x074), + DEF_GEN3_SD("sd1", R8A77965_CLK_SD1, CLK_SDSRC, 0x078), + DEF_GEN3_SD("sd2", R8A77965_CLK_SD2, CLK_SDSRC, 0x268), + DEF_GEN3_SD("sd3", R8A77965_CLK_SD3, CLK_SDSRC, 0x26c), + + DEF_FIXED("cl", R8A77965_CLK_CL, CLK_PLL1_DIV2, 48, 1), + DEF_FIXED("cp", R8A77965_CLK_CP, CLK_EXTAL, 2, 1), + + DEF_DIV6P1("canfd", R8A77965_CLK_CANFD, CLK_PLL1_DIV4, 0x244), + DEF_DIV6P1("csi0", R8A77965_CLK_CSI0, CLK_PLL1_DIV4, 0x00c), + DEF_DIV6P1("mso", R8A77965_CLK_MSO, CLK_PLL1_DIV4, 0x014), + DEF_DIV6P1("hdmi", R8A77965_CLK_HDMI, CLK_PLL1_DIV4, 0x250), + + DEF_DIV6_RO("osc", R8A77965_CLK_OSC, CLK_EXTAL, CPG_RCKCR, 8), + DEF_DIV6_RO("r_int", CLK_RINT, CLK_EXTAL, CPG_RCKCR, 32), + + DEF_BASE("r", R8A77965_CLK_R, CLK_TYPE_GEN3_R, CLK_RINT), +}; + +static const struct mssr_mod_clk r8a77965_mod_clks[] __initconst = { + DEF_MOD("scif5", 202, R8A77965_CLK_S3D4), + DEF_MOD("scif4", 203, R8A77965_CLK_S3D4), + DEF_MOD("scif3", 204, R8A77965_CLK_S3D4), + DEF_MOD("scif1", 206, R8A77965_CLK_S3D4), + DEF_MOD("scif0", 207, R8A77965_CLK_S3D4), + DEF_MOD("sys-dmac2", 217, R8A77965_CLK_S0D3), + DEF_MOD("sys-dmac1", 218, R8A77965_CLK_S0D3), + DEF_MOD("sys-dmac0", 219, R8A77965_CLK_S0D3), + + DEF_MOD("cmt3", 300, R8A77965_CLK_R), + DEF_MOD("cmt2", 301, R8A77965_CLK_R), + DEF_MOD("cmt1", 302, R8A77965_CLK_R), + DEF_MOD("cmt0", 303, R8A77965_CLK_R), + DEF_MOD("scif2", 310, R8A77965_CLK_S3D4), + DEF_MOD("sdif3", 311, R8A77965_CLK_SD3), + DEF_MOD("sdif2", 312, R8A77965_CLK_SD2), + DEF_MOD("sdif1", 313, R8A77965_CLK_SD1), + DEF_MOD("sdif0", 314, R8A77965_CLK_SD0), + DEF_MOD("pcie1", 318, R8A77965_CLK_S3D1), + DEF_MOD("pcie0", 319, R8A77965_CLK_S3D1), + DEF_MOD("usb3-if0", 328, R8A77965_CLK_S3D1), + DEF_MOD("usb-dmac0", 330, R8A77965_CLK_S3D1), + DEF_MOD("usb-dmac1", 331, R8A77965_CLK_S3D1), + + DEF_MOD("rwdt", 402, R8A77965_CLK_R), + DEF_MOD("intc-ex", 407, R8A77965_CLK_CP), + DEF_MOD("intc-ap", 408, R8A77965_CLK_S0D3), + + DEF_MOD("audmac1", 501, R8A77965_CLK_S0D3), + DEF_MOD("audmac0", 502, R8A77965_CLK_S0D3), + DEF_MOD("drif7", 508, R8A77965_CLK_S3D2), + DEF_MOD("drif6", 509, R8A77965_CLK_S3D2), + DEF_MOD("drif5", 510, R8A77965_CLK_S3D2), + DEF_MOD("drif4", 511, R8A77965_CLK_S3D2), + DEF_MOD("drif3", 512, R8A77965_CLK_S3D2), + DEF_MOD("drif2", 513, R8A77965_CLK_S3D2), + DEF_MOD("drif1", 514, R8A77965_CLK_S3D2), + DEF_MOD("drif0", 515, R8A77965_CLK_S3D2), + DEF_MOD("hscif4", 516, R8A77965_CLK_S3D1), + DEF_MOD("hscif3", 517, R8A77965_CLK_S3D1), + DEF_MOD("hscif2", 518, R8A77965_CLK_S3D1), + DEF_MOD("hscif1", 519, R8A77965_CLK_S3D1), + DEF_MOD("hscif0", 520, R8A77965_CLK_S3D1), + DEF_MOD("thermal", 522, R8A77965_CLK_CP), + DEF_MOD("pwm", 523, R8A77965_CLK_S0D12), + + DEF_MOD("fcpvd1", 602, R8A77965_CLK_S0D2), + DEF_MOD("fcpvd0", 603, R8A77965_CLK_S0D2), + DEF_MOD("fcpvb0", 607, R8A77965_CLK_S0D1), + DEF_MOD("fcpvi0", 611, R8A77965_CLK_S0D1), + DEF_MOD("fcpf0", 615, R8A77965_CLK_S0D1), + DEF_MOD("fcpcs", 619, R8A77965_CLK_S0D2), + DEF_MOD("vspd1", 622, R8A77965_CLK_S0D2), + DEF_MOD("vspd0", 623, R8A77965_CLK_S0D2), + DEF_MOD("vspb", 626, R8A77965_CLK_S0D1), + DEF_MOD("vspi0", 631, R8A77965_CLK_S0D1), + + DEF_MOD("ehci1", 702, R8A77965_CLK_S3D4), + DEF_MOD("ehci0", 703, R8A77965_CLK_S3D4), + DEF_MOD("hsusb", 704, R8A77965_CLK_S3D4), + DEF_MOD("csi20", 714, R8A77965_CLK_CSI0), + DEF_MOD("csi40", 716, R8A77965_CLK_CSI0), + DEF_MOD("du2", 722, R8A77965_CLK_S2D1), + DEF_MOD("du1", 723, R8A77965_CLK_S2D1), + DEF_MOD("du0", 724, R8A77965_CLK_S2D1), + DEF_MOD("lvds", 727, R8A77965_CLK_S2D1), + DEF_MOD("hdmi0", 729, R8A77965_CLK_HDMI), + + DEF_MOD("vin7", 804, R8A77965_CLK_S0D2), + DEF_MOD("vin6", 805, R8A77965_CLK_S0D2), + DEF_MOD("vin5", 806, R8A77965_CLK_S0D2), + DEF_MOD("vin4", 807, R8A77965_CLK_S0D2), + DEF_MOD("vin3", 808, R8A77965_CLK_S0D2), + DEF_MOD("vin2", 809, R8A77965_CLK_S0D2), + DEF_MOD("vin1", 810, R8A77965_CLK_S0D2), + DEF_MOD("vin0", 811, R8A77965_CLK_S0D2), + DEF_MOD("etheravb", 812, R8A77965_CLK_S0D6), + DEF_MOD("imr1", 822, R8A77965_CLK_S0D2), + DEF_MOD("imr0", 823, R8A77965_CLK_S0D2), + + DEF_MOD("gpio7", 905, R8A77965_CLK_S3D4), + DEF_MOD("gpio6", 906, R8A77965_CLK_S3D4), + DEF_MOD("gpio5", 907, R8A77965_CLK_S3D4), + DEF_MOD("gpio4", 908, R8A77965_CLK_S3D4), + DEF_MOD("gpio3", 909, R8A77965_CLK_S3D4), + DEF_MOD("gpio2", 910, R8A77965_CLK_S3D4), + DEF_MOD("gpio1", 911, R8A77965_CLK_S3D4), + DEF_MOD("gpio0", 912, R8A77965_CLK_S3D4), + DEF_MOD("can-fd", 914, R8A77965_CLK_S3D2), + DEF_MOD("can-if1", 915, R8A77965_CLK_S3D4), + DEF_MOD("can-if0", 916, R8A77965_CLK_S3D4), + DEF_MOD("i2c6", 918, R8A77965_CLK_S0D6), + DEF_MOD("i2c5", 919, R8A77965_CLK_S0D6), + DEF_MOD("i2c-dvfs", 926, R8A77965_CLK_CP), + DEF_MOD("i2c4", 927, R8A77965_CLK_S0D6), + DEF_MOD("i2c3", 928, R8A77965_CLK_S0D6), + DEF_MOD("i2c2", 929, R8A77965_CLK_S3D2), + DEF_MOD("i2c1", 930, R8A77965_CLK_S3D2), + DEF_MOD("i2c0", 931, R8A77965_CLK_S3D2), + + DEF_MOD("ssi-all", 1005, R8A77965_CLK_S3D4), + DEF_MOD("ssi9", 1006, MOD_CLK_ID(1005)), + DEF_MOD("ssi8", 1007, MOD_CLK_ID(1005)), + DEF_MOD("ssi7", 1008, MOD_CLK_ID(1005)), + DEF_MOD("ssi6", 1009, MOD_CLK_ID(1005)), + DEF_MOD("ssi5", 1010, MOD_CLK_ID(1005)), + DEF_MOD("ssi4", 1011, MOD_CLK_ID(1005)), + DEF_MOD("ssi3", 1012, MOD_CLK_ID(1005)), + DEF_MOD("ssi2", 1013, MOD_CLK_ID(1005)), + DEF_MOD("ssi1", 1014, MOD_CLK_ID(1005)), + DEF_MOD("ssi0", 1015, MOD_CLK_ID(1005)), + DEF_MOD("scu-all", 1017, R8A77965_CLK_S3D4), + DEF_MOD("scu-dvc1", 1018, MOD_CLK_ID(1017)), + DEF_MOD("scu-dvc0", 1019, MOD_CLK_ID(1017)), + DEF_MOD("scu-ctu1-mix1", 1020, MOD_CLK_ID(1017)), + DEF_MOD("scu-ctu0-mix0", 1021, MOD_CLK_ID(1017)), + DEF_MOD("scu-src9", 1022, MOD_CLK_ID(1017)), + DEF_MOD("scu-src8", 1023, MOD_CLK_ID(1017)), + DEF_MOD("scu-src7", 1024, MOD_CLK_ID(1017)), + DEF_MOD("scu-src6", 1025, MOD_CLK_ID(1017)), + DEF_MOD("scu-src5", 1026, MOD_CLK_ID(1017)), + DEF_MOD("scu-src4", 1027, MOD_CLK_ID(1017)), + DEF_MOD("scu-src3", 1028, MOD_CLK_ID(1017)), + DEF_MOD("scu-src2", 1029, MOD_CLK_ID(1017)), + DEF_MOD("scu-src1", 1030, MOD_CLK_ID(1017)), + DEF_MOD("scu-src0", 1031, MOD_CLK_ID(1017)), +}; + +static const unsigned int r8a77965_crit_mod_clks[] __initconst = { + MOD_CLK_ID(408), /* INTC-AP (GIC) */ +}; + +/* + * CPG Clock Data + */ + +/* + * MD EXTAL PLL0 PLL1 PLL3 PLL4 + * 14 13 19 17 (MHz) + *----------------------------------------------------------- + * 0 0 0 0 16.66 x 1 x180 x192 x192 x144 + * 0 0 0 1 16.66 x 1 x180 x192 x128 x144 + * 0 0 1 0 Prohibited setting + * 0 0 1 1 16.66 x 1 x180 x192 x192 x144 + * 0 1 0 0 20 x 1 x150 x160 x160 x120 + * 0 1 0 1 20 x 1 x150 x160 x106 x120 + * 0 1 1 0 Prohibited setting + * 0 1 1 1 20 x 1 x150 x160 x160 x120 + * 1 0 0 0 25 x 1 x120 x128 x128 x96 + * 1 0 0 1 25 x 1 x120 x128 x84 x96 + * 1 0 1 0 Prohibited setting + * 1 0 1 1 25 x 1 x120 x128 x128 x96 + * 1 1 0 0 33.33 / 2 x180 x192 x192 x144 + * 1 1 0 1 33.33 / 2 x180 x192 x128 x144 + * 1 1 1 0 Prohibited setting + * 1 1 1 1 33.33 / 2 x180 x192 x192 x144 + */ +#define CPG_PLL_CONFIG_INDEX(md) ((((md) & BIT(14)) >> 11) | \ + (((md) & BIT(13)) >> 11) | \ + (((md) & BIT(19)) >> 18) | \ + (((md) & BIT(17)) >> 17)) + +static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[16] __initconst = { + /* EXTAL div PLL1 mult/div PLL3 mult/div */ + { 1, 192, 1, 192, 1, }, + { 1, 192, 1, 128, 1, }, + { 0, /* Prohibited setting */ }, + { 1, 192, 1, 192, 1, }, + { 1, 160, 1, 160, 1, }, + { 1, 160, 1, 106, 1, }, + { 0, /* Prohibited setting */ }, + { 1, 160, 1, 160, 1, }, + { 1, 128, 1, 128, 1, }, + { 1, 128, 1, 84, 1, }, + { 0, /* Prohibited setting */ }, + { 1, 128, 1, 128, 1, }, + { 2, 192, 1, 192, 1, }, + { 2, 192, 1, 128, 1, }, + { 0, /* Prohibited setting */ }, + { 2, 192, 1, 192, 1, }, +}; + +static int __init r8a77965_cpg_mssr_init(struct device *dev) +{ + const struct rcar_gen3_cpg_pll_config *cpg_pll_config; + u32 cpg_mode; + int error; + + error = rcar_rst_read_mode_pins(&cpg_mode); + if (error) + return error; + + cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)]; + if (!cpg_pll_config->extal_div) { + dev_err(dev, "Prohibited setting (cpg_mode=0x%x)\n", cpg_mode); + return -EINVAL; + } + + return rcar_gen3_cpg_init(cpg_pll_config, CLK_EXTALR, cpg_mode); +}; + +const struct cpg_mssr_info r8a77965_cpg_mssr_info __initconst = { + /* Core Clocks */ + .core_clks = r8a77965_core_clks, + .num_core_clks = ARRAY_SIZE(r8a77965_core_clks), + .last_dt_core_clk = LAST_DT_CORE_CLK, + .num_total_core_clks = MOD_CLK_BASE, + + /* Module Clocks */ + .mod_clks = r8a77965_mod_clks, + .num_mod_clks = ARRAY_SIZE(r8a77965_mod_clks), + .num_hw_mod_clks = 12 * 32, + + /* Critical Module Clocks */ + .crit_mod_clks = r8a77965_crit_mod_clks, + .num_crit_mod_clks = ARRAY_SIZE(r8a77965_crit_mod_clks), + + /* Callbacks */ + .init = r8a77965_cpg_mssr_init, + .cpg_clk_register = rcar_gen3_cpg_clk_register, +}; diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index aadfa6d..96c6787 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -693,6 +693,12 @@ static const struct of_device_id cpg_mssr_match[] = { .data = &r8a7796_cpg_mssr_info, }, #endif +#ifdef CONFIG_CLK_R8A77965 + { + .compatible = "renesas,r8a77965-cpg-mssr", + .data = &r8a77965_cpg_mssr_info, + }, +#endif #ifdef CONFIG_CLK_R8A77970 { .compatible = "renesas,r8a77970-cpg-mssr", diff --git a/drivers/clk/renesas/renesas-cpg-mssr.h b/drivers/clk/renesas/renesas-cpg-mssr.h index 143293e..97ccb09 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.h +++ b/drivers/clk/renesas/renesas-cpg-mssr.h @@ -139,6 +139,7 @@ extern const struct cpg_mssr_info r8a7792_cpg_mssr_info; extern const struct cpg_mssr_info r8a7794_cpg_mssr_info; extern const struct cpg_mssr_info r8a7795_cpg_mssr_info; extern const struct cpg_mssr_info r8a7796_cpg_mssr_info; +extern const struct cpg_mssr_info r8a77965_cpg_mssr_info; extern const struct cpg_mssr_info r8a77970_cpg_mssr_info; extern const struct cpg_mssr_info r8a77980_cpg_mssr_info; extern const struct cpg_mssr_info r8a77995_cpg_mssr_info; diff --git a/include/dt-bindings/clock/r8a77965-cpg-mssr.h b/include/dt-bindings/clock/r8a77965-cpg-mssr.h new file mode 100644 index 0000000..6d3b5a9 --- /dev/null +++ b/include/dt-bindings/clock/r8a77965-cpg-mssr.h @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2018 Jacopo Mondi + */ +#ifndef __DT_BINDINGS_CLOCK_R8A77965_CPG_MSSR_H__ +#define __DT_BINDINGS_CLOCK_R8A77965_CPG_MSSR_H__ + +#include + +/* r8a77965 CPG Core Clocks */ +#define R8A77965_CLK_Z 0 +#define R8A77965_CLK_ZR 1 +#define R8A77965_CLK_ZG 2 +#define R8A77965_CLK_ZTR 3 +#define R8A77965_CLK_ZTRD2 4 +#define R8A77965_CLK_ZT 5 +#define R8A77965_CLK_ZX 6 +#define R8A77965_CLK_S0D1 7 +#define R8A77965_CLK_S0D2 8 +#define R8A77965_CLK_S0D3 9 +#define R8A77965_CLK_S0D4 10 +#define R8A77965_CLK_S0D6 11 +#define R8A77965_CLK_S0D8 12 +#define R8A77965_CLK_S0D12 13 +#define R8A77965_CLK_S1D1 14 +#define R8A77965_CLK_S1D2 15 +#define R8A77965_CLK_S1D4 16 +#define R8A77965_CLK_S2D1 17 +#define R8A77965_CLK_S2D2 18 +#define R8A77965_CLK_S2D4 19 +#define R8A77965_CLK_S3D1 20 +#define R8A77965_CLK_S3D2 21 +#define R8A77965_CLK_S3D4 22 +#define R8A77965_CLK_LB 23 +#define R8A77965_CLK_CL 24 +#define R8A77965_CLK_ZB3 25 +#define R8A77965_CLK_ZB3D2 26 +#define R8A77965_CLK_CR 27 +#define R8A77965_CLK_CRD2 28 +#define R8A77965_CLK_SD0H 29 +#define R8A77965_CLK_SD0 30 +#define R8A77965_CLK_SD1H 31 +#define R8A77965_CLK_SD1 32 +#define R8A77965_CLK_SD2H 33 +#define R8A77965_CLK_SD2 34 +#define R8A77965_CLK_SD3H 35 +#define R8A77965_CLK_SD3 36 +#define R8A77965_CLK_SSP2 37 +#define R8A77965_CLK_SSP1 38 +#define R8A77965_CLK_SSPRS 39 +#define R8A77965_CLK_RPC 40 +#define R8A77965_CLK_RPCD2 41 +#define R8A77965_CLK_MSO 42 +#define R8A77965_CLK_CANFD 43 +#define R8A77965_CLK_HDMI 44 +#define R8A77965_CLK_CSI0 45 +#define R8A77965_CLK_CP 46 +#define R8A77965_CLK_CPEX 47 +#define R8A77965_CLK_R 48 +#define R8A77965_CLK_OSC 49 + +#endif /* __DT_BINDINGS_CLOCK_R8A77965_CPG_MSSR_H__ */ -- cgit v1.1 From 055d56891ea7a6bb39444db58ea30eafa5a1cb40 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Wed, 24 Jan 2018 19:48:23 +0800 Subject: clk: hi3798cv200: fix unregister call sequence in error path The unregister call sequence in error path of function hi3798cv200_clk_register() should be opposite to the order of register calls. Let's reverse the call sequence to fix the problem. Signed-off-by: Shawn Guo --- drivers/clk/hisilicon/crg-hi3798cv200.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/clk/hisilicon/crg-hi3798cv200.c b/drivers/clk/hisilicon/crg-hi3798cv200.c index 8478948..c586c79 100644 --- a/drivers/clk/hisilicon/crg-hi3798cv200.c +++ b/drivers/clk/hisilicon/crg-hi3798cv200.c @@ -202,18 +202,17 @@ static struct hisi_clock_data *hi3798cv200_clk_register( return clk_data; -unregister_fixed_rate: - hisi_clk_unregister_fixed_rate(hi3798cv200_fixed_rate_clks, - ARRAY_SIZE(hi3798cv200_fixed_rate_clks), +unregister_gate: + hisi_clk_unregister_gate(hi3798cv200_gate_clks, + ARRAY_SIZE(hi3798cv200_gate_clks), clk_data); - unregister_mux: hisi_clk_unregister_mux(hi3798cv200_mux_clks, ARRAY_SIZE(hi3798cv200_mux_clks), clk_data); -unregister_gate: - hisi_clk_unregister_gate(hi3798cv200_gate_clks, - ARRAY_SIZE(hi3798cv200_gate_clks), +unregister_fixed_rate: + hisi_clk_unregister_fixed_rate(hi3798cv200_fixed_rate_clks, + ARRAY_SIZE(hi3798cv200_fixed_rate_clks), clk_data); return ERR_PTR(ret); } -- cgit v1.1 From 47629f676518f1808dc98c5740a31d8d23c940c7 Mon Sep 17 00:00:00 2001 From: Younian Wang Date: Wed, 24 Jan 2018 19:48:24 +0800 Subject: clk: hi3798cv200: correct IR clock parent The IR clock is sourced from '24m' rather than '100m'. Correct it. Signed-off-by: Younian Wang Signed-off-by: Shawn Guo --- drivers/clk/hisilicon/crg-hi3798cv200.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/hisilicon/crg-hi3798cv200.c b/drivers/clk/hisilicon/crg-hi3798cv200.c index c586c79..d7d1ba0 100644 --- a/drivers/clk/hisilicon/crg-hi3798cv200.c +++ b/drivers/clk/hisilicon/crg-hi3798cv200.c @@ -244,7 +244,7 @@ static const struct hisi_crg_funcs hi3798cv200_crg_funcs = { #define HI3798CV200_SYSCTRL_NR_CLKS 16 static const struct hisi_gate_clock hi3798cv200_sysctrl_gate_clks[] = { - { HISTB_IR_CLK, "clk_ir", "100m", + { HISTB_IR_CLK, "clk_ir", "24m", CLK_SET_RATE_PARENT, 0x48, 4, 0, }, { HISTB_TIMER01_CLK, "clk_timer01", "24m", CLK_SET_RATE_PARENT, 0x48, 6, 0, }, -- cgit v1.1 From 50fd588ae4a6808d9ecd09c3ffe587e306bfa6a9 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Wed, 24 Jan 2018 19:48:25 +0800 Subject: clk: hi3798cv200: add support for HISTB_USB2_OTG_UTMI_CLK The clock HISTB_USB2_OTG_UTMI_CLK is defined by device tree bindings in include/dt-bindings/clock/histb-clock.h, but hasn't been supported by hi3798cv200 clock driver. Let's add the support for it. Signed-off-by: Shawn Guo --- drivers/clk/hisilicon/crg-hi3798cv200.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/clk/hisilicon/crg-hi3798cv200.c b/drivers/clk/hisilicon/crg-hi3798cv200.c index d7d1ba0..6017ade 100644 --- a/drivers/clk/hisilicon/crg-hi3798cv200.c +++ b/drivers/clk/hisilicon/crg-hi3798cv200.c @@ -161,6 +161,8 @@ static const struct hisi_gate_clock hi3798cv200_gate_clks[] = { CLK_SET_RATE_PARENT, 0xb8, 1, 0 }, { HISTB_USB2_UTMI_CLK, "clk_u2_utmi", "60m", CLK_SET_RATE_PARENT, 0xb8, 5, 0 }, + { HISTB_USB2_OTG_UTMI_CLK, "clk_u2_otg_utmi", "60m", + CLK_SET_RATE_PARENT, 0xb8, 3, 0 }, { HISTB_USB2_PHY1_REF_CLK, "clk_u2_phy1_ref", "24m", CLK_SET_RATE_PARENT, 0xbc, 0, 0 }, { HISTB_USB2_PHY2_REF_CLK, "clk_u2_phy2_ref", "24m", -- cgit v1.1 From a44d1f531a39da8cd6497372e713f5998b2d67af Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Wed, 24 Jan 2018 19:48:26 +0800 Subject: clk: hi3798cv200: fix define indentation It's a coding-style fix, which corrects the indentation for all those clock definitions, so that the code looks nicer and new definitions can be added with a recommended indentation. Signed-off-by: Shawn Guo --- drivers/clk/hisilicon/crg-hi3798cv200.c | 48 ++++++++++++++--------------- include/dt-bindings/clock/histb-clock.h | 54 ++++++++++++++++----------------- 2 files changed, 51 insertions(+), 51 deletions(-) diff --git a/drivers/clk/hisilicon/crg-hi3798cv200.c b/drivers/clk/hisilicon/crg-hi3798cv200.c index 6017ade..451830e 100644 --- a/drivers/clk/hisilicon/crg-hi3798cv200.c +++ b/drivers/clk/hisilicon/crg-hi3798cv200.c @@ -27,30 +27,30 @@ #include "reset.h" /* hi3798CV200 core CRG */ -#define HI3798CV200_INNER_CLK_OFFSET 64 -#define HI3798CV200_FIXED_24M 65 -#define HI3798CV200_FIXED_25M 66 -#define HI3798CV200_FIXED_50M 67 -#define HI3798CV200_FIXED_75M 68 -#define HI3798CV200_FIXED_100M 69 -#define HI3798CV200_FIXED_150M 70 -#define HI3798CV200_FIXED_200M 71 -#define HI3798CV200_FIXED_250M 72 -#define HI3798CV200_FIXED_300M 73 -#define HI3798CV200_FIXED_400M 74 -#define HI3798CV200_MMC_MUX 75 -#define HI3798CV200_ETH_PUB_CLK 76 -#define HI3798CV200_ETH_BUS_CLK 77 -#define HI3798CV200_ETH_BUS0_CLK 78 -#define HI3798CV200_ETH_BUS1_CLK 79 -#define HI3798CV200_COMBPHY1_MUX 80 -#define HI3798CV200_FIXED_12M 81 -#define HI3798CV200_FIXED_48M 82 -#define HI3798CV200_FIXED_60M 83 -#define HI3798CV200_FIXED_166P5M 84 -#define HI3798CV200_SDIO0_MUX 85 - -#define HI3798CV200_CRG_NR_CLKS 128 +#define HI3798CV200_INNER_CLK_OFFSET 64 +#define HI3798CV200_FIXED_24M 65 +#define HI3798CV200_FIXED_25M 66 +#define HI3798CV200_FIXED_50M 67 +#define HI3798CV200_FIXED_75M 68 +#define HI3798CV200_FIXED_100M 69 +#define HI3798CV200_FIXED_150M 70 +#define HI3798CV200_FIXED_200M 71 +#define HI3798CV200_FIXED_250M 72 +#define HI3798CV200_FIXED_300M 73 +#define HI3798CV200_FIXED_400M 74 +#define HI3798CV200_MMC_MUX 75 +#define HI3798CV200_ETH_PUB_CLK 76 +#define HI3798CV200_ETH_BUS_CLK 77 +#define HI3798CV200_ETH_BUS0_CLK 78 +#define HI3798CV200_ETH_BUS1_CLK 79 +#define HI3798CV200_COMBPHY1_MUX 80 +#define HI3798CV200_FIXED_12M 81 +#define HI3798CV200_FIXED_48M 82 +#define HI3798CV200_FIXED_60M 83 +#define HI3798CV200_FIXED_166P5M 84 +#define HI3798CV200_SDIO0_MUX 85 + +#define HI3798CV200_CRG_NR_CLKS 128 static const struct hisi_fixed_rate_clock hi3798cv200_fixed_rate_clks[] = { { HISTB_OSC_CLK, "clk_osc", NULL, 0, 24000000, }, diff --git a/include/dt-bindings/clock/histb-clock.h b/include/dt-bindings/clock/histb-clock.h index 067f5e5..eba850f 100644 --- a/include/dt-bindings/clock/histb-clock.h +++ b/include/dt-bindings/clock/histb-clock.h @@ -22,18 +22,18 @@ #define HISTB_OSC_CLK 0 #define HISTB_APB_CLK 1 #define HISTB_AHB_CLK 2 -#define HISTB_UART1_CLK 3 -#define HISTB_UART2_CLK 4 -#define HISTB_UART3_CLK 5 -#define HISTB_I2C0_CLK 6 -#define HISTB_I2C1_CLK 7 -#define HISTB_I2C2_CLK 8 -#define HISTB_I2C3_CLK 9 -#define HISTB_I2C4_CLK 10 -#define HISTB_I2C5_CLK 11 -#define HISTB_SPI0_CLK 12 -#define HISTB_SPI1_CLK 13 -#define HISTB_SPI2_CLK 14 +#define HISTB_UART1_CLK 3 +#define HISTB_UART2_CLK 4 +#define HISTB_UART3_CLK 5 +#define HISTB_I2C0_CLK 6 +#define HISTB_I2C1_CLK 7 +#define HISTB_I2C2_CLK 8 +#define HISTB_I2C3_CLK 9 +#define HISTB_I2C4_CLK 10 +#define HISTB_I2C5_CLK 11 +#define HISTB_SPI0_CLK 12 +#define HISTB_SPI1_CLK 13 +#define HISTB_SPI2_CLK 14 #define HISTB_SCI_CLK 15 #define HISTB_FMC_CLK 16 #define HISTB_MMC_BIU_CLK 17 @@ -43,7 +43,7 @@ #define HISTB_SDIO0_BIU_CLK 21 #define HISTB_SDIO0_CIU_CLK 22 #define HISTB_SDIO0_DRV_CLK 23 -#define HISTB_SDIO0_SAMPLE_CLK 24 +#define HISTB_SDIO0_SAMPLE_CLK 24 #define HISTB_PCIE_AUX_CLK 25 #define HISTB_PCIE_PIPE_CLK 26 #define HISTB_PCIE_SYS_CLK 27 @@ -53,21 +53,21 @@ #define HISTB_ETH1_MAC_CLK 31 #define HISTB_ETH1_MACIF_CLK 32 #define HISTB_COMBPHY1_CLK 33 -#define HISTB_USB2_BUS_CLK 34 -#define HISTB_USB2_PHY_CLK 35 -#define HISTB_USB2_UTMI_CLK 36 -#define HISTB_USB2_12M_CLK 37 -#define HISTB_USB2_48M_CLK 38 -#define HISTB_USB2_OTG_UTMI_CLK 39 -#define HISTB_USB2_PHY1_REF_CLK 40 -#define HISTB_USB2_PHY2_REF_CLK 41 +#define HISTB_USB2_BUS_CLK 34 +#define HISTB_USB2_PHY_CLK 35 +#define HISTB_USB2_UTMI_CLK 36 +#define HISTB_USB2_12M_CLK 37 +#define HISTB_USB2_48M_CLK 38 +#define HISTB_USB2_OTG_UTMI_CLK 39 +#define HISTB_USB2_PHY1_REF_CLK 40 +#define HISTB_USB2_PHY2_REF_CLK 41 /* clocks provided by mcu CRG */ -#define HISTB_MCE_CLK 1 -#define HISTB_IR_CLK 2 -#define HISTB_TIMER01_CLK 3 -#define HISTB_LEDC_CLK 4 -#define HISTB_UART0_CLK 5 -#define HISTB_LSADC_CLK 6 +#define HISTB_MCE_CLK 1 +#define HISTB_IR_CLK 2 +#define HISTB_TIMER01_CLK 3 +#define HISTB_LEDC_CLK 4 +#define HISTB_UART0_CLK 5 +#define HISTB_LSADC_CLK 6 #endif /* __DTS_HISTB_CLOCK_H */ -- cgit v1.1 From 80f8ce589517c478abdae07a758b37b362886cb2 Mon Sep 17 00:00:00 2001 From: Jianguo Sun Date: Wed, 24 Jan 2018 19:48:27 +0800 Subject: clk: hi3798cv200: add COMBPHY0 clock support The clock COMBPHY1 has already been supported by hi3798cv200 driver, but COMBPHY0 is missing. It adds COMBPHY0 clock support. Since the mux table is being shared by COMBPHY0 and COMBPHY1, it renames comphy1_mux_p and comphy1_mux_table a bit to drop instance number '1' from there. Signed-off-by: Jianguo Sun Signed-off-by: Shawn Guo --- drivers/clk/hisilicon/crg-hi3798cv200.c | 15 +++++++++++---- include/dt-bindings/clock/histb-clock.h | 1 + 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/clk/hisilicon/crg-hi3798cv200.c b/drivers/clk/hisilicon/crg-hi3798cv200.c index 451830e..d6e3971 100644 --- a/drivers/clk/hisilicon/crg-hi3798cv200.c +++ b/drivers/clk/hisilicon/crg-hi3798cv200.c @@ -49,6 +49,7 @@ #define HI3798CV200_FIXED_60M 83 #define HI3798CV200_FIXED_166P5M 84 #define HI3798CV200_SDIO0_MUX 85 +#define HI3798CV200_COMBPHY0_MUX 86 #define HI3798CV200_CRG_NR_CLKS 128 @@ -74,9 +75,9 @@ static const char *const mmc_mux_p[] = { "100m", "50m", "25m", "200m", "150m" }; static u32 mmc_mux_table[] = {0, 1, 2, 3, 6}; -static const char *const comphy1_mux_p[] = { +static const char *const comphy_mux_p[] = { "100m", "25m"}; -static u32 comphy1_mux_table[] = {2, 3}; +static u32 comphy_mux_table[] = {2, 3}; static const char *const sdio_mux_p[] = { "100m", "50m", "150m", "166p5m" }; @@ -85,9 +86,12 @@ static u32 sdio_mux_table[] = {0, 1, 2, 3}; static struct hisi_mux_clock hi3798cv200_mux_clks[] = { { HI3798CV200_MMC_MUX, "mmc_mux", mmc_mux_p, ARRAY_SIZE(mmc_mux_p), CLK_SET_RATE_PARENT, 0xa0, 8, 3, 0, mmc_mux_table, }, + { HI3798CV200_COMBPHY0_MUX, "combphy0_mux", + comphy_mux_p, ARRAY_SIZE(comphy_mux_p), + CLK_SET_RATE_PARENT, 0x188, 2, 2, 0, comphy_mux_table, }, { HI3798CV200_COMBPHY1_MUX, "combphy1_mux", - comphy1_mux_p, ARRAY_SIZE(comphy1_mux_p), - CLK_SET_RATE_PARENT, 0x188, 10, 2, 0, comphy1_mux_table, }, + comphy_mux_p, ARRAY_SIZE(comphy_mux_p), + CLK_SET_RATE_PARENT, 0x188, 10, 2, 0, comphy_mux_table, }, { HI3798CV200_SDIO0_MUX, "sdio0_mux", sdio_mux_p, ARRAY_SIZE(sdio_mux_p), CLK_SET_RATE_PARENT, 0x9c, 8, 2, 0, sdio_mux_table, }, @@ -147,6 +151,9 @@ static const struct hisi_gate_clock hi3798cv200_gate_clks[] = { CLK_SET_RATE_PARENT, 0xcc, 4, 0, }, { HISTB_ETH1_MACIF_CLK, "clk_macif1", "clk_bus_m1", CLK_SET_RATE_PARENT, 0xcc, 25, 0, }, + /* COMBPHY0 */ + { HISTB_COMBPHY0_CLK, "clk_combphy0", "combphy0_mux", + CLK_SET_RATE_PARENT, 0x188, 0, 0, }, /* COMBPHY1 */ { HISTB_COMBPHY1_CLK, "clk_combphy1", "combphy1_mux", CLK_SET_RATE_PARENT, 0x188, 8, 0, }, diff --git a/include/dt-bindings/clock/histb-clock.h b/include/dt-bindings/clock/histb-clock.h index eba850f..fab30b3 100644 --- a/include/dt-bindings/clock/histb-clock.h +++ b/include/dt-bindings/clock/histb-clock.h @@ -61,6 +61,7 @@ #define HISTB_USB2_OTG_UTMI_CLK 39 #define HISTB_USB2_PHY1_REF_CLK 40 #define HISTB_USB2_PHY2_REF_CLK 41 +#define HISTB_COMBPHY0_CLK 42 /* clocks provided by mcu CRG */ #define HISTB_MCE_CLK 1 -- cgit v1.1 From 2d2b61c13a4b39c8ba6b9c1daa79d5891689864e Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Thu, 1 Mar 2018 22:34:27 +0100 Subject: clk: sunxi-ng: Add check for minimal rate to NM PLLs Some NM PLLs doesn't work well when their output clock rate is set below certain rate. Add support for that constrain. Signed-off-by: Jernej Skrabec Signed-off-by: Maxime Ripard --- drivers/clk/sunxi-ng/ccu_nm.c | 7 +++++++ drivers/clk/sunxi-ng/ccu_nm.h | 27 +++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/drivers/clk/sunxi-ng/ccu_nm.c b/drivers/clk/sunxi-ng/ccu_nm.c index a16de09..4e20733 100644 --- a/drivers/clk/sunxi-ng/ccu_nm.c +++ b/drivers/clk/sunxi-ng/ccu_nm.c @@ -117,6 +117,13 @@ static long ccu_nm_round_rate(struct clk_hw *hw, unsigned long rate, if (nm->common.features & CCU_FEATURE_FIXED_POSTDIV) rate *= nm->fixed_post_div; + if (rate < nm->min_rate) { + rate = nm->min_rate; + if (nm->common.features & CCU_FEATURE_FIXED_POSTDIV) + rate /= nm->fixed_post_div; + return rate; + } + if (ccu_frac_helper_has_rate(&nm->common, &nm->frac, rate)) { if (nm->common.features & CCU_FEATURE_FIXED_POSTDIV) rate /= nm->fixed_post_div; diff --git a/drivers/clk/sunxi-ng/ccu_nm.h b/drivers/clk/sunxi-ng/ccu_nm.h index eba586b..1d8b459 100644 --- a/drivers/clk/sunxi-ng/ccu_nm.h +++ b/drivers/clk/sunxi-ng/ccu_nm.h @@ -37,6 +37,7 @@ struct ccu_nm { struct ccu_sdm_internal sdm; unsigned int fixed_post_div; + unsigned int min_rate; struct ccu_common common; }; @@ -88,6 +89,32 @@ struct ccu_nm { }, \ } +#define SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN(_struct, _name, _parent, \ + _reg, _min_rate, \ + _nshift, _nwidth, \ + _mshift, _mwidth, \ + _frac_en, _frac_sel, \ + _frac_rate_0, _frac_rate_1,\ + _gate, _lock, _flags) \ + struct ccu_nm _struct = { \ + .enable = _gate, \ + .lock = _lock, \ + .n = _SUNXI_CCU_MULT(_nshift, _nwidth), \ + .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \ + .frac = _SUNXI_CCU_FRAC(_frac_en, _frac_sel, \ + _frac_rate_0, \ + _frac_rate_1), \ + .min_rate = _min_rate, \ + .common = { \ + .reg = _reg, \ + .features = CCU_FEATURE_FRACTIONAL, \ + .hw.init = CLK_HW_INIT(_name, \ + _parent, \ + &ccu_nm_ops, \ + _flags), \ + }, \ + } + #define SUNXI_CCU_NM_WITH_GATE_LOCK(_struct, _name, _parent, _reg, \ _nshift, _nwidth, \ _mshift, _mwidth, \ -- cgit v1.1 From 4fd8ae912f9829c4324fa85d945cc0288c218bc5 Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Thu, 1 Mar 2018 22:34:28 +0100 Subject: clk: sunxi-ng: h3: h5: Add minimal rate for video PLL Although user manuals for H3 and H5 SoCs state that minimal rate supported by video PLL is around 30 MHz, it seems that in reality minimal rate is around 192 MHz. Experiments showed that any rate below 96 MHz doesn't produce any video output at all. Even at this frequency, stable output depends on right factors. For example, when N = 4 and M = 1, output is stable and when N = 8 and M = 2, it's not. BSP clock driver suggest that minimum stable frequency is 192 MHz. That would also be in line with A64 SoC, which has similar periphery. Set minimal video PLL rate for H3/H5 to 192 MHz. Signed-off-by: Jernej Skrabec Signed-off-by: Maxime Ripard --- drivers/clk/sunxi-ng/ccu-sun8i-h3.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c index 29bc056..b9f3907 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c @@ -69,17 +69,18 @@ static SUNXI_CCU_NM_WITH_SDM_GATE_LOCK(pll_audio_base_clk, "pll-audio-base", BIT(28), /* lock */ CLK_SET_RATE_UNGATE); -static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video_clk, "pll-video", - "osc24M", 0x0010, - 8, 7, /* N */ - 0, 4, /* M */ - BIT(24), /* frac enable */ - BIT(25), /* frac select */ - 270000000, /* frac rate 0 */ - 297000000, /* frac rate 1 */ - BIT(31), /* gate */ - BIT(28), /* lock */ - CLK_SET_RATE_UNGATE); +static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN(pll_video_clk, "pll-video", + "osc24M", 0x0010, + 192000000, /* Minimum rate */ + 8, 7, /* N */ + 0, 4, /* M */ + BIT(24), /* frac enable */ + BIT(25), /* frac select */ + 270000000, /* frac rate 0 */ + 297000000, /* frac rate 1 */ + BIT(31), /* gate */ + BIT(28), /* lock */ + CLK_SET_RATE_UNGATE); static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve", "osc24M", 0x0018, -- cgit v1.1 From b1a1ad4b75b876ccf200f2351ae61364bf856613 Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Thu, 1 Mar 2018 22:34:29 +0100 Subject: clk: sunxi-ng: h3: h5: Allow some clocks to set parent rate Some units have to be able to set it's own clock precisely to work correctly. Allow them to do so by adding CLK_SET_RATE_PARENT flag. Add this flag to DE, TCON and HDMI clocks. Signed-off-by: Jernej Skrabec Signed-off-by: Maxime Ripard --- drivers/clk/sunxi-ng/ccu-sun8i-h3.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c index b9f3907..77ed0b0 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c @@ -452,11 +452,13 @@ static SUNXI_CCU_GATE(dram_ts_clk, "dram-ts", "dram", static const char * const de_parents[] = { "pll-periph0-2x", "pll-de" }; static SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de", de_parents, - 0x104, 0, 4, 24, 3, BIT(31), 0); + 0x104, 0, 4, 24, 3, BIT(31), + CLK_SET_RATE_PARENT); static const char * const tcon_parents[] = { "pll-video" }; static SUNXI_CCU_M_WITH_MUX_GATE(tcon_clk, "tcon", tcon_parents, - 0x118, 0, 4, 24, 3, BIT(31), 0); + 0x118, 0, 4, 24, 3, BIT(31), + CLK_SET_RATE_PARENT); static const char * const tve_parents[] = { "pll-de", "pll-periph1" }; static SUNXI_CCU_M_WITH_MUX_GATE(tve_clk, "tve", tve_parents, @@ -487,7 +489,8 @@ static SUNXI_CCU_GATE(avs_clk, "avs", "osc24M", static const char * const hdmi_parents[] = { "pll-video" }; static SUNXI_CCU_M_WITH_MUX_GATE(hdmi_clk, "hdmi", hdmi_parents, - 0x150, 0, 4, 24, 2, BIT(31), 0); + 0x150, 0, 4, 24, 2, BIT(31), + CLK_SET_RATE_PARENT); static SUNXI_CCU_GATE(hdmi_ddc_clk, "hdmi-ddc", "osc24M", 0x154, BIT(31), 0); -- cgit v1.1 From 55de0f31df1a31b346edfe98d061f11162ff1ad4 Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Thu, 1 Mar 2018 22:34:30 +0100 Subject: clk: sunxi-ng: h3: h5: export CLK_PLL_VIDEO CLK_PLL_VIDEO needs to be referenced in HDMI DT entry as a possible PHY clock parent. Export it so it can be used later in DT. Signed-off-by: Jernej Skrabec Signed-off-by: Maxime Ripard --- drivers/clk/sunxi-ng/ccu-sun8i-h3.h | 4 +++- include/dt-bindings/clock/sun8i-h3-ccu.h | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-h3.h b/drivers/clk/sunxi-ng/ccu-sun8i-h3.h index 1b4baea..73d7392 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-h3.h +++ b/drivers/clk/sunxi-ng/ccu-sun8i-h3.h @@ -26,7 +26,9 @@ #define CLK_PLL_AUDIO_2X 3 #define CLK_PLL_AUDIO_4X 4 #define CLK_PLL_AUDIO_8X 5 -#define CLK_PLL_VIDEO 6 + +/* PLL_VIDEO is exported */ + #define CLK_PLL_VE 7 #define CLK_PLL_DDR 8 diff --git a/include/dt-bindings/clock/sun8i-h3-ccu.h b/include/dt-bindings/clock/sun8i-h3-ccu.h index e139fe5..c5f7e9a 100644 --- a/include/dt-bindings/clock/sun8i-h3-ccu.h +++ b/include/dt-bindings/clock/sun8i-h3-ccu.h @@ -43,6 +43,8 @@ #ifndef _DT_BINDINGS_CLK_SUN8I_H3_H_ #define _DT_BINDINGS_CLK_SUN8I_H3_H_ +#define CLK_PLL_VIDEO 6 + #define CLK_PLL_PERIPH0 9 #define CLK_CPUX 14 -- cgit v1.1 From 811f67cc16ec76c3953ca1b9d7c34e3f0c17f779 Mon Sep 17 00:00:00 2001 From: tianshuliang Date: Mon, 5 Mar 2018 15:01:31 +0800 Subject: clk: hisilicon: add hisi phase clock support Add a phase clock type for HiSilicon SoCs,which supports clk_set_phase operation. Signed-off-by: tianshuliang Signed-off-by: Jiancheng Xue Signed-off-by: Shawn Guo --- drivers/clk/hisilicon/Makefile | 2 +- drivers/clk/hisilicon/clk-hisi-phase.c | 121 +++++++++++++++++++++++++++++++++ drivers/clk/hisilicon/clk.c | 24 +++++++ drivers/clk/hisilicon/clk.h | 19 ++++++ 4 files changed, 165 insertions(+), 1 deletion(-) create mode 100644 drivers/clk/hisilicon/clk-hisi-phase.c diff --git a/drivers/clk/hisilicon/Makefile b/drivers/clk/hisilicon/Makefile index 4806fc2..2a714c0 100644 --- a/drivers/clk/hisilicon/Makefile +++ b/drivers/clk/hisilicon/Makefile @@ -3,7 +3,7 @@ # Hisilicon Clock specific Makefile # -obj-y += clk.o clkgate-separated.o clkdivider-hi6220.o +obj-y += clk.o clkgate-separated.o clkdivider-hi6220.o clk-hisi-phase.o obj-$(CONFIG_ARCH_HI3xxx) += clk-hi3620.o obj-$(CONFIG_ARCH_HIP04) += clk-hip04.o diff --git a/drivers/clk/hisilicon/clk-hisi-phase.c b/drivers/clk/hisilicon/clk-hisi-phase.c new file mode 100644 index 0000000..42ce157 --- /dev/null +++ b/drivers/clk/hisilicon/clk-hisi-phase.c @@ -0,0 +1,121 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2017 HiSilicon Technologies Co., Ltd. + * + * Simple HiSilicon phase clock implementation. + */ + +#include +#include +#include +#include +#include + +#include "clk.h" + +struct clk_hisi_phase { + struct clk_hw hw; + void __iomem *reg; + u32 *phase_degrees; + u32 *phase_regvals; + u8 phase_num; + u32 mask; + u8 shift; + u8 flags; + spinlock_t *lock; +}; + +#define to_clk_hisi_phase(_hw) container_of(_hw, struct clk_hisi_phase, hw) + +static int hisi_phase_regval_to_degrees(struct clk_hisi_phase *phase, + u32 regval) +{ + int i; + + for (i = 0; i < phase->phase_num; i++) + if (phase->phase_regvals[i] == regval) + return phase->phase_degrees[i]; + + return -EINVAL; +} + +static int hisi_clk_get_phase(struct clk_hw *hw) +{ + struct clk_hisi_phase *phase = to_clk_hisi_phase(hw); + u32 regval; + + regval = readl(phase->reg); + regval = (regval & phase->mask) >> phase->shift; + + return hisi_phase_regval_to_degrees(phase, regval); +} + +static int hisi_phase_degrees_to_regval(struct clk_hisi_phase *phase, + int degrees) +{ + int i; + + for (i = 0; i < phase->phase_num; i++) + if (phase->phase_degrees[i] == degrees) + return phase->phase_regvals[i]; + + return -EINVAL; +} + +static int hisi_clk_set_phase(struct clk_hw *hw, int degrees) +{ + struct clk_hisi_phase *phase = to_clk_hisi_phase(hw); + unsigned long flags = 0; + int regval; + u32 val; + + regval = hisi_phase_degrees_to_regval(phase, degrees); + if (regval < 0) + return regval; + + spin_lock_irqsave(phase->lock, flags); + + val = clk_readl(phase->reg); + val &= ~phase->mask; + val |= regval << phase->shift; + clk_writel(val, phase->reg); + + spin_unlock_irqrestore(phase->lock, flags); + + return 0; +} + +const struct clk_ops clk_phase_ops = { + .get_phase = hisi_clk_get_phase, + .set_phase = hisi_clk_set_phase, +}; + +struct clk *clk_register_hisi_phase(struct device *dev, + const struct hisi_phase_clock *clks, + void __iomem *base, spinlock_t *lock) +{ + struct clk_hisi_phase *phase; + struct clk_init_data init; + + phase = devm_kzalloc(dev, sizeof(struct clk_hisi_phase), GFP_KERNEL); + if (!phase) + return ERR_PTR(-ENOMEM); + + init.name = clks->name; + init.ops = &clk_phase_ops; + init.flags = clks->flags | CLK_IS_BASIC; + init.parent_names = clks->parent_names ? &clks->parent_names : NULL; + init.num_parents = clks->parent_names ? 1 : 0; + + phase->reg = base + clks->offset; + phase->shift = clks->shift; + phase->mask = (BIT(clks->width) - 1) << clks->shift; + phase->lock = lock; + phase->phase_degrees = clks->phase_degrees; + phase->phase_regvals = clks->phase_regvals; + phase->phase_num = clks->phase_num; + phase->hw.init = &init; + + return devm_clk_register(dev, &phase->hw); +} +EXPORT_SYMBOL_GPL(clk_register_hisi_phase); diff --git a/drivers/clk/hisilicon/clk.c b/drivers/clk/hisilicon/clk.c index b73c1df..29046b8 100644 --- a/drivers/clk/hisilicon/clk.c +++ b/drivers/clk/hisilicon/clk.c @@ -197,6 +197,30 @@ err: } EXPORT_SYMBOL_GPL(hisi_clk_register_mux); +int hisi_clk_register_phase(struct device *dev, + const struct hisi_phase_clock *clks, + int nums, struct hisi_clock_data *data) +{ + void __iomem *base = data->base; + struct clk *clk; + int i; + + for (i = 0; i < nums; i++) { + clk = clk_register_hisi_phase(dev, &clks[i], base, + &hisi_clk_lock); + if (IS_ERR(clk)) { + pr_err("%s: failed to register clock %s\n", __func__, + clks[i].name); + return PTR_ERR(clk); + } + + data->clk_data.clks[clks[i].id] = clk; + } + + return 0; +} +EXPORT_SYMBOL_GPL(hisi_clk_register_phase); + int hisi_clk_register_divider(const struct hisi_divider_clock *clks, int nums, struct hisi_clock_data *data) { diff --git a/drivers/clk/hisilicon/clk.h b/drivers/clk/hisilicon/clk.h index 4e1d1af..8d7ee5c 100644 --- a/drivers/clk/hisilicon/clk.h +++ b/drivers/clk/hisilicon/clk.h @@ -68,6 +68,19 @@ struct hisi_mux_clock { const char *alias; }; +struct hisi_phase_clock { + unsigned int id; + const char *name; + const char *parent_names; + unsigned long flags; + unsigned long offset; + u8 shift; + u8 width; + u32 *phase_degrees; + u32 *phase_regvals; + u8 phase_num; +}; + struct hisi_divider_clock { unsigned int id; const char *name; @@ -120,6 +133,12 @@ int hisi_clk_register_fixed_factor(const struct hisi_fixed_factor_clock *, int, struct hisi_clock_data *); int hisi_clk_register_mux(const struct hisi_mux_clock *, int, struct hisi_clock_data *); +struct clk *clk_register_hisi_phase(struct device *dev, + const struct hisi_phase_clock *clks, + void __iomem *base, spinlock_t *lock); +int hisi_clk_register_phase(struct device *dev, + const struct hisi_phase_clock *clks, + int nums, struct hisi_clock_data *data); int hisi_clk_register_divider(const struct hisi_divider_clock *, int, struct hisi_clock_data *); int hisi_clk_register_gate(const struct hisi_gate_clock *, -- cgit v1.1 From d1b0399543cec5fa5d3a2d33b525a7cd7912e635 Mon Sep 17 00:00:00 2001 From: tianshuliang Date: Mon, 5 Mar 2018 15:01:32 +0800 Subject: clk: hi3798cv200: add emmc sample and drive clock It adds eMMC sample clock HISTB_MMC_SAMPLE_CLK and drive clock HISTB_MMC_DRV_CLK support for Hi3798cv200 SoC. Signed-off-by: tianshuliang Signed-off-by: Jiancheng Xue Signed-off-by: Shawn Guo --- drivers/clk/hisilicon/crg-hi3798cv200.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/clk/hisilicon/crg-hi3798cv200.c b/drivers/clk/hisilicon/crg-hi3798cv200.c index d6e3971..743eec1 100644 --- a/drivers/clk/hisilicon/crg-hi3798cv200.c +++ b/drivers/clk/hisilicon/crg-hi3798cv200.c @@ -97,6 +97,18 @@ static struct hisi_mux_clock hi3798cv200_mux_clks[] = { 0x9c, 8, 2, 0, sdio_mux_table, }, }; +static u32 mmc_phase_regvals[] = {0, 1, 2, 3, 4, 5, 6, 7}; +static u32 mmc_phase_degrees[] = {0, 45, 90, 135, 180, 225, 270, 315}; + +static struct hisi_phase_clock hi3798cv200_phase_clks[] = { + { HISTB_MMC_SAMPLE_CLK, "mmc_sample", "clk_mmc_ciu", + CLK_SET_RATE_PARENT, 0xa0, 12, 3, mmc_phase_degrees, + mmc_phase_regvals, ARRAY_SIZE(mmc_phase_regvals) }, + { HISTB_MMC_DRV_CLK, "mmc_drive", "clk_mmc_ciu", + CLK_SET_RATE_PARENT, 0xa0, 16, 3, mmc_phase_degrees, + mmc_phase_regvals, ARRAY_SIZE(mmc_phase_regvals) }, +}; + static const struct hisi_gate_clock hi3798cv200_gate_clks[] = { /* UART */ { HISTB_UART2_CLK, "clk_uart2", "75m", @@ -186,6 +198,14 @@ static struct hisi_clock_data *hi3798cv200_clk_register( if (!clk_data) return ERR_PTR(-ENOMEM); + /* hisi_phase_clock is resource managed */ + ret = hisi_clk_register_phase(&pdev->dev, + hi3798cv200_phase_clks, + ARRAY_SIZE(hi3798cv200_phase_clks), + clk_data); + if (ret) + return ERR_PTR(ret); + ret = hisi_clk_register_fixed_rate(hi3798cv200_fixed_rate_clks, ARRAY_SIZE(hi3798cv200_fixed_rate_clks), clk_data); -- cgit v1.1 From 1e04204eff99b520737315af882f7fb61a9443be Mon Sep 17 00:00:00 2001 From: Jacopo Mondi Date: Tue, 13 Mar 2018 16:18:20 +0100 Subject: clk: renesas: r8a77965: Replace DU2 clock R-Car M3-N does not have the DU2 unit but it has DU3 instead. Fix the module clock definition to reflect that. Fixes: 7ce36da900c0a2ff ("clk: renesas: cpg-mssr: Add support for R-Car M3-N") Reported-by: Yoshihiro Shimoda Signed-off-by: Jacopo Mondi Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r8a77965-cpg-mssr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/renesas/r8a77965-cpg-mssr.c b/drivers/clk/renesas/r8a77965-cpg-mssr.c index 41e506a..b1acfb6 100644 --- a/drivers/clk/renesas/r8a77965-cpg-mssr.c +++ b/drivers/clk/renesas/r8a77965-cpg-mssr.c @@ -173,7 +173,7 @@ static const struct mssr_mod_clk r8a77965_mod_clks[] __initconst = { DEF_MOD("hsusb", 704, R8A77965_CLK_S3D4), DEF_MOD("csi20", 714, R8A77965_CLK_CSI0), DEF_MOD("csi40", 716, R8A77965_CLK_CSI0), - DEF_MOD("du2", 722, R8A77965_CLK_S2D1), + DEF_MOD("du3", 721, R8A77965_CLK_S2D1), DEF_MOD("du1", 723, R8A77965_CLK_S2D1), DEF_MOD("du0", 724, R8A77965_CLK_S2D1), DEF_MOD("lvds", 727, R8A77965_CLK_S2D1), -- cgit v1.1 From a91f77ef155e90b738c0d716844e31e136e9c6b4 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Wed, 14 Mar 2018 14:34:16 -0700 Subject: clk: hisilicon: Mark phase_ops static Sparse rightfully complains: drivers/clk/hisilicon/clk-hisi-phase.c:88:22: warning: symbol 'clk_phase_ops' was not declared. Should it be static? drivers/clk/hisilicon/clk-hisi-phase.c:88:22: warning: symbol 'clk_phase_ops' was not declared. Should it be static? Signed-off-by: Stephen Boyd --- drivers/clk/hisilicon/clk-hisi-phase.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/hisilicon/clk-hisi-phase.c b/drivers/clk/hisilicon/clk-hisi-phase.c index 42ce157..5bce929 100644 --- a/drivers/clk/hisilicon/clk-hisi-phase.c +++ b/drivers/clk/hisilicon/clk-hisi-phase.c @@ -85,7 +85,7 @@ static int hisi_clk_set_phase(struct clk_hw *hw, int degrees) return 0; } -const struct clk_ops clk_phase_ops = { +static const struct clk_ops clk_phase_ops = { .get_phase = hisi_clk_get_phase, .set_phase = hisi_clk_set_phase, }; -- cgit v1.1 From ce33f284935e08229046b30635e6aadcbab02b53 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 16 Feb 2018 16:27:47 +0100 Subject: clk: fix false-positive Wmaybe-uninitialized warning When we build this driver with on x86-32, gcc produces a false-positive warning: drivers/clk/renesas/clk-sh73a0.c: In function 'sh73a0_cpg_clocks_init': drivers/clk/renesas/clk-sh73a0.c:155:10: error: 'parent_name' may be used uninitialized in this function [-Werror=maybe-uninitialized] return clk_register_fixed_factor(NULL, name, parent_name, 0, We can work around that warning by adding a fake initialization, I tried and failed to come up with any better workaround. This is currently one of few remaining warnings for a 4.14.y randconfig build, so it would be good to also have it backported at least to that version. Older versions have more randconfig warnings, so we might not care. I had not noticed this earlier, because one patch in my randconfig test tree removes the '-ffreestanding' option on x86-32, and that avoids the warning. The -ffreestanding flag was originally global but moved into arch/i386 by Andi Kleen in commit 6edfba1b33c7 ("[PATCH] x86_64: Don't define string functions to builtin") as a 'temporary workaround'. Like many temporary hacks, this turned out to be rather long-lived, from all I can tell we still need a simple fix to asm/string_32.h before it can be removed, but I'm not sure about how to best do that. Cc: stable@vger.kernel.org Cc: Andi Kleen Signed-off-by: Arnd Bergmann Acked-by: Geert Uytterhoeven Signed-off-by: Stephen Boyd --- drivers/clk/renesas/clk-sh73a0.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/clk/renesas/clk-sh73a0.c b/drivers/clk/renesas/clk-sh73a0.c index eea38f6..3892346 100644 --- a/drivers/clk/renesas/clk-sh73a0.c +++ b/drivers/clk/renesas/clk-sh73a0.c @@ -46,7 +46,7 @@ struct div4_clk { unsigned int shift; }; -static struct div4_clk div4_clks[] = { +static const struct div4_clk div4_clks[] = { { "zg", "pll0", CPG_FRQCRA, 16 }, { "m3", "pll1", CPG_FRQCRA, 12 }, { "b", "pll1", CPG_FRQCRA, 8 }, @@ -79,7 +79,7 @@ sh73a0_cpg_register_clock(struct device_node *np, struct sh73a0_cpg *cpg, { const struct clk_div_table *table = NULL; unsigned int shift, reg, width; - const char *parent_name; + const char *parent_name = NULL; unsigned int mult = 1; unsigned int div = 1; @@ -135,7 +135,7 @@ sh73a0_cpg_register_clock(struct device_node *np, struct sh73a0_cpg *cpg, shift = 24; width = 5; } else { - struct div4_clk *c; + const struct div4_clk *c; for (c = div4_clks; c->name; c++) { if (!strcmp(name, c->name)) { -- cgit v1.1 From df934cbcbff7afbc024bf05f02615917c61f6470 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 Feb 2018 16:15:21 +0100 Subject: clk: hisilicon: mark wdt_mux_p[] as const The symbol is in the __initconst section but not marked init, which caused a warning when building with LTO. This makes it 'const' as was obviously intended. Signed-off-by: Arnd Bergmann Fixes: c80dfd9bf54e ("clk: hisilicon: add CRG driver for Hi3516CV300 SoC") Signed-off-by: Stephen Boyd --- drivers/clk/hisilicon/crg-hi3516cv300.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/hisilicon/crg-hi3516cv300.c b/drivers/clk/hisilicon/crg-hi3516cv300.c index 2007123..53450b6 100644 --- a/drivers/clk/hisilicon/crg-hi3516cv300.c +++ b/drivers/clk/hisilicon/crg-hi3516cv300.c @@ -204,7 +204,7 @@ static const struct hisi_crg_funcs hi3516cv300_crg_funcs = { /* hi3516CV300 sysctrl CRG */ #define HI3516CV300_SYSCTRL_NR_CLKS 16 -static const char *wdt_mux_p[] __initconst = { "3m", "apb" }; +static const char *const wdt_mux_p[] __initconst = { "3m", "apb" }; static u32 wdt_mux_table[] = {0, 1}; static const struct hisi_mux_clock hi3516cv300_sysctrl_mux_clks[] = { -- cgit v1.1 From a910f251ee084230e2f8d214f1621346cec94e69 Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Fri, 16 Mar 2018 22:02:11 +0800 Subject: clk: sunxi-ng: Support fixed post-dividers on NKMP style clocks On the new Allwinner H6 SoC, multiple PLL's are NMP style clocks (modelled as NKMP with no K) and have fixed post-dividers. Add fixed post divider support to the NKMP style clocks. Signed-off-by: Icenowy Zheng Signed-off-by: Maxime Ripard --- drivers/clk/sunxi-ng/ccu_nkmp.c | 20 +++++++++++++++++--- drivers/clk/sunxi-ng/ccu_nkmp.h | 2 ++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/drivers/clk/sunxi-ng/ccu_nkmp.c b/drivers/clk/sunxi-ng/ccu_nkmp.c index c3f6fe7..ebd9436 100644 --- a/drivers/clk/sunxi-ng/ccu_nkmp.c +++ b/drivers/clk/sunxi-ng/ccu_nkmp.c @@ -95,7 +95,7 @@ static unsigned long ccu_nkmp_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { struct ccu_nkmp *nkmp = hw_to_ccu_nkmp(hw); - unsigned long n, m, k, p; + unsigned long n, m, k, p, rate; u32 reg; reg = readl(nkmp->common.base + nkmp->common.reg); @@ -121,7 +121,11 @@ static unsigned long ccu_nkmp_recalc_rate(struct clk_hw *hw, p = reg >> nkmp->p.shift; p &= (1 << nkmp->p.width) - 1; - return ccu_nkmp_calc_rate(parent_rate, n, k, m, 1 << p); + rate = ccu_nkmp_calc_rate(parent_rate, n, k, m, 1 << p); + if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV) + rate /= nkmp->fixed_post_div; + + return rate; } static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate, @@ -130,6 +134,9 @@ static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate, struct ccu_nkmp *nkmp = hw_to_ccu_nkmp(hw); struct _ccu_nkmp _nkmp; + if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV) + rate *= nkmp->fixed_post_div; + _nkmp.min_n = nkmp->n.min ?: 1; _nkmp.max_n = nkmp->n.max ?: 1 << nkmp->n.width; _nkmp.min_k = nkmp->k.min ?: 1; @@ -141,8 +148,12 @@ static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate, ccu_nkmp_find_best(*parent_rate, rate, &_nkmp); - return ccu_nkmp_calc_rate(*parent_rate, _nkmp.n, _nkmp.k, + rate = ccu_nkmp_calc_rate(*parent_rate, _nkmp.n, _nkmp.k, _nkmp.m, _nkmp.p); + if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV) + rate = rate / nkmp->fixed_post_div; + + return rate; } static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate, @@ -154,6 +165,9 @@ static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long flags; u32 reg; + if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV) + rate = rate * nkmp->fixed_post_div; + _nkmp.min_n = nkmp->n.min ?: 1; _nkmp.max_n = nkmp->n.max ?: 1 << nkmp->n.width; _nkmp.min_k = nkmp->k.min ?: 1; diff --git a/drivers/clk/sunxi-ng/ccu_nkmp.h b/drivers/clk/sunxi-ng/ccu_nkmp.h index a82facb..6940503 100644 --- a/drivers/clk/sunxi-ng/ccu_nkmp.h +++ b/drivers/clk/sunxi-ng/ccu_nkmp.h @@ -34,6 +34,8 @@ struct ccu_nkmp { struct ccu_div_internal m; struct ccu_div_internal p; + unsigned int fixed_post_div; + struct ccu_common common; }; -- cgit v1.1 From 2e08e4d2ff488424919d69dd211ac860a019ac1d Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Fri, 16 Mar 2018 22:02:12 +0800 Subject: dt-bindings: add device tree binding for Allwinner H6 main CCU The Allwinner H6 main CCU uses the internal oscillator of the SoC, which is different with old SoCs' main CCU. Add device tree binding for the Allwinner H6 main CCU. Signed-off-by: Icenowy Zheng Signed-off-by: Maxime Ripard --- Documentation/devicetree/bindings/clock/sunxi-ccu.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/clock/sunxi-ccu.txt b/Documentation/devicetree/bindings/clock/sunxi-ccu.txt index 4ca21c3..460ef27 100644 --- a/Documentation/devicetree/bindings/clock/sunxi-ccu.txt +++ b/Documentation/devicetree/bindings/clock/sunxi-ccu.txt @@ -20,6 +20,7 @@ Required properties : - "allwinner,sun50i-a64-ccu" - "allwinner,sun50i-a64-r-ccu" - "allwinner,sun50i-h5-ccu" + - "allwinner,sun50i-h6-ccu" - "nextthing,gr8-ccu" - reg: Must contain the registers base address and length @@ -31,6 +32,9 @@ Required properties : - #clock-cells : must contain 1 - #reset-cells : must contain 1 +For the main CCU on H6, one more clock is needed: +- "iosc": the SoC's internal frequency oscillator + For the PRCM CCUs on A83T/H3/A64, two more clocks are needed: - "pll-periph": the SoC's peripheral PLL from the main CCU - "iosc": the SoC's internal frequency oscillator -- cgit v1.1 From 524353ea480b0094c16f2b5684ce7e0a23ab3685 Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Fri, 16 Mar 2018 22:02:13 +0800 Subject: clk: sunxi-ng: add support for the Allwinner H6 CCU The Allwinner H6 SoC has a CCU which has been largely rearranged. Add support for it in the sunxi-ng CCU framework. Signed-off-by: Icenowy Zheng Acked-by: Maxime Ripard Signed-off-by: Maxime Ripard --- drivers/clk/sunxi-ng/Kconfig | 5 + drivers/clk/sunxi-ng/Makefile | 1 + drivers/clk/sunxi-ng/ccu-sun50i-h6.c | 1207 +++++++++++++++++++++++++++++ drivers/clk/sunxi-ng/ccu-sun50i-h6.h | 56 ++ include/dt-bindings/clock/sun50i-h6-ccu.h | 124 +++ include/dt-bindings/reset/sun50i-h6-ccu.h | 73 ++ 6 files changed, 1466 insertions(+) create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-h6.c create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-h6.h create mode 100644 include/dt-bindings/clock/sun50i-h6-ccu.h create mode 100644 include/dt-bindings/reset/sun50i-h6-ccu.h diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig index 33168f9..79dfd29 100644 --- a/drivers/clk/sunxi-ng/Kconfig +++ b/drivers/clk/sunxi-ng/Kconfig @@ -11,6 +11,11 @@ config SUN50I_A64_CCU default ARM64 && ARCH_SUNXI depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST +config SUN50I_H6_CCU + bool "Support for the Allwinner H6 CCU" + default ARM64 && ARCH_SUNXI + depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST + config SUN4I_A10_CCU bool "Support for the Allwinner A10/A20 CCU" default MACH_SUN4I diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile index 4141c3f..128a40e 100644 --- a/drivers/clk/sunxi-ng/Makefile +++ b/drivers/clk/sunxi-ng/Makefile @@ -22,6 +22,7 @@ lib-$(CONFIG_SUNXI_CCU) += ccu_mp.o # SoC support obj-$(CONFIG_SUN50I_A64_CCU) += ccu-sun50i-a64.o +obj-$(CONFIG_SUN50I_H6_CCU) += ccu-sun50i-h6.o obj-$(CONFIG_SUN4I_A10_CCU) += ccu-sun4i-a10.o obj-$(CONFIG_SUN5I_CCU) += ccu-sun5i.o obj-$(CONFIG_SUN6I_A31_CCU) += ccu-sun6i-a31.o diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c new file mode 100644 index 0000000..d5eab49 --- /dev/null +++ b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c @@ -0,0 +1,1207 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2017 Icenowy Zheng + */ + +#include +#include +#include + +#include "ccu_common.h" +#include "ccu_reset.h" + +#include "ccu_div.h" +#include "ccu_gate.h" +#include "ccu_mp.h" +#include "ccu_mult.h" +#include "ccu_nk.h" +#include "ccu_nkm.h" +#include "ccu_nkmp.h" +#include "ccu_nm.h" + +#include "ccu-sun50i-h6.h" + +/* + * The CPU PLL is actually NP clock, with P being /1, /2 or /4. However + * P should only be used for output frequencies lower than 288 MHz. + * + * For now we can just model it as a multiplier clock, and force P to /1. + * + * The M factor is present in the register's description, but not in the + * frequency formula, and it's documented as "M is only used for backdoor + * testing", so it's not modelled and then force to 0. + */ +#define SUN50I_H6_PLL_CPUX_REG 0x000 +static struct ccu_mult pll_cpux_clk = { + .enable = BIT(31), + .lock = BIT(28), + .mult = _SUNXI_CCU_MULT_MIN(8, 8, 12), + .common = { + .reg = 0x000, + .hw.init = CLK_HW_INIT("pll-cpux", "osc24M", + &ccu_mult_ops, + CLK_SET_RATE_UNGATE), + }, +}; + +/* Some PLLs are input * N / div1 / P. Model them as NKMP with no K */ +#define SUN50I_H6_PLL_DDR0_REG 0x010 +static struct ccu_nkmp pll_ddr0_clk = { + .enable = BIT(31), + .lock = BIT(28), + .n = _SUNXI_CCU_MULT_MIN(8, 8, 12), + .m = _SUNXI_CCU_DIV(1, 1), /* input divider */ + .p = _SUNXI_CCU_DIV(0, 1), /* output divider */ + .common = { + .reg = 0x010, + .hw.init = CLK_HW_INIT("pll-ddr0", "osc24M", + &ccu_nkmp_ops, + CLK_SET_RATE_UNGATE), + }, +}; + +#define SUN50I_H6_PLL_PERIPH0_REG 0x020 +static struct ccu_nkmp pll_periph0_clk = { + .enable = BIT(31), + .lock = BIT(28), + .n = _SUNXI_CCU_MULT_MIN(8, 8, 12), + .m = _SUNXI_CCU_DIV(1, 1), /* input divider */ + .p = _SUNXI_CCU_DIV(0, 1), /* output divider */ + .fixed_post_div = 4, + .common = { + .reg = 0x020, + .features = CCU_FEATURE_FIXED_POSTDIV, + .hw.init = CLK_HW_INIT("pll-periph0", "osc24M", + &ccu_nkmp_ops, + CLK_SET_RATE_UNGATE), + }, +}; + +#define SUN50I_H6_PLL_PERIPH1_REG 0x028 +static struct ccu_nkmp pll_periph1_clk = { + .enable = BIT(31), + .lock = BIT(28), + .n = _SUNXI_CCU_MULT_MIN(8, 8, 12), + .m = _SUNXI_CCU_DIV(1, 1), /* input divider */ + .p = _SUNXI_CCU_DIV(0, 1), /* output divider */ + .fixed_post_div = 4, + .common = { + .reg = 0x028, + .features = CCU_FEATURE_FIXED_POSTDIV, + .hw.init = CLK_HW_INIT("pll-periph1", "osc24M", + &ccu_nkmp_ops, + CLK_SET_RATE_UNGATE), + }, +}; + +#define SUN50I_H6_PLL_GPU_REG 0x030 +static struct ccu_nkmp pll_gpu_clk = { + .enable = BIT(31), + .lock = BIT(28), + .n = _SUNXI_CCU_MULT_MIN(8, 8, 12), + .m = _SUNXI_CCU_DIV(1, 1), /* input divider */ + .p = _SUNXI_CCU_DIV(0, 1), /* output divider */ + .common = { + .reg = 0x030, + .hw.init = CLK_HW_INIT("pll-gpu", "osc24M", + &ccu_nkmp_ops, + CLK_SET_RATE_UNGATE), + }, +}; + +/* + * For Video PLLs, the output divider is described as "used for testing" + * in the user manual. So it's not modelled and forced to 0. + */ +#define SUN50I_H6_PLL_VIDEO0_REG 0x040 +static struct ccu_nm pll_video0_clk = { + .enable = BIT(31), + .lock = BIT(28), + .n = _SUNXI_CCU_MULT_MIN(8, 8, 12), + .m = _SUNXI_CCU_DIV(1, 1), /* input divider */ + .fixed_post_div = 4, + .common = { + .reg = 0x040, + .features = CCU_FEATURE_FIXED_POSTDIV, + .hw.init = CLK_HW_INIT("pll-video0", "osc24M", + &ccu_nm_ops, + CLK_SET_RATE_UNGATE), + }, +}; + +#define SUN50I_H6_PLL_VIDEO1_REG 0x048 +static struct ccu_nm pll_video1_clk = { + .enable = BIT(31), + .lock = BIT(28), + .n = _SUNXI_CCU_MULT_MIN(8, 8, 12), + .m = _SUNXI_CCU_DIV(1, 1), /* input divider */ + .fixed_post_div = 4, + .common = { + .reg = 0x048, + .features = CCU_FEATURE_FIXED_POSTDIV, + .hw.init = CLK_HW_INIT("pll-video1", "osc24M", + &ccu_nm_ops, + CLK_SET_RATE_UNGATE), + }, +}; + +#define SUN50I_H6_PLL_VE_REG 0x058 +static struct ccu_nkmp pll_ve_clk = { + .enable = BIT(31), + .lock = BIT(28), + .n = _SUNXI_CCU_MULT_MIN(8, 8, 12), + .m = _SUNXI_CCU_DIV(1, 1), /* input divider */ + .p = _SUNXI_CCU_DIV(0, 1), /* output divider */ + .common = { + .reg = 0x058, + .hw.init = CLK_HW_INIT("pll-ve", "osc24M", + &ccu_nkmp_ops, + CLK_SET_RATE_UNGATE), + }, +}; + +#define SUN50I_H6_PLL_DE_REG 0x060 +static struct ccu_nkmp pll_de_clk = { + .enable = BIT(31), + .lock = BIT(28), + .n = _SUNXI_CCU_MULT_MIN(8, 8, 12), + .m = _SUNXI_CCU_DIV(1, 1), /* input divider */ + .p = _SUNXI_CCU_DIV(0, 1), /* output divider */ + .common = { + .reg = 0x060, + .hw.init = CLK_HW_INIT("pll-de", "osc24M", + &ccu_nkmp_ops, + CLK_SET_RATE_UNGATE), + }, +}; + +#define SUN50I_H6_PLL_HSIC_REG 0x070 +static struct ccu_nkmp pll_hsic_clk = { + .enable = BIT(31), + .lock = BIT(28), + .n = _SUNXI_CCU_MULT_MIN(8, 8, 12), + .m = _SUNXI_CCU_DIV(1, 1), /* input divider */ + .p = _SUNXI_CCU_DIV(0, 1), /* output divider */ + .common = { + .reg = 0x070, + .hw.init = CLK_HW_INIT("pll-hsic", "osc24M", + &ccu_nkmp_ops, + CLK_SET_RATE_UNGATE), + }, +}; + +/* + * The Audio PLL is supposed to have 3 outputs: 2 fixed factors from + * the base (2x and 4x), and one variable divider (the one true pll audio). + * + * We don't have any need for the variable divider for now, so we just + * hardcode it to match with the clock names. + */ +#define SUN50I_H6_PLL_AUDIO_REG 0x078 +static struct ccu_nm pll_audio_base_clk = { + .enable = BIT(31), + .lock = BIT(28), + .n = _SUNXI_CCU_MULT_MIN(8, 8, 12), + .m = _SUNXI_CCU_DIV(1, 1), /* input divider */ + .common = { + .reg = 0x078, + .hw.init = CLK_HW_INIT("pll-audio-base", "osc24M", + &ccu_nm_ops, + CLK_SET_RATE_UNGATE), + }, +}; + +static const char * const cpux_parents[] = { "osc24M", "osc32k", + "iosc", "pll-cpux" }; +static SUNXI_CCU_MUX(cpux_clk, "cpux", cpux_parents, + 0x500, 24, 2, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL); +static SUNXI_CCU_M(axi_clk, "axi", "cpux", 0x500, 0, 2, 0); +static SUNXI_CCU_M(cpux_apb_clk, "cpux-apb", "cpux", 0x500, 8, 2, 0); + +static const char * const psi_ahb1_ahb2_parents[] = { "osc24M", "osc32k", + "iosc", "pll-periph0" }; +static SUNXI_CCU_MP_WITH_MUX(psi_ahb1_ahb2_clk, "psi-ahb1-ahb2", + psi_ahb1_ahb2_parents, + 0x510, + 0, 5, /* M */ + 16, 2, /* P */ + 24, 2, /* mux */ + 0); + +static const char * const ahb3_apb1_apb2_parents[] = { "osc24M", "osc32k", + "psi-ahb1-ahb2", + "pll-periph0" }; +static SUNXI_CCU_MP_WITH_MUX(ahb3_clk, "ahb3", ahb3_apb1_apb2_parents, 0x51c, + 0, 5, /* M */ + 16, 2, /* P */ + 24, 2, /* mux */ + 0); + +static SUNXI_CCU_MP_WITH_MUX(apb1_clk, "apb1", ahb3_apb1_apb2_parents, 0x520, + 0, 5, /* M */ + 16, 2, /* P */ + 24, 2, /* mux */ + 0); + +static SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2", ahb3_apb1_apb2_parents, 0x524, + 0, 5, /* M */ + 16, 2, /* P */ + 24, 2, /* mux */ + 0); + +static const char * const mbus_parents[] = { "osc24M", "pll-periph0-2x", + "pll-ddr0", "pll-periph0-4x" }; +static SUNXI_CCU_M_WITH_MUX_GATE(mbus_clk, "mbus", mbus_parents, 0x540, + 0, 3, /* M */ + 24, 2, /* mux */ + BIT(31), /* gate */ + CLK_IS_CRITICAL); + +static const char * const de_parents[] = { "pll-de", "pll-periph0-2x" }; +static SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de", de_parents, 0x600, + 0, 4, /* M */ + 24, 1, /* mux */ + BIT(31), /* gate */ + 0); + +static SUNXI_CCU_GATE(bus_de_clk, "bus-de", "psi-ahb1-ahb2", + 0x60c, BIT(0), 0); + +static const char * const deinterlace_parents[] = { "pll-periph0", + "pll-periph1" }; +static SUNXI_CCU_M_WITH_MUX_GATE(deinterlace_clk, "deinterlace", + deinterlace_parents, + 0x620, + 0, 4, /* M */ + 24, 1, /* mux */ + BIT(31), /* gate */ + 0); + +static SUNXI_CCU_GATE(bus_deinterlace_clk, "bus-deinterlace", "psi-ahb1-ahb2", + 0x62c, BIT(0), 0); + +static const char * const gpu_parents[] = { "pll-gpu" }; +static SUNXI_CCU_M_WITH_MUX_GATE(gpu_clk, "gpu", gpu_parents, 0x670, + 0, 3, /* M */ + 24, 1, /* mux */ + BIT(31), /* gate */ + 0); + +static SUNXI_CCU_GATE(bus_gpu_clk, "bus-gpu", "psi-ahb1-ahb2", + 0x67c, BIT(0), 0); + +/* Also applies to EMCE */ +static const char * const ce_parents[] = { "osc24M", "pll-periph0-2x" }; +static SUNXI_CCU_MP_WITH_MUX_GATE(ce_clk, "ce", ce_parents, 0x680, + 0, 4, /* M */ + 8, 2, /* N */ + 24, 1, /* mux */ + BIT(31),/* gate */ + 0); + +static SUNXI_CCU_GATE(bus_ce_clk, "bus-ce", "psi-ahb1-ahb2", + 0x68c, BIT(0), 0); + +static const char * const ve_parents[] = { "pll-ve" }; +static SUNXI_CCU_M_WITH_MUX_GATE(ve_clk, "ve", ve_parents, 0x690, + 0, 3, /* M */ + 24, 1, /* mux */ + BIT(31), /* gate */ + 0); + +static SUNXI_CCU_GATE(bus_ve_clk, "bus-ve", "psi-ahb1-ahb2", + 0x69c, BIT(0), 0); + +static SUNXI_CCU_MP_WITH_MUX_GATE(emce_clk, "emce", ce_parents, 0x6b0, + 0, 4, /* M */ + 8, 2, /* N */ + 24, 1, /* mux */ + BIT(31),/* gate */ + 0); + +static SUNXI_CCU_GATE(bus_emce_clk, "bus-emce", "psi-ahb1-ahb2", + 0x6bc, BIT(0), 0); + +static const char * const vp9_parents[] = { "pll-ve", "pll-periph0-2x" }; +static SUNXI_CCU_M_WITH_MUX_GATE(vp9_clk, "vp9", vp9_parents, 0x6c0, + 0, 3, /* M */ + 24, 1, /* mux */ + BIT(31), /* gate */ + 0); + +static SUNXI_CCU_GATE(bus_vp9_clk, "bus-vp9", "psi-ahb1-ahb2", + 0x6cc, BIT(0), 0); + +static SUNXI_CCU_GATE(bus_dma_clk, "bus-dma", "psi-ahb1-ahb2", + 0x70c, BIT(0), 0); + +static SUNXI_CCU_GATE(bus_msgbox_clk, "bus-msgbox", "psi-ahb1-ahb2", + 0x71c, BIT(0), 0); + +static SUNXI_CCU_GATE(bus_spinlock_clk, "bus-spinlock", "psi-ahb1-ahb2", + 0x72c, BIT(0), 0); + +static SUNXI_CCU_GATE(bus_hstimer_clk, "bus-hstimer", "psi-ahb1-ahb2", + 0x73c, BIT(0), 0); + +static SUNXI_CCU_GATE(avs_clk, "avs", "osc24M", 0x740, BIT(31), 0); + +static SUNXI_CCU_GATE(bus_dbg_clk, "bus-dbg", "psi-ahb1-ahb2", + 0x78c, BIT(0), 0); + +static SUNXI_CCU_GATE(bus_psi_clk, "bus-psi", "psi-ahb1-ahb2", + 0x79c, BIT(0), 0); + +static SUNXI_CCU_GATE(bus_pwm_clk, "bus-pwm", "apb1", 0x79c, BIT(0), 0); + +static SUNXI_CCU_GATE(bus_iommu_clk, "bus-iommu", "apb1", 0x7bc, BIT(0), 0); + +static const char * const dram_parents[] = { "pll-ddr0" }; +static struct ccu_div dram_clk = { + .div = _SUNXI_CCU_DIV(0, 2), + .mux = _SUNXI_CCU_MUX(24, 2), + .common = { + .reg = 0x800, + .hw.init = CLK_HW_INIT_PARENTS("dram", + dram_parents, + &ccu_div_ops, + CLK_IS_CRITICAL), + }, +}; + +static SUNXI_CCU_GATE(mbus_dma_clk, "mbus-dma", "mbus", + 0x804, BIT(0), 0); +static SUNXI_CCU_GATE(mbus_ve_clk, "mbus-ve", "mbus", + 0x804, BIT(1), 0); +static SUNXI_CCU_GATE(mbus_ce_clk, "mbus-ce", "mbus", + 0x804, BIT(2), 0); +static SUNXI_CCU_GATE(mbus_ts_clk, "mbus-ts", "mbus", + 0x804, BIT(3), 0); +static SUNXI_CCU_GATE(mbus_nand_clk, "mbus-nand", "mbus", + 0x804, BIT(5), 0); +static SUNXI_CCU_GATE(mbus_csi_clk, "mbus-csi", "mbus", + 0x804, BIT(8), 0); +static SUNXI_CCU_GATE(mbus_deinterlace_clk, "mbus-deinterlace", "mbus", + 0x804, BIT(11), 0); + +static SUNXI_CCU_GATE(bus_dram_clk, "bus-dram", "psi-ahb1-ahb2", + 0x80c, BIT(0), CLK_IS_CRITICAL); + +static const char * const nand_spi_parents[] = { "osc24M", "pll-periph0", + "pll-periph1", "pll-periph0-2x", + "pll-periph1-2x" }; +static SUNXI_CCU_MP_WITH_MUX_GATE(nand0_clk, "nand0", nand_spi_parents, 0x810, + 0, 4, /* M */ + 8, 2, /* N */ + 24, 3, /* mux */ + BIT(31),/* gate */ + 0); + +static SUNXI_CCU_MP_WITH_MUX_GATE(nand1_clk, "nand1", nand_spi_parents, 0x814, + 0, 4, /* M */ + 8, 2, /* N */ + 24, 3, /* mux */ + BIT(31),/* gate */ + 0); + +static SUNXI_CCU_GATE(bus_nand_clk, "bus-nand", "ahb3", 0x82c, BIT(0), 0); + +static const char * const mmc_parents[] = { "osc24M", "pll-periph0-2x", + "pll-periph1-2x" }; +static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk, "mmc0", mmc_parents, 0x830, + 0, 4, /* M */ + 8, 2, /* N */ + 24, 3, /* mux */ + BIT(31),/* gate */ + 0); + +static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk, "mmc1", mmc_parents, 0x834, + 0, 4, /* M */ + 8, 2, /* N */ + 24, 3, /* mux */ + BIT(31),/* gate */ + 0); + +static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2", mmc_parents, 0x838, + 0, 4, /* M */ + 8, 2, /* N */ + 24, 3, /* mux */ + BIT(31),/* gate */ + 0); + +static SUNXI_CCU_GATE(bus_mmc0_clk, "bus-mmc0", "ahb3", 0x84c, BIT(0), 0); +static SUNXI_CCU_GATE(bus_mmc1_clk, "bus-mmc1", "ahb3", 0x84c, BIT(1), 0); +static SUNXI_CCU_GATE(bus_mmc2_clk, "bus-mmc2", "ahb3", 0x84c, BIT(2), 0); + +static SUNXI_CCU_GATE(bus_uart0_clk, "bus-uart0", "apb2", 0x90c, BIT(0), 0); +static SUNXI_CCU_GATE(bus_uart1_clk, "bus-uart1", "apb2", 0x90c, BIT(1), 0); +static SUNXI_CCU_GATE(bus_uart2_clk, "bus-uart2", "apb2", 0x90c, BIT(2), 0); +static SUNXI_CCU_GATE(bus_uart3_clk, "bus-uart3", "apb2", 0x90c, BIT(3), 0); + +static SUNXI_CCU_GATE(bus_i2c0_clk, "bus-i2c0", "apb2", 0x91c, BIT(0), 0); +static SUNXI_CCU_GATE(bus_i2c1_clk, "bus-i2c1", "apb2", 0x91c, BIT(1), 0); +static SUNXI_CCU_GATE(bus_i2c2_clk, "bus-i2c2", "apb2", 0x91c, BIT(2), 0); +static SUNXI_CCU_GATE(bus_i2c3_clk, "bus-i2c3", "apb2", 0x91c, BIT(3), 0); + +static SUNXI_CCU_GATE(bus_scr0_clk, "bus-scr0", "apb2", 0x93c, BIT(0), 0); +static SUNXI_CCU_GATE(bus_scr1_clk, "bus-scr1", "apb2", 0x93c, BIT(1), 0); + +static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", nand_spi_parents, 0x940, + 0, 4, /* M */ + 8, 2, /* N */ + 24, 3, /* mux */ + BIT(31),/* gate */ + 0); + +static SUNXI_CCU_MP_WITH_MUX_GATE(spi1_clk, "spi1", nand_spi_parents, 0x944, + 0, 4, /* M */ + 8, 2, /* N */ + 24, 3, /* mux */ + BIT(31),/* gate */ + 0); + +static SUNXI_CCU_GATE(bus_spi0_clk, "bus-spi0", "ahb3", 0x96c, BIT(0), 0); +static SUNXI_CCU_GATE(bus_spi1_clk, "bus-spi1", "ahb3", 0x96c, BIT(1), 0); + +static SUNXI_CCU_GATE(bus_emac_clk, "bus-emac", "ahb3", 0x97c, BIT(0), 0); + +static const char * const ts_parents[] = { "osc24M", "pll-periph0" }; +static SUNXI_CCU_MP_WITH_MUX_GATE(ts_clk, "ts", ts_parents, 0x9b0, + 0, 4, /* M */ + 8, 2, /* N */ + 24, 1, /* mux */ + BIT(31),/* gate */ + 0); + +static SUNXI_CCU_GATE(bus_ts_clk, "bus-ts", "ahb3", 0x9bc, BIT(0), 0); + +static const char * const ir_tx_parents[] = { "osc32k", "osc24M" }; +static SUNXI_CCU_MP_WITH_MUX_GATE(ir_tx_clk, "ir-tx", ir_tx_parents, 0x9c0, + 0, 4, /* M */ + 8, 2, /* N */ + 24, 1, /* mux */ + BIT(31),/* gate */ + 0); + +static SUNXI_CCU_GATE(bus_ir_tx_clk, "bus-ir-tx", "apb1", 0x9cc, BIT(0), 0); + +static SUNXI_CCU_GATE(bus_ths_clk, "bus-ths", "apb1", 0x9fc, BIT(0), 0); + +static const char * const audio_parents[] = { "pll-audio", "pll-audio-2x", "pll-audio-4x" }; +static struct ccu_div i2s3_clk = { + .enable = BIT(31), + .div = _SUNXI_CCU_DIV_FLAGS(8, 2, CLK_DIVIDER_POWER_OF_TWO), + .mux = _SUNXI_CCU_MUX(24, 2), + .common = { + .reg = 0xa0c, + .hw.init = CLK_HW_INIT_PARENTS("i2s3", + audio_parents, + &ccu_div_ops, + 0), + }, +}; + +static struct ccu_div i2s0_clk = { + .enable = BIT(31), + .div = _SUNXI_CCU_DIV_FLAGS(8, 2, CLK_DIVIDER_POWER_OF_TWO), + .mux = _SUNXI_CCU_MUX(24, 2), + .common = { + .reg = 0xa10, + .hw.init = CLK_HW_INIT_PARENTS("i2s0", + audio_parents, + &ccu_div_ops, + 0), + }, +}; + +static struct ccu_div i2s1_clk = { + .enable = BIT(31), + .div = _SUNXI_CCU_DIV_FLAGS(8, 2, CLK_DIVIDER_POWER_OF_TWO), + .mux = _SUNXI_CCU_MUX(24, 2), + .common = { + .reg = 0xa14, + .hw.init = CLK_HW_INIT_PARENTS("i2s1", + audio_parents, + &ccu_div_ops, + 0), + }, +}; + +static struct ccu_div i2s2_clk = { + .enable = BIT(31), + .div = _SUNXI_CCU_DIV_FLAGS(8, 2, CLK_DIVIDER_POWER_OF_TWO), + .mux = _SUNXI_CCU_MUX(24, 2), + .common = { + .reg = 0xa18, + .hw.init = CLK_HW_INIT_PARENTS("i2s2", + audio_parents, + &ccu_div_ops, + 0), + }, +}; + +static SUNXI_CCU_GATE(bus_i2s0_clk, "bus-i2s0", "apb1", 0xa1c, BIT(0), 0); +static SUNXI_CCU_GATE(bus_i2s1_clk, "bus-i2s1", "apb1", 0xa1c, BIT(1), 0); +static SUNXI_CCU_GATE(bus_i2s2_clk, "bus-i2s2", "apb1", 0xa1c, BIT(2), 0); +static SUNXI_CCU_GATE(bus_i2s3_clk, "bus-i2s3", "apb1", 0xa1c, BIT(3), 0); + +static struct ccu_div spdif_clk = { + .enable = BIT(31), + .div = _SUNXI_CCU_DIV_FLAGS(8, 2, CLK_DIVIDER_POWER_OF_TWO), + .mux = _SUNXI_CCU_MUX(24, 2), + .common = { + .reg = 0xa20, + .hw.init = CLK_HW_INIT_PARENTS("spdif", + audio_parents, + &ccu_div_ops, + 0), + }, +}; + +static SUNXI_CCU_GATE(bus_spdif_clk, "bus-spdif", "apb1", 0xa2c, BIT(0), 0); + +static struct ccu_div dmic_clk = { + .enable = BIT(31), + .div = _SUNXI_CCU_DIV_FLAGS(8, 2, CLK_DIVIDER_POWER_OF_TWO), + .mux = _SUNXI_CCU_MUX(24, 2), + .common = { + .reg = 0xa40, + .hw.init = CLK_HW_INIT_PARENTS("dmic", + audio_parents, + &ccu_div_ops, + 0), + }, +}; + +static SUNXI_CCU_GATE(bus_dmic_clk, "bus-dmic", "apb1", 0xa4c, BIT(0), 0); + +static struct ccu_div audio_hub_clk = { + .enable = BIT(31), + .div = _SUNXI_CCU_DIV_FLAGS(8, 2, CLK_DIVIDER_POWER_OF_TWO), + .mux = _SUNXI_CCU_MUX(24, 2), + .common = { + .reg = 0xa60, + .hw.init = CLK_HW_INIT_PARENTS("audio-hub", + audio_parents, + &ccu_div_ops, + 0), + }, +}; + +static SUNXI_CCU_GATE(bus_audio_hub_clk, "bus-audio-hub", "apb1", 0xa6c, BIT(0), 0); + +/* + * There are OHCI 12M clock source selection bits for 2 USB 2.0 ports. + * We will force them to 0 (12M divided from 48M). + */ +#define SUN50I_H6_USB0_CLK_REG 0xa70 +#define SUN50I_H6_USB3_CLK_REG 0xa7c + +static SUNXI_CCU_GATE(usb_ohci0_clk, "usb-ohci0", "osc12M", 0xa70, BIT(31), 0); +static SUNXI_CCU_GATE(usb_phy0_clk, "usb-phy0", "osc24M", 0xa70, BIT(29), 0); + +static SUNXI_CCU_GATE(usb_phy1_clk, "usb-phy1", "osc24M", 0xa74, BIT(29), 0); + +static SUNXI_CCU_GATE(usb_ohci3_clk, "usb-ohci3", "osc12M", 0xa7c, BIT(31), 0); +static SUNXI_CCU_GATE(usb_phy3_clk, "usb-phy3", "osc12M", 0xa7c, BIT(29), 0); +static SUNXI_CCU_GATE(usb_hsic_12m_clk, "usb-hsic-12M", "osc12M", 0xa7c, BIT(27), 0); +static SUNXI_CCU_GATE(usb_hsic_clk, "usb-hsic", "pll-hsic", 0xa7c, BIT(26), 0); + +static SUNXI_CCU_GATE(bus_ohci0_clk, "bus-ohci0", "ahb3", 0xa8c, BIT(0), 0); +static SUNXI_CCU_GATE(bus_ohci3_clk, "bus-ohci3", "ahb3", 0xa8c, BIT(3), 0); +static SUNXI_CCU_GATE(bus_ehci0_clk, "bus-ehci0", "ahb3", 0xa8c, BIT(4), 0); +static SUNXI_CCU_GATE(bus_xhci_clk, "bus-xhci", "ahb3", 0xa8c, BIT(5), 0); +static SUNXI_CCU_GATE(bus_ehci3_clk, "bus-ehci3", "ahb3", 0xa8c, BIT(7), 0); +static SUNXI_CCU_GATE(bus_otg_clk, "bus-otg", "ahb3", 0xa8c, BIT(8), 0); + +static CLK_FIXED_FACTOR(pcie_ref_100m_clk, "pcie-ref-100M", + "pll-periph0-4x", 24, 1, 0); +static SUNXI_CCU_GATE(pcie_ref_clk, "pcie-ref", "pcie-ref-100M", + 0xab0, BIT(31), 0); +static SUNXI_CCU_GATE(pcie_ref_out_clk, "pcie-ref-out", "pcie-ref", + 0xab0, BIT(30), 0); + +static SUNXI_CCU_M_WITH_GATE(pcie_maxi_clk, "pcie-maxi", + "pll-periph0", 0xab4, + 0, 4, /* M */ + BIT(31), /* gate */ + 0); + +static SUNXI_CCU_M_WITH_GATE(pcie_aux_clk, "pcie-aux", "osc24M", 0xab8, + 0, 5, /* M */ + BIT(31), /* gate */ + 0); + +static SUNXI_CCU_GATE(bus_pcie_clk, "bus-pcie", "psi-ahb1-ahb2", + 0xabc, BIT(0), 0); + +static const char * const hdmi_parents[] = { "pll-video0", "pll-video1", + "pll-video1-4x" }; +static SUNXI_CCU_M_WITH_MUX_GATE(hdmi_clk, "hdmi", hdmi_parents, 0xb00, + 0, 4, /* M */ + 24, 2, /* mux */ + BIT(31), /* gate */ + 0); + +static const char * const hdmi_cec_parents[] = { "osc32k", "pll-periph0-2x" }; +static const struct ccu_mux_fixed_prediv hdmi_cec_predivs[] = { + { .index = 1, .div = 36621 }, +}; +static struct ccu_mux hdmi_cec_clk = { + .enable = BIT(31), + + .mux = { + .shift = 24, + .width = 2, + + .fixed_predivs = hdmi_cec_predivs, + .n_predivs = ARRAY_SIZE(hdmi_cec_predivs), + }, + + .common = { + .reg = 0xb10, + .features = CCU_FEATURE_VARIABLE_PREDIV, + .hw.init = CLK_HW_INIT_PARENTS("hdmi-cec", + hdmi_cec_parents, + &ccu_mux_ops, + 0), + }, +}; + +static SUNXI_CCU_GATE(bus_hdmi_clk, "bus-hdmi", "ahb3", 0xb1c, BIT(0), 0); + +static SUNXI_CCU_GATE(bus_tcon_top_clk, "bus-tcon-top", "ahb3", + 0xb5c, BIT(0), 0); + +static const char * const tcon_lcd0_parents[] = { "pll-video0", + "pll-video0-4x", + "pll-video1" }; +static SUNXI_CCU_MUX_WITH_GATE(tcon_lcd0_clk, "tcon-lcd0", + tcon_lcd0_parents, 0xb60, + 24, 3, /* mux */ + BIT(31), /* gate */ + 0); + +static SUNXI_CCU_GATE(bus_tcon_lcd0_clk, "bus-tcon-lcd0", "ahb3", + 0xb7c, BIT(0), 0); + +static const char * const tcon_tv0_parents[] = { "pll-video0", + "pll-video0-4x", + "pll-video1", + "pll-video1-4x" }; +static SUNXI_CCU_MP_WITH_MUX_GATE(tcon_tv0_clk, "tcon-tv0", + tcon_tv0_parents, 0xb80, + 0, 4, /* M */ + 8, 2, /* P */ + 24, 3, /* mux */ + BIT(31), /* gate */ + 0); + +static SUNXI_CCU_GATE(bus_tcon_tv0_clk, "bus-tcon-tv0", "ahb3", + 0xb9c, BIT(0), 0); + +static SUNXI_CCU_GATE(csi_cci_clk, "csi-cci", "osc24M", 0xc00, BIT(0), 0); + +static const char * const csi_top_parents[] = { "pll-video0", "pll-ve", + "pll-periph0" }; +static const u8 csi_top_table[] = { 0, 2, 3 }; +static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi_top_clk, "csi-top", + csi_top_parents, csi_top_table, 0xc04, + 0, 4, /* M */ + 24, 3, /* mux */ + BIT(31), /* gate */ + 0); + +static const char * const csi_mclk_parents[] = { "osc24M", "pll-video0", + "pll-periph0", "pll-periph1" }; +static SUNXI_CCU_M_WITH_MUX_GATE(csi_mclk_clk, "csi-mclk", + csi_mclk_parents, 0xc08, + 0, 5, /* M */ + 24, 3, /* mux */ + BIT(31), /* gate */ + 0); + +static SUNXI_CCU_GATE(bus_csi_clk, "bus-csi", "ahb3", 0xc2c, BIT(0), 0); + +static const char * const hdcp_parents[] = { "pll-periph0", "pll-periph1" }; +static SUNXI_CCU_M_WITH_MUX_GATE(hdcp_clk, "hdcp", hdcp_parents, 0xc40, + 0, 4, /* M */ + 24, 2, /* mux */ + BIT(31), /* gate */ + 0); + +static SUNXI_CCU_GATE(bus_hdcp_clk, "bus-hdcp", "ahb3", 0xc4c, BIT(0), 0); + +/* Fixed factor clocks */ +static CLK_FIXED_FACTOR(osc12M_clk, "osc12M", "osc24M", 2, 1, 0); + +/* + * The divider of pll-audio is fixed to 8 now, as pll-audio-4x has a + * fixed post-divider 2. + */ +static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio", + "pll-audio-base", 8, 1, CLK_SET_RATE_PARENT); +static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x", + "pll-audio-base", 4, 1, CLK_SET_RATE_PARENT); +static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x", + "pll-audio-base", 2, 1, CLK_SET_RATE_PARENT); + +static CLK_FIXED_FACTOR(pll_periph0_4x_clk, "pll-periph0-4x", + "pll-periph0", 1, 4, 0); +static CLK_FIXED_FACTOR(pll_periph0_2x_clk, "pll-periph0-2x", + "pll-periph0", 1, 2, 0); + +static CLK_FIXED_FACTOR(pll_periph1_4x_clk, "pll-periph1-4x", + "pll-periph1", 1, 4, 0); +static CLK_FIXED_FACTOR(pll_periph1_2x_clk, "pll-periph1-2x", + "pll-periph1", 1, 2, 0); + +static CLK_FIXED_FACTOR(pll_video0_4x_clk, "pll-video0-4x", + "pll-video0", 1, 4, CLK_SET_RATE_PARENT); + +static CLK_FIXED_FACTOR(pll_video1_4x_clk, "pll-video1-4x", + "pll-video1", 1, 4, CLK_SET_RATE_PARENT); + +static struct ccu_common *sun50i_h6_ccu_clks[] = { + &pll_cpux_clk.common, + &pll_ddr0_clk.common, + &pll_periph0_clk.common, + &pll_periph1_clk.common, + &pll_gpu_clk.common, + &pll_video0_clk.common, + &pll_video1_clk.common, + &pll_ve_clk.common, + &pll_de_clk.common, + &pll_hsic_clk.common, + &pll_audio_base_clk.common, + &cpux_clk.common, + &axi_clk.common, + &cpux_apb_clk.common, + &psi_ahb1_ahb2_clk.common, + &ahb3_clk.common, + &apb1_clk.common, + &apb2_clk.common, + &mbus_clk.common, + &de_clk.common, + &bus_de_clk.common, + &deinterlace_clk.common, + &bus_deinterlace_clk.common, + &gpu_clk.common, + &bus_gpu_clk.common, + &ce_clk.common, + &bus_ce_clk.common, + &ve_clk.common, + &bus_ve_clk.common, + &emce_clk.common, + &bus_emce_clk.common, + &vp9_clk.common, + &bus_vp9_clk.common, + &bus_dma_clk.common, + &bus_msgbox_clk.common, + &bus_spinlock_clk.common, + &bus_hstimer_clk.common, + &avs_clk.common, + &bus_dbg_clk.common, + &bus_psi_clk.common, + &bus_pwm_clk.common, + &bus_iommu_clk.common, + &dram_clk.common, + &mbus_dma_clk.common, + &mbus_ve_clk.common, + &mbus_ce_clk.common, + &mbus_ts_clk.common, + &mbus_nand_clk.common, + &mbus_csi_clk.common, + &mbus_deinterlace_clk.common, + &bus_dram_clk.common, + &nand0_clk.common, + &nand1_clk.common, + &bus_nand_clk.common, + &mmc0_clk.common, + &mmc1_clk.common, + &mmc2_clk.common, + &bus_mmc0_clk.common, + &bus_mmc1_clk.common, + &bus_mmc2_clk.common, + &bus_uart0_clk.common, + &bus_uart1_clk.common, + &bus_uart2_clk.common, + &bus_uart3_clk.common, + &bus_i2c0_clk.common, + &bus_i2c1_clk.common, + &bus_i2c2_clk.common, + &bus_i2c3_clk.common, + &bus_scr0_clk.common, + &bus_scr1_clk.common, + &spi0_clk.common, + &spi1_clk.common, + &bus_spi0_clk.common, + &bus_spi1_clk.common, + &bus_emac_clk.common, + &ts_clk.common, + &bus_ts_clk.common, + &ir_tx_clk.common, + &bus_ir_tx_clk.common, + &bus_ths_clk.common, + &i2s3_clk.common, + &i2s0_clk.common, + &i2s1_clk.common, + &i2s2_clk.common, + &bus_i2s0_clk.common, + &bus_i2s1_clk.common, + &bus_i2s2_clk.common, + &bus_i2s3_clk.common, + &spdif_clk.common, + &bus_spdif_clk.common, + &dmic_clk.common, + &bus_dmic_clk.common, + &audio_hub_clk.common, + &bus_audio_hub_clk.common, + &usb_ohci0_clk.common, + &usb_phy0_clk.common, + &usb_phy1_clk.common, + &usb_ohci3_clk.common, + &usb_phy3_clk.common, + &usb_hsic_12m_clk.common, + &usb_hsic_clk.common, + &bus_ohci0_clk.common, + &bus_ohci3_clk.common, + &bus_ehci0_clk.common, + &bus_xhci_clk.common, + &bus_ehci3_clk.common, + &bus_otg_clk.common, + &pcie_ref_clk.common, + &pcie_ref_out_clk.common, + &pcie_maxi_clk.common, + &pcie_aux_clk.common, + &bus_pcie_clk.common, + &hdmi_clk.common, + &hdmi_cec_clk.common, + &bus_hdmi_clk.common, + &bus_tcon_top_clk.common, + &tcon_lcd0_clk.common, + &bus_tcon_lcd0_clk.common, + &tcon_tv0_clk.common, + &bus_tcon_tv0_clk.common, + &csi_cci_clk.common, + &csi_top_clk.common, + &csi_mclk_clk.common, + &bus_csi_clk.common, + &hdcp_clk.common, + &bus_hdcp_clk.common, +}; + +static struct clk_hw_onecell_data sun50i_h6_hw_clks = { + .hws = { + [CLK_OSC12M] = &osc12M_clk.hw, + [CLK_PLL_CPUX] = &pll_cpux_clk.common.hw, + [CLK_PLL_DDR0] = &pll_ddr0_clk.common.hw, + [CLK_PLL_PERIPH0] = &pll_periph0_clk.common.hw, + [CLK_PLL_PERIPH0_2X] = &pll_periph0_2x_clk.hw, + [CLK_PLL_PERIPH0_4X] = &pll_periph0_4x_clk.hw, + [CLK_PLL_PERIPH1] = &pll_periph1_clk.common.hw, + [CLK_PLL_PERIPH1_2X] = &pll_periph1_2x_clk.hw, + [CLK_PLL_PERIPH1_4X] = &pll_periph1_4x_clk.hw, + [CLK_PLL_GPU] = &pll_gpu_clk.common.hw, + [CLK_PLL_VIDEO0] = &pll_video0_clk.common.hw, + [CLK_PLL_VIDEO0_4X] = &pll_video0_4x_clk.hw, + [CLK_PLL_VIDEO1] = &pll_video1_clk.common.hw, + [CLK_PLL_VIDEO1_4X] = &pll_video1_4x_clk.hw, + [CLK_PLL_VE] = &pll_ve_clk.common.hw, + [CLK_PLL_DE] = &pll_de_clk.common.hw, + [CLK_PLL_HSIC] = &pll_hsic_clk.common.hw, + [CLK_PLL_AUDIO_BASE] = &pll_audio_base_clk.common.hw, + [CLK_PLL_AUDIO] = &pll_audio_clk.hw, + [CLK_PLL_AUDIO_2X] = &pll_audio_2x_clk.hw, + [CLK_PLL_AUDIO_4X] = &pll_audio_4x_clk.hw, + [CLK_CPUX] = &cpux_clk.common.hw, + [CLK_AXI] = &axi_clk.common.hw, + [CLK_CPUX_APB] = &cpux_apb_clk.common.hw, + [CLK_PSI_AHB1_AHB2] = &psi_ahb1_ahb2_clk.common.hw, + [CLK_AHB3] = &ahb3_clk.common.hw, + [CLK_APB1] = &apb1_clk.common.hw, + [CLK_APB2] = &apb2_clk.common.hw, + [CLK_MBUS] = &mbus_clk.common.hw, + [CLK_DE] = &de_clk.common.hw, + [CLK_BUS_DE] = &bus_de_clk.common.hw, + [CLK_DEINTERLACE] = &deinterlace_clk.common.hw, + [CLK_BUS_DEINTERLACE] = &bus_deinterlace_clk.common.hw, + [CLK_GPU] = &gpu_clk.common.hw, + [CLK_BUS_GPU] = &bus_gpu_clk.common.hw, + [CLK_CE] = &ce_clk.common.hw, + [CLK_BUS_CE] = &bus_ce_clk.common.hw, + [CLK_VE] = &ve_clk.common.hw, + [CLK_BUS_VE] = &bus_ve_clk.common.hw, + [CLK_EMCE] = &emce_clk.common.hw, + [CLK_BUS_EMCE] = &bus_emce_clk.common.hw, + [CLK_VP9] = &vp9_clk.common.hw, + [CLK_BUS_VP9] = &bus_vp9_clk.common.hw, + [CLK_BUS_DMA] = &bus_dma_clk.common.hw, + [CLK_BUS_MSGBOX] = &bus_msgbox_clk.common.hw, + [CLK_BUS_SPINLOCK] = &bus_spinlock_clk.common.hw, + [CLK_BUS_HSTIMER] = &bus_hstimer_clk.common.hw, + [CLK_AVS] = &avs_clk.common.hw, + [CLK_BUS_DBG] = &bus_dbg_clk.common.hw, + [CLK_BUS_PSI] = &bus_psi_clk.common.hw, + [CLK_BUS_PWM] = &bus_pwm_clk.common.hw, + [CLK_BUS_IOMMU] = &bus_iommu_clk.common.hw, + [CLK_DRAM] = &dram_clk.common.hw, + [CLK_MBUS_DMA] = &mbus_dma_clk.common.hw, + [CLK_MBUS_VE] = &mbus_ve_clk.common.hw, + [CLK_MBUS_CE] = &mbus_ce_clk.common.hw, + [CLK_MBUS_TS] = &mbus_ts_clk.common.hw, + [CLK_MBUS_NAND] = &mbus_nand_clk.common.hw, + [CLK_MBUS_CSI] = &mbus_csi_clk.common.hw, + [CLK_MBUS_DEINTERLACE] = &mbus_deinterlace_clk.common.hw, + [CLK_BUS_DRAM] = &bus_dram_clk.common.hw, + [CLK_NAND0] = &nand0_clk.common.hw, + [CLK_NAND1] = &nand1_clk.common.hw, + [CLK_BUS_NAND] = &bus_nand_clk.common.hw, + [CLK_MMC0] = &mmc0_clk.common.hw, + [CLK_MMC1] = &mmc1_clk.common.hw, + [CLK_MMC2] = &mmc2_clk.common.hw, + [CLK_BUS_MMC0] = &bus_mmc0_clk.common.hw, + [CLK_BUS_MMC1] = &bus_mmc1_clk.common.hw, + [CLK_BUS_MMC2] = &bus_mmc2_clk.common.hw, + [CLK_BUS_UART0] = &bus_uart0_clk.common.hw, + [CLK_BUS_UART1] = &bus_uart1_clk.common.hw, + [CLK_BUS_UART2] = &bus_uart2_clk.common.hw, + [CLK_BUS_UART3] = &bus_uart3_clk.common.hw, + [CLK_BUS_I2C0] = &bus_i2c0_clk.common.hw, + [CLK_BUS_I2C1] = &bus_i2c1_clk.common.hw, + [CLK_BUS_I2C2] = &bus_i2c2_clk.common.hw, + [CLK_BUS_I2C3] = &bus_i2c3_clk.common.hw, + [CLK_BUS_SCR0] = &bus_scr0_clk.common.hw, + [CLK_BUS_SCR1] = &bus_scr1_clk.common.hw, + [CLK_SPI0] = &spi0_clk.common.hw, + [CLK_SPI1] = &spi1_clk.common.hw, + [CLK_BUS_SPI0] = &bus_spi0_clk.common.hw, + [CLK_BUS_SPI1] = &bus_spi1_clk.common.hw, + [CLK_BUS_EMAC] = &bus_emac_clk.common.hw, + [CLK_TS] = &ts_clk.common.hw, + [CLK_BUS_TS] = &bus_ts_clk.common.hw, + [CLK_IR_TX] = &ir_tx_clk.common.hw, + [CLK_BUS_IR_TX] = &bus_ir_tx_clk.common.hw, + [CLK_BUS_THS] = &bus_ths_clk.common.hw, + [CLK_I2S3] = &i2s3_clk.common.hw, + [CLK_I2S0] = &i2s0_clk.common.hw, + [CLK_I2S1] = &i2s1_clk.common.hw, + [CLK_I2S2] = &i2s2_clk.common.hw, + [CLK_BUS_I2S0] = &bus_i2s0_clk.common.hw, + [CLK_BUS_I2S1] = &bus_i2s1_clk.common.hw, + [CLK_BUS_I2S2] = &bus_i2s2_clk.common.hw, + [CLK_BUS_I2S3] = &bus_i2s3_clk.common.hw, + [CLK_SPDIF] = &spdif_clk.common.hw, + [CLK_BUS_SPDIF] = &bus_spdif_clk.common.hw, + [CLK_DMIC] = &dmic_clk.common.hw, + [CLK_BUS_DMIC] = &bus_dmic_clk.common.hw, + [CLK_AUDIO_HUB] = &audio_hub_clk.common.hw, + [CLK_BUS_AUDIO_HUB] = &bus_audio_hub_clk.common.hw, + [CLK_USB_OHCI0] = &usb_ohci0_clk.common.hw, + [CLK_USB_PHY0] = &usb_phy0_clk.common.hw, + [CLK_USB_PHY1] = &usb_phy1_clk.common.hw, + [CLK_USB_OHCI3] = &usb_ohci3_clk.common.hw, + [CLK_USB_PHY3] = &usb_phy3_clk.common.hw, + [CLK_USB_HSIC_12M] = &usb_hsic_12m_clk.common.hw, + [CLK_USB_HSIC] = &usb_hsic_clk.common.hw, + [CLK_BUS_OHCI0] = &bus_ohci0_clk.common.hw, + [CLK_BUS_OHCI3] = &bus_ohci3_clk.common.hw, + [CLK_BUS_EHCI0] = &bus_ehci0_clk.common.hw, + [CLK_BUS_XHCI] = &bus_xhci_clk.common.hw, + [CLK_BUS_EHCI3] = &bus_ehci3_clk.common.hw, + [CLK_BUS_OTG] = &bus_otg_clk.common.hw, + [CLK_PCIE_REF_100M] = &pcie_ref_100m_clk.hw, + [CLK_PCIE_REF] = &pcie_ref_clk.common.hw, + [CLK_PCIE_REF_OUT] = &pcie_ref_out_clk.common.hw, + [CLK_PCIE_MAXI] = &pcie_maxi_clk.common.hw, + [CLK_PCIE_AUX] = &pcie_aux_clk.common.hw, + [CLK_BUS_PCIE] = &bus_pcie_clk.common.hw, + [CLK_HDMI] = &hdmi_clk.common.hw, + [CLK_HDMI_CEC] = &hdmi_cec_clk.common.hw, + [CLK_BUS_HDMI] = &bus_hdmi_clk.common.hw, + [CLK_BUS_TCON_TOP] = &bus_tcon_top_clk.common.hw, + [CLK_TCON_LCD0] = &tcon_lcd0_clk.common.hw, + [CLK_BUS_TCON_LCD0] = &bus_tcon_lcd0_clk.common.hw, + [CLK_TCON_TV0] = &tcon_tv0_clk.common.hw, + [CLK_BUS_TCON_TV0] = &bus_tcon_tv0_clk.common.hw, + [CLK_CSI_CCI] = &csi_cci_clk.common.hw, + [CLK_CSI_TOP] = &csi_top_clk.common.hw, + [CLK_CSI_MCLK] = &csi_mclk_clk.common.hw, + [CLK_BUS_CSI] = &bus_csi_clk.common.hw, + [CLK_HDCP] = &hdcp_clk.common.hw, + [CLK_BUS_HDCP] = &bus_hdcp_clk.common.hw, + }, + .num = CLK_NUMBER, +}; + +static struct ccu_reset_map sun50i_h6_ccu_resets[] = { + [RST_MBUS] = { 0x540, BIT(30) }, + + [RST_BUS_DE] = { 0x60c, BIT(16) }, + [RST_BUS_DEINTERLACE] = { 0x62c, BIT(16) }, + [RST_BUS_GPU] = { 0x67c, BIT(16) }, + [RST_BUS_CE] = { 0x68c, BIT(16) }, + [RST_BUS_VE] = { 0x69c, BIT(16) }, + [RST_BUS_EMCE] = { 0x6bc, BIT(16) }, + [RST_BUS_VP9] = { 0x6cc, BIT(16) }, + [RST_BUS_DMA] = { 0x70c, BIT(16) }, + [RST_BUS_MSGBOX] = { 0x71c, BIT(16) }, + [RST_BUS_SPINLOCK] = { 0x72c, BIT(16) }, + [RST_BUS_HSTIMER] = { 0x73c, BIT(16) }, + [RST_BUS_DBG] = { 0x78c, BIT(16) }, + [RST_BUS_PSI] = { 0x79c, BIT(16) }, + [RST_BUS_PWM] = { 0x7ac, BIT(16) }, + [RST_BUS_IOMMU] = { 0x7bc, BIT(16) }, + [RST_BUS_DRAM] = { 0x80c, BIT(16) }, + [RST_BUS_NAND] = { 0x82c, BIT(16) }, + [RST_BUS_MMC0] = { 0x84c, BIT(16) }, + [RST_BUS_MMC1] = { 0x84c, BIT(17) }, + [RST_BUS_MMC2] = { 0x84c, BIT(18) }, + [RST_BUS_UART0] = { 0x90c, BIT(16) }, + [RST_BUS_UART1] = { 0x90c, BIT(17) }, + [RST_BUS_UART2] = { 0x90c, BIT(18) }, + [RST_BUS_UART3] = { 0x90c, BIT(19) }, + [RST_BUS_I2C0] = { 0x91c, BIT(16) }, + [RST_BUS_I2C1] = { 0x91c, BIT(17) }, + [RST_BUS_I2C2] = { 0x91c, BIT(18) }, + [RST_BUS_I2C3] = { 0x91c, BIT(19) }, + [RST_BUS_SCR0] = { 0x93c, BIT(16) }, + [RST_BUS_SCR1] = { 0x93c, BIT(17) }, + [RST_BUS_SPI0] = { 0x96c, BIT(16) }, + [RST_BUS_SPI1] = { 0x96c, BIT(17) }, + [RST_BUS_EMAC] = { 0x97c, BIT(16) }, + [RST_BUS_TS] = { 0x9bc, BIT(16) }, + [RST_BUS_IR_TX] = { 0x9cc, BIT(16) }, + [RST_BUS_THS] = { 0x9fc, BIT(16) }, + [RST_BUS_I2S0] = { 0xa1c, BIT(16) }, + [RST_BUS_I2S1] = { 0xa1c, BIT(17) }, + [RST_BUS_I2S2] = { 0xa1c, BIT(18) }, + [RST_BUS_I2S3] = { 0xa1c, BIT(19) }, + [RST_BUS_SPDIF] = { 0xa2c, BIT(16) }, + [RST_BUS_DMIC] = { 0xa4c, BIT(16) }, + [RST_BUS_AUDIO_HUB] = { 0xa6c, BIT(16) }, + + [RST_USB_PHY0] = { 0xa70, BIT(30) }, + [RST_USB_PHY1] = { 0xa74, BIT(30) }, + [RST_USB_PHY3] = { 0xa7c, BIT(30) }, + [RST_USB_HSIC] = { 0xa7c, BIT(28) }, + + [RST_BUS_OHCI0] = { 0xa8c, BIT(16) }, + [RST_BUS_OHCI3] = { 0xa8c, BIT(19) }, + [RST_BUS_EHCI0] = { 0xa8c, BIT(20) }, + [RST_BUS_XHCI] = { 0xa8c, BIT(21) }, + [RST_BUS_EHCI3] = { 0xa8c, BIT(23) }, + [RST_BUS_OTG] = { 0xa8c, BIT(24) }, + [RST_BUS_PCIE] = { 0xabc, BIT(16) }, + + [RST_PCIE_POWERUP] = { 0xabc, BIT(17) }, + + [RST_BUS_HDMI] = { 0xb1c, BIT(16) }, + [RST_BUS_HDMI_SUB] = { 0xb1c, BIT(17) }, + [RST_BUS_TCON_TOP] = { 0xb5c, BIT(16) }, + [RST_BUS_TCON_LCD0] = { 0xb7c, BIT(16) }, + [RST_BUS_TCON_TV0] = { 0xb9c, BIT(16) }, + [RST_BUS_CSI] = { 0xc2c, BIT(16) }, + [RST_BUS_HDCP] = { 0xc4c, BIT(16) }, +}; + +static const struct sunxi_ccu_desc sun50i_h6_ccu_desc = { + .ccu_clks = sun50i_h6_ccu_clks, + .num_ccu_clks = ARRAY_SIZE(sun50i_h6_ccu_clks), + + .hw_clks = &sun50i_h6_hw_clks, + + .resets = sun50i_h6_ccu_resets, + .num_resets = ARRAY_SIZE(sun50i_h6_ccu_resets), +}; + +static const u32 pll_regs[] = { + SUN50I_H6_PLL_CPUX_REG, + SUN50I_H6_PLL_DDR0_REG, + SUN50I_H6_PLL_PERIPH0_REG, + SUN50I_H6_PLL_PERIPH1_REG, + SUN50I_H6_PLL_GPU_REG, + SUN50I_H6_PLL_VIDEO0_REG, + SUN50I_H6_PLL_VIDEO1_REG, + SUN50I_H6_PLL_VE_REG, + SUN50I_H6_PLL_DE_REG, + SUN50I_H6_PLL_HSIC_REG, + SUN50I_H6_PLL_AUDIO_REG, +}; + +static const u32 pll_video_regs[] = { + SUN50I_H6_PLL_VIDEO0_REG, + SUN50I_H6_PLL_VIDEO1_REG, +}; + +static const u32 usb2_clk_regs[] = { + SUN50I_H6_USB0_CLK_REG, + SUN50I_H6_USB3_CLK_REG, +}; + +static int sun50i_h6_ccu_probe(struct platform_device *pdev) +{ + struct resource *res; + void __iomem *reg; + u32 val; + int i; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + reg = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(reg)) + return PTR_ERR(reg); + + /* Enable the lock bits on all PLLs */ + for (i = 0; i < ARRAY_SIZE(pll_regs); i++) { + val = readl(reg + pll_regs[i]); + val |= BIT(29); + writel(val, reg + pll_regs[i]); + } + + /* + * Force the output divider of video PLLs to 0. + * + * See the comment before pll-video0 definition for the reason. + */ + for (i = 0; i < ARRAY_SIZE(pll_video_regs); i++) { + val = readl(reg + pll_video_regs[i]); + val &= ~BIT(0); + writel(val, reg + pll_video_regs[i]); + } + + /* + * Force OHCI 12M clock sources to 00 (12MHz divided from 48MHz) + * + * This clock mux is still mysterious, and the code just enforces + * it to have a valid clock parent. + */ + for (i = 0; i < ARRAY_SIZE(usb2_clk_regs); i++) { + val = readl(reg + usb2_clk_regs[i]); + val &= ~GENMASK(25, 24); + writel (val, reg + usb2_clk_regs[i]); + } + + /* + * Force the post-divider of pll-audio to 8 and the output divider + * of it to 1, to make the clock name represents the real frequency. + */ + val = readl(reg + SUN50I_H6_PLL_AUDIO_REG); + val &= ~(GENMASK(21, 16) | BIT(0)); + writel(val | (7 << 16), reg + SUN50I_H6_PLL_AUDIO_REG); + + return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_h6_ccu_desc); +} + +static const struct of_device_id sun50i_h6_ccu_ids[] = { + { .compatible = "allwinner,sun50i-h6-ccu" }, + { } +}; + +static struct platform_driver sun50i_h6_ccu_driver = { + .probe = sun50i_h6_ccu_probe, + .driver = { + .name = "sun50i-h6-ccu", + .of_match_table = sun50i_h6_ccu_ids, + }, +}; +builtin_platform_driver(sun50i_h6_ccu_driver); diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6.h b/drivers/clk/sunxi-ng/ccu-sun50i-h6.h new file mode 100644 index 0000000..ad6da4a --- /dev/null +++ b/drivers/clk/sunxi-ng/ccu-sun50i-h6.h @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2016 Icenowy Zheng + */ + +#ifndef _CCU_SUN50I_H6_H_ +#define _CCU_SUN50I_H6_H_ + +#include +#include + +#define CLK_OSC12M 0 +#define CLK_PLL_CPUX 1 +#define CLK_PLL_DDR0 2 + +/* PLL_PERIPH0 exported for PRCM */ + +#define CLK_PLL_PERIPH0_2X 4 +#define CLK_PLL_PERIPH0_4X 5 +#define CLK_PLL_PERIPH1 6 +#define CLK_PLL_PERIPH1_2X 7 +#define CLK_PLL_PERIPH1_4X 8 +#define CLK_PLL_GPU 9 +#define CLK_PLL_VIDEO0 10 +#define CLK_PLL_VIDEO0_4X 11 +#define CLK_PLL_VIDEO1 12 +#define CLK_PLL_VIDEO1_4X 13 +#define CLK_PLL_VE 14 +#define CLK_PLL_DE 15 +#define CLK_PLL_HSIC 16 +#define CLK_PLL_AUDIO_BASE 17 +#define CLK_PLL_AUDIO 18 +#define CLK_PLL_AUDIO_2X 19 +#define CLK_PLL_AUDIO_4X 20 + +/* CPUX clock exported for DVFS */ + +#define CLK_AXI 22 +#define CLK_CPUX_APB 23 +#define CLK_PSI_AHB1_AHB2 24 +#define CLK_AHB3 25 + +/* APB1 clock exported for PIO */ + +#define CLK_APB2 27 +#define CLK_MBUS 28 + +/* All module clocks and bus gates are exported except DRAM */ + +#define CLK_DRAM 52 + +#define CLK_BUS_DRAM 60 + +#define CLK_NUMBER 137 + +#endif /* _CCU_SUN50I_H6_H_ */ diff --git a/include/dt-bindings/clock/sun50i-h6-ccu.h b/include/dt-bindings/clock/sun50i-h6-ccu.h new file mode 100644 index 0000000..6045735 --- /dev/null +++ b/include/dt-bindings/clock/sun50i-h6-ccu.h @@ -0,0 +1,124 @@ +// SPDX-License-Identifier: (GPL-2.0+ or MIT) +/* + * Copyright (C) 2017 Icenowy Zheng + */ + +#ifndef _DT_BINDINGS_CLK_SUN50I_H6_H_ +#define _DT_BINDINGS_CLK_SUN50I_H6_H_ + +#define CLK_PLL_PERIPH0 3 + +#define CLK_CPUX 21 + +#define CLK_APB1 26 + +#define CLK_DE 29 +#define CLK_BUS_DE 30 +#define CLK_DEINTERLACE 31 +#define CLK_BUS_DEINTERLACE 32 +#define CLK_GPU 33 +#define CLK_BUS_GPU 34 +#define CLK_CE 35 +#define CLK_BUS_CE 36 +#define CLK_VE 37 +#define CLK_BUS_VE 38 +#define CLK_EMCE 39 +#define CLK_BUS_EMCE 40 +#define CLK_VP9 41 +#define CLK_BUS_VP9 42 +#define CLK_BUS_DMA 43 +#define CLK_BUS_MSGBOX 44 +#define CLK_BUS_SPINLOCK 45 +#define CLK_BUS_HSTIMER 46 +#define CLK_AVS 47 +#define CLK_BUS_DBG 48 +#define CLK_BUS_PSI 49 +#define CLK_BUS_PWM 50 +#define CLK_BUS_IOMMU 51 + +#define CLK_MBUS_DMA 53 +#define CLK_MBUS_VE 54 +#define CLK_MBUS_CE 55 +#define CLK_MBUS_TS 56 +#define CLK_MBUS_NAND 57 +#define CLK_MBUS_CSI 58 +#define CLK_MBUS_DEINTERLACE 59 + +#define CLK_NAND0 61 +#define CLK_NAND1 62 +#define CLK_BUS_NAND 63 +#define CLK_MMC0 64 +#define CLK_MMC1 65 +#define CLK_MMC2 66 +#define CLK_BUS_MMC0 67 +#define CLK_BUS_MMC1 68 +#define CLK_BUS_MMC2 69 +#define CLK_BUS_UART0 70 +#define CLK_BUS_UART1 71 +#define CLK_BUS_UART2 72 +#define CLK_BUS_UART3 73 +#define CLK_BUS_I2C0 74 +#define CLK_BUS_I2C1 75 +#define CLK_BUS_I2C2 76 +#define CLK_BUS_I2C3 77 +#define CLK_BUS_SCR0 78 +#define CLK_BUS_SCR1 79 +#define CLK_SPI0 80 +#define CLK_SPI1 81 +#define CLK_BUS_SPI0 82 +#define CLK_BUS_SPI1 83 +#define CLK_BUS_EMAC 84 +#define CLK_TS 85 +#define CLK_BUS_TS 86 +#define CLK_IR_TX 87 +#define CLK_BUS_IR_TX 88 +#define CLK_BUS_THS 89 +#define CLK_I2S3 90 +#define CLK_I2S0 91 +#define CLK_I2S1 92 +#define CLK_I2S2 93 +#define CLK_BUS_I2S0 94 +#define CLK_BUS_I2S1 95 +#define CLK_BUS_I2S2 96 +#define CLK_BUS_I2S3 97 +#define CLK_SPDIF 98 +#define CLK_BUS_SPDIF 99 +#define CLK_DMIC 100 +#define CLK_BUS_DMIC 101 +#define CLK_AUDIO_HUB 102 +#define CLK_BUS_AUDIO_HUB 103 +#define CLK_USB_OHCI0 104 +#define CLK_USB_PHY0 105 +#define CLK_USB_PHY1 106 +#define CLK_USB_OHCI3 107 +#define CLK_USB_PHY3 108 +#define CLK_USB_HSIC_12M 109 +#define CLK_USB_HSIC 110 +#define CLK_BUS_OHCI0 111 +#define CLK_BUS_OHCI3 112 +#define CLK_BUS_EHCI0 113 +#define CLK_BUS_XHCI 114 +#define CLK_BUS_EHCI3 115 +#define CLK_BUS_OTG 116 +#define CLK_PCIE_REF_100M 117 +#define CLK_PCIE_REF 118 +#define CLK_PCIE_REF_OUT 119 +#define CLK_PCIE_MAXI 120 +#define CLK_PCIE_AUX 121 +#define CLK_BUS_PCIE 122 +#define CLK_HDMI 123 +#define CLK_HDMI_CEC 124 +#define CLK_BUS_HDMI 125 +#define CLK_BUS_TCON_TOP 126 +#define CLK_TCON_LCD0 127 +#define CLK_BUS_TCON_LCD0 128 +#define CLK_TCON_TV0 129 +#define CLK_BUS_TCON_TV0 130 +#define CLK_CSI_CCI 131 +#define CLK_CSI_TOP 132 +#define CLK_CSI_MCLK 133 +#define CLK_BUS_CSI 134 +#define CLK_HDCP 135 +#define CLK_BUS_HDCP 136 + +#endif /* _DT_BINDINGS_CLK_SUN50I_H6_H_ */ diff --git a/include/dt-bindings/reset/sun50i-h6-ccu.h b/include/dt-bindings/reset/sun50i-h6-ccu.h new file mode 100644 index 0000000..81106f4 --- /dev/null +++ b/include/dt-bindings/reset/sun50i-h6-ccu.h @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: (GPL-2.0+ or MIT) +/* + * Copyright (C) 2017 Icenowy Zheng + */ + +#ifndef _DT_BINDINGS_RESET_SUN50I_H6_H_ +#define _DT_BINDINGS_RESET_SUN50I_H6_H_ + +#define RST_MBUS 0 +#define RST_BUS_DE 1 +#define RST_BUS_DEINTERLACE 2 +#define RST_BUS_GPU 3 +#define RST_BUS_CE 4 +#define RST_BUS_VE 5 +#define RST_BUS_EMCE 6 +#define RST_BUS_VP9 7 +#define RST_BUS_DMA 8 +#define RST_BUS_MSGBOX 9 +#define RST_BUS_SPINLOCK 10 +#define RST_BUS_HSTIMER 11 +#define RST_BUS_DBG 12 +#define RST_BUS_PSI 13 +#define RST_BUS_PWM 14 +#define RST_BUS_IOMMU 15 +#define RST_BUS_DRAM 16 +#define RST_BUS_NAND 17 +#define RST_BUS_MMC0 18 +#define RST_BUS_MMC1 19 +#define RST_BUS_MMC2 20 +#define RST_BUS_UART0 21 +#define RST_BUS_UART1 22 +#define RST_BUS_UART2 23 +#define RST_BUS_UART3 24 +#define RST_BUS_I2C0 25 +#define RST_BUS_I2C1 26 +#define RST_BUS_I2C2 27 +#define RST_BUS_I2C3 28 +#define RST_BUS_SCR0 29 +#define RST_BUS_SCR1 30 +#define RST_BUS_SPI0 31 +#define RST_BUS_SPI1 32 +#define RST_BUS_EMAC 33 +#define RST_BUS_TS 34 +#define RST_BUS_IR_TX 35 +#define RST_BUS_THS 36 +#define RST_BUS_I2S0 37 +#define RST_BUS_I2S1 38 +#define RST_BUS_I2S2 39 +#define RST_BUS_I2S3 40 +#define RST_BUS_SPDIF 41 +#define RST_BUS_DMIC 42 +#define RST_BUS_AUDIO_HUB 43 +#define RST_USB_PHY0 44 +#define RST_USB_PHY1 45 +#define RST_USB_PHY3 46 +#define RST_USB_HSIC 47 +#define RST_BUS_OHCI0 48 +#define RST_BUS_OHCI3 49 +#define RST_BUS_EHCI0 50 +#define RST_BUS_XHCI 51 +#define RST_BUS_EHCI3 52 +#define RST_BUS_OTG 53 +#define RST_BUS_PCIE 54 +#define RST_PCIE_POWERUP 55 +#define RST_BUS_HDMI 56 +#define RST_BUS_HDMI_SUB 57 +#define RST_BUS_TCON_TOP 58 +#define RST_BUS_TCON_LCD0 59 +#define RST_BUS_TCON_TV0 60 +#define RST_BUS_CSI 61 +#define RST_BUS_HDCP 62 + +#endif /* _DT_BINDINGS_RESET_SUN50I_H6_H_ */ -- cgit v1.1 From 55a5fcafe3a94e8a0777bb993d09107d362258d2 Mon Sep 17 00:00:00 2001 From: Sean Wang Date: Thu, 1 Mar 2018 11:27:50 +0800 Subject: dt-bindings: clock: mediatek: add binding for fixed-factor clock axisel_d4 Just add binding for a fixed-factor clock axisel_d4, which would be referenced by PWM devices on MT7623 or MT2701 SoC. Cc: stable@vger.kernel.org Fixes: 1de9b21633d6 ("clk: mediatek: Add dt-bindings for MT2701 clocks") Signed-off-by: Sean Wang Reviewed-by: Rob Herring Cc: Mark Rutland Cc: devicetree@vger.kernel.org Signed-off-by: Stephen Boyd --- include/dt-bindings/clock/mt2701-clk.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/dt-bindings/clock/mt2701-clk.h b/include/dt-bindings/clock/mt2701-clk.h index 551f760..24e93df 100644 --- a/include/dt-bindings/clock/mt2701-clk.h +++ b/include/dt-bindings/clock/mt2701-clk.h @@ -176,7 +176,8 @@ #define CLK_TOP_AUD_EXT1 156 #define CLK_TOP_AUD_EXT2 157 #define CLK_TOP_NFI1X_PAD 158 -#define CLK_TOP_NR 159 +#define CLK_TOP_AXISEL_D4 159 +#define CLK_TOP_NR 160 /* APMIXEDSYS */ -- cgit v1.1 From 89cd7aec21af26fd0c117bfc4bfc781724f201de Mon Sep 17 00:00:00 2001 From: Sean Wang Date: Thu, 1 Mar 2018 11:27:51 +0800 Subject: clk: mediatek: fix PWM clock source by adding a fixed-factor clock The clock for which all PWM devices on MT7623 or MT2701 actually depending on has to be divided by four from its parent clock axi_sel in the clock path prior to PWM devices. Consequently, adding a fixed-factor clock axisel_d4 as one-fourth of clock axi_sel allows that PWM devices can have the correct resolution calculation. Cc: stable@vger.kernel.org Fixes: e9862118272a ("clk: mediatek: Add MT2701 clock support") Signed-off-by: Sean Wang Signed-off-by: Stephen Boyd --- drivers/clk/mediatek/clk-mt2701.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/clk/mediatek/clk-mt2701.c b/drivers/clk/mediatek/clk-mt2701.c index 8e7f16f..deca752 100644 --- a/drivers/clk/mediatek/clk-mt2701.c +++ b/drivers/clk/mediatek/clk-mt2701.c @@ -148,6 +148,7 @@ static const struct mtk_fixed_factor top_fixed_divs[] = { FACTOR(CLK_TOP_CLK26M_D8, "clk26m_d8", "clk26m", 1, 8), FACTOR(CLK_TOP_32K_INTERNAL, "32k_internal", "clk26m", 1, 793), FACTOR(CLK_TOP_32K_EXTERNAL, "32k_external", "rtc32k", 1, 1), + FACTOR(CLK_TOP_AXISEL_D4, "axisel_d4", "axi_sel", 1, 4), }; static const char * const axi_parents[] = { @@ -857,13 +858,13 @@ static const struct mtk_gate peri_clks[] = { GATE_PERI0(CLK_PERI_USB1, "usb1_ck", "usb20_sel", 11), GATE_PERI0(CLK_PERI_USB0, "usb0_ck", "usb20_sel", 10), GATE_PERI0(CLK_PERI_PWM, "pwm_ck", "axi_sel", 9), - GATE_PERI0(CLK_PERI_PWM7, "pwm7_ck", "axi_sel", 8), - GATE_PERI0(CLK_PERI_PWM6, "pwm6_ck", "axi_sel", 7), - GATE_PERI0(CLK_PERI_PWM5, "pwm5_ck", "axi_sel", 6), - GATE_PERI0(CLK_PERI_PWM4, "pwm4_ck", "axi_sel", 5), - GATE_PERI0(CLK_PERI_PWM3, "pwm3_ck", "axi_sel", 4), - GATE_PERI0(CLK_PERI_PWM2, "pwm2_ck", "axi_sel", 3), - GATE_PERI0(CLK_PERI_PWM1, "pwm1_ck", "axi_sel", 2), + GATE_PERI0(CLK_PERI_PWM7, "pwm7_ck", "axisel_d4", 8), + GATE_PERI0(CLK_PERI_PWM6, "pwm6_ck", "axisel_d4", 7), + GATE_PERI0(CLK_PERI_PWM5, "pwm5_ck", "axisel_d4", 6), + GATE_PERI0(CLK_PERI_PWM4, "pwm4_ck", "axisel_d4", 5), + GATE_PERI0(CLK_PERI_PWM3, "pwm3_ck", "axisel_d4", 4), + GATE_PERI0(CLK_PERI_PWM2, "pwm2_ck", "axisel_d4", 3), + GATE_PERI0(CLK_PERI_PWM1, "pwm1_ck", "axisel_d4", 2), GATE_PERI0(CLK_PERI_THERM, "therm_ck", "axi_sel", 1), GATE_PERI0(CLK_PERI_NFI, "nfi_ck", "nfi2x_sel", 0), -- cgit v1.1 From 936ceb12c5f72cd087149e3cf01347969a472801 Mon Sep 17 00:00:00 2001 From: Ryder Lee Date: Tue, 6 Mar 2018 17:09:26 +0800 Subject: clk: mediatek: update missing clock data for MT7622 audsys Add missing clock data 'CLK_AUDIO_AFE_CONN' for MT7622 audsys. Signed-off-by: Ryder Lee Reviewed-by: Rob Herring Reviewed-by: Matthias Brugger Signed-off-by: Stephen Boyd --- drivers/clk/mediatek/clk-mt7622-aud.c | 1 + include/dt-bindings/clock/mt7622-clk.h | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/clk/mediatek/clk-mt7622-aud.c b/drivers/clk/mediatek/clk-mt7622-aud.c index fad7d9f..13f752d 100644 --- a/drivers/clk/mediatek/clk-mt7622-aud.c +++ b/drivers/clk/mediatek/clk-mt7622-aud.c @@ -106,6 +106,7 @@ static const struct mtk_gate audio_clks[] = { GATE_AUDIO1(CLK_AUDIO_INTDIR, "audio_intdir", "intdir_sel", 20), GATE_AUDIO1(CLK_AUDIO_A1SYS, "audio_a1sys", "a1sys_hp_sel", 21), GATE_AUDIO1(CLK_AUDIO_A2SYS, "audio_a2sys", "a2sys_hp_sel", 22), + GATE_AUDIO1(CLK_AUDIO_AFE_CONN, "audio_afe_conn", "a1sys_hp_sel", 23), /* AUDIO2 */ GATE_AUDIO2(CLK_AUDIO_UL1, "audio_ul1", "a1sys_hp_sel", 0), GATE_AUDIO2(CLK_AUDIO_UL2, "audio_ul2", "a1sys_hp_sel", 1), diff --git a/include/dt-bindings/clock/mt7622-clk.h b/include/dt-bindings/clock/mt7622-clk.h index 3e514ed..e9d77f0 100644 --- a/include/dt-bindings/clock/mt7622-clk.h +++ b/include/dt-bindings/clock/mt7622-clk.h @@ -235,7 +235,8 @@ #define CLK_AUDIO_MEM_ASRC3 43 #define CLK_AUDIO_MEM_ASRC4 44 #define CLK_AUDIO_MEM_ASRC5 45 -#define CLK_AUDIO_NR_CLK 46 +#define CLK_AUDIO_AFE_CONN 46 +#define CLK_AUDIO_NR_CLK 47 /* SSUSBSYS */ -- cgit v1.1 From 2817a92dd90ab8c53f2c03b7c4d5f8590ee36940 Mon Sep 17 00:00:00 2001 From: Ryder Lee Date: Tue, 6 Mar 2018 17:09:29 +0800 Subject: dt-bindings: clock: mediatek: update audsys documentation to adapt MFD device The MediaTek audio hardware block that exposes functionalities that are handled by separate subsystems in the kernel. These functions are all mapped somewhere at 0x112xxxxx, and there are some control bits are mixed up with other functions within the same registers. This patch modifies example to illustrate child nodes. Signed-off-by: Ryder Lee Signed-off-by: Stephen Boyd --- .../bindings/arm/mediatek/mediatek,audsys.txt | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt index 9b8f578..97b304e 100644 --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt @@ -13,10 +13,19 @@ The AUDSYS controller uses the common clk binding from Documentation/devicetree/bindings/clock/clock-bindings.txt The available clocks are defined in dt-bindings/clock/mt*-clk.h. +Required sub-nodes: +------- +For common binding part and usage, refer to +../sonud/mt2701-afe-pcm.txt. + Example: -audsys: audsys@11220000 { - compatible = "mediatek,mt7622-audsys", "syscon"; - reg = <0 0x11220000 0 0x1000>; - #clock-cells = <1>; -}; + audsys: clock-controller@11220000 { + compatible = "mediatek,mt7622-audsys", "syscon"; + reg = <0 0x11220000 0 0x2000>; + #clock-cells = <1>; + + afe: audio-controller { + ... + }; + }; -- cgit v1.1 From 9cb12501f38f924567ea7ba10041d32ecd7bf809 Mon Sep 17 00:00:00 2001 From: Ryder Lee Date: Tue, 6 Mar 2018 17:09:30 +0800 Subject: dt-bindings: clock: mediatek: add audsys support for MT2701 This patch adds a compatible string for MT2701. Signed-off-by: Ryder Lee Signed-off-by: Stephen Boyd --- Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt index 97b304e..34a69ba 100644 --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt @@ -6,6 +6,7 @@ The MediaTek AUDSYS controller provides various clocks to the system. Required Properties: - compatible: Should be one of: + - "mediatek,mt2701-audsys", "syscon" - "mediatek,mt7622-audsys", "syscon" - #clock-cells: Must be 1 -- cgit v1.1 From 037b21133e5367c833908db0226d77138ba4c5eb Mon Sep 17 00:00:00 2001 From: Ryder Lee Date: Tue, 20 Mar 2018 11:16:51 +0800 Subject: clk: mediatek: add devm_of_platform_populate() for MT7622 audsys Add devm_of_platform_populate() to populate devices which are children of the root node. Signed-off-by: Ryder Lee Signed-off-by: Stephen Boyd --- drivers/clk/mediatek/clk-mt7622-aud.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/clk/mediatek/clk-mt7622-aud.c b/drivers/clk/mediatek/clk-mt7622-aud.c index 13f752d..4f3d47b 100644 --- a/drivers/clk/mediatek/clk-mt7622-aud.c +++ b/drivers/clk/mediatek/clk-mt7622-aud.c @@ -150,11 +150,23 @@ static int clk_mt7622_audiosys_init(struct platform_device *pdev) clk_data); r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); - if (r) + if (r) { dev_err(&pdev->dev, "could not register clock provider: %s: %d\n", pdev->name, r); + goto err_clk_provider; + } + + r = devm_of_platform_populate(&pdev->dev); + if (r) + goto err_plat_populate; + + return 0; + +err_plat_populate: + of_clk_del_provider(node); +err_clk_provider: return r; } -- cgit v1.1 From b572f6393ee54bd4173a4313da8f2fb986a11089 Mon Sep 17 00:00:00 2001 From: Ryder Lee Date: Tue, 20 Mar 2018 11:16:52 +0800 Subject: clk: mediatek: add audsys support for MT2701 Add clock driver support for MT2701 audsys. Signed-off-by: Ryder Lee Signed-off-by: Stephen Boyd --- drivers/clk/mediatek/Kconfig | 6 ++ drivers/clk/mediatek/Makefile | 1 + drivers/clk/mediatek/clk-mt2701-aud.c | 186 ++++++++++++++++++++++++++++++++++ 3 files changed, 193 insertions(+) create mode 100644 drivers/clk/mediatek/clk-mt2701-aud.c diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig index 1f9ea0f..92afe59 100644 --- a/drivers/clk/mediatek/Kconfig +++ b/drivers/clk/mediatek/Kconfig @@ -54,6 +54,12 @@ config COMMON_CLK_MT2701_BDPSYS ---help--- This driver supports MediaTek MT2701 bdpsys clocks. +config COMMON_CLK_MT2701_AUDSYS + bool "Clock driver for Mediatek MT2701 audsys" + depends on COMMON_CLK_MT2701 + ---help--- + This driver supports Mediatek MT2701 audsys clocks. + config COMMON_CLK_MT2712 bool "Clock driver for MediaTek MT2712" depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile index 5160fdc..b80eff2 100644 --- a/drivers/clk/mediatek/Makefile +++ b/drivers/clk/mediatek/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_COMMON_CLK_MT6797_MMSYS) += clk-mt6797-mm.o obj-$(CONFIG_COMMON_CLK_MT6797_VDECSYS) += clk-mt6797-vdec.o obj-$(CONFIG_COMMON_CLK_MT6797_VENCSYS) += clk-mt6797-venc.o obj-$(CONFIG_COMMON_CLK_MT2701) += clk-mt2701.o +obj-$(CONFIG_COMMON_CLK_MT2701_AUDSYS) += clk-mt2701-aud.o obj-$(CONFIG_COMMON_CLK_MT2701_BDPSYS) += clk-mt2701-bdp.o obj-$(CONFIG_COMMON_CLK_MT2701_ETHSYS) += clk-mt2701-eth.o obj-$(CONFIG_COMMON_CLK_MT2701_HIFSYS) += clk-mt2701-hif.o diff --git a/drivers/clk/mediatek/clk-mt2701-aud.c b/drivers/clk/mediatek/clk-mt2701-aud.c new file mode 100644 index 0000000..e66896a --- /dev/null +++ b/drivers/clk/mediatek/clk-mt2701-aud.c @@ -0,0 +1,186 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018 MediaTek Inc. + * Author: Ryder Lee + */ + +#include +#include +#include +#include +#include + +#include "clk-mtk.h" +#include "clk-gate.h" + +#include + +#define GATE_AUDIO0(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &audio0_cg_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_ops_no_setclr, \ + } + +#define GATE_AUDIO1(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &audio1_cg_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_ops_no_setclr, \ + } + +#define GATE_AUDIO2(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &audio2_cg_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_ops_no_setclr, \ + } + +#define GATE_AUDIO3(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &audio3_cg_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_ops_no_setclr, \ + } + +static const struct mtk_gate_regs audio0_cg_regs = { + .set_ofs = 0x0, + .clr_ofs = 0x0, + .sta_ofs = 0x0, +}; + +static const struct mtk_gate_regs audio1_cg_regs = { + .set_ofs = 0x10, + .clr_ofs = 0x10, + .sta_ofs = 0x10, +}; + +static const struct mtk_gate_regs audio2_cg_regs = { + .set_ofs = 0x14, + .clr_ofs = 0x14, + .sta_ofs = 0x14, +}; + +static const struct mtk_gate_regs audio3_cg_regs = { + .set_ofs = 0x634, + .clr_ofs = 0x634, + .sta_ofs = 0x634, +}; + +static const struct mtk_gate audio_clks[] = { + /* AUDIO0 */ + GATE_AUDIO0(CLK_AUD_AFE, "audio_afe", "aud_intbus_sel", 2), + GATE_AUDIO0(CLK_AUD_HDMI, "audio_hdmi", "audpll_sel", 20), + GATE_AUDIO0(CLK_AUD_SPDF, "audio_spdf", "audpll_sel", 21), + GATE_AUDIO0(CLK_AUD_SPDF2, "audio_spdf2", "audpll_sel", 22), + GATE_AUDIO0(CLK_AUD_APLL, "audio_apll", "audpll_sel", 23), + /* AUDIO1 */ + GATE_AUDIO1(CLK_AUD_I2SIN1, "audio_i2sin1", "aud_mux1_sel", 0), + GATE_AUDIO1(CLK_AUD_I2SIN2, "audio_i2sin2", "aud_mux1_sel", 1), + GATE_AUDIO1(CLK_AUD_I2SIN3, "audio_i2sin3", "aud_mux1_sel", 2), + GATE_AUDIO1(CLK_AUD_I2SIN4, "audio_i2sin4", "aud_mux1_sel", 3), + GATE_AUDIO1(CLK_AUD_I2SIN5, "audio_i2sin5", "aud_mux1_sel", 4), + GATE_AUDIO1(CLK_AUD_I2SIN6, "audio_i2sin6", "aud_mux1_sel", 5), + GATE_AUDIO1(CLK_AUD_I2SO1, "audio_i2so1", "aud_mux1_sel", 6), + GATE_AUDIO1(CLK_AUD_I2SO2, "audio_i2so2", "aud_mux1_sel", 7), + GATE_AUDIO1(CLK_AUD_I2SO3, "audio_i2so3", "aud_mux1_sel", 8), + GATE_AUDIO1(CLK_AUD_I2SO4, "audio_i2so4", "aud_mux1_sel", 9), + GATE_AUDIO1(CLK_AUD_I2SO5, "audio_i2so5", "aud_mux1_sel", 10), + GATE_AUDIO1(CLK_AUD_I2SO6, "audio_i2so6", "aud_mux1_sel", 11), + GATE_AUDIO1(CLK_AUD_ASRCI1, "audio_asrci1", "asm_h_sel", 12), + GATE_AUDIO1(CLK_AUD_ASRCI2, "audio_asrci2", "asm_h_sel", 13), + GATE_AUDIO1(CLK_AUD_ASRCO1, "audio_asrco1", "asm_h_sel", 14), + GATE_AUDIO1(CLK_AUD_ASRCO2, "audio_asrco2", "asm_h_sel", 15), + GATE_AUDIO1(CLK_AUD_INTDIR, "audio_intdir", "intdir_sel", 20), + GATE_AUDIO1(CLK_AUD_A1SYS, "audio_a1sys", "aud_mux1_sel", 21), + GATE_AUDIO1(CLK_AUD_A2SYS, "audio_a2sys", "aud_mux2_sel", 22), + GATE_AUDIO1(CLK_AUD_AFE_CONN, "audio_afe_conn", "aud_mux1_sel", 23), + GATE_AUDIO1(CLK_AUD_AFE_MRGIF, "audio_afe_mrgif", "aud_mux1_sel", 25), + /* AUDIO2 */ + GATE_AUDIO2(CLK_AUD_MMIF_UL1, "audio_ul1", "aud_mux1_sel", 0), + GATE_AUDIO2(CLK_AUD_MMIF_UL2, "audio_ul2", "aud_mux1_sel", 1), + GATE_AUDIO2(CLK_AUD_MMIF_UL3, "audio_ul3", "aud_mux1_sel", 2), + GATE_AUDIO2(CLK_AUD_MMIF_UL4, "audio_ul4", "aud_mux1_sel", 3), + GATE_AUDIO2(CLK_AUD_MMIF_UL5, "audio_ul5", "aud_mux1_sel", 4), + GATE_AUDIO2(CLK_AUD_MMIF_UL6, "audio_ul6", "aud_mux1_sel", 5), + GATE_AUDIO2(CLK_AUD_MMIF_DL1, "audio_dl1", "aud_mux1_sel", 6), + GATE_AUDIO2(CLK_AUD_MMIF_DL2, "audio_dl2", "aud_mux1_sel", 7), + GATE_AUDIO2(CLK_AUD_MMIF_DL3, "audio_dl3", "aud_mux1_sel", 8), + GATE_AUDIO2(CLK_AUD_MMIF_DL4, "audio_dl4", "aud_mux1_sel", 9), + GATE_AUDIO2(CLK_AUD_MMIF_DL5, "audio_dl5", "aud_mux1_sel", 10), + GATE_AUDIO2(CLK_AUD_MMIF_DL6, "audio_dl6", "aud_mux1_sel", 11), + GATE_AUDIO2(CLK_AUD_MMIF_DLMCH, "audio_dlmch", "aud_mux1_sel", 12), + GATE_AUDIO2(CLK_AUD_MMIF_ARB1, "audio_arb1", "aud_mux1_sel", 13), + GATE_AUDIO2(CLK_AUD_MMIF_AWB1, "audio_awb", "aud_mux1_sel", 14), + GATE_AUDIO2(CLK_AUD_MMIF_AWB2, "audio_awb2", "aud_mux1_sel", 15), + GATE_AUDIO2(CLK_AUD_MMIF_DAI, "audio_dai", "aud_mux1_sel", 16), + /* AUDIO3 */ + GATE_AUDIO3(CLK_AUD_ASRCI3, "audio_asrci3", "asm_h_sel", 2), + GATE_AUDIO3(CLK_AUD_ASRCI4, "audio_asrci4", "asm_h_sel", 3), + GATE_AUDIO3(CLK_AUD_ASRCI5, "audio_asrci5", "asm_h_sel", 4), + GATE_AUDIO3(CLK_AUD_ASRCI6, "audio_asrci6", "asm_h_sel", 5), + GATE_AUDIO3(CLK_AUD_ASRCO3, "audio_asrco3", "asm_h_sel", 6), + GATE_AUDIO3(CLK_AUD_ASRCO4, "audio_asrco4", "asm_h_sel", 7), + GATE_AUDIO3(CLK_AUD_ASRCO5, "audio_asrco5", "asm_h_sel", 8), + GATE_AUDIO3(CLK_AUD_ASRCO6, "audio_asrco6", "asm_h_sel", 9), + GATE_AUDIO3(CLK_AUD_MEM_ASRC1, "audio_mem_asrc1", "asm_h_sel", 10), + GATE_AUDIO3(CLK_AUD_MEM_ASRC2, "audio_mem_asrc2", "asm_h_sel", 11), + GATE_AUDIO3(CLK_AUD_MEM_ASRC3, "audio_mem_asrc3", "asm_h_sel", 12), + GATE_AUDIO3(CLK_AUD_MEM_ASRC4, "audio_mem_asrc4", "asm_h_sel", 13), + GATE_AUDIO3(CLK_AUD_MEM_ASRC5, "audio_mem_asrc5", "asm_h_sel", 14), +}; + +static const struct of_device_id of_match_clk_mt2701_aud[] = { + { .compatible = "mediatek,mt2701-audsys", }, + {} +}; + +static int clk_mt2701_aud_probe(struct platform_device *pdev) +{ + struct clk_onecell_data *clk_data; + struct device_node *node = pdev->dev.of_node; + int r; + + clk_data = mtk_alloc_clk_data(CLK_AUD_NR); + + mtk_clk_register_gates(node, audio_clks, ARRAY_SIZE(audio_clks), + clk_data); + + r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); + if (r) { + dev_err(&pdev->dev, + "could not register clock provider: %s: %d\n", + pdev->name, r); + + goto err_clk_provider; + } + + r = devm_of_platform_populate(&pdev->dev); + if (r) + goto err_plat_populate; + + return 0; + +err_plat_populate: + of_clk_del_provider(node); +err_clk_provider: + return r; +} + +static struct platform_driver clk_mt2701_aud_drv = { + .probe = clk_mt2701_aud_probe, + .driver = { + .name = "clk-mt2701-aud", + .of_match_table = of_match_clk_mt2701_aud, + }, +}; + +builtin_platform_driver(clk_mt2701_aud_drv); -- cgit v1.1 From c744b63b6c422776293cc526ef7887623926f33e Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Tue, 20 Mar 2018 14:19:34 +0000 Subject: clk: hisilicon: fix potential NULL dereference in hisi_clk_alloc() platform_get_resource() may fail and return NULL, so we should better check it's return value to avoid a NULL pointer dereference a bit later in the code. This is detected by Coccinelle semantic patch. @@ expression pdev, res, n, t, e, e1, e2; @@ res = platform_get_resource(pdev, t, n); + if (!res) + return -EINVAL; ... when != res == NULL e = devm_ioremap(e1, res->start, e2); Signed-off-by: Wei Yongjun Fixes: 322269163a36 ("clk: hisilicon: add hisi_clk_alloc function.") Signed-off-by: Stephen Boyd --- drivers/clk/hisilicon/clk.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/clk/hisilicon/clk.c b/drivers/clk/hisilicon/clk.c index 29046b8..953c8da 100644 --- a/drivers/clk/hisilicon/clk.c +++ b/drivers/clk/hisilicon/clk.c @@ -49,6 +49,8 @@ struct hisi_clock_data *hisi_clk_alloc(struct platform_device *pdev, return NULL; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return NULL; clk_data->base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); if (!clk_data->base) -- cgit v1.1 From f422fa558aada511406432bc5974d3a5bf728227 Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Wed, 21 Mar 2018 10:46:25 +0800 Subject: clk: sunxi-ng: add missing hdmi-slow clock for H6 CCU The Allwinner H6 CCU has a "HDMI Slow Clock", which is currently missing in the ccu-sun50i-h6 driver. Add this missing clock to the driver. Fixes: 542353ea ("clk: sunxi-ng: add support for the Allwinner H6 CCU") Signed-off-by: Icenowy Zheng Signed-off-by: Maxime Ripard --- drivers/clk/sunxi-ng/ccu-sun50i-h6.c | 4 ++++ drivers/clk/sunxi-ng/ccu-sun50i-h6.h | 2 +- include/dt-bindings/clock/sun50i-h6-ccu.h | 27 ++++++++++++++------------- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c index d5eab49..bdbfe78 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c +++ b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c @@ -643,6 +643,8 @@ static SUNXI_CCU_M_WITH_MUX_GATE(hdmi_clk, "hdmi", hdmi_parents, 0xb00, BIT(31), /* gate */ 0); +static SUNXI_CCU_GATE(hdmi_slow_clk, "hdmi-slow", "osc24M", 0xb04, BIT(31), 0); + static const char * const hdmi_cec_parents[] = { "osc32k", "pll-periph0-2x" }; static const struct ccu_mux_fixed_prediv hdmi_cec_predivs[] = { { .index = 1, .div = 36621 }, @@ -876,6 +878,7 @@ static struct ccu_common *sun50i_h6_ccu_clks[] = { &pcie_aux_clk.common, &bus_pcie_clk.common, &hdmi_clk.common, + &hdmi_slow_clk.common, &hdmi_cec_clk.common, &bus_hdmi_clk.common, &bus_tcon_top_clk.common, @@ -1017,6 +1020,7 @@ static struct clk_hw_onecell_data sun50i_h6_hw_clks = { [CLK_PCIE_AUX] = &pcie_aux_clk.common.hw, [CLK_BUS_PCIE] = &bus_pcie_clk.common.hw, [CLK_HDMI] = &hdmi_clk.common.hw, + [CLK_HDMI_SLOW] = &hdmi_slow_clk.common.hw, [CLK_HDMI_CEC] = &hdmi_cec_clk.common.hw, [CLK_BUS_HDMI] = &bus_hdmi_clk.common.hw, [CLK_BUS_TCON_TOP] = &bus_tcon_top_clk.common.hw, diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6.h b/drivers/clk/sunxi-ng/ccu-sun50i-h6.h index ad6da4a..2ccfe44 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-h6.h +++ b/drivers/clk/sunxi-ng/ccu-sun50i-h6.h @@ -51,6 +51,6 @@ #define CLK_BUS_DRAM 60 -#define CLK_NUMBER 137 +#define CLK_NUMBER (CLK_BUS_HDCP + 1) #endif /* _CCU_SUN50I_H6_H_ */ diff --git a/include/dt-bindings/clock/sun50i-h6-ccu.h b/include/dt-bindings/clock/sun50i-h6-ccu.h index 6045735..a1545cd 100644 --- a/include/dt-bindings/clock/sun50i-h6-ccu.h +++ b/include/dt-bindings/clock/sun50i-h6-ccu.h @@ -107,18 +107,19 @@ #define CLK_PCIE_AUX 121 #define CLK_BUS_PCIE 122 #define CLK_HDMI 123 -#define CLK_HDMI_CEC 124 -#define CLK_BUS_HDMI 125 -#define CLK_BUS_TCON_TOP 126 -#define CLK_TCON_LCD0 127 -#define CLK_BUS_TCON_LCD0 128 -#define CLK_TCON_TV0 129 -#define CLK_BUS_TCON_TV0 130 -#define CLK_CSI_CCI 131 -#define CLK_CSI_TOP 132 -#define CLK_CSI_MCLK 133 -#define CLK_BUS_CSI 134 -#define CLK_HDCP 135 -#define CLK_BUS_HDCP 136 +#define CLK_HDMI_SLOW 124 +#define CLK_HDMI_CEC 125 +#define CLK_BUS_HDMI 126 +#define CLK_BUS_TCON_TOP 127 +#define CLK_TCON_LCD0 128 +#define CLK_BUS_TCON_LCD0 129 +#define CLK_TCON_TV0 130 +#define CLK_BUS_TCON_TV0 131 +#define CLK_CSI_CCI 132 +#define CLK_CSI_TOP 133 +#define CLK_CSI_MCLK 134 +#define CLK_BUS_CSI 135 +#define CLK_HDCP 136 +#define CLK_BUS_HDCP 137 #endif /* _DT_BINDINGS_CLK_SUN50I_H6_H_ */ -- cgit v1.1 From c733c7d9374191cac6668ce6ea074909d036d8f4 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 15 Mar 2018 10:43:12 +0100 Subject: clk: renesas: div6: Always use readl()/writel() On arm32/arm64, there is no reason to use the (soon deprecated) clk_readl()/clk_writel(). Hence use the generic readl()/writel() instead. Signed-off-by: Geert Uytterhoeven Reviewed-by: Simon Horman --- drivers/clk/renesas/clk-div6.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/clk/renesas/clk-div6.c b/drivers/clk/renesas/clk-div6.c index 151336d..9febbf4 100644 --- a/drivers/clk/renesas/clk-div6.c +++ b/drivers/clk/renesas/clk-div6.c @@ -53,9 +53,9 @@ static int cpg_div6_clock_enable(struct clk_hw *hw) struct div6_clock *clock = to_div6_clock(hw); u32 val; - val = (clk_readl(clock->reg) & ~(CPG_DIV6_DIV_MASK | CPG_DIV6_CKSTP)) + val = (readl(clock->reg) & ~(CPG_DIV6_DIV_MASK | CPG_DIV6_CKSTP)) | CPG_DIV6_DIV(clock->div - 1); - clk_writel(val, clock->reg); + writel(val, clock->reg); return 0; } @@ -65,7 +65,7 @@ static void cpg_div6_clock_disable(struct clk_hw *hw) struct div6_clock *clock = to_div6_clock(hw); u32 val; - val = clk_readl(clock->reg); + val = readl(clock->reg); val |= CPG_DIV6_CKSTP; /* * DIV6 clocks require the divisor field to be non-zero when stopping @@ -75,14 +75,14 @@ static void cpg_div6_clock_disable(struct clk_hw *hw) */ if (!(val & CPG_DIV6_DIV_MASK)) val |= CPG_DIV6_DIV_MASK; - clk_writel(val, clock->reg); + writel(val, clock->reg); } static int cpg_div6_clock_is_enabled(struct clk_hw *hw) { struct div6_clock *clock = to_div6_clock(hw); - return !(clk_readl(clock->reg) & CPG_DIV6_CKSTP); + return !(readl(clock->reg) & CPG_DIV6_CKSTP); } static unsigned long cpg_div6_clock_recalc_rate(struct clk_hw *hw, @@ -122,10 +122,10 @@ static int cpg_div6_clock_set_rate(struct clk_hw *hw, unsigned long rate, clock->div = div; - val = clk_readl(clock->reg) & ~CPG_DIV6_DIV_MASK; + val = readl(clock->reg) & ~CPG_DIV6_DIV_MASK; /* Only program the new divisor if the clock isn't stopped. */ if (!(val & CPG_DIV6_CKSTP)) - clk_writel(val | CPG_DIV6_DIV(clock->div - 1), clock->reg); + writel(val | CPG_DIV6_DIV(clock->div - 1), clock->reg); return 0; } @@ -139,7 +139,7 @@ static u8 cpg_div6_clock_get_parent(struct clk_hw *hw) if (clock->src_width == 0) return 0; - hw_index = (clk_readl(clock->reg) >> clock->src_shift) & + hw_index = (readl(clock->reg) >> clock->src_shift) & (BIT(clock->src_width) - 1); for (i = 0; i < clk_hw_get_num_parents(hw); i++) { if (clock->parents[i] == hw_index) @@ -163,8 +163,8 @@ static int cpg_div6_clock_set_parent(struct clk_hw *hw, u8 index) mask = ~((BIT(clock->src_width) - 1) << clock->src_shift); hw_index = clock->parents[index]; - clk_writel((clk_readl(clock->reg) & mask) | - (hw_index << clock->src_shift), clock->reg); + writel((readl(clock->reg) & mask) | (hw_index << clock->src_shift), + clock->reg); return 0; } @@ -241,7 +241,7 @@ struct clk * __init cpg_div6_register(const char *name, * Read the divisor. Disabling the clock overwrites the divisor, so we * need to cache its value for the enable operation. */ - clock->div = (clk_readl(clock->reg) & CPG_DIV6_DIV_MASK) + 1; + clock->div = (readl(clock->reg) & CPG_DIV6_DIV_MASK) + 1; switch (num_parents) { case 1: -- cgit v1.1 From 8027519840653520c256cb5e7768b60af3bc895e Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 15 Mar 2018 10:43:37 +0100 Subject: clk: renesas: mstp: Always use readl()/writel() On arm32, there is no reason to use the (soon deprecated) clk_readl()/clk_writel(). Hence use the generic readl()/writel() instead. Signed-off-by: Geert Uytterhoeven Reviewed-by: Simon Horman --- drivers/clk/renesas/clk-mstp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/renesas/clk-mstp.c b/drivers/clk/renesas/clk-mstp.c index 858c24d..e82adcb 100644 --- a/drivers/clk/renesas/clk-mstp.c +++ b/drivers/clk/renesas/clk-mstp.c @@ -64,13 +64,13 @@ struct mstp_clock { static inline u32 cpg_mstp_read(struct mstp_clock_group *group, u32 __iomem *reg) { - return group->width_8bit ? readb(reg) : clk_readl(reg); + return group->width_8bit ? readb(reg) : readl(reg); } static inline void cpg_mstp_write(struct mstp_clock_group *group, u32 val, u32 __iomem *reg) { - group->width_8bit ? writeb(val, reg) : clk_writel(val, reg); + group->width_8bit ? writeb(val, reg) : writel(val, reg); } static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable) -- cgit v1.1 From b86b493eb29120b82ba919e2653c863c0b3804d6 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 15 Mar 2018 10:43:47 +0100 Subject: clk: renesas: r8a73a4: Always use readl()/writel() On arm32, there is no reason to use the (soon deprecated) clk_readl()/clk_writel(). Hence use the generic readl()/writel() instead. Signed-off-by: Geert Uytterhoeven Reviewed-by: Simon Horman --- drivers/clk/renesas/clk-r8a73a4.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/clk/renesas/clk-r8a73a4.c b/drivers/clk/renesas/clk-r8a73a4.c index 28d204b..7b903ce 100644 --- a/drivers/clk/renesas/clk-r8a73a4.c +++ b/drivers/clk/renesas/clk-r8a73a4.c @@ -71,7 +71,7 @@ r8a73a4_cpg_register_clock(struct device_node *np, struct r8a73a4_cpg *cpg, if (!strcmp(name, "main")) { - u32 ckscr = clk_readl(cpg->reg + CPG_CKSCR); + u32 ckscr = readl(cpg->reg + CPG_CKSCR); switch ((ckscr >> 28) & 3) { case 0: /* extal1 */ @@ -95,14 +95,14 @@ r8a73a4_cpg_register_clock(struct device_node *np, struct r8a73a4_cpg *cpg, * clock implementation and we currently have no need to change * the multiplier value. */ - u32 value = clk_readl(cpg->reg + CPG_PLL0CR); + u32 value = readl(cpg->reg + CPG_PLL0CR); parent_name = "main"; mult = ((value >> 24) & 0x7f) + 1; if (value & BIT(20)) div = 2; } else if (!strcmp(name, "pll1")) { - u32 value = clk_readl(cpg->reg + CPG_PLL1CR); + u32 value = readl(cpg->reg + CPG_PLL1CR); parent_name = "main"; /* XXX: enable bit? */ @@ -125,7 +125,7 @@ r8a73a4_cpg_register_clock(struct device_node *np, struct r8a73a4_cpg *cpg, default: return ERR_PTR(-EINVAL); } - value = clk_readl(cpg->reg + cr); + value = readl(cpg->reg + cr); switch ((value >> 5) & 7) { case 0: parent_name = "main"; @@ -161,8 +161,7 @@ r8a73a4_cpg_register_clock(struct device_node *np, struct r8a73a4_cpg *cpg, shift = 0; } div *= 32; - mult = 0x20 - ((clk_readl(cpg->reg + CPG_FRQCRC) >> shift) - & 0x1f); + mult = 0x20 - ((readl(cpg->reg + CPG_FRQCRC) >> shift) & 0x1f); } else { struct div4_clk *c; -- cgit v1.1 From f32b0696eabd7a9dc6efd6a97448742d5f2a7db0 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 15 Mar 2018 10:43:57 +0100 Subject: clk: renesas: r8a7740: Always use readl()/writel() On arm32, there is no reason to use the (soon deprecated) clk_readl()/clk_writel(). Hence use the generic readl()/writel() instead. Signed-off-by: Geert Uytterhoeven Reviewed-by: Simon Horman --- drivers/clk/renesas/clk-r8a7740.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/clk/renesas/clk-r8a7740.c b/drivers/clk/renesas/clk-r8a7740.c index 2f7ce66..d074f8e 100644 --- a/drivers/clk/renesas/clk-r8a7740.c +++ b/drivers/clk/renesas/clk-r8a7740.c @@ -98,20 +98,20 @@ r8a7740_cpg_register_clock(struct device_node *np, struct r8a7740_cpg *cpg, * clock implementation and we currently have no need to change * the multiplier value. */ - u32 value = clk_readl(cpg->reg + CPG_FRQCRC); + u32 value = readl(cpg->reg + CPG_FRQCRC); parent_name = "system"; mult = ((value >> 24) & 0x7f) + 1; } else if (!strcmp(name, "pllc1")) { - u32 value = clk_readl(cpg->reg + CPG_FRQCRA); + u32 value = readl(cpg->reg + CPG_FRQCRA); parent_name = "system"; mult = ((value >> 24) & 0x7f) + 1; div = 2; } else if (!strcmp(name, "pllc2")) { - u32 value = clk_readl(cpg->reg + CPG_PLLC2CR); + u32 value = readl(cpg->reg + CPG_PLLC2CR); parent_name = "system"; mult = ((value >> 24) & 0x3f) + 1; } else if (!strcmp(name, "usb24s")) { - u32 value = clk_readl(cpg->reg + CPG_USBCKCR); + u32 value = readl(cpg->reg + CPG_USBCKCR); if (value & BIT(7)) /* extal2 */ parent_name = of_clk_get_parent_name(np, 1); -- cgit v1.1 From 6c669e504a62641fd7189df13ef57d182373e36f Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 15 Mar 2018 10:44:09 +0100 Subject: clk: renesas: rcar-gen2: Always use readl()/writel() On arm32, there is no reason to use the (soon deprecated) clk_readl()/clk_writel(). Hence use the generic readl()/writel() instead. Signed-off-by: Geert Uytterhoeven Reviewed-by: Simon Horman --- drivers/clk/renesas/clk-rcar-gen2.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/clk/renesas/clk-rcar-gen2.c b/drivers/clk/renesas/clk-rcar-gen2.c index d14cbe1..ee32a02 100644 --- a/drivers/clk/renesas/clk-rcar-gen2.c +++ b/drivers/clk/renesas/clk-rcar-gen2.c @@ -62,8 +62,7 @@ static unsigned long cpg_z_clk_recalc_rate(struct clk_hw *hw, unsigned int mult; unsigned int val; - val = (clk_readl(zclk->reg) & CPG_FRQCRC_ZFC_MASK) - >> CPG_FRQCRC_ZFC_SHIFT; + val = (readl(zclk->reg) & CPG_FRQCRC_ZFC_MASK) >> CPG_FRQCRC_ZFC_SHIFT; mult = 32 - val; return div_u64((u64)parent_rate * mult, 32); @@ -95,21 +94,21 @@ static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate, mult = div_u64((u64)rate * 32, parent_rate); mult = clamp(mult, 1U, 32U); - if (clk_readl(zclk->kick_reg) & CPG_FRQCRB_KICK) + if (readl(zclk->kick_reg) & CPG_FRQCRB_KICK) return -EBUSY; - val = clk_readl(zclk->reg); + val = readl(zclk->reg); val &= ~CPG_FRQCRC_ZFC_MASK; val |= (32 - mult) << CPG_FRQCRC_ZFC_SHIFT; - clk_writel(val, zclk->reg); + writel(val, zclk->reg); /* * Set KICK bit in FRQCRB to update hardware setting and wait for * clock change completion. */ - kick = clk_readl(zclk->kick_reg); + kick = readl(zclk->kick_reg); kick |= CPG_FRQCRB_KICK; - clk_writel(kick, zclk->kick_reg); + writel(kick, zclk->kick_reg); /* * Note: There is no HW information about the worst case latency. @@ -121,7 +120,7 @@ static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate, * "super" safe value. */ for (i = 1000; i; i--) { - if (!(clk_readl(zclk->kick_reg) & CPG_FRQCRB_KICK)) + if (!(readl(zclk->kick_reg) & CPG_FRQCRB_KICK)) return 0; cpu_relax(); @@ -332,7 +331,7 @@ rcar_gen2_cpg_register_clock(struct device_node *np, struct rcar_gen2_cpg *cpg, mult = config->pll0_mult; div = 3; } else { - u32 value = clk_readl(cpg->reg + CPG_PLL0CR); + u32 value = readl(cpg->reg + CPG_PLL0CR); mult = ((value >> 24) & ((1 << 7) - 1)) + 1; } parent_name = "main"; -- cgit v1.1 From fcf371b3517771589819ffefe2aa16b31f0b0a63 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 15 Mar 2018 10:44:19 +0100 Subject: clk: renesas: rza1: Always use readl()/writel() On arm32, there is no reason to use the (soon deprecated) clk_readl()/clk_writel(). Hence use the generic readl()/writel() instead. Signed-off-by: Geert Uytterhoeven Reviewed-by: Simon Horman --- drivers/clk/renesas/clk-rz.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/renesas/clk-rz.c b/drivers/clk/renesas/clk-rz.c index 127c581..67dd712 100644 --- a/drivers/clk/renesas/clk-rz.c +++ b/drivers/clk/renesas/clk-rz.c @@ -75,9 +75,9 @@ rz_cpg_register_clock(struct device_node *np, struct rz_cpg *cpg, const char *na * let them run at fixed current speed and implement the details later. */ if (strcmp(name, "i") == 0) - val = (clk_readl(cpg->reg + CPG_FRQCR) >> 8) & 3; + val = (readl(cpg->reg + CPG_FRQCR) >> 8) & 3; else if (strcmp(name, "g") == 0) - val = clk_readl(cpg->reg + CPG_FRQCR2) & 3; + val = readl(cpg->reg + CPG_FRQCR2) & 3; else return ERR_PTR(-EINVAL); -- cgit v1.1 From f046d6a6bf2a1f0db5e2f61b5236efb1b6bebfde Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 15 Mar 2018 10:44:30 +0100 Subject: clk: renesas: sh73a0: Always use readl()/writel() On arm32, there is no reason to use the (soon deprecated) clk_readl()/clk_writel(). Hence use the generic readl()/writel() instead. Signed-off-by: Geert Uytterhoeven Reviewed-by: Simon Horman --- drivers/clk/renesas/clk-sh73a0.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/clk/renesas/clk-sh73a0.c b/drivers/clk/renesas/clk-sh73a0.c index eea38f6..6cfa6b5 100644 --- a/drivers/clk/renesas/clk-sh73a0.c +++ b/drivers/clk/renesas/clk-sh73a0.c @@ -85,7 +85,7 @@ sh73a0_cpg_register_clock(struct device_node *np, struct sh73a0_cpg *cpg, if (!strcmp(name, "main")) { /* extal1, extal1_div2, extal2, extal2_div2 */ - u32 parent_idx = (clk_readl(cpg->reg + CPG_CKSCR) >> 28) & 3; + u32 parent_idx = (readl(cpg->reg + CPG_CKSCR) >> 28) & 3; parent_name = of_clk_get_parent_name(np, parent_idx >> 1); div = (parent_idx & 1) + 1; @@ -110,11 +110,11 @@ sh73a0_cpg_register_clock(struct device_node *np, struct sh73a0_cpg *cpg, default: return ERR_PTR(-EINVAL); } - if (clk_readl(cpg->reg + CPG_PLLECR) & BIT(enable_bit)) { - mult = ((clk_readl(enable_reg) >> 24) & 0x3f) + 1; + if (readl(cpg->reg + CPG_PLLECR) & BIT(enable_bit)) { + mult = ((readl(enable_reg) >> 24) & 0x3f) + 1; /* handle CFG bit for PLL1 and PLL2 */ if (enable_bit == 1 || enable_bit == 2) - if (clk_readl(enable_reg) & BIT(20)) + if (readl(enable_reg) & BIT(20)) mult *= 2; } } else if (!strcmp(name, "dsi0phy") || !strcmp(name, "dsi1phy")) { @@ -193,9 +193,9 @@ static void __init sh73a0_cpg_clocks_init(struct device_node *np) return; /* Set SDHI clocks to a known state */ - clk_writel(0x108, cpg->reg + CPG_SD0CKCR); - clk_writel(0x108, cpg->reg + CPG_SD1CKCR); - clk_writel(0x108, cpg->reg + CPG_SD2CKCR); + writel(0x108, cpg->reg + CPG_SD0CKCR); + writel(0x108, cpg->reg + CPG_SD1CKCR); + writel(0x108, cpg->reg + CPG_SD2CKCR); for (i = 0; i < num_clks; ++i) { const char *name; -- cgit v1.1 From 2b935d524d851830b68dd8c58d3098d775d6047a Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 15 Mar 2018 10:44:37 +0100 Subject: clk: renesas: rcar-gen3: Always use readl()/writel() The R-Car Gen3 CPG/MSSR driver (again) uses a mix of clk_readl()/clk_writel() and readl()/writel() to access the clock registers. Settle on the generic readl()/writel(). Cfr. commit 30ad3cf00e94f4a7 ("clk: renesas: rcar-gen3-cpg: Always use readl()/writel()"). Signed-off-by: Geert Uytterhoeven Reviewed-by: Simon Horman --- drivers/clk/renesas/rcar-gen3-cpg.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c index 0c8fe10..628b63b 100644 --- a/drivers/clk/renesas/rcar-gen3-cpg.c +++ b/drivers/clk/renesas/rcar-gen3-cpg.c @@ -93,7 +93,7 @@ static unsigned long cpg_z_clk_recalc_rate(struct clk_hw *hw, unsigned int mult; u32 val; - val = clk_readl(zclk->reg) & zclk->mask; + val = readl(zclk->reg) & zclk->mask; mult = 32 - (val >> __ffs(zclk->mask)); /* Factor of 2 is for fixed divider */ @@ -125,20 +125,20 @@ static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate, mult = DIV_ROUND_CLOSEST_ULL(rate * 32ULL * 2, parent_rate); mult = clamp(mult, 1U, 32U); - if (clk_readl(zclk->kick_reg) & CPG_FRQCRB_KICK) + if (readl(zclk->kick_reg) & CPG_FRQCRB_KICK) return -EBUSY; - val = clk_readl(zclk->reg) & ~zclk->mask; + val = readl(zclk->reg) & ~zclk->mask; val |= ((32 - mult) << __ffs(zclk->mask)) & zclk->mask; - clk_writel(val, zclk->reg); + writel(val, zclk->reg); /* * Set KICK bit in FRQCRB to update hardware setting and wait for * clock change completion. */ - kick = clk_readl(zclk->kick_reg); + kick = readl(zclk->kick_reg); kick |= CPG_FRQCRB_KICK; - clk_writel(kick, zclk->kick_reg); + writel(kick, zclk->kick_reg); /* * Note: There is no HW information about the worst case latency. @@ -150,7 +150,7 @@ static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate, * "super" safe value. */ for (i = 1000; i; i--) { - if (!(clk_readl(zclk->kick_reg) & CPG_FRQCRB_KICK)) + if (!(readl(zclk->kick_reg) & CPG_FRQCRB_KICK)) return 0; cpu_relax(); -- cgit v1.1 From 472f5f391819b4b22ec040f227aea26f515b6ae2 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 20 Mar 2018 16:40:16 +0900 Subject: clk: renesas: cpg-mssr: Adjust r8a77980 ifdef Adjust the R8A77980-specific #ifdefs to use CLK instead of ARCH to follow same style as other SoCs. Fixes: ce15783c510a9905 ("clk: renesas: cpg-mssr: add R8A77980 support") Signed-off-by: Magnus Damm Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/renesas-cpg-mssr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index 96c6787..4e88e98 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -705,7 +705,7 @@ static const struct of_device_id cpg_mssr_match[] = { .data = &r8a77970_cpg_mssr_info, }, #endif -#ifdef CONFIG_ARCH_R8A77980 +#ifdef CONFIG_CLK_R8A77980 { .compatible = "renesas,r8a77980-cpg-mssr", .data = &r8a77980_cpg_mssr_info, -- cgit v1.1 From 726fef09b8018e58f1930fc7bc0a46e8d12ed8c1 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 22 Mar 2018 11:16:18 +0100 Subject: clk: ux500: Drop AB8540/9540 support The AB8540 was an evolved version of the AB8500, but it was never mass produced or put into products, only reference designs exist. The upstream support was never completed and it is unlikely that this will happen so drop the support for now to simplify maintenance of the AB8500. Cc: Loic Pallardy Signed-off-by: Linus Walleij Acked-by: Ulf Hansson Signed-off-by: Stephen Boyd --- drivers/clk/ux500/Makefile | 2 - drivers/clk/ux500/abx500-clk.c | 16 -- drivers/clk/ux500/u8540_clk.c | 597 ----------------------------------------- drivers/clk/ux500/u9540_clk.c | 18 -- 4 files changed, 633 deletions(-) delete mode 100644 drivers/clk/ux500/u8540_clk.c delete mode 100644 drivers/clk/ux500/u9540_clk.c diff --git a/drivers/clk/ux500/Makefile b/drivers/clk/ux500/Makefile index fedc083..53fd290 100644 --- a/drivers/clk/ux500/Makefile +++ b/drivers/clk/ux500/Makefile @@ -10,8 +10,6 @@ obj-y += clk-sysctrl.o # Clock definitions obj-y += u8500_of_clk.o -obj-y += u9540_clk.o -obj-y += u8540_clk.o # ABX500 clock driver obj-y += abx500-clk.o diff --git a/drivers/clk/ux500/abx500-clk.c b/drivers/clk/ux500/abx500-clk.c index 2257d12b..5a86cd8 100644 --- a/drivers/clk/ux500/abx500-clk.c +++ b/drivers/clk/ux500/abx500-clk.c @@ -88,18 +88,6 @@ static int ab8500_reg_clks(struct device *dev) return 0; } -/* Clock definitions for ab8540 */ -static int ab8540_reg_clks(struct device *dev) -{ - return 0; -} - -/* Clock definitions for ab9540 */ -static int ab9540_reg_clks(struct device *dev) -{ - return 0; -} - static int abx500_clk_probe(struct platform_device *pdev) { struct ab8500 *parent = dev_get_drvdata(pdev->dev.parent); @@ -107,10 +95,6 @@ static int abx500_clk_probe(struct platform_device *pdev) if (is_ab8500(parent) || is_ab8505(parent)) { ret = ab8500_reg_clks(&pdev->dev); - } else if (is_ab8540(parent)) { - ret = ab8540_reg_clks(&pdev->dev); - } else if (is_ab9540(parent)) { - ret = ab9540_reg_clks(&pdev->dev); } else { dev_err(&pdev->dev, "non supported plf id\n"); return -ENODEV; diff --git a/drivers/clk/ux500/u8540_clk.c b/drivers/clk/ux500/u8540_clk.c deleted file mode 100644 index 133859f..0000000 --- a/drivers/clk/ux500/u8540_clk.c +++ /dev/null @@ -1,597 +0,0 @@ -/* - * Clock definitions for u8540 platform. - * - * Copyright (C) 2012 ST-Ericsson SA - * Author: Ulf Hansson - * - * License terms: GNU General Public License (GPL) version 2 - */ - -#include -#include -#include -#include -#include -#include "clk.h" - -/* CLKRST4 is missing making it hard to index things */ -enum clkrst_index { - CLKRST1_INDEX = 0, - CLKRST2_INDEX, - CLKRST3_INDEX, - CLKRST5_INDEX, - CLKRST6_INDEX, - CLKRST_MAX, -}; - -static void u8540_clk_init(struct device_node *np) -{ - struct clk *clk; - u32 bases[CLKRST_MAX]; - int i; - - for (i = 0; i < ARRAY_SIZE(bases); i++) { - struct resource r; - - if (of_address_to_resource(np, i, &r)) - /* Not much choice but to continue */ - pr_err("failed to get CLKRST %d base address\n", - i + 1); - bases[i] = r.start; - } - - /* Clock sources. */ - /* Fixed ClockGen */ - clk = clk_reg_prcmu_gate("soc0_pll", NULL, PRCMU_PLLSOC0, - CLK_IGNORE_UNUSED); - clk_register_clkdev(clk, "soc0_pll", NULL); - - clk = clk_reg_prcmu_gate("soc1_pll", NULL, PRCMU_PLLSOC1, - CLK_IGNORE_UNUSED); - clk_register_clkdev(clk, "soc1_pll", NULL); - - clk = clk_reg_prcmu_gate("ddr_pll", NULL, PRCMU_PLLDDR, - CLK_IGNORE_UNUSED); - clk_register_clkdev(clk, "ddr_pll", NULL); - - clk = clk_register_fixed_rate(NULL, "rtc32k", NULL, - CLK_IGNORE_UNUSED, - 32768); - clk_register_clkdev(clk, "clk32k", NULL); - clk_register_clkdev(clk, "apb_pclk", "rtc-pl031"); - - clk = clk_register_fixed_rate(NULL, "ulp38m4", NULL, - CLK_IGNORE_UNUSED, - 38400000); - - clk = clk_reg_prcmu_gate("uartclk", NULL, PRCMU_UARTCLK, 0); - clk_register_clkdev(clk, NULL, "UART"); - - /* msp02clk needs a abx500 clk as parent. Handle by abx500 clk driver */ - clk = clk_reg_prcmu_gate("msp02clk", "ab9540_sysclk12_b1", - PRCMU_MSP02CLK, 0); - clk_register_clkdev(clk, NULL, "MSP02"); - - clk = clk_reg_prcmu_gate("msp1clk", NULL, PRCMU_MSP1CLK, 0); - clk_register_clkdev(clk, NULL, "MSP1"); - - clk = clk_reg_prcmu_gate("i2cclk", NULL, PRCMU_I2CCLK, 0); - clk_register_clkdev(clk, NULL, "I2C"); - - clk = clk_reg_prcmu_gate("slimclk", NULL, PRCMU_SLIMCLK, 0); - clk_register_clkdev(clk, NULL, "slim"); - - clk = clk_reg_prcmu_gate("per1clk", NULL, PRCMU_PER1CLK, 0); - clk_register_clkdev(clk, NULL, "PERIPH1"); - - clk = clk_reg_prcmu_gate("per2clk", NULL, PRCMU_PER2CLK, 0); - clk_register_clkdev(clk, NULL, "PERIPH2"); - - clk = clk_reg_prcmu_gate("per3clk", NULL, PRCMU_PER3CLK, 0); - clk_register_clkdev(clk, NULL, "PERIPH3"); - - clk = clk_reg_prcmu_gate("per5clk", NULL, PRCMU_PER5CLK, 0); - clk_register_clkdev(clk, NULL, "PERIPH5"); - - clk = clk_reg_prcmu_gate("per6clk", NULL, PRCMU_PER6CLK, 0); - clk_register_clkdev(clk, NULL, "PERIPH6"); - - clk = clk_reg_prcmu_gate("per7clk", NULL, PRCMU_PER7CLK, 0); - clk_register_clkdev(clk, NULL, "PERIPH7"); - - clk = clk_reg_prcmu_scalable("lcdclk", NULL, PRCMU_LCDCLK, 0, - CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "lcd"); - clk_register_clkdev(clk, "lcd", "mcde"); - - clk = clk_reg_prcmu_opp_gate("bmlclk", NULL, PRCMU_BMLCLK, 0); - clk_register_clkdev(clk, NULL, "bml"); - - clk = clk_reg_prcmu_scalable("hsitxclk", NULL, PRCMU_HSITXCLK, 0, - CLK_SET_RATE_GATE); - - clk = clk_reg_prcmu_scalable("hsirxclk", NULL, PRCMU_HSIRXCLK, 0, - CLK_SET_RATE_GATE); - - clk = clk_reg_prcmu_scalable("hdmiclk", NULL, PRCMU_HDMICLK, 0, - CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "hdmi"); - clk_register_clkdev(clk, "hdmi", "mcde"); - - clk = clk_reg_prcmu_gate("apeatclk", NULL, PRCMU_APEATCLK, 0); - clk_register_clkdev(clk, NULL, "apeat"); - - clk = clk_reg_prcmu_gate("apetraceclk", NULL, PRCMU_APETRACECLK, 0); - clk_register_clkdev(clk, NULL, "apetrace"); - - clk = clk_reg_prcmu_gate("mcdeclk", NULL, PRCMU_MCDECLK, 0); - clk_register_clkdev(clk, NULL, "mcde"); - clk_register_clkdev(clk, "mcde", "mcde"); - clk_register_clkdev(clk, NULL, "dsilink.0"); - clk_register_clkdev(clk, NULL, "dsilink.1"); - clk_register_clkdev(clk, NULL, "dsilink.2"); - - clk = clk_reg_prcmu_opp_gate("ipi2cclk", NULL, PRCMU_IPI2CCLK, 0); - clk_register_clkdev(clk, NULL, "ipi2"); - - clk = clk_reg_prcmu_gate("dsialtclk", NULL, PRCMU_DSIALTCLK, 0); - clk_register_clkdev(clk, NULL, "dsialt"); - - clk = clk_reg_prcmu_gate("dmaclk", NULL, PRCMU_DMACLK, 0); - clk_register_clkdev(clk, NULL, "dma40.0"); - - clk = clk_reg_prcmu_gate("b2r2clk", NULL, PRCMU_B2R2CLK, 0); - clk_register_clkdev(clk, NULL, "b2r2"); - clk_register_clkdev(clk, NULL, "b2r2_core"); - clk_register_clkdev(clk, NULL, "U8500-B2R2.0"); - clk_register_clkdev(clk, NULL, "b2r2_1_core"); - - clk = clk_reg_prcmu_scalable("tvclk", NULL, PRCMU_TVCLK, 0, - CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "tv"); - clk_register_clkdev(clk, "tv", "mcde"); - - clk = clk_reg_prcmu_gate("sspclk", NULL, PRCMU_SSPCLK, 0); - clk_register_clkdev(clk, NULL, "SSP"); - - clk = clk_reg_prcmu_gate("rngclk", NULL, PRCMU_RNGCLK, 0); - clk_register_clkdev(clk, NULL, "rngclk"); - - clk = clk_reg_prcmu_gate("uiccclk", NULL, PRCMU_UICCCLK, 0); - clk_register_clkdev(clk, NULL, "uicc"); - - clk = clk_reg_prcmu_gate("timclk", NULL, PRCMU_TIMCLK, 0); - clk_register_clkdev(clk, NULL, "mtu0"); - clk_register_clkdev(clk, NULL, "mtu1"); - - clk = clk_reg_prcmu_opp_volt_scalable("sdmmcclk", NULL, - PRCMU_SDMMCCLK, 100000000, - CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "sdmmc"); - - clk = clk_reg_prcmu_opp_volt_scalable("sdmmchclk", NULL, - PRCMU_SDMMCHCLK, 400000000, - CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "sdmmchclk"); - - clk = clk_reg_prcmu_gate("hvaclk", NULL, PRCMU_HVACLK, 0); - clk_register_clkdev(clk, NULL, "hva"); - - clk = clk_reg_prcmu_gate("g1clk", NULL, PRCMU_G1CLK, 0); - clk_register_clkdev(clk, NULL, "g1"); - - clk = clk_reg_prcmu_scalable("spare1clk", NULL, PRCMU_SPARE1CLK, 0, - CLK_SET_RATE_GATE); - clk_register_clkdev(clk, "dsilcd", "mcde"); - - clk = clk_reg_prcmu_scalable("dsi_pll", "hdmiclk", - PRCMU_PLLDSI, 0, CLK_SET_RATE_GATE); - clk_register_clkdev(clk, "dsihs2", "mcde"); - clk_register_clkdev(clk, "hs_clk", "dsilink.2"); - - clk = clk_reg_prcmu_scalable("dsilcd_pll", "spare1clk", - PRCMU_PLLDSI_LCD, 0, CLK_SET_RATE_GATE); - clk_register_clkdev(clk, "dsilcd_pll", "mcde"); - - clk = clk_reg_prcmu_scalable("dsi0clk", "dsi_pll", - PRCMU_DSI0CLK, 0, CLK_SET_RATE_GATE); - clk_register_clkdev(clk, "dsihs0", "mcde"); - - clk = clk_reg_prcmu_scalable("dsi0lcdclk", "dsilcd_pll", - PRCMU_DSI0CLK_LCD, 0, CLK_SET_RATE_GATE); - clk_register_clkdev(clk, "dsihs0", "mcde"); - clk_register_clkdev(clk, "hs_clk", "dsilink.0"); - - clk = clk_reg_prcmu_scalable("dsi1clk", "dsi_pll", - PRCMU_DSI1CLK, 0, CLK_SET_RATE_GATE); - clk_register_clkdev(clk, "dsihs1", "mcde"); - - clk = clk_reg_prcmu_scalable("dsi1lcdclk", "dsilcd_pll", - PRCMU_DSI1CLK_LCD, 0, CLK_SET_RATE_GATE); - clk_register_clkdev(clk, "dsihs1", "mcde"); - clk_register_clkdev(clk, "hs_clk", "dsilink.1"); - - clk = clk_reg_prcmu_scalable("dsi0escclk", "tvclk", - PRCMU_DSI0ESCCLK, 0, CLK_SET_RATE_GATE); - clk_register_clkdev(clk, "lp_clk", "dsilink.0"); - clk_register_clkdev(clk, "dsilp0", "mcde"); - - clk = clk_reg_prcmu_scalable("dsi1escclk", "tvclk", - PRCMU_DSI1ESCCLK, 0, CLK_SET_RATE_GATE); - clk_register_clkdev(clk, "lp_clk", "dsilink.1"); - clk_register_clkdev(clk, "dsilp1", "mcde"); - - clk = clk_reg_prcmu_scalable("dsi2escclk", "tvclk", - PRCMU_DSI2ESCCLK, 0, CLK_SET_RATE_GATE); - clk_register_clkdev(clk, "lp_clk", "dsilink.2"); - clk_register_clkdev(clk, "dsilp2", "mcde"); - - clk = clk_reg_prcmu_scalable_rate("armss", NULL, - PRCMU_ARMSS, 0, CLK_IGNORE_UNUSED); - clk_register_clkdev(clk, "armss", NULL); - - clk = clk_register_fixed_factor(NULL, "smp_twd", "armss", - CLK_IGNORE_UNUSED, 1, 2); - clk_register_clkdev(clk, NULL, "smp_twd"); - - /* PRCC P-clocks */ - /* Peripheral 1 : PRCC P-clocks */ - clk = clk_reg_prcc_pclk("p1_pclk0", "per1clk", bases[CLKRST1_INDEX], - BIT(0), 0); - clk_register_clkdev(clk, "apb_pclk", "uart0"); - - clk = clk_reg_prcc_pclk("p1_pclk1", "per1clk", bases[CLKRST1_INDEX], - BIT(1), 0); - clk_register_clkdev(clk, "apb_pclk", "uart1"); - - clk = clk_reg_prcc_pclk("p1_pclk2", "per1clk", bases[CLKRST1_INDEX], - BIT(2), 0); - clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.1"); - - clk = clk_reg_prcc_pclk("p1_pclk3", "per1clk", bases[CLKRST1_INDEX], - BIT(3), 0); - clk_register_clkdev(clk, "apb_pclk", "msp0"); - clk_register_clkdev(clk, "apb_pclk", "dbx5x0-msp-i2s.0"); - - clk = clk_reg_prcc_pclk("p1_pclk4", "per1clk", bases[CLKRST1_INDEX], - BIT(4), 0); - clk_register_clkdev(clk, "apb_pclk", "msp1"); - clk_register_clkdev(clk, "apb_pclk", "dbx5x0-msp-i2s.1"); - - clk = clk_reg_prcc_pclk("p1_pclk5", "per1clk", bases[CLKRST1_INDEX], - BIT(5), 0); - clk_register_clkdev(clk, "apb_pclk", "sdi0"); - - clk = clk_reg_prcc_pclk("p1_pclk6", "per1clk", bases[CLKRST1_INDEX], - BIT(6), 0); - clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.2"); - - clk = clk_reg_prcc_pclk("p1_pclk7", "per1clk", bases[CLKRST1_INDEX], - BIT(7), 0); - clk_register_clkdev(clk, NULL, "spi3"); - - clk = clk_reg_prcc_pclk("p1_pclk8", "per1clk", bases[CLKRST1_INDEX], - BIT(8), 0); - clk_register_clkdev(clk, "apb_pclk", "slimbus0"); - - clk = clk_reg_prcc_pclk("p1_pclk9", "per1clk", bases[CLKRST1_INDEX], - BIT(9), 0); - clk_register_clkdev(clk, NULL, "gpio.0"); - clk_register_clkdev(clk, NULL, "gpio.1"); - clk_register_clkdev(clk, NULL, "gpioblock0"); - clk_register_clkdev(clk, "apb_pclk", "ab85xx-codec.0"); - - clk = clk_reg_prcc_pclk("p1_pclk10", "per1clk", bases[CLKRST1_INDEX], - BIT(10), 0); - clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.4"); - - clk = clk_reg_prcc_pclk("p1_pclk11", "per1clk", bases[CLKRST1_INDEX], - BIT(11), 0); - clk_register_clkdev(clk, "apb_pclk", "msp3"); - clk_register_clkdev(clk, "apb_pclk", "dbx5x0-msp-i2s.3"); - - /* Peripheral 2 : PRCC P-clocks */ - clk = clk_reg_prcc_pclk("p2_pclk0", "per2clk", bases[CLKRST2_INDEX], - BIT(0), 0); - clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.3"); - - clk = clk_reg_prcc_pclk("p2_pclk1", "per2clk", bases[CLKRST2_INDEX], - BIT(1), 0); - clk_register_clkdev(clk, NULL, "spi2"); - - clk = clk_reg_prcc_pclk("p2_pclk2", "per2clk", bases[CLKRST2_INDEX], - BIT(2), 0); - clk_register_clkdev(clk, NULL, "spi1"); - - clk = clk_reg_prcc_pclk("p2_pclk3", "per2clk", bases[CLKRST2_INDEX], - BIT(3), 0); - clk_register_clkdev(clk, NULL, "pwl"); - - clk = clk_reg_prcc_pclk("p2_pclk4", "per2clk", bases[CLKRST2_INDEX], - BIT(4), 0); - clk_register_clkdev(clk, "apb_pclk", "sdi4"); - - clk = clk_reg_prcc_pclk("p2_pclk5", "per2clk", bases[CLKRST2_INDEX], - BIT(5), 0); - clk_register_clkdev(clk, "apb_pclk", "msp2"); - clk_register_clkdev(clk, "apb_pclk", "dbx5x0-msp-i2s.2"); - - clk = clk_reg_prcc_pclk("p2_pclk6", "per2clk", bases[CLKRST2_INDEX], - BIT(6), 0); - clk_register_clkdev(clk, "apb_pclk", "sdi1"); - - clk = clk_reg_prcc_pclk("p2_pclk7", "per2clk", bases[CLKRST2_INDEX], - BIT(7), 0); - clk_register_clkdev(clk, "apb_pclk", "sdi3"); - - clk = clk_reg_prcc_pclk("p2_pclk8", "per2clk", bases[CLKRST2_INDEX], - BIT(8), 0); - clk_register_clkdev(clk, NULL, "spi0"); - - clk = clk_reg_prcc_pclk("p2_pclk9", "per2clk", bases[CLKRST2_INDEX], - BIT(9), 0); - clk_register_clkdev(clk, "hsir_hclk", "ste_hsi.0"); - - clk = clk_reg_prcc_pclk("p2_pclk10", "per2clk", bases[CLKRST2_INDEX], - BIT(10), 0); - clk_register_clkdev(clk, "hsit_hclk", "ste_hsi.0"); - - clk = clk_reg_prcc_pclk("p2_pclk11", "per2clk", bases[CLKRST2_INDEX], - BIT(11), 0); - clk_register_clkdev(clk, NULL, "gpio.6"); - clk_register_clkdev(clk, NULL, "gpio.7"); - clk_register_clkdev(clk, NULL, "gpioblock1"); - - clk = clk_reg_prcc_pclk("p2_pclk12", "per2clk", bases[CLKRST2_INDEX], - BIT(12), 0); - clk_register_clkdev(clk, "msp4-pclk", "ab85xx-codec.0"); - - /* Peripheral 3 : PRCC P-clocks */ - clk = clk_reg_prcc_pclk("p3_pclk0", "per3clk", bases[CLKRST3_INDEX], - BIT(0), 0); - clk_register_clkdev(clk, NULL, "fsmc"); - - clk = clk_reg_prcc_pclk("p3_pclk1", "per3clk", bases[CLKRST3_INDEX], - BIT(1), 0); - clk_register_clkdev(clk, "apb_pclk", "ssp0"); - - clk = clk_reg_prcc_pclk("p3_pclk2", "per3clk", bases[CLKRST3_INDEX], - BIT(2), 0); - clk_register_clkdev(clk, "apb_pclk", "ssp1"); - - clk = clk_reg_prcc_pclk("p3_pclk3", "per3clk", bases[CLKRST3_INDEX], - BIT(3), 0); - clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.0"); - - clk = clk_reg_prcc_pclk("p3_pclk4", "per3clk", bases[CLKRST3_INDEX], - BIT(4), 0); - clk_register_clkdev(clk, "apb_pclk", "sdi2"); - - clk = clk_reg_prcc_pclk("p3_pclk5", "per3clk", bases[CLKRST3_INDEX], - BIT(5), 0); - clk_register_clkdev(clk, "apb_pclk", "ske"); - clk_register_clkdev(clk, "apb_pclk", "nmk-ske-keypad"); - - clk = clk_reg_prcc_pclk("p3_pclk6", "per3clk", bases[CLKRST3_INDEX], - BIT(6), 0); - clk_register_clkdev(clk, "apb_pclk", "uart2"); - - clk = clk_reg_prcc_pclk("p3_pclk7", "per3clk", bases[CLKRST3_INDEX], - BIT(7), 0); - clk_register_clkdev(clk, "apb_pclk", "sdi5"); - - clk = clk_reg_prcc_pclk("p3_pclk8", "per3clk", bases[CLKRST3_INDEX], - BIT(8), 0); - clk_register_clkdev(clk, NULL, "gpio.2"); - clk_register_clkdev(clk, NULL, "gpio.3"); - clk_register_clkdev(clk, NULL, "gpio.4"); - clk_register_clkdev(clk, NULL, "gpio.5"); - clk_register_clkdev(clk, NULL, "gpioblock2"); - - clk = clk_reg_prcc_pclk("p3_pclk9", "per3clk", bases[CLKRST3_INDEX], - BIT(9), 0); - clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.5"); - - clk = clk_reg_prcc_pclk("p3_pclk10", "per3clk", bases[CLKRST3_INDEX], - BIT(10), 0); - clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.6"); - - clk = clk_reg_prcc_pclk("p3_pclk11", "per3clk", bases[CLKRST3_INDEX], - BIT(11), 0); - clk_register_clkdev(clk, "apb_pclk", "uart3"); - - clk = clk_reg_prcc_pclk("p3_pclk12", "per3clk", bases[CLKRST3_INDEX], - BIT(12), 0); - clk_register_clkdev(clk, "apb_pclk", "uart4"); - - /* Peripheral 5 : PRCC P-clocks */ - clk = clk_reg_prcc_pclk("p5_pclk0", "per5clk", bases[CLKRST5_INDEX], - BIT(0), 0); - clk_register_clkdev(clk, "usb", "musb-ux500.0"); - clk_register_clkdev(clk, "usbclk", "ab-iddet.0"); - - clk = clk_reg_prcc_pclk("p5_pclk1", "per5clk", bases[CLKRST5_INDEX], - BIT(1), 0); - clk_register_clkdev(clk, NULL, "gpio.8"); - clk_register_clkdev(clk, NULL, "gpioblock3"); - - /* Peripheral 6 : PRCC P-clocks */ - clk = clk_reg_prcc_pclk("p6_pclk0", "per6clk", bases[CLKRST6_INDEX], - BIT(0), 0); - clk_register_clkdev(clk, "apb_pclk", "rng"); - - clk = clk_reg_prcc_pclk("p6_pclk1", "per6clk", bases[CLKRST6_INDEX], - BIT(1), 0); - clk_register_clkdev(clk, NULL, "cryp0"); - clk_register_clkdev(clk, NULL, "cryp1"); - - clk = clk_reg_prcc_pclk("p6_pclk2", "per6clk", bases[CLKRST6_INDEX], - BIT(2), 0); - clk_register_clkdev(clk, NULL, "hash0"); - - clk = clk_reg_prcc_pclk("p6_pclk3", "per6clk", bases[CLKRST6_INDEX], - BIT(3), 0); - clk_register_clkdev(clk, NULL, "pka"); - - clk = clk_reg_prcc_pclk("p6_pclk4", "per6clk", bases[CLKRST6_INDEX], - BIT(4), 0); - clk_register_clkdev(clk, NULL, "db8540-hash1"); - - clk = clk_reg_prcc_pclk("p6_pclk5", "per6clk", bases[CLKRST6_INDEX], - BIT(5), 0); - clk_register_clkdev(clk, NULL, "cfgreg"); - - clk = clk_reg_prcc_pclk("p6_pclk6", "per6clk", bases[CLKRST6_INDEX], - BIT(6), 0); - clk_register_clkdev(clk, "apb_pclk", "mtu0"); - - clk = clk_reg_prcc_pclk("p6_pclk7", "per6clk", bases[CLKRST6_INDEX], - BIT(7), 0); - clk_register_clkdev(clk, "apb_pclk", "mtu1"); - - /* - * PRCC K-clocks ==> see table PRCC_PCKEN/PRCC_KCKEN - * This differs from the internal implementation: - * We don't use the PERPIH[n| clock as parent, since those _should_ - * only be used as parents for the P-clocks. - * TODO: "parentjoin" with corresponding P-clocks for all K-clocks. - */ - - /* Peripheral 1 : PRCC K-clocks */ - clk = clk_reg_prcc_kclk("p1_uart0_kclk", "uartclk", - bases[CLKRST1_INDEX], BIT(0), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "uart0"); - - clk = clk_reg_prcc_kclk("p1_uart1_kclk", "uartclk", - bases[CLKRST1_INDEX], BIT(1), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "uart1"); - - clk = clk_reg_prcc_kclk("p1_i2c1_kclk", "i2cclk", - bases[CLKRST1_INDEX], BIT(2), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "nmk-i2c.1"); - - clk = clk_reg_prcc_kclk("p1_msp0_kclk", "msp02clk", - bases[CLKRST1_INDEX], BIT(3), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "msp0"); - clk_register_clkdev(clk, NULL, "dbx5x0-msp-i2s.0"); - - clk = clk_reg_prcc_kclk("p1_msp1_kclk", "msp1clk", - bases[CLKRST1_INDEX], BIT(4), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "msp1"); - clk_register_clkdev(clk, NULL, "dbx5x0-msp-i2s.1"); - - clk = clk_reg_prcc_kclk("p1_sdi0_kclk", "sdmmchclk", - bases[CLKRST1_INDEX], BIT(5), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "sdi0"); - - clk = clk_reg_prcc_kclk("p1_i2c2_kclk", "i2cclk", - bases[CLKRST1_INDEX], BIT(6), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "nmk-i2c.2"); - - clk = clk_reg_prcc_kclk("p1_slimbus0_kclk", "slimclk", - bases[CLKRST1_INDEX], BIT(8), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "slimbus0"); - - clk = clk_reg_prcc_kclk("p1_i2c4_kclk", "i2cclk", - bases[CLKRST1_INDEX], BIT(9), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "nmk-i2c.4"); - - clk = clk_reg_prcc_kclk("p1_msp3_kclk", "msp1clk", - bases[CLKRST1_INDEX], BIT(10), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "msp3"); - clk_register_clkdev(clk, NULL, "dbx5x0-msp-i2s.3"); - - /* Peripheral 2 : PRCC K-clocks */ - clk = clk_reg_prcc_kclk("p2_i2c3_kclk", "i2cclk", - bases[CLKRST2_INDEX], BIT(0), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "nmk-i2c.3"); - - clk = clk_reg_prcc_kclk("p2_pwl_kclk", "rtc32k", - bases[CLKRST2_INDEX], BIT(1), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "pwl"); - - clk = clk_reg_prcc_kclk("p2_sdi4_kclk", "sdmmchclk", - bases[CLKRST2_INDEX], BIT(2), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "sdi4"); - - clk = clk_reg_prcc_kclk("p2_msp2_kclk", "msp02clk", - bases[CLKRST2_INDEX], BIT(3), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "msp2"); - clk_register_clkdev(clk, NULL, "dbx5x0-msp-i2s.2"); - - clk = clk_reg_prcc_kclk("p2_sdi1_kclk", "sdmmchclk", - bases[CLKRST2_INDEX], BIT(4), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "sdi1"); - - clk = clk_reg_prcc_kclk("p2_sdi3_kclk", "sdmmcclk", - bases[CLKRST2_INDEX], BIT(5), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "sdi3"); - - clk = clk_reg_prcc_kclk("p2_ssirx_kclk", "hsirxclk", - bases[CLKRST2_INDEX], BIT(6), - CLK_SET_RATE_GATE|CLK_SET_RATE_PARENT); - clk_register_clkdev(clk, "hsir_hsirxclk", "ste_hsi.0"); - - clk = clk_reg_prcc_kclk("p2_ssitx_kclk", "hsitxclk", - bases[CLKRST2_INDEX], BIT(7), - CLK_SET_RATE_GATE|CLK_SET_RATE_PARENT); - clk_register_clkdev(clk, "hsit_hsitxclk", "ste_hsi.0"); - - /* Should only be 9540, but might be added for 85xx as well */ - clk = clk_reg_prcc_kclk("p2_msp4_kclk", "msp02clk", - bases[CLKRST2_INDEX], BIT(9), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "msp4"); - clk_register_clkdev(clk, "msp4", "ab85xx-codec.0"); - - /* Peripheral 3 : PRCC K-clocks */ - clk = clk_reg_prcc_kclk("p3_ssp0_kclk", "sspclk", - bases[CLKRST3_INDEX], BIT(1), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "ssp0"); - - clk = clk_reg_prcc_kclk("p3_ssp1_kclk", "sspclk", - bases[CLKRST3_INDEX], BIT(2), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "ssp1"); - - clk = clk_reg_prcc_kclk("p3_i2c0_kclk", "i2cclk", - bases[CLKRST3_INDEX], BIT(3), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "nmk-i2c.0"); - - clk = clk_reg_prcc_kclk("p3_sdi2_kclk", "sdmmchclk", - bases[CLKRST3_INDEX], BIT(4), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "sdi2"); - - clk = clk_reg_prcc_kclk("p3_ske_kclk", "rtc32k", - bases[CLKRST3_INDEX], BIT(5), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "ske"); - clk_register_clkdev(clk, NULL, "nmk-ske-keypad"); - - clk = clk_reg_prcc_kclk("p3_uart2_kclk", "uartclk", - bases[CLKRST3_INDEX], BIT(6), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "uart2"); - - clk = clk_reg_prcc_kclk("p3_sdi5_kclk", "sdmmcclk", - bases[CLKRST3_INDEX], BIT(7), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "sdi5"); - - clk = clk_reg_prcc_kclk("p3_i2c5_kclk", "i2cclk", - bases[CLKRST3_INDEX], BIT(8), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "nmk-i2c.5"); - - clk = clk_reg_prcc_kclk("p3_i2c6_kclk", "i2cclk", - bases[CLKRST3_INDEX], BIT(9), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "nmk-i2c.6"); - - clk = clk_reg_prcc_kclk("p3_uart3_kclk", "uartclk", - bases[CLKRST3_INDEX], BIT(10), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "uart3"); - - clk = clk_reg_prcc_kclk("p3_uart4_kclk", "uartclk", - bases[CLKRST3_INDEX], BIT(11), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "uart4"); - - /* Peripheral 6 : PRCC K-clocks */ - clk = clk_reg_prcc_kclk("p6_rng_kclk", "rngclk", - bases[CLKRST6_INDEX], BIT(0), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "rng"); -} -CLK_OF_DECLARE(u8540_clks, "stericsson,u8540-clks", u8540_clk_init); diff --git a/drivers/clk/ux500/u9540_clk.c b/drivers/clk/ux500/u9540_clk.c deleted file mode 100644 index 7b6bca4..0000000 --- a/drivers/clk/ux500/u9540_clk.c +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Clock definitions for u9540 platform. - * - * Copyright (C) 2012 ST-Ericsson SA - * Author: Ulf Hansson - * - * License terms: GNU General Public License (GPL) version 2 - */ - -#include -#include -#include "clk.h" - -static void u9540_clk_init(struct device_node *np) -{ - /* register clocks here */ -} -CLK_OF_DECLARE(u9540_clks, "stericsson,u9540-clks", u9540_clk_init); -- cgit v1.1