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(-) (limited to 'drivers/clk') diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig index 6427d0ebe2de..33168f94ee39 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.2.3 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(-) (limited to 'drivers/clk') diff --git a/drivers/clk/sunxi-ng/ccu_nkmp.c b/drivers/clk/sunxi-ng/ccu_nkmp.c index e58c95787f94..a99068a08315 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.2.3 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(-) (limited to 'drivers/clk') diff --git a/drivers/clk/sunxi-ng/ccu_nkmp.c b/drivers/clk/sunxi-ng/ccu_nkmp.c index a99068a08315..c3f6fe7be565 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.2.3 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(+) (limited to 'drivers/clk') diff --git a/drivers/clk/sunxi-ng/ccu_nm.c b/drivers/clk/sunxi-ng/ccu_nm.c index a16de092bf94..4e2073307f34 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 eba586b4c7d0..1d8b459c50b7 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.2.3 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(-) (limited to 'drivers/clk') diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c index 29bc0566b776..b9f39078c0b2 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.2.3 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(-) (limited to 'drivers/clk') diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c index b9f39078c0b2..77ed0b0ba681 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.2.3 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(-) (limited to 'drivers/clk') diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-h3.h b/drivers/clk/sunxi-ng/ccu-sun8i-h3.h index 1b4baea37d81..73d7392c968c 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 e139fe5c62ec..c5f7e9a70968 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.2.3 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(-) (limited to 'drivers/clk') diff --git a/drivers/clk/sunxi-ng/ccu_nkmp.c b/drivers/clk/sunxi-ng/ccu_nkmp.c index c3f6fe7be565..ebd9436d2c7c 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 a82facbc6144..6940503e7fc4 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.2.3 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 (limited to 'drivers/clk') diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig index 33168f94ee39..79dfd296c3d1 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 4141c3fe08ae..128a40ee5c5e 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 000000000000..d5eab49e6350 --- /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 000000000000..ad6da4aa733c --- /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 000000000000..6045735a2821 --- /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 000000000000..81106f455097 --- /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.2.3 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(-) (limited to 'drivers/clk') diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c index d5eab49e6350..bdbfe78fe133 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 ad6da4aa733c..2ccfe4428260 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 6045735a2821..a1545cd60e75 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.2.3