diff options
Diffstat (limited to 'drivers')
108 files changed, 12809 insertions, 1626 deletions
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 45653a0e6ecd..4c14e26aa919 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -27,7 +27,7 @@ config COMMON_CLK_WM831X tristate "Clock driver for WM831x/2x PMICs" depends on MFD_WM831X ---help--- - Supports the clocking subsystem of the WM831x/2x series of + Supports the clocking subsystem of the WM831x/2x series of PMICs from Wolfson Microelectronics. source "drivers/clk/versatile/Kconfig" @@ -174,6 +174,18 @@ config COMMON_CLK_CS2000_CP help If you say yes here you get support for the CS2000 clock multiplier. +config COMMON_CLK_FSL_SAI + bool "Clock driver for BCLK of Freescale SAI cores" + depends on ARCH_LAYERSCAPE || COMPILE_TEST + help + This driver supports the Freescale SAI (Synchronous Audio Interface) + to be used as a generic clock output. Some SoCs have restrictions + regarding the possible pin multiplexer settings. Eg. on some SoCs + two SAI interfaces can only be enabled together. If just one is + needed, the BCLK pin of the second one can be used as general + purpose clock output. Ideally, it can be used to drive an audio + codec (sometimes known as MCLK). + config COMMON_CLK_GEMINI bool "Clock driver for Cortina Systems Gemini SoC" depends on ARCH_GEMINI || COMPILE_TEST @@ -225,6 +237,16 @@ config CLK_QORIQ This adds the clock driver support for Freescale QorIQ platforms using common clock framework. +config CLK_LS1028A_PLLDIG + tristate "Clock driver for LS1028A Display output" + depends on ARCH_LAYERSCAPE || COMPILE_TEST + default ARCH_LAYERSCAPE + help + This driver support the Display output interfaces(LCD, DPHY) pixel clocks + of the QorIQ Layerscape LS1028A, as implemented TSMC CLN28HPM PLL. Not all + features of the PLL are currently supported by the driver. By default, + configured bypass mode with this PLL. + config COMMON_CLK_XGENE bool "Clock driver for APM XGene SoC" default ARCH_XGENE diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 0696a0c1ab58..f4169cc2fd31 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -29,6 +29,7 @@ obj-$(CONFIG_ARCH_CLPS711X) += clk-clps711x.o obj-$(CONFIG_COMMON_CLK_CS2000_CP) += clk-cs2000-cp.o obj-$(CONFIG_ARCH_EFM32) += clk-efm32gg.o obj-$(CONFIG_COMMON_CLK_FIXED_MMIO) += clk-fixed-mmio.o +obj-$(CONFIG_COMMON_CLK_FSL_SAI) += clk-fsl-sai.o obj-$(CONFIG_COMMON_CLK_GEMINI) += clk-gemini.o obj-$(CONFIG_COMMON_CLK_ASPEED) += clk-aspeed.o obj-$(CONFIG_MACH_ASPEED_G6) += clk-ast2600.o @@ -44,6 +45,7 @@ obj-$(CONFIG_ARCH_NPCM7XX) += clk-npcm7xx.o obj-$(CONFIG_ARCH_NSPIRE) += clk-nspire.o obj-$(CONFIG_COMMON_CLK_OXNAS) += clk-oxnas.o obj-$(CONFIG_COMMON_CLK_PALMAS) += clk-palmas.o +obj-$(CONFIG_CLK_LS1028A_PLLDIG) += clk-plldig.o obj-$(CONFIG_COMMON_CLK_PWM) += clk-pwm.o obj-$(CONFIG_CLK_QORIQ) += clk-qoriq.o obj-$(CONFIG_COMMON_CLK_RK808) += clk-rk808.o diff --git a/drivers/clk/at91/at91sam9260.c b/drivers/clk/at91/at91sam9260.c index 0aabe49aed09..a9d4234758d7 100644 --- a/drivers/clk/at91/at91sam9260.c +++ b/drivers/clk/at91/at91sam9260.c @@ -348,7 +348,7 @@ static void __init at91sam926x_pmc_setup(struct device_node *np, return; mainxtal_name = of_clk_get_parent_name(np, i); - regmap = syscon_node_to_regmap(np); + regmap = device_node_to_regmap(np); if (IS_ERR(regmap)) return; diff --git a/drivers/clk/at91/at91sam9rl.c b/drivers/clk/at91/at91sam9rl.c index 0ac34cdaa106..77fe83a73bf4 100644 --- a/drivers/clk/at91/at91sam9rl.c +++ b/drivers/clk/at91/at91sam9rl.c @@ -83,7 +83,7 @@ static void __init at91sam9rl_pmc_setup(struct device_node *np) return; mainxtal_name = of_clk_get_parent_name(np, i); - regmap = syscon_node_to_regmap(np); + regmap = device_node_to_regmap(np); if (IS_ERR(regmap)) return; diff --git a/drivers/clk/at91/at91sam9x5.c b/drivers/clk/at91/at91sam9x5.c index 0855f3a80cc7..086cf0b4955c 100644 --- a/drivers/clk/at91/at91sam9x5.c +++ b/drivers/clk/at91/at91sam9x5.c @@ -146,7 +146,7 @@ static void __init at91sam9x5_pmc_setup(struct device_node *np, return; mainxtal_name = of_clk_get_parent_name(np, i); - regmap = syscon_node_to_regmap(np); + regmap = device_node_to_regmap(np); if (IS_ERR(regmap)) return; diff --git a/drivers/clk/at91/clk-sam9x60-pll.c b/drivers/clk/at91/clk-sam9x60-pll.c index 34b817825b22..dfb354a5ff18 100644 --- a/drivers/clk/at91/clk-sam9x60-pll.c +++ b/drivers/clk/at91/clk-sam9x60-pll.c @@ -25,7 +25,8 @@ #define PMC_PLL_CTRL1_MUL_MSK GENMASK(30, 24) #define PMC_PLL_ACR 0x18 -#define PMC_PLL_ACR_DEFAULT 0x1b040010UL +#define PMC_PLL_ACR_DEFAULT_UPLL 0x12020010UL +#define PMC_PLL_ACR_DEFAULT_PLLA 0x00020010UL #define PMC_PLL_ACR_UTMIVR BIT(12) #define PMC_PLL_ACR_UTMIBG BIT(13) #define PMC_PLL_ACR_LOOP_FILTER_MSK GENMASK(31, 24) @@ -88,7 +89,10 @@ static int sam9x60_pll_prepare(struct clk_hw *hw) } /* Recommended value for PMC_PLL_ACR */ - val = PMC_PLL_ACR_DEFAULT; + if (pll->characteristics->upll) + val = PMC_PLL_ACR_DEFAULT_UPLL; + else + val = PMC_PLL_ACR_DEFAULT_PLLA; regmap_write(regmap, PMC_PLL_ACR, val); regmap_write(regmap, PMC_PLL_CTRL1, diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c index 0b03cfae3a9d..b71515acdec1 100644 --- a/drivers/clk/at91/pmc.c +++ b/drivers/clk/at91/pmc.c @@ -275,7 +275,7 @@ static int __init pmc_register_ops(void) np = of_find_matching_node(NULL, sama5d2_pmc_dt_ids); - pmcreg = syscon_node_to_regmap(np); + pmcreg = device_node_to_regmap(np); if (IS_ERR(pmcreg)) return PTR_ERR(pmcreg); diff --git a/drivers/clk/at91/sam9x60.c b/drivers/clk/at91/sam9x60.c index 86238d5ecb4d..77398aefeb6d 100644 --- a/drivers/clk/at91/sam9x60.c +++ b/drivers/clk/at91/sam9x60.c @@ -47,6 +47,7 @@ static const struct clk_programmable_layout sam9x60_programmable_layout = { .pres_shift = 8, .css_mask = 0x1f, .have_slck_mck = 0, + .is_pres_direct = 1, }; static const struct clk_pcr_layout sam9x60_pcr_layout = { diff --git a/drivers/clk/at91/sama5d2.c b/drivers/clk/at91/sama5d2.c index 0de1108737db..ff7e3f727082 100644 --- a/drivers/clk/at91/sama5d2.c +++ b/drivers/clk/at91/sama5d2.c @@ -162,7 +162,7 @@ static void __init sama5d2_pmc_setup(struct device_node *np) return; mainxtal_name = of_clk_get_parent_name(np, i); - regmap = syscon_node_to_regmap(np); + regmap = device_node_to_regmap(np); if (IS_ERR(regmap)) return; diff --git a/drivers/clk/at91/sama5d4.c b/drivers/clk/at91/sama5d4.c index 25b156d4e645..a6dee4a3b6e4 100644 --- a/drivers/clk/at91/sama5d4.c +++ b/drivers/clk/at91/sama5d4.c @@ -136,7 +136,7 @@ static void __init sama5d4_pmc_setup(struct device_node *np) return; mainxtal_name = of_clk_get_parent_name(np, i); - regmap = syscon_node_to_regmap(np); + regmap = device_node_to_regmap(np); if (IS_ERR(regmap)) return; diff --git a/drivers/clk/clk-asm9260.c b/drivers/clk/clk-asm9260.c index dd0f90c9dd0e..536b59aabd2c 100644 --- a/drivers/clk/clk-asm9260.c +++ b/drivers/clk/clk-asm9260.c @@ -260,7 +260,6 @@ static void __init asm9260_acc_init(struct device_node *np) const char *ref_clk, *pll_clk = "pll"; u32 rate; int n; - u32 accuracy = 0; clk_data = kzalloc(struct_size(clk_data, hws, MAX_CLKS), GFP_KERNEL); if (!clk_data) @@ -275,10 +274,11 @@ static void __init asm9260_acc_init(struct device_node *np) /* register pll */ rate = (ioread32(base + HW_SYSPLLCTRL) & 0xffff) * 1000000; + /* TODO: Convert to DT parent scheme */ ref_clk = of_clk_get_parent_name(np, 0); - accuracy = clk_get_accuracy(__clk_lookup(ref_clk)); - hw = clk_hw_register_fixed_rate_with_accuracy(NULL, pll_clk, - ref_clk, 0, rate, accuracy); + hw = __clk_hw_register_fixed_rate_with_accuracy(NULL, NULL, pll_clk, + ref_clk, NULL, NULL, 0, rate, 0, + CLK_FIXED_RATE_PARENT_ACCURACY); if (IS_ERR(hw)) panic("%pOFn: can't register REFCLK. Check DT!", np); diff --git a/drivers/clk/clk-bm1880.c b/drivers/clk/clk-bm1880.c index 4cd175afce9b..e6d6599d310a 100644 --- a/drivers/clk/clk-bm1880.c +++ b/drivers/clk/clk-bm1880.c @@ -474,11 +474,10 @@ static struct bm1880_composite_clock bm1880_composite_clks[] = { static unsigned long bm1880_pll_rate_calc(u32 regval, unsigned long parent_rate) { u64 numerator; - u32 fbdiv, fref, refdiv; + u32 fbdiv, refdiv; u32 postdiv1, postdiv2, denominator; fbdiv = (regval >> 16) & 0xfff; - fref = parent_rate; refdiv = regval & 0x1f; postdiv1 = (regval >> 8) & 0x7; postdiv2 = (regval >> 12) & 0x7; diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c index 3e9c3e608769..7376f573bfdb 100644 --- a/drivers/clk/clk-composite.c +++ b/drivers/clk/clk-composite.c @@ -199,8 +199,9 @@ static void clk_composite_disable(struct clk_hw *hw) gate_ops->disable(gate_hw); } -struct clk_hw *clk_hw_register_composite(struct device *dev, const char *name, - const char * const *parent_names, int num_parents, +static struct clk_hw *__clk_hw_register_composite(struct device *dev, + const char *name, const char * const *parent_names, + const struct clk_parent_data *pdata, int num_parents, struct clk_hw *mux_hw, const struct clk_ops *mux_ops, struct clk_hw *rate_hw, const struct clk_ops *rate_ops, struct clk_hw *gate_hw, const struct clk_ops *gate_ops, @@ -218,7 +219,10 @@ struct clk_hw *clk_hw_register_composite(struct device *dev, const char *name, init.name = name; init.flags = flags; - init.parent_names = parent_names; + if (parent_names) + init.parent_names = parent_names; + else + init.parent_data = pdata; init.num_parents = num_parents; hw = &composite->hw; @@ -312,6 +316,34 @@ err: return hw; } +struct clk_hw *clk_hw_register_composite(struct device *dev, const char *name, + const char * const *parent_names, int num_parents, + struct clk_hw *mux_hw, const struct clk_ops *mux_ops, + struct clk_hw *rate_hw, const struct clk_ops *rate_ops, + struct clk_hw *gate_hw, const struct clk_ops *gate_ops, + unsigned long flags) +{ + return __clk_hw_register_composite(dev, name, parent_names, NULL, + num_parents, mux_hw, mux_ops, + rate_hw, rate_ops, gate_hw, + gate_ops, flags); +} + +struct clk_hw *clk_hw_register_composite_pdata(struct device *dev, + const char *name, + const struct clk_parent_data *parent_data, + int num_parents, + struct clk_hw *mux_hw, const struct clk_ops *mux_ops, + struct clk_hw *rate_hw, const struct clk_ops *rate_ops, + struct clk_hw *gate_hw, const struct clk_ops *gate_ops, + unsigned long flags) +{ + return __clk_hw_register_composite(dev, name, NULL, parent_data, + num_parents, mux_hw, mux_ops, + rate_hw, rate_ops, gate_hw, + gate_ops, flags); +} + struct clk *clk_register_composite(struct device *dev, const char *name, const char * const *parent_names, int num_parents, struct clk_hw *mux_hw, const struct clk_ops *mux_ops, @@ -329,6 +361,24 @@ struct clk *clk_register_composite(struct device *dev, const char *name, return hw->clk; } +struct clk *clk_register_composite_pdata(struct device *dev, const char *name, + const struct clk_parent_data *parent_data, + int num_parents, + struct clk_hw *mux_hw, const struct clk_ops *mux_ops, + struct clk_hw *rate_hw, const struct clk_ops *rate_ops, + struct clk_hw *gate_hw, const struct clk_ops *gate_ops, + unsigned long flags) +{ + struct clk_hw *hw; + + hw = clk_hw_register_composite_pdata(dev, name, parent_data, + num_parents, mux_hw, mux_ops, rate_hw, rate_ops, + gate_hw, gate_ops, flags); + if (IS_ERR(hw)) + return ERR_CAST(hw); + return hw->clk; +} + void clk_unregister_composite(struct clk *clk) { struct clk_composite *composite; diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c index 098b2b01f0af..8de12cb0c43d 100644 --- a/drivers/clk/clk-divider.c +++ b/drivers/clk/clk-divider.c @@ -463,11 +463,12 @@ const struct clk_ops clk_divider_ro_ops = { }; EXPORT_SYMBOL_GPL(clk_divider_ro_ops); -static struct clk_hw *_register_divider(struct device *dev, const char *name, - const char *parent_name, unsigned long flags, - void __iomem *reg, u8 shift, u8 width, - u8 clk_divider_flags, const struct clk_div_table *table, - spinlock_t *lock) +struct clk_hw *__clk_hw_register_divider(struct device *dev, + struct device_node *np, const char *name, + const char *parent_name, const struct clk_hw *parent_hw, + const struct clk_parent_data *parent_data, unsigned long flags, + void __iomem *reg, u8 shift, u8 width, u8 clk_divider_flags, + const struct clk_div_table *table, spinlock_t *lock) { struct clk_divider *div; struct clk_hw *hw; @@ -514,55 +515,7 @@ static struct clk_hw *_register_divider(struct device *dev, const char *name, return hw; } - -/** - * clk_register_divider - register a divider clock with the clock framework - * @dev: device registering this clock - * @name: name of this clock - * @parent_name: name of clock's parent - * @flags: framework-specific flags - * @reg: register address to adjust divider - * @shift: number of bits to shift the bitfield - * @width: width of the bitfield - * @clk_divider_flags: divider-specific flags for this clock - * @lock: shared register lock for this clock - */ -struct clk *clk_register_divider(struct device *dev, const char *name, - const char *parent_name, unsigned long flags, - void __iomem *reg, u8 shift, u8 width, - u8 clk_divider_flags, spinlock_t *lock) -{ - struct clk_hw *hw; - - hw = _register_divider(dev, name, parent_name, flags, reg, shift, - width, clk_divider_flags, NULL, lock); - if (IS_ERR(hw)) - return ERR_CAST(hw); - return hw->clk; -} -EXPORT_SYMBOL_GPL(clk_register_divider); - -/** - * clk_hw_register_divider - register a divider clock with the clock framework - * @dev: device registering this clock - * @name: name of this clock - * @parent_name: name of clock's parent - * @flags: framework-specific flags - * @reg: register address to adjust divider - * @shift: number of bits to shift the bitfield - * @width: width of the bitfield - * @clk_divider_flags: divider-specific flags for this clock - * @lock: shared register lock for this clock - */ -struct clk_hw *clk_hw_register_divider(struct device *dev, const char *name, - const char *parent_name, unsigned long flags, - void __iomem *reg, u8 shift, u8 width, - u8 clk_divider_flags, spinlock_t *lock) -{ - return _register_divider(dev, name, parent_name, flags, reg, shift, - width, clk_divider_flags, NULL, lock); -} -EXPORT_SYMBOL_GPL(clk_hw_register_divider); +EXPORT_SYMBOL_GPL(__clk_hw_register_divider); /** * clk_register_divider_table - register a table based divider clock with @@ -586,39 +539,15 @@ struct clk *clk_register_divider_table(struct device *dev, const char *name, { struct clk_hw *hw; - hw = _register_divider(dev, name, parent_name, flags, reg, shift, - width, clk_divider_flags, table, lock); + hw = __clk_hw_register_divider(dev, NULL, name, parent_name, NULL, + NULL, flags, reg, shift, width, clk_divider_flags, + table, lock); if (IS_ERR(hw)) return ERR_CAST(hw); return hw->clk; } EXPORT_SYMBOL_GPL(clk_register_divider_table); -/** - * clk_hw_register_divider_table - register a table based divider clock with - * the clock framework - * @dev: device registering this clock - * @name: name of this clock - * @parent_name: name of clock's parent - * @flags: framework-specific flags - * @reg: register address to adjust divider - * @shift: number of bits to shift the bitfield - * @width: width of the bitfield - * @clk_divider_flags: divider-specific flags for this clock - * @table: array of divider/value pairs ending with a div set to 0 - * @lock: shared register lock for this clock - */ -struct clk_hw *clk_hw_register_divider_table(struct device *dev, - const char *name, const char *parent_name, unsigned long flags, - void __iomem *reg, u8 shift, u8 width, - u8 clk_divider_flags, const struct clk_div_table *table, - spinlock_t *lock) -{ - return _register_divider(dev, name, parent_name, flags, reg, shift, - width, clk_divider_flags, table, lock); -} -EXPORT_SYMBOL_GPL(clk_hw_register_divider_table); - void clk_unregister_divider(struct clk *clk) { struct clk_divider *div; diff --git a/drivers/clk/clk-fixed-rate.c b/drivers/clk/clk-fixed-rate.c index 2c4486c09040..77499a27c8fb 100644 --- a/drivers/clk/clk-fixed-rate.c +++ b/drivers/clk/clk-fixed-rate.c @@ -24,6 +24,8 @@ * parent - fixed parent. No clk_set_parent support */ +#define to_clk_fixed_rate(_hw) container_of(_hw, struct clk_fixed_rate, hw) + static unsigned long clk_fixed_rate_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { @@ -33,7 +35,12 @@ static unsigned long clk_fixed_rate_recalc_rate(struct clk_hw *hw, static unsigned long clk_fixed_rate_recalc_accuracy(struct clk_hw *hw, unsigned long parent_accuracy) { - return to_clk_fixed_rate(hw)->fixed_accuracy; + struct clk_fixed_rate *fixed = to_clk_fixed_rate(hw); + + if (fixed->flags & CLK_FIXED_RATE_PARENT_ACCURACY) + return parent_accuracy; + + return fixed->fixed_accuracy; } const struct clk_ops clk_fixed_rate_ops = { @@ -42,24 +49,17 @@ const struct clk_ops clk_fixed_rate_ops = { }; EXPORT_SYMBOL_GPL(clk_fixed_rate_ops); -/** - * clk_hw_register_fixed_rate_with_accuracy - register fixed-rate clock with - * the clock framework - * @dev: device that is registering this clock - * @name: name of this clock - * @parent_name: name of clock's parent - * @flags: framework-specific flags - * @fixed_rate: non-adjustable clock rate - * @fixed_accuracy: non-adjustable clock rate - */ -struct clk_hw *clk_hw_register_fixed_rate_with_accuracy(struct device *dev, - const char *name, const char *parent_name, unsigned long flags, - unsigned long fixed_rate, unsigned long fixed_accuracy) +struct clk_hw *__clk_hw_register_fixed_rate(struct device *dev, + struct device_node *np, const char *name, + const char *parent_name, const struct clk_hw *parent_hw, + const struct clk_parent_data *parent_data, unsigned long flags, + unsigned long fixed_rate, unsigned long fixed_accuracy, + unsigned long clk_fixed_flags) { struct clk_fixed_rate *fixed; struct clk_hw *hw; struct clk_init_data init = {}; - int ret; + int ret = -EINVAL; /* allocate fixed-rate clock */ fixed = kzalloc(sizeof(*fixed), GFP_KERNEL); @@ -69,17 +69,26 @@ struct clk_hw *clk_hw_register_fixed_rate_with_accuracy(struct device *dev, init.name = name; init.ops = &clk_fixed_rate_ops; init.flags = flags; - init.parent_names = (parent_name ? &parent_name: NULL); - init.num_parents = (parent_name ? 1 : 0); + init.parent_names = parent_name ? &parent_name : NULL; + init.parent_hws = parent_hw ? &parent_hw : NULL; + init.parent_data = parent_data; + if (parent_name || parent_hw || parent_data) + init.num_parents = 1; + else + init.num_parents = 0; /* struct clk_fixed_rate assignments */ + fixed->flags = clk_fixed_flags; fixed->fixed_rate = fixed_rate; fixed->fixed_accuracy = fixed_accuracy; fixed->hw.init = &init; /* register the clock */ hw = &fixed->hw; - ret = clk_hw_register(dev, hw); + if (dev || !np) + ret = clk_hw_register(dev, hw); + else if (np) + ret = of_clk_hw_register(np, hw); if (ret) { kfree(fixed); hw = ERR_PTR(ret); @@ -87,47 +96,20 @@ struct clk_hw *clk_hw_register_fixed_rate_with_accuracy(struct device *dev, return hw; } -EXPORT_SYMBOL_GPL(clk_hw_register_fixed_rate_with_accuracy); +EXPORT_SYMBOL_GPL(__clk_hw_register_fixed_rate); -struct clk *clk_register_fixed_rate_with_accuracy(struct device *dev, - const char *name, const char *parent_name, unsigned long flags, - unsigned long fixed_rate, unsigned long fixed_accuracy) +struct clk *clk_register_fixed_rate(struct device *dev, const char *name, + const char *parent_name, unsigned long flags, + unsigned long fixed_rate) { struct clk_hw *hw; hw = clk_hw_register_fixed_rate_with_accuracy(dev, name, parent_name, - flags, fixed_rate, fixed_accuracy); + flags, fixed_rate, 0); if (IS_ERR(hw)) return ERR_CAST(hw); return hw->clk; } -EXPORT_SYMBOL_GPL(clk_register_fixed_rate_with_accuracy); - -/** - * clk_hw_register_fixed_rate - register fixed-rate clock with the clock - * framework - * @dev: device that is registering this clock - * @name: name of this clock - * @parent_name: name of clock's parent - * @flags: framework-specific flags - * @fixed_rate: non-adjustable clock rate - */ -struct clk_hw *clk_hw_register_fixed_rate(struct device *dev, const char *name, - const char *parent_name, unsigned long flags, - unsigned long fixed_rate) -{ - return clk_hw_register_fixed_rate_with_accuracy(dev, name, parent_name, - flags, fixed_rate, 0); -} -EXPORT_SYMBOL_GPL(clk_hw_register_fixed_rate); - -struct clk *clk_register_fixed_rate(struct device *dev, const char *name, - const char *parent_name, unsigned long flags, - unsigned long fixed_rate) -{ - return clk_register_fixed_rate_with_accuracy(dev, name, parent_name, - flags, fixed_rate, 0); -} EXPORT_SYMBOL_GPL(clk_register_fixed_rate); void clk_unregister_fixed_rate(struct clk *clk) @@ -155,9 +137,9 @@ void clk_hw_unregister_fixed_rate(struct clk_hw *hw) EXPORT_SYMBOL_GPL(clk_hw_unregister_fixed_rate); #ifdef CONFIG_OF -static struct clk *_of_fixed_clk_setup(struct device_node *node) +static struct clk_hw *_of_fixed_clk_setup(struct device_node *node) { - struct clk *clk; + struct clk_hw *hw; const char *clk_name = node->name; u32 rate; u32 accuracy = 0; @@ -170,18 +152,18 @@ static struct clk *_of_fixed_clk_setup(struct device_node *node) of_property_read_string(node, "clock-output-names", &clk_name); - clk = clk_register_fixed_rate_with_accuracy(NULL, clk_name, NULL, + hw = clk_hw_register_fixed_rate_with_accuracy(NULL, clk_name, NULL, 0, rate, accuracy); - if (IS_ERR(clk)) - return clk; + if (IS_ERR(hw)) + return hw; - ret = of_clk_add_provider(node, of_clk_src_simple_get, clk); + ret = of_clk_add_hw_provider(node, of_clk_hw_simple_get, hw); if (ret) { - clk_unregister(clk); + clk_hw_unregister_fixed_rate(hw); return ERR_PTR(ret); } - return clk; + return hw; } /** @@ -195,27 +177,27 @@ CLK_OF_DECLARE(fixed_clk, "fixed-clock", of_fixed_clk_setup); static int of_fixed_clk_remove(struct platform_device *pdev) { - struct clk *clk = platform_get_drvdata(pdev); + struct clk_hw *hw = platform_get_drvdata(pdev); of_clk_del_provider(pdev->dev.of_node); - clk_unregister_fixed_rate(clk); + clk_hw_unregister_fixed_rate(hw); return 0; } static int of_fixed_clk_probe(struct platform_device *pdev) { - struct clk *clk; + struct clk_hw *hw; /* * This function is not executed when of_fixed_clk_setup * succeeded. */ - clk = _of_fixed_clk_setup(pdev->dev.of_node); - if (IS_ERR(clk)) - return PTR_ERR(clk); + hw = _of_fixed_clk_setup(pdev->dev.of_node); + if (IS_ERR(hw)) + return PTR_ERR(hw); - platform_set_drvdata(pdev, clk); + platform_set_drvdata(pdev, hw); return 0; } @@ -224,7 +206,6 @@ static const struct of_device_id of_fixed_clk_ids[] = { { .compatible = "fixed-clock" }, { } }; -MODULE_DEVICE_TABLE(of, of_fixed_clk_ids); static struct platform_driver of_fixed_clk_driver = { .driver = { diff --git a/drivers/clk/clk-fsl-sai.c b/drivers/clk/clk-fsl-sai.c new file mode 100644 index 000000000000..0221180a4dd7 --- /dev/null +++ b/drivers/clk/clk-fsl-sai.c @@ -0,0 +1,92 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Freescale SAI BCLK as a generic clock driver + * + * Copyright 2020 Michael Walle <michael@walle.cc> + */ + +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/clk-provider.h> +#include <linux/err.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/slab.h> + +#define I2S_CSR 0x00 +#define I2S_CR2 0x08 +#define CSR_BCE_BIT 28 +#define CR2_BCD BIT(24) +#define CR2_DIV_SHIFT 0 +#define CR2_DIV_WIDTH 8 + +struct fsl_sai_clk { + struct clk_divider div; + struct clk_gate gate; + spinlock_t lock; +}; + +static int fsl_sai_clk_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct fsl_sai_clk *sai_clk; + struct clk_parent_data pdata = { .index = 0 }; + void __iomem *base; + struct clk_hw *hw; + struct resource *res; + + sai_clk = devm_kzalloc(dev, sizeof(*sai_clk), GFP_KERNEL); + if (!sai_clk) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + base = devm_ioremap_resource(dev, res); + if (IS_ERR(base)) + return PTR_ERR(base); + + spin_lock_init(&sai_clk->lock); + + sai_clk->gate.reg = base + I2S_CSR; + sai_clk->gate.bit_idx = CSR_BCE_BIT; + sai_clk->gate.lock = &sai_clk->lock; + + sai_clk->div.reg = base + I2S_CR2; + sai_clk->div.shift = CR2_DIV_SHIFT; + sai_clk->div.width = CR2_DIV_WIDTH; + sai_clk->div.lock = &sai_clk->lock; + + /* set clock direction, we are the BCLK master */ + writel(CR2_BCD, base + I2S_CR2); + + hw = clk_hw_register_composite_pdata(dev, dev->of_node->name, + &pdata, 1, NULL, NULL, + &sai_clk->div.hw, + &clk_divider_ops, + &sai_clk->gate.hw, + &clk_gate_ops, + CLK_SET_RATE_GATE); + if (IS_ERR(hw)) + return PTR_ERR(hw); + + return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, hw); +} + +static const struct of_device_id of_fsl_sai_clk_ids[] = { + { .compatible = "fsl,vf610-sai-clock" }, + { } +}; +MODULE_DEVICE_TABLE(of, of_fsl_sai_clk_ids); + +static struct platform_driver fsl_sai_clk_driver = { + .probe = fsl_sai_clk_probe, + .driver = { + .name = "fsl-sai-clk", + .of_match_table = of_fsl_sai_clk_ids, + }, +}; +module_platform_driver(fsl_sai_clk_driver); + +MODULE_DESCRIPTION("Freescale SAI bitclock-as-a-clock driver"); +MODULE_AUTHOR("Michael Walle <michael@walle.cc>"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:fsl-sai-clk"); diff --git a/drivers/clk/clk-gate.c b/drivers/clk/clk-gate.c index 670053c58c1a..2ca1f2ac38a6 100644 --- a/drivers/clk/clk-gate.c +++ b/drivers/clk/clk-gate.c @@ -123,26 +123,18 @@ const struct clk_ops clk_gate_ops = { }; EXPORT_SYMBOL_GPL(clk_gate_ops); -/** - * clk_hw_register_gate - register a gate clock with the clock framework - * @dev: device that is registering this clock - * @name: name of this clock - * @parent_name: name of this clock's parent - * @flags: framework-specific flags for this clock - * @reg: register address to control gating of this clock - * @bit_idx: which bit in the register controls gating of this clock - * @clk_gate_flags: gate-specific flags for this clock - * @lock: shared register lock for this clock - */ -struct clk_hw *clk_hw_register_gate(struct device *dev, const char *name, - const char *parent_name, unsigned long flags, +struct clk_hw *__clk_hw_register_gate(struct device *dev, + struct device_node *np, const char *name, + const char *parent_name, const struct clk_hw *parent_hw, + const struct clk_parent_data *parent_data, + unsigned long flags, void __iomem *reg, u8 bit_idx, u8 clk_gate_flags, spinlock_t *lock) { struct clk_gate *gate; struct clk_hw *hw; struct clk_init_data init = {}; - int ret; + int ret = -EINVAL; if (clk_gate_flags & CLK_GATE_HIWORD_MASK) { if (bit_idx > 15) { @@ -160,7 +152,12 @@ struct clk_hw *clk_hw_register_gate(struct device *dev, const char *name, init.ops = &clk_gate_ops; init.flags = flags; init.parent_names = parent_name ? &parent_name : NULL; - init.num_parents = parent_name ? 1 : 0; + init.parent_hws = parent_hw ? &parent_hw : NULL; + init.parent_data = parent_data; + if (parent_name || parent_hw || parent_data) + init.num_parents = 1; + else + init.num_parents = 0; /* struct clk_gate assignments */ gate->reg = reg; @@ -170,15 +167,19 @@ struct clk_hw *clk_hw_register_gate(struct device *dev, const char *name, gate->hw.init = &init; hw = &gate->hw; - ret = clk_hw_register(dev, hw); + if (dev || !np) + ret = clk_hw_register(dev, hw); + else if (np) + ret = of_clk_hw_register(np, hw); if (ret) { kfree(gate); hw = ERR_PTR(ret); } return hw; + } -EXPORT_SYMBOL_GPL(clk_hw_register_gate); +EXPORT_SYMBOL_GPL(__clk_hw_register_gate); struct clk *clk_register_gate(struct device *dev, const char *name, const char *parent_name, unsigned long flags, diff --git a/drivers/clk/clk-gpio.c b/drivers/clk/clk-gpio.c index 13304cf5f2a8..70397b4b5ffe 100644 --- a/drivers/clk/clk-gpio.c +++ b/drivers/clk/clk-gpio.c @@ -28,6 +28,26 @@ * parent - fixed parent. No clk_set_parent support */ +/** + * struct clk_gpio - gpio gated clock + * + * @hw: handle between common and hardware-specific interfaces + * @gpiod: gpio descriptor + * + * Clock with a gpio control for enabling and disabling the parent clock + * or switching between two parents by asserting or deasserting the gpio. + * + * Implements .enable, .disable and .is_enabled or + * .get_parent, .set_parent and .determine_rate depending on which clk_ops + * is used. + */ +struct clk_gpio { + struct clk_hw hw; + struct gpio_desc *gpiod; +}; + +#define to_clk_gpio(_hw) container_of(_hw, struct clk_gpio, hw) + static int clk_gpio_gate_enable(struct clk_hw *hw) { struct clk_gpio *clk = to_clk_gpio(hw); @@ -51,12 +71,11 @@ static int clk_gpio_gate_is_enabled(struct clk_hw *hw) return gpiod_get_value(clk->gpiod); } -const struct clk_ops clk_gpio_gate_ops = { +static const struct clk_ops clk_gpio_gate_ops = { .enable = clk_gpio_gate_enable, .disable = clk_gpio_gate_disable, .is_enabled = clk_gpio_gate_is_enabled, }; -EXPORT_SYMBOL_GPL(clk_gpio_gate_ops); static int clk_sleeping_gpio_gate_prepare(struct clk_hw *hw) { @@ -111,67 +130,49 @@ static int clk_gpio_mux_set_parent(struct clk_hw *hw, u8 index) return 0; } -const struct clk_ops clk_gpio_mux_ops = { +static const struct clk_ops clk_gpio_mux_ops = { .get_parent = clk_gpio_mux_get_parent, .set_parent = clk_gpio_mux_set_parent, .determine_rate = __clk_mux_determine_rate, }; -EXPORT_SYMBOL_GPL(clk_gpio_mux_ops); -static struct clk_hw *clk_register_gpio(struct device *dev, const char *name, - const char * const *parent_names, u8 num_parents, struct gpio_desc *gpiod, - unsigned long flags, const struct clk_ops *clk_gpio_ops) +static struct clk_hw *clk_register_gpio(struct device *dev, u8 num_parents, + struct gpio_desc *gpiod, + const struct clk_ops *clk_gpio_ops) { struct clk_gpio *clk_gpio; struct clk_hw *hw; struct clk_init_data init = {}; int err; + const struct clk_parent_data gpio_parent_data[] = { + { .index = 0 }, + { .index = 1 }, + }; - if (dev) - clk_gpio = devm_kzalloc(dev, sizeof(*clk_gpio), GFP_KERNEL); - else - clk_gpio = kzalloc(sizeof(*clk_gpio), GFP_KERNEL); - + clk_gpio = devm_kzalloc(dev, sizeof(*clk_gpio), GFP_KERNEL); if (!clk_gpio) return ERR_PTR(-ENOMEM); - init.name = name; + init.name = dev->of_node->name; init.ops = clk_gpio_ops; - init.flags = flags; - init.parent_names = parent_names; + init.parent_data = gpio_parent_data; init.num_parents = num_parents; + init.flags = CLK_SET_RATE_PARENT; clk_gpio->gpiod = gpiod; clk_gpio->hw.init = &init; hw = &clk_gpio->hw; - if (dev) - err = devm_clk_hw_register(dev, hw); - else - err = clk_hw_register(NULL, hw); - - if (!err) - return hw; - - if (!dev) { - kfree(clk_gpio); - } + err = devm_clk_hw_register(dev, hw); + if (err) + return ERR_PTR(err); - return ERR_PTR(err); + return hw; } -/** - * clk_hw_register_gpio_gate - register a gpio clock gate with the clock - * framework - * @dev: device that is registering this clock - * @name: name of this clock - * @parent_name: name of this clock's parent - * @gpiod: gpio descriptor to gate this clock - * @flags: clock flags - */ -struct clk_hw *clk_hw_register_gpio_gate(struct device *dev, const char *name, - const char *parent_name, struct gpio_desc *gpiod, - unsigned long flags) +static struct clk_hw *clk_hw_register_gpio_gate(struct device *dev, + int num_parents, + struct gpio_desc *gpiod) { const struct clk_ops *ops; @@ -180,88 +181,36 @@ struct clk_hw *clk_hw_register_gpio_gate(struct device *dev, const char *name, else ops = &clk_gpio_gate_ops; - return clk_register_gpio(dev, name, - (parent_name ? &parent_name : NULL), - (parent_name ? 1 : 0), gpiod, flags, ops); + return clk_register_gpio(dev, num_parents, gpiod, ops); } -EXPORT_SYMBOL_GPL(clk_hw_register_gpio_gate); -struct clk *clk_register_gpio_gate(struct device *dev, const char *name, - const char *parent_name, struct gpio_desc *gpiod, - unsigned long flags) +static struct clk_hw *clk_hw_register_gpio_mux(struct device *dev, + struct gpio_desc *gpiod) { - struct clk_hw *hw; - - hw = clk_hw_register_gpio_gate(dev, name, parent_name, gpiod, flags); - if (IS_ERR(hw)) - return ERR_CAST(hw); - return hw->clk; + return clk_register_gpio(dev, 2, gpiod, &clk_gpio_mux_ops); } -EXPORT_SYMBOL_GPL(clk_register_gpio_gate); - -/** - * clk_hw_register_gpio_mux - register a gpio clock mux with the clock framework - * @dev: device that is registering this clock - * @name: name of this clock - * @parent_names: names of this clock's parents - * @num_parents: number of parents listed in @parent_names - * @gpiod: gpio descriptor to gate this clock - * @flags: clock flags - */ -struct clk_hw *clk_hw_register_gpio_mux(struct device *dev, const char *name, - const char * const *parent_names, u8 num_parents, struct gpio_desc *gpiod, - unsigned long flags) -{ - if (num_parents != 2) { - pr_err("mux-clock %s must have 2 parents\n", name); - return ERR_PTR(-EINVAL); - } - - return clk_register_gpio(dev, name, parent_names, num_parents, - gpiod, flags, &clk_gpio_mux_ops); -} -EXPORT_SYMBOL_GPL(clk_hw_register_gpio_mux); - -struct clk *clk_register_gpio_mux(struct device *dev, const char *name, - const char * const *parent_names, u8 num_parents, struct gpio_desc *gpiod, - unsigned long flags) -{ - struct clk_hw *hw; - - hw = clk_hw_register_gpio_mux(dev, name, parent_names, num_parents, - gpiod, flags); - if (IS_ERR(hw)) - return ERR_CAST(hw); - return hw->clk; -} -EXPORT_SYMBOL_GPL(clk_register_gpio_mux); static int gpio_clk_driver_probe(struct platform_device *pdev) { - struct device_node *node = pdev->dev.of_node; - const char **parent_names, *gpio_name; + struct device *dev = &pdev->dev; + struct device_node *node = dev->of_node; + const char *gpio_name; unsigned int num_parents; struct gpio_desc *gpiod; - struct clk *clk; + struct clk_hw *hw; bool is_mux; int ret; + is_mux = of_device_is_compatible(node, "gpio-mux-clock"); + num_parents = of_clk_get_parent_count(node); - if (num_parents) { - parent_names = devm_kcalloc(&pdev->dev, num_parents, - sizeof(char *), GFP_KERNEL); - if (!parent_names) - return -ENOMEM; - - of_clk_parent_fill(node, parent_names, num_parents); - } else { - parent_names = NULL; + if (is_mux && num_parents != 2) { + dev_err(dev, "mux-clock must have 2 parents\n"); + return -EINVAL; } - is_mux = of_device_is_compatible(node, "gpio-mux-clock"); - gpio_name = is_mux ? "select" : "enable"; - gpiod = devm_gpiod_get(&pdev->dev, gpio_name, GPIOD_OUT_LOW); + gpiod = devm_gpiod_get(dev, gpio_name, GPIOD_OUT_LOW); if (IS_ERR(gpiod)) { ret = PTR_ERR(gpiod); if (ret == -EPROBE_DEFER) @@ -275,16 +224,13 @@ static int gpio_clk_driver_probe(struct platform_device *pdev) } if (is_mux) - clk = clk_register_gpio_mux(&pdev->dev, node->name, - parent_names, num_parents, gpiod, 0); + hw = clk_hw_register_gpio_mux(dev, gpiod); else - clk = clk_register_gpio_gate(&pdev->dev, node->name, - parent_names ? parent_names[0] : NULL, gpiod, - CLK_SET_RATE_PARENT); - if (IS_ERR(clk)) - return PTR_ERR(clk); + hw = clk_hw_register_gpio_gate(dev, num_parents, gpiod); + if (IS_ERR(hw)) + return PTR_ERR(hw); - return of_clk_add_provider(node, of_clk_src_simple_get, clk); + return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, hw); } static const struct of_device_id gpio_clk_match_table[] = { diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c index 570b6e5b603b..e54e79714818 100644 --- a/drivers/clk/clk-mux.c +++ b/drivers/clk/clk-mux.c @@ -145,17 +145,19 @@ const struct clk_ops clk_mux_ro_ops = { }; EXPORT_SYMBOL_GPL(clk_mux_ro_ops); -struct clk_hw *clk_hw_register_mux_table(struct device *dev, const char *name, - const char * const *parent_names, u8 num_parents, - unsigned long flags, - void __iomem *reg, u8 shift, u32 mask, +struct clk_hw *__clk_hw_register_mux(struct device *dev, struct device_node *np, + const char *name, u8 num_parents, + const char * const *parent_names, + const struct clk_hw **parent_hws, + const struct clk_parent_data *parent_data, + unsigned long flags, void __iomem *reg, u8 shift, u32 mask, u8 clk_mux_flags, u32 *table, spinlock_t *lock) { struct clk_mux *mux; struct clk_hw *hw; struct clk_init_data init = {}; u8 width = 0; - int ret; + int ret = -EINVAL; if (clk_mux_flags & CLK_MUX_HIWORD_MASK) { width = fls(mask) - ffs(mask) + 1; @@ -177,6 +179,8 @@ struct clk_hw *clk_hw_register_mux_table(struct device *dev, const char *name, init.ops = &clk_mux_ops; init.flags = flags; init.parent_names = parent_names; + init.parent_data = parent_data; + init.parent_hws = parent_hws; init.num_parents = num_parents; /* struct clk_mux assignments */ @@ -189,7 +193,10 @@ struct clk_hw *clk_hw_register_mux_table(struct device *dev, const char *name, mux->hw.init = &init; hw = &mux->hw; - ret = clk_hw_register(dev, hw); + if (dev || !np) + ret = clk_hw_register(dev, hw); + else if (np) + ret = of_clk_hw_register(np, hw); if (ret) { kfree(mux); hw = ERR_PTR(ret); @@ -197,53 +204,24 @@ struct clk_hw *clk_hw_register_mux_table(struct device *dev, const char *name, return hw; } -EXPORT_SYMBOL_GPL(clk_hw_register_mux_table); +EXPORT_SYMBOL_GPL(__clk_hw_register_mux); struct clk *clk_register_mux_table(struct device *dev, const char *name, const char * const *parent_names, u8 num_parents, - unsigned long flags, - void __iomem *reg, u8 shift, u32 mask, + unsigned long flags, void __iomem *reg, u8 shift, u32 mask, u8 clk_mux_flags, u32 *table, spinlock_t *lock) { struct clk_hw *hw; - hw = clk_hw_register_mux_table(dev, name, parent_names, num_parents, - flags, reg, shift, mask, clk_mux_flags, - table, lock); + hw = clk_hw_register_mux_table(dev, name, parent_names, + num_parents, flags, reg, shift, mask, + clk_mux_flags, table, lock); if (IS_ERR(hw)) return ERR_CAST(hw); return hw->clk; } EXPORT_SYMBOL_GPL(clk_register_mux_table); -struct clk *clk_register_mux(struct device *dev, const char *name, - const char * const *parent_names, u8 num_parents, - unsigned long flags, - void __iomem *reg, u8 shift, u8 width, - u8 clk_mux_flags, spinlock_t *lock) -{ - u32 mask = BIT(width) - 1; - - return clk_register_mux_table(dev, name, parent_names, num_parents, - flags, reg, shift, mask, clk_mux_flags, - NULL, lock); -} -EXPORT_SYMBOL_GPL(clk_register_mux); - -struct clk_hw *clk_hw_register_mux(struct device *dev, const char *name, - const char * const *parent_names, u8 num_parents, - unsigned long flags, - void __iomem *reg, u8 shift, u8 width, - u8 clk_mux_flags, spinlock_t *lock) -{ - u32 mask = BIT(width) - 1; - - return clk_hw_register_mux_table(dev, name, parent_names, num_parents, - flags, reg, shift, mask, clk_mux_flags, - NULL, lock); -} -EXPORT_SYMBOL_GPL(clk_hw_register_mux); - void clk_unregister_mux(struct clk *clk) { struct clk_mux *mux; diff --git a/drivers/clk/clk-plldig.c b/drivers/clk/clk-plldig.c new file mode 100644 index 000000000000..a5da08f98d01 --- /dev/null +++ b/drivers/clk/clk-plldig.c @@ -0,0 +1,286 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2019 NXP + * + * Clock driver for LS1028A Display output interfaces(LCD, DPHY). + */ + +#include <linux/clk-provider.h> +#include <linux/device.h> +#include <linux/module.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/iopoll.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <linux/bitfield.h> + +/* PLLDIG register offsets and bit masks */ +#define PLLDIG_REG_PLLSR 0x24 +#define PLLDIG_LOCK_MASK BIT(2) +#define PLLDIG_REG_PLLDV 0x28 +#define PLLDIG_MFD_MASK GENMASK(7, 0) +#define PLLDIG_RFDPHI1_MASK GENMASK(30, 25) +#define PLLDIG_REG_PLLFM 0x2c +#define PLLDIG_SSCGBYP_ENABLE BIT(30) +#define PLLDIG_REG_PLLFD 0x30 +#define PLLDIG_FDEN BIT(30) +#define PLLDIG_FRAC_MASK GENMASK(15, 0) +#define PLLDIG_REG_PLLCAL1 0x38 +#define PLLDIG_REG_PLLCAL2 0x3c + +/* Range of the VCO frequencies, in Hz */ +#define PLLDIG_MIN_VCO_FREQ 650000000 +#define PLLDIG_MAX_VCO_FREQ 1300000000 + +/* Range of the output frequencies, in Hz */ +#define PHI1_MIN_FREQ 27000000 +#define PHI1_MAX_FREQ 600000000 + +/* Maximum value of the reduced frequency divider */ +#define MAX_RFDPHI1 63UL + +/* Best value of multiplication factor divider */ +#define PLLDIG_DEFAULT_MFD 44 + +/* + * Denominator part of the fractional part of the + * loop multiplication factor. + */ +#define MFDEN 20480 + +static const struct clk_parent_data parent_data[] = { + { .index = 0 }, +}; + +struct clk_plldig { + struct clk_hw hw; + void __iomem *regs; + unsigned int vco_freq; +}; + +#define to_clk_plldig(_hw) container_of(_hw, struct clk_plldig, hw) + +static int plldig_enable(struct clk_hw *hw) +{ + struct clk_plldig *data = to_clk_plldig(hw); + u32 val; + + val = readl(data->regs + PLLDIG_REG_PLLFM); + /* + * Use Bypass mode with PLL off by default, the frequency overshoot + * detector output was disable. SSCG Bypass mode should be enable. + */ + val |= PLLDIG_SSCGBYP_ENABLE; + writel(val, data->regs + PLLDIG_REG_PLLFM); + + return 0; +} + +static void plldig_disable(struct clk_hw *hw) +{ + struct clk_plldig *data = to_clk_plldig(hw); + u32 val; + + val = readl(data->regs + PLLDIG_REG_PLLFM); + + val &= ~PLLDIG_SSCGBYP_ENABLE; + val |= FIELD_PREP(PLLDIG_SSCGBYP_ENABLE, 0x0); + + writel(val, data->regs + PLLDIG_REG_PLLFM); +} + +static int plldig_is_enabled(struct clk_hw *hw) +{ + struct clk_plldig *data = to_clk_plldig(hw); + + return readl(data->regs + PLLDIG_REG_PLLFM) & + PLLDIG_SSCGBYP_ENABLE; +} + +static unsigned long plldig_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_plldig *data = to_clk_plldig(hw); + u32 val, rfdphi1; + + val = readl(data->regs + PLLDIG_REG_PLLDV); + + /* Check if PLL is bypassed */ + if (val & PLLDIG_SSCGBYP_ENABLE) + return parent_rate; + + rfdphi1 = FIELD_GET(PLLDIG_RFDPHI1_MASK, val); + + /* + * If RFDPHI1 has a value of 1 the VCO frequency is also divided by + * one. + */ + if (!rfdphi1) + rfdphi1 = 1; + + return DIV_ROUND_UP(data->vco_freq, rfdphi1); +} + +static unsigned long plldig_calc_target_div(unsigned long vco_freq, + unsigned long target_rate) +{ + unsigned long div; + + div = DIV_ROUND_CLOSEST(vco_freq, target_rate); + div = clamp(div, 1UL, MAX_RFDPHI1); + + return div; +} + +static int plldig_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + struct clk_plldig *data = to_clk_plldig(hw); + unsigned int div; + + req->rate = clamp(req->rate, PHI1_MIN_FREQ, PHI1_MAX_FREQ); + div = plldig_calc_target_div(data->vco_freq, req->rate); + req->rate = DIV_ROUND_UP(data->vco_freq, div); + + return 0; +} + +static int plldig_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct clk_plldig *data = to_clk_plldig(hw); + unsigned int val, cond; + unsigned int rfdphi1; + + rate = clamp(rate, PHI1_MIN_FREQ, PHI1_MAX_FREQ); + rfdphi1 = plldig_calc_target_div(data->vco_freq, rate); + + /* update the divider value */ + val = readl(data->regs + PLLDIG_REG_PLLDV); + val &= ~PLLDIG_RFDPHI1_MASK; + val |= FIELD_PREP(PLLDIG_RFDPHI1_MASK, rfdphi1); + writel(val, data->regs + PLLDIG_REG_PLLDV); + + /* waiting for old lock state to clear */ + udelay(200); + + /* Wait until PLL is locked or timeout */ + return readl_poll_timeout_atomic(data->regs + PLLDIG_REG_PLLSR, cond, + cond & PLLDIG_LOCK_MASK, 0, + USEC_PER_MSEC); +} + +static const struct clk_ops plldig_clk_ops = { + .enable = plldig_enable, + .disable = plldig_disable, + .is_enabled = plldig_is_enabled, + .recalc_rate = plldig_recalc_rate, + .determine_rate = plldig_determine_rate, + .set_rate = plldig_set_rate, +}; + +static int plldig_init(struct clk_hw *hw) +{ + struct clk_plldig *data = to_clk_plldig(hw); + struct clk_hw *parent = clk_hw_get_parent(hw); + unsigned long parent_rate = clk_hw_get_rate(parent); + unsigned long val; + unsigned long long lltmp; + unsigned int mfd, fracdiv = 0; + + if (!parent) + return -EINVAL; + + if (data->vco_freq) { + mfd = data->vco_freq / parent_rate; + lltmp = data->vco_freq % parent_rate; + lltmp *= MFDEN; + do_div(lltmp, parent_rate); + fracdiv = lltmp; + } else { + mfd = PLLDIG_DEFAULT_MFD; + data->vco_freq = parent_rate * mfd; + } + + val = FIELD_PREP(PLLDIG_MFD_MASK, mfd); + writel(val, data->regs + PLLDIG_REG_PLLDV); + + /* Enable fractional divider */ + if (fracdiv) { + val = FIELD_PREP(PLLDIG_FRAC_MASK, fracdiv); + val |= PLLDIG_FDEN; + writel(val, data->regs + PLLDIG_REG_PLLFD); + } + + return 0; +} + +static int plldig_clk_probe(struct platform_device *pdev) +{ + struct clk_plldig *data; + struct device *dev = &pdev->dev; + int ret; + + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(data->regs)) + return PTR_ERR(data->regs); + + data->hw.init = CLK_HW_INIT_PARENTS_DATA("dpclk", + parent_data, + &plldig_clk_ops, + 0); + + ret = devm_clk_hw_register(dev, &data->hw); + if (ret) { + dev_err(dev, "failed to register %s clock\n", + dev->of_node->name); + return ret; + } + + ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, + &data->hw); + if (ret) { + dev_err(dev, "unable to add clk provider\n"); + return ret; + } + + /* + * The frequency of the VCO cannot be changed during runtime. + * Therefore, let the user specify a desired frequency. + */ + if (!of_property_read_u32(dev->of_node, "fsl,vco-hz", + &data->vco_freq)) { + if (data->vco_freq < PLLDIG_MIN_VCO_FREQ || + data->vco_freq > PLLDIG_MAX_VCO_FREQ) + return -EINVAL; + } + + return plldig_init(&data->hw); +} + +static const struct of_device_id plldig_clk_id[] = { + { .compatible = "fsl,ls1028a-plldig" }, + { } +}; +MODULE_DEVICE_TABLE(of, plldig_clk_id); + +static struct platform_driver plldig_clk_driver = { + .driver = { + .name = "plldig-clock", + .of_match_table = plldig_clk_id, + }, + .probe = plldig_clk_probe, +}; +module_platform_driver(plldig_clk_driver); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Wen He <wen.he_1@nxp.com>"); +MODULE_DESCRIPTION("LS1028A Display output interface pixel clock driver"); diff --git a/drivers/clk/clk-qoriq.c b/drivers/clk/clk-qoriq.c index bed140f7375f..d5946f7486d6 100644 --- a/drivers/clk/clk-qoriq.c +++ b/drivers/clk/clk-qoriq.c @@ -342,6 +342,32 @@ static const struct clockgen_muxinfo ls1046a_hwa2 = { }, }; +static const struct clockgen_muxinfo ls1088a_hwa1 = { + { + {}, + { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 }, + { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 }, + { CLKSEL_VALID, CGA_PLL1, PLL_DIV3 }, + { CLKSEL_VALID, CGA_PLL1, PLL_DIV4 }, + {}, + { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 }, + { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 }, + }, +}; + +static const struct clockgen_muxinfo ls1088a_hwa2 = { + { + {}, + { CLKSEL_VALID, CGA_PLL2, PLL_DIV1 }, + { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 }, + { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 }, + { CLKSEL_VALID, CGA_PLL2, PLL_DIV4 }, + {}, + { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 }, + { CLKSEL_VALID, CGA_PLL1, PLL_DIV3 }, + }, +}; + static const struct clockgen_muxinfo ls1012a_cmux = { { [0] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 }, @@ -607,6 +633,9 @@ static const struct clockgen_chipinfo chipinfo[] = { .cmux_groups = { &clockgen2_cmux_cga12 }, + .hwaccel = { + &ls1088a_hwa1, &ls1088a_hwa2 + }, .cmux_to_group = { 0, 0, -1 }, diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index b68e200829f2..d529ad67805c 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -2996,6 +2996,41 @@ static int clk_dump_show(struct seq_file *s, void *data) } DEFINE_SHOW_ATTRIBUTE(clk_dump); +#undef CLOCK_ALLOW_WRITE_DEBUGFS +#ifdef CLOCK_ALLOW_WRITE_DEBUGFS +/* + * This can be dangerous, therefore don't provide any real compile time + * configuration option for this feature. + * People who want to use this will need to modify the source code directly. + */ +static int clk_rate_set(void *data, u64 val) +{ + struct clk_core *core = data; + int ret; + + clk_prepare_lock(); + ret = clk_core_set_rate_nolock(core, val); + clk_prepare_unlock(); + + return ret; +} + +#define clk_rate_mode 0644 +#else +#define clk_rate_set NULL +#define clk_rate_mode 0444 +#endif + +static int clk_rate_get(void *data, u64 *val) +{ + struct clk_core *core = data; + + *val = core->rate; + return 0; +} + +DEFINE_DEBUGFS_ATTRIBUTE(clk_rate_fops, clk_rate_get, clk_rate_set, "%llu\n"); + static const struct { unsigned long flag; const char *name; @@ -3145,7 +3180,8 @@ static void clk_debug_create_one(struct clk_core *core, struct dentry *pdentry) root = debugfs_create_dir(core->name, pdentry); core->dentry = root; - debugfs_create_ulong("clk_rate", 0444, root, &core->rate); + debugfs_create_file("clk_rate", clk_rate_mode, root, core, + &clk_rate_fops); debugfs_create_file("clk_min_rate", 0444, root, core, &clk_min_rate_fops); debugfs_create_file("clk_max_rate", 0444, root, core, &clk_max_rate_fops); debugfs_create_ulong("clk_accuracy", 0444, root, &core->accuracy); @@ -3249,6 +3285,34 @@ static inline void clk_debug_unregister(struct clk_core *core) } #endif +static void clk_core_reparent_orphans_nolock(void) +{ + struct clk_core *orphan; + struct hlist_node *tmp2; + + /* + * walk the list of orphan clocks and reparent any that newly finds a + * parent. + */ + hlist_for_each_entry_safe(orphan, tmp2, &clk_orphan_list, child_node) { + struct clk_core *parent = __clk_init_parent(orphan); + + /* + * We need to use __clk_set_parent_before() and _after() to + * to properly migrate any prepare/enable count of the orphan + * clock. This is important for CLK_IS_CRITICAL clocks, which + * are enabled during init but might not have a parent yet. + */ + if (parent) { + /* update the clk tree topology */ + __clk_set_parent_before(orphan, parent); + __clk_set_parent_after(orphan, parent, NULL); + __clk_recalc_accuracies(orphan); + __clk_recalc_rates(orphan, 0); + } + } +} + /** * __clk_core_init - initialize the data structures in a struct clk_core * @core: clk_core being initialized @@ -3259,8 +3323,6 @@ static inline void clk_debug_unregister(struct clk_core *core) static int __clk_core_init(struct clk_core *core) { int ret; - struct clk_core *orphan; - struct hlist_node *tmp2; unsigned long rate; if (!core) @@ -3312,6 +3374,26 @@ static int __clk_core_init(struct clk_core *core) goto out; } + /* + * optional platform-specific magic + * + * The .init callback is not used by any of the basic clock types, but + * exists for weird hardware that must perform initialization magic for + * CCF to get an accurate view of clock for any other callbacks. It may + * also be used needs to perform dynamic allocations. Such allocation + * must be freed in the terminate() callback. + * This callback shall not be used to initialize the parameters state, + * such as rate, parent, etc ... + * + * If it exist, this callback should called before any other callback of + * the clock + */ + if (core->ops->init) { + ret = core->ops->init(core->hw); + if (ret) + goto out; + } + core->parent = __clk_init_parent(core); /* @@ -3337,17 +3419,6 @@ static int __clk_core_init(struct clk_core *core) } /* - * optional platform-specific magic - * - * The .init callback is not used by any of the basic clock types, but - * exists for weird hardware that must perform initialization magic. - * Please consider other ways of solving initialization problems before - * using this callback, as its use is discouraged. - */ - if (core->ops->init) - core->ops->init(core->hw); - - /* * Set clk's accuracy. The preferred method is to use * .recalc_accuracy. For simple clocks and lazy developers the default * fallback is to use the parent's accuracy. If a clock doesn't have a @@ -3400,34 +3471,26 @@ static int __clk_core_init(struct clk_core *core) if (core->flags & CLK_IS_CRITICAL) { unsigned long flags; - clk_core_prepare(core); + ret = clk_core_prepare(core); + if (ret) { + pr_warn("%s: critical clk '%s' failed to prepare\n", + __func__, core->name); + goto out; + } flags = clk_enable_lock(); - clk_core_enable(core); + ret = clk_core_enable(core); clk_enable_unlock(flags); + if (ret) { + pr_warn("%s: critical clk '%s' failed to enable\n", + __func__, core->name); + clk_core_unprepare(core); + goto out; + } } - /* - * walk the list of orphan clocks and reparent any that newly finds a - * parent. - */ - hlist_for_each_entry_safe(orphan, tmp2, &clk_orphan_list, child_node) { - struct clk_core *parent = __clk_init_parent(orphan); + clk_core_reparent_orphans_nolock(); - /* - * We need to use __clk_set_parent_before() and _after() to - * to properly migrate any prepare/enable count of the orphan - * clock. This is important for CLK_IS_CRITICAL clocks, which - * are enabled during init but might not have a parent yet. - */ - if (parent) { - /* update the clk tree topology */ - __clk_set_parent_before(orphan, parent); - __clk_set_parent_after(orphan, parent, NULL); - __clk_recalc_accuracies(orphan); - __clk_recalc_rates(orphan, 0); - } - } kref_init(&core->ref); out: @@ -3720,6 +3783,28 @@ fail_out: } /** + * dev_or_parent_of_node() - Get device node of @dev or @dev's parent + * @dev: Device to get device node of + * + * Return: device node pointer of @dev, or the device node pointer of + * @dev->parent if dev doesn't have a device node, or NULL if neither + * @dev or @dev->parent have a device node. + */ +static struct device_node *dev_or_parent_of_node(struct device *dev) +{ + struct device_node *np; + + if (!dev) + return NULL; + + np = dev_of_node(dev); + if (!np) + np = dev_of_node(dev->parent); + + return np; +} + +/** * clk_register - allocate a new clock, register it and return an opaque cookie * @dev: device that is registering this clock * @hw: link to hardware-specific clock data @@ -3734,7 +3819,7 @@ fail_out: */ struct clk *clk_register(struct device *dev, struct clk_hw *hw) { - return __clk_register(dev, dev_of_node(dev), hw); + return __clk_register(dev, dev_or_parent_of_node(dev), hw); } EXPORT_SYMBOL_GPL(clk_register); @@ -3750,7 +3835,8 @@ EXPORT_SYMBOL_GPL(clk_register); */ int clk_hw_register(struct device *dev, struct clk_hw *hw) { - return PTR_ERR_OR_ZERO(__clk_register(dev, dev_of_node(dev), hw)); + return PTR_ERR_OR_ZERO(__clk_register(dev, dev_or_parent_of_node(dev), + hw)); } EXPORT_SYMBOL_GPL(clk_hw_register); @@ -3853,6 +3939,7 @@ static void clk_core_evict_parent_cache(struct clk_core *core) void clk_unregister(struct clk *clk) { unsigned long flags; + const struct clk_ops *ops; if (!clk || WARN_ON_ONCE(IS_ERR(clk))) return; @@ -3861,7 +3948,8 @@ void clk_unregister(struct clk *clk) clk_prepare_lock(); - if (clk->core->ops == &clk_nodrv_ops) { + ops = clk->core->ops; + if (ops == &clk_nodrv_ops) { pr_err("%s: unregistered clock: %s\n", __func__, clk->core->name); goto unlock; @@ -3874,6 +3962,9 @@ void clk_unregister(struct clk *clk) clk->core->ops = &clk_nodrv_ops; clk_enable_unlock(flags); + if (ops->terminate) + ops->terminate(clk->core->hw); + if (!hlist_empty(&clk->core->children)) { struct clk_core *child; struct hlist_node *t; @@ -4179,6 +4270,13 @@ int clk_notifier_unregister(struct clk *clk, struct notifier_block *nb) EXPORT_SYMBOL_GPL(clk_notifier_unregister); #ifdef CONFIG_OF +static void clk_core_reparent_orphans(void) +{ + clk_prepare_lock(); + clk_core_reparent_orphans_nolock(); + clk_prepare_unlock(); +} + /** * struct of_clk_provider - Clock provider registration structure * @link: Entry in global list of clock providers @@ -4274,6 +4372,8 @@ int of_clk_add_provider(struct device_node *np, mutex_unlock(&of_clk_mutex); pr_debug("Added clock from %pOF\n", np); + clk_core_reparent_orphans(); + ret = of_clk_set_defaults(np, true); if (ret < 0) of_clk_del_provider(np); @@ -4309,6 +4409,8 @@ int of_clk_add_hw_provider(struct device_node *np, mutex_unlock(&of_clk_mutex); pr_debug("Added clk_hw provider from %pOF\n", np); + clk_core_reparent_orphans(); + ret = of_clk_set_defaults(np, true); if (ret < 0) of_clk_del_provider(np); diff --git a/drivers/clk/imx/Kconfig b/drivers/clk/imx/Kconfig index 1ac0c7990392..01eadee88d66 100644 --- a/drivers/clk/imx/Kconfig +++ b/drivers/clk/imx/Kconfig @@ -20,6 +20,12 @@ config CLK_IMX8MN help Build the driver for i.MX8MN CCM Clock Driver +config CLK_IMX8MP + bool "IMX8MP CCM Clock Driver" + depends on ARCH_MXC && ARM64 + help + Build the driver for i.MX8MP CCM Clock Driver + config CLK_IMX8MQ bool "IMX8MQ CCM Clock Driver" depends on ARCH_MXC && ARM64 diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile index 77a3d714f1d5..928f874c73d2 100644 --- a/drivers/clk/imx/Makefile +++ b/drivers/clk/imx/Makefile @@ -18,7 +18,7 @@ obj-$(CONFIG_MXC_CLK) += \ clk-pllv2.o \ clk-pllv3.o \ clk-pllv4.o \ - clk-sccg-pll.o \ + clk-sscg-pll.o \ clk-pll14xx.o obj-$(CONFIG_MXC_CLK_SCU) += \ @@ -27,6 +27,7 @@ obj-$(CONFIG_MXC_CLK_SCU) += \ obj-$(CONFIG_CLK_IMX8MM) += clk-imx8mm.o obj-$(CONFIG_CLK_IMX8MN) += clk-imx8mn.o +obj-$(CONFIG_CLK_IMX8MP) += clk-imx8mp.o obj-$(CONFIG_CLK_IMX8MQ) += clk-imx8mq.o obj-$(CONFIG_CLK_IMX8QXP) += clk-imx8qxp.o clk-imx8qxp-lpcg.o diff --git a/drivers/clk/imx/clk-composite-7ulp.c b/drivers/clk/imx/clk-composite-7ulp.c index 060f8600ea0d..b9efcc8a855d 100644 --- a/drivers/clk/imx/clk-composite-7ulp.c +++ b/drivers/clk/imx/clk-composite-7ulp.c @@ -21,7 +21,7 @@ #define PCG_PCD_WIDTH 3 #define PCG_PCD_MASK 0x7 -struct clk_hw *imx7ulp_clk_composite(const char *name, +struct clk_hw *imx7ulp_clk_hw_composite(const char *name, const char * const *parent_names, int num_parents, bool mux_present, bool rate_present, bool gate_present, diff --git a/drivers/clk/imx/clk-composite-8m.c b/drivers/clk/imx/clk-composite-8m.c index 388bdb94f841..20f7c91c03d2 100644 --- a/drivers/clk/imx/clk-composite-8m.c +++ b/drivers/clk/imx/clk-composite-8m.c @@ -123,7 +123,7 @@ static const struct clk_ops imx8m_clk_composite_divider_ops = { .set_rate = imx8m_clk_composite_divider_set_rate, }; -struct clk *imx8m_clk_composite_flags(const char *name, +struct clk_hw *imx8m_clk_hw_composite_flags(const char *name, const char * const *parent_names, int num_parents, void __iomem *reg, unsigned long flags) @@ -142,6 +142,7 @@ struct clk *imx8m_clk_composite_flags(const char *name, mux->reg = reg; mux->shift = PCG_PCS_SHIFT; mux->mask = PCG_PCS_MASK; + mux->lock = &imx_ccm_lock; div = kzalloc(sizeof(*div), GFP_KERNEL); if (!div) @@ -161,6 +162,7 @@ struct clk *imx8m_clk_composite_flags(const char *name, gate_hw = &gate->hw; gate->reg = reg; gate->bit_idx = PCG_CGC_SHIFT; + gate->lock = &imx_ccm_lock; hw = clk_hw_register_composite(NULL, name, parent_names, num_parents, mux_hw, &clk_mux_ops, div_hw, @@ -169,7 +171,7 @@ struct clk *imx8m_clk_composite_flags(const char *name, if (IS_ERR(hw)) goto fail; - return hw->clk; + return hw; fail: kfree(gate); diff --git a/drivers/clk/imx/clk-divider-gate.c b/drivers/clk/imx/clk-divider-gate.c index 2a8352a316c7..0322a843d245 100644 --- a/drivers/clk/imx/clk-divider-gate.c +++ b/drivers/clk/imx/clk-divider-gate.c @@ -43,7 +43,7 @@ static unsigned long clk_divider_gate_recalc_rate(struct clk_hw *hw, { struct clk_divider_gate *div_gate = to_clk_divider_gate(hw); struct clk_divider *div = to_clk_divider(hw); - unsigned long flags = 0; + unsigned long flags; unsigned int val; spin_lock_irqsave(div->lock, flags); @@ -75,7 +75,7 @@ static int clk_divider_gate_set_rate(struct clk_hw *hw, unsigned long rate, { struct clk_divider_gate *div_gate = to_clk_divider_gate(hw); struct clk_divider *div = to_clk_divider(hw); - unsigned long flags = 0; + unsigned long flags; int value; u32 val; @@ -104,7 +104,7 @@ static int clk_divider_enable(struct clk_hw *hw) { struct clk_divider_gate *div_gate = to_clk_divider_gate(hw); struct clk_divider *div = to_clk_divider(hw); - unsigned long flags = 0; + unsigned long flags; u32 val; if (!div_gate->cached_val) { @@ -127,7 +127,7 @@ static void clk_divider_disable(struct clk_hw *hw) { struct clk_divider_gate *div_gate = to_clk_divider_gate(hw); struct clk_divider *div = to_clk_divider(hw); - unsigned long flags = 0; + unsigned long flags; u32 val; spin_lock_irqsave(div->lock, flags); @@ -167,13 +167,13 @@ static const struct clk_ops clk_divider_gate_ops = { }; /* - * NOTE: In order to resue the most code from the common divider, + * NOTE: In order to reuse the most code from the common divider, * we also design our divider following the way that provids an extra * clk_divider_flags, however it's fixed to CLK_DIVIDER_ONE_BASED by * default as our HW is. Besides that it supports only CLK_DIVIDER_READ_ONLY * flag which can be specified by user flexibly. */ -struct clk_hw *imx_clk_divider_gate(const char *name, const char *parent_name, +struct clk_hw *imx_clk_hw_divider_gate(const char *name, const char *parent_name, unsigned long flags, void __iomem *reg, u8 shift, u8 width, u8 clk_divider_flags, const struct clk_div_table *table, diff --git a/drivers/clk/imx/clk-frac-pll.c b/drivers/clk/imx/clk-frac-pll.c index fece503e3610..101e0a300376 100644 --- a/drivers/clk/imx/clk-frac-pll.c +++ b/drivers/clk/imx/clk-frac-pll.c @@ -201,8 +201,9 @@ static const struct clk_ops clk_frac_pll_ops = { .set_rate = clk_pll_set_rate, }; -struct clk *imx_clk_frac_pll(const char *name, const char *parent_name, - void __iomem *base) +struct clk_hw *imx_clk_hw_frac_pll(const char *name, + const char *parent_name, + void __iomem *base) { struct clk_init_data init; struct clk_frac_pll *pll; @@ -230,5 +231,5 @@ struct clk *imx_clk_frac_pll(const char *name, const char *parent_name, return ERR_PTR(ret); } - return hw->clk; + return hw; } diff --git a/drivers/clk/imx/clk-imx6q.c b/drivers/clk/imx/clk-imx6q.c index 60f2de851f39..ba33c79158de 100644 --- a/drivers/clk/imx/clk-imx6q.c +++ b/drivers/clk/imx/clk-imx6q.c @@ -598,7 +598,10 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) } hws[IMX6QDL_CLK_PLL4_POST_DIV] = clk_hw_register_divider_table(NULL, "pll4_post_div", "pll4_audio", CLK_SET_RATE_PARENT, base + 0x70, 19, 2, 0, post_div_table, &imx_ccm_lock); - hws[IMX6QDL_CLK_PLL4_AUDIO_DIV] = clk_hw_register_divider(NULL, "pll4_audio_div", "pll4_post_div", CLK_SET_RATE_PARENT, base + 0x170, 15, 1, 0, &imx_ccm_lock); + if (clk_on_imx6q() || clk_on_imx6qp()) + hws[IMX6QDL_CLK_PLL4_AUDIO_DIV] = imx_clk_hw_fixed_factor("pll4_audio_div", "pll4_post_div", 1, 1); + else + hws[IMX6QDL_CLK_PLL4_AUDIO_DIV] = clk_hw_register_divider(NULL, "pll4_audio_div", "pll4_post_div", CLK_SET_RATE_PARENT, base + 0x170, 15, 1, 0, &imx_ccm_lock); hws[IMX6QDL_CLK_PLL5_POST_DIV] = clk_hw_register_divider_table(NULL, "pll5_post_div", "pll5_video", CLK_SET_RATE_PARENT, base + 0xa0, 19, 2, 0, post_div_table, &imx_ccm_lock); hws[IMX6QDL_CLK_PLL5_VIDEO_DIV] = clk_hw_register_divider_table(NULL, "pll5_video_div", "pll5_post_div", CLK_SET_RATE_PARENT, base + 0x170, 30, 2, 0, video_div_table, &imx_ccm_lock); diff --git a/drivers/clk/imx/clk-imx7ulp.c b/drivers/clk/imx/clk-imx7ulp.c index 3fdf3d494f0a..0620d6c8c072 100644 --- a/drivers/clk/imx/clk-imx7ulp.c +++ b/drivers/clk/imx/clk-imx7ulp.c @@ -40,6 +40,7 @@ static const struct clk_div_table ulp_div_table[] = { { .val = 5, .div = 16, }, { .val = 6, .div = 32, }, { .val = 7, .div = 64, }, + { /* sentinel */ }, }; static const int pcc2_uart_clk_ids[] __initconst = { @@ -58,7 +59,7 @@ static struct clk **pcc3_uart_clks[ARRAY_SIZE(pcc3_uart_clk_ids) + 1] __initdata static void __init imx7ulp_clk_scg1_init(struct device_node *np) { struct clk_hw_onecell_data *clk_data; - struct clk_hw **clks; + struct clk_hw **hws; void __iomem *base; clk_data = kzalloc(struct_size(clk_data, hws, IMX7ULP_CLK_SCG1_END), @@ -67,76 +68,76 @@ static void __init imx7ulp_clk_scg1_init(struct device_node *np) return; clk_data->num = IMX7ULP_CLK_SCG1_END; - clks = clk_data->hws; + hws = clk_data->hws; - clks[IMX7ULP_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0); + hws[IMX7ULP_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0); - clks[IMX7ULP_CLK_ROSC] = imx_obtain_fixed_clk_hw(np, "rosc"); - clks[IMX7ULP_CLK_SOSC] = imx_obtain_fixed_clk_hw(np, "sosc"); - clks[IMX7ULP_CLK_SIRC] = imx_obtain_fixed_clk_hw(np, "sirc"); - clks[IMX7ULP_CLK_FIRC] = imx_obtain_fixed_clk_hw(np, "firc"); - clks[IMX7ULP_CLK_UPLL] = imx_obtain_fixed_clk_hw(np, "upll"); + hws[IMX7ULP_CLK_ROSC] = imx_obtain_fixed_clk_hw(np, "rosc"); + hws[IMX7ULP_CLK_SOSC] = imx_obtain_fixed_clk_hw(np, "sosc"); + hws[IMX7ULP_CLK_SIRC] = imx_obtain_fixed_clk_hw(np, "sirc"); + hws[IMX7ULP_CLK_FIRC] = imx_obtain_fixed_clk_hw(np, "firc"); + hws[IMX7ULP_CLK_UPLL] = imx_obtain_fixed_clk_hw(np, "upll"); /* SCG1 */ base = of_iomap(np, 0); WARN_ON(!base); /* NOTE: xPLL config can't be changed when xPLL is enabled */ - clks[IMX7ULP_CLK_APLL_PRE_SEL] = imx_clk_hw_mux_flags("apll_pre_sel", base + 0x508, 0, 1, pll_pre_sels, ARRAY_SIZE(pll_pre_sels), CLK_SET_PARENT_GATE); - clks[IMX7ULP_CLK_SPLL_PRE_SEL] = imx_clk_hw_mux_flags("spll_pre_sel", base + 0x608, 0, 1, pll_pre_sels, ARRAY_SIZE(pll_pre_sels), CLK_SET_PARENT_GATE); + hws[IMX7ULP_CLK_APLL_PRE_SEL] = imx_clk_hw_mux_flags("apll_pre_sel", base + 0x508, 0, 1, pll_pre_sels, ARRAY_SIZE(pll_pre_sels), CLK_SET_PARENT_GATE); + hws[IMX7ULP_CLK_SPLL_PRE_SEL] = imx_clk_hw_mux_flags("spll_pre_sel", base + 0x608, 0, 1, pll_pre_sels, ARRAY_SIZE(pll_pre_sels), CLK_SET_PARENT_GATE); /* name parent_name reg shift width flags */ - clks[IMX7ULP_CLK_APLL_PRE_DIV] = imx_clk_hw_divider_flags("apll_pre_div", "apll_pre_sel", base + 0x508, 8, 3, CLK_SET_RATE_GATE); - clks[IMX7ULP_CLK_SPLL_PRE_DIV] = imx_clk_hw_divider_flags("spll_pre_div", "spll_pre_sel", base + 0x608, 8, 3, CLK_SET_RATE_GATE); + hws[IMX7ULP_CLK_APLL_PRE_DIV] = imx_clk_hw_divider_flags("apll_pre_div", "apll_pre_sel", base + 0x508, 8, 3, CLK_SET_RATE_GATE); + hws[IMX7ULP_CLK_SPLL_PRE_DIV] = imx_clk_hw_divider_flags("spll_pre_div", "spll_pre_sel", base + 0x608, 8, 3, CLK_SET_RATE_GATE); /* name parent_name base */ - clks[IMX7ULP_CLK_APLL] = imx_clk_pllv4("apll", "apll_pre_div", base + 0x500); - clks[IMX7ULP_CLK_SPLL] = imx_clk_pllv4("spll", "spll_pre_div", base + 0x600); + hws[IMX7ULP_CLK_APLL] = imx_clk_hw_pllv4("apll", "apll_pre_div", base + 0x500); + hws[IMX7ULP_CLK_SPLL] = imx_clk_hw_pllv4("spll", "spll_pre_div", base + 0x600); /* APLL PFDs */ - clks[IMX7ULP_CLK_APLL_PFD0] = imx_clk_pfdv2("apll_pfd0", "apll", base + 0x50c, 0); - clks[IMX7ULP_CLK_APLL_PFD1] = imx_clk_pfdv2("apll_pfd1", "apll", base + 0x50c, 1); - clks[IMX7ULP_CLK_APLL_PFD2] = imx_clk_pfdv2("apll_pfd2", "apll", base + 0x50c, 2); - clks[IMX7ULP_CLK_APLL_PFD3] = imx_clk_pfdv2("apll_pfd3", "apll", base + 0x50c, 3); + hws[IMX7ULP_CLK_APLL_PFD0] = imx_clk_hw_pfdv2("apll_pfd0", "apll", base + 0x50c, 0); + hws[IMX7ULP_CLK_APLL_PFD1] = imx_clk_hw_pfdv2("apll_pfd1", "apll", base + 0x50c, 1); + hws[IMX7ULP_CLK_APLL_PFD2] = imx_clk_hw_pfdv2("apll_pfd2", "apll", base + 0x50c, 2); + hws[IMX7ULP_CLK_APLL_PFD3] = imx_clk_hw_pfdv2("apll_pfd3", "apll", base + 0x50c, 3); /* SPLL PFDs */ - clks[IMX7ULP_CLK_SPLL_PFD0] = imx_clk_pfdv2("spll_pfd0", "spll", base + 0x60C, 0); - clks[IMX7ULP_CLK_SPLL_PFD1] = imx_clk_pfdv2("spll_pfd1", "spll", base + 0x60C, 1); - clks[IMX7ULP_CLK_SPLL_PFD2] = imx_clk_pfdv2("spll_pfd2", "spll", base + 0x60C, 2); - clks[IMX7ULP_CLK_SPLL_PFD3] = imx_clk_pfdv2("spll_pfd3", "spll", base + 0x60C, 3); + hws[IMX7ULP_CLK_SPLL_PFD0] = imx_clk_hw_pfdv2("spll_pfd0", "spll", base + 0x60C, 0); + hws[IMX7ULP_CLK_SPLL_PFD1] = imx_clk_hw_pfdv2("spll_pfd1", "spll", base + 0x60C, 1); + hws[IMX7ULP_CLK_SPLL_PFD2] = imx_clk_hw_pfdv2("spll_pfd2", "spll", base + 0x60C, 2); + hws[IMX7ULP_CLK_SPLL_PFD3] = imx_clk_hw_pfdv2("spll_pfd3", "spll", base + 0x60C, 3); /* PLL Mux */ - clks[IMX7ULP_CLK_APLL_PFD_SEL] = imx_clk_hw_mux_flags("apll_pfd_sel", base + 0x508, 14, 2, apll_pfd_sels, ARRAY_SIZE(apll_pfd_sels), CLK_SET_RATE_PARENT | CLK_SET_PARENT_GATE); - clks[IMX7ULP_CLK_SPLL_PFD_SEL] = imx_clk_hw_mux_flags("spll_pfd_sel", base + 0x608, 14, 2, spll_pfd_sels, ARRAY_SIZE(spll_pfd_sels), CLK_SET_RATE_PARENT | CLK_SET_PARENT_GATE); - clks[IMX7ULP_CLK_APLL_SEL] = imx_clk_hw_mux_flags("apll_sel", base + 0x508, 1, 1, apll_sels, ARRAY_SIZE(apll_sels), CLK_SET_RATE_PARENT | CLK_SET_PARENT_GATE); - clks[IMX7ULP_CLK_SPLL_SEL] = imx_clk_hw_mux_flags("spll_sel", base + 0x608, 1, 1, spll_sels, ARRAY_SIZE(spll_sels), CLK_SET_RATE_PARENT | CLK_SET_PARENT_GATE); + hws[IMX7ULP_CLK_APLL_PFD_SEL] = imx_clk_hw_mux_flags("apll_pfd_sel", base + 0x508, 14, 2, apll_pfd_sels, ARRAY_SIZE(apll_pfd_sels), CLK_SET_RATE_PARENT | CLK_SET_PARENT_GATE); + hws[IMX7ULP_CLK_SPLL_PFD_SEL] = imx_clk_hw_mux_flags("spll_pfd_sel", base + 0x608, 14, 2, spll_pfd_sels, ARRAY_SIZE(spll_pfd_sels), CLK_SET_RATE_PARENT | CLK_SET_PARENT_GATE); + hws[IMX7ULP_CLK_APLL_SEL] = imx_clk_hw_mux_flags("apll_sel", base + 0x508, 1, 1, apll_sels, ARRAY_SIZE(apll_sels), CLK_SET_RATE_PARENT | CLK_SET_PARENT_GATE); + hws[IMX7ULP_CLK_SPLL_SEL] = imx_clk_hw_mux_flags("spll_sel", base + 0x608, 1, 1, spll_sels, ARRAY_SIZE(spll_sels), CLK_SET_RATE_PARENT | CLK_SET_PARENT_GATE); - clks[IMX7ULP_CLK_SPLL_BUS_CLK] = imx_clk_divider_gate("spll_bus_clk", "spll_sel", CLK_SET_RATE_GATE, base + 0x604, 8, 3, 0, ulp_div_table, &imx_ccm_lock); + hws[IMX7ULP_CLK_SPLL_BUS_CLK] = imx_clk_hw_divider_gate("spll_bus_clk", "spll_sel", CLK_SET_RATE_GATE, base + 0x604, 8, 3, 0, ulp_div_table, &imx_ccm_lock); /* scs/ddr/nic select different clock source requires that clock to be enabled first */ - clks[IMX7ULP_CLK_SYS_SEL] = imx_clk_hw_mux2("scs_sel", base + 0x14, 24, 4, scs_sels, ARRAY_SIZE(scs_sels)); - clks[IMX7ULP_CLK_HSRUN_SYS_SEL] = imx_clk_hw_mux2("hsrun_scs_sel", base + 0x1c, 24, 4, scs_sels, ARRAY_SIZE(scs_sels)); - clks[IMX7ULP_CLK_NIC_SEL] = imx_clk_hw_mux2("nic_sel", base + 0x40, 28, 1, nic_sels, ARRAY_SIZE(nic_sels)); - clks[IMX7ULP_CLK_DDR_SEL] = imx_clk_hw_mux_flags("ddr_sel", base + 0x30, 24, 2, ddr_sels, ARRAY_SIZE(ddr_sels), CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE); + hws[IMX7ULP_CLK_SYS_SEL] = imx_clk_hw_mux2("scs_sel", base + 0x14, 24, 4, scs_sels, ARRAY_SIZE(scs_sels)); + hws[IMX7ULP_CLK_HSRUN_SYS_SEL] = imx_clk_hw_mux2("hsrun_scs_sel", base + 0x1c, 24, 4, scs_sels, ARRAY_SIZE(scs_sels)); + hws[IMX7ULP_CLK_NIC_SEL] = imx_clk_hw_mux2("nic_sel", base + 0x40, 28, 1, nic_sels, ARRAY_SIZE(nic_sels)); + hws[IMX7ULP_CLK_DDR_SEL] = imx_clk_hw_mux_flags("ddr_sel", base + 0x30, 24, 2, ddr_sels, ARRAY_SIZE(ddr_sels), CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE); - clks[IMX7ULP_CLK_CORE_DIV] = imx_clk_hw_divider_flags("divcore", "scs_sel", base + 0x14, 16, 4, CLK_SET_RATE_PARENT); - clks[IMX7ULP_CLK_HSRUN_CORE_DIV] = imx_clk_hw_divider_flags("hsrun_divcore", "hsrun_scs_sel", base + 0x1c, 16, 4, CLK_SET_RATE_PARENT); + hws[IMX7ULP_CLK_CORE_DIV] = imx_clk_hw_divider_flags("divcore", "scs_sel", base + 0x14, 16, 4, CLK_SET_RATE_PARENT); + hws[IMX7ULP_CLK_HSRUN_CORE_DIV] = imx_clk_hw_divider_flags("hsrun_divcore", "hsrun_scs_sel", base + 0x1c, 16, 4, CLK_SET_RATE_PARENT); - clks[IMX7ULP_CLK_DDR_DIV] = imx_clk_divider_gate("ddr_clk", "ddr_sel", CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, base + 0x30, 0, 3, + hws[IMX7ULP_CLK_DDR_DIV] = imx_clk_hw_divider_gate("ddr_clk", "ddr_sel", CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, base + 0x30, 0, 3, 0, ulp_div_table, &imx_ccm_lock); - clks[IMX7ULP_CLK_NIC0_DIV] = imx_clk_hw_divider_flags("nic0_clk", "nic_sel", base + 0x40, 24, 4, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL); - clks[IMX7ULP_CLK_NIC1_DIV] = imx_clk_hw_divider_flags("nic1_clk", "nic0_clk", base + 0x40, 16, 4, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL); - clks[IMX7ULP_CLK_NIC1_BUS_DIV] = imx_clk_hw_divider_flags("nic1_bus_clk", "nic0_clk", base + 0x40, 4, 4, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL); + hws[IMX7ULP_CLK_NIC0_DIV] = imx_clk_hw_divider_flags("nic0_clk", "nic_sel", base + 0x40, 24, 4, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL); + hws[IMX7ULP_CLK_NIC1_DIV] = imx_clk_hw_divider_flags("nic1_clk", "nic0_clk", base + 0x40, 16, 4, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL); + hws[IMX7ULP_CLK_NIC1_BUS_DIV] = imx_clk_hw_divider_flags("nic1_bus_clk", "nic0_clk", base + 0x40, 4, 4, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL); - clks[IMX7ULP_CLK_GPU_DIV] = imx_clk_hw_divider("gpu_clk", "nic0_clk", base + 0x40, 20, 4); + hws[IMX7ULP_CLK_GPU_DIV] = imx_clk_hw_divider("gpu_clk", "nic0_clk", base + 0x40, 20, 4); - clks[IMX7ULP_CLK_SOSC_BUS_CLK] = imx_clk_divider_gate("sosc_bus_clk", "sosc", 0, base + 0x104, 8, 3, + hws[IMX7ULP_CLK_SOSC_BUS_CLK] = imx_clk_hw_divider_gate("sosc_bus_clk", "sosc", 0, base + 0x104, 8, 3, CLK_DIVIDER_READ_ONLY, ulp_div_table, &imx_ccm_lock); - clks[IMX7ULP_CLK_FIRC_BUS_CLK] = imx_clk_divider_gate("firc_bus_clk", "firc", 0, base + 0x304, 8, 3, + hws[IMX7ULP_CLK_FIRC_BUS_CLK] = imx_clk_hw_divider_gate("firc_bus_clk", "firc", 0, base + 0x304, 8, 3, CLK_DIVIDER_READ_ONLY, ulp_div_table, &imx_ccm_lock); - imx_check_clk_hws(clks, clk_data->num); + imx_check_clk_hws(hws, clk_data->num); of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data); } @@ -145,7 +146,7 @@ CLK_OF_DECLARE(imx7ulp_clk_scg1, "fsl,imx7ulp-scg1", imx7ulp_clk_scg1_init); static void __init imx7ulp_clk_pcc2_init(struct device_node *np) { struct clk_hw_onecell_data *clk_data; - struct clk_hw **clks; + struct clk_hw **hws; void __iomem *base; int i; @@ -155,42 +156,42 @@ static void __init imx7ulp_clk_pcc2_init(struct device_node *np) return; clk_data->num = IMX7ULP_CLK_PCC2_END; - clks = clk_data->hws; + hws = clk_data->hws; /* PCC2 */ base = of_iomap(np, 0); WARN_ON(!base); - clks[IMX7ULP_CLK_DMA1] = imx_clk_hw_gate("dma1", "nic1_clk", base + 0x20, 30); - clks[IMX7ULP_CLK_RGPIO2P1] = imx_clk_hw_gate("rgpio2p1", "nic1_bus_clk", base + 0x3c, 30); - clks[IMX7ULP_CLK_DMA_MUX1] = imx_clk_hw_gate("dma_mux1", "nic1_bus_clk", base + 0x84, 30); - clks[IMX7ULP_CLK_CAAM] = imx_clk_hw_gate("caam", "nic1_clk", base + 0x90, 30); - clks[IMX7ULP_CLK_LPTPM4] = imx7ulp_clk_composite("lptpm4", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x94); - clks[IMX7ULP_CLK_LPTPM5] = imx7ulp_clk_composite("lptpm5", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x98); - clks[IMX7ULP_CLK_LPIT1] = imx7ulp_clk_composite("lpit1", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x9c); - clks[IMX7ULP_CLK_LPSPI2] = imx7ulp_clk_composite("lpspi2", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xa4); - clks[IMX7ULP_CLK_LPSPI3] = imx7ulp_clk_composite("lpspi3", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xa8); - clks[IMX7ULP_CLK_LPI2C4] = imx7ulp_clk_composite("lpi2c4", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xac); - clks[IMX7ULP_CLK_LPI2C5] = imx7ulp_clk_composite("lpi2c5", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xb0); - clks[IMX7ULP_CLK_LPUART4] = imx7ulp_clk_composite("lpuart4", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xb4); - clks[IMX7ULP_CLK_LPUART5] = imx7ulp_clk_composite("lpuart5", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xb8); - clks[IMX7ULP_CLK_FLEXIO1] = imx7ulp_clk_composite("flexio1", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xc4); - clks[IMX7ULP_CLK_USB0] = imx7ulp_clk_composite("usb0", periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, true, true, base + 0xcc); - clks[IMX7ULP_CLK_USB1] = imx7ulp_clk_composite("usb1", periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, true, true, base + 0xd0); - clks[IMX7ULP_CLK_USB_PHY] = imx_clk_hw_gate("usb_phy", "nic1_bus_clk", base + 0xd4, 30); - clks[IMX7ULP_CLK_USDHC0] = imx7ulp_clk_composite("usdhc0", periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, true, true, base + 0xdc); - clks[IMX7ULP_CLK_USDHC1] = imx7ulp_clk_composite("usdhc1", periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, true, true, base + 0xe0); - clks[IMX7ULP_CLK_WDG1] = imx7ulp_clk_composite("wdg1", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, true, true, base + 0xf4); - clks[IMX7ULP_CLK_WDG2] = imx7ulp_clk_composite("sdg2", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, true, true, base + 0x10c); - - imx_check_clk_hws(clks, clk_data->num); + hws[IMX7ULP_CLK_DMA1] = imx_clk_hw_gate("dma1", "nic1_clk", base + 0x20, 30); + hws[IMX7ULP_CLK_RGPIO2P1] = imx_clk_hw_gate("rgpio2p1", "nic1_bus_clk", base + 0x3c, 30); + hws[IMX7ULP_CLK_DMA_MUX1] = imx_clk_hw_gate("dma_mux1", "nic1_bus_clk", base + 0x84, 30); + hws[IMX7ULP_CLK_CAAM] = imx_clk_hw_gate("caam", "nic1_clk", base + 0x90, 30); + hws[IMX7ULP_CLK_LPTPM4] = imx7ulp_clk_hw_composite("lptpm4", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x94); + hws[IMX7ULP_CLK_LPTPM5] = imx7ulp_clk_hw_composite("lptpm5", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x98); + hws[IMX7ULP_CLK_LPIT1] = imx7ulp_clk_hw_composite("lpit1", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x9c); + hws[IMX7ULP_CLK_LPSPI2] = imx7ulp_clk_hw_composite("lpspi2", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xa4); + hws[IMX7ULP_CLK_LPSPI3] = imx7ulp_clk_hw_composite("lpspi3", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xa8); + hws[IMX7ULP_CLK_LPI2C4] = imx7ulp_clk_hw_composite("lpi2c4", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xac); + hws[IMX7ULP_CLK_LPI2C5] = imx7ulp_clk_hw_composite("lpi2c5", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xb0); + hws[IMX7ULP_CLK_LPUART4] = imx7ulp_clk_hw_composite("lpuart4", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xb4); + hws[IMX7ULP_CLK_LPUART5] = imx7ulp_clk_hw_composite("lpuart5", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xb8); + hws[IMX7ULP_CLK_FLEXIO1] = imx7ulp_clk_hw_composite("flexio1", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xc4); + hws[IMX7ULP_CLK_USB0] = imx7ulp_clk_hw_composite("usb0", periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, true, true, base + 0xcc); + hws[IMX7ULP_CLK_USB1] = imx7ulp_clk_hw_composite("usb1", periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, true, true, base + 0xd0); + hws[IMX7ULP_CLK_USB_PHY] = imx_clk_hw_gate("usb_phy", "nic1_bus_clk", base + 0xd4, 30); + hws[IMX7ULP_CLK_USDHC0] = imx7ulp_clk_hw_composite("usdhc0", periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, true, true, base + 0xdc); + hws[IMX7ULP_CLK_USDHC1] = imx7ulp_clk_hw_composite("usdhc1", periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, true, true, base + 0xe0); + hws[IMX7ULP_CLK_WDG1] = imx7ulp_clk_hw_composite("wdg1", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, true, true, base + 0xf4); + hws[IMX7ULP_CLK_WDG2] = imx7ulp_clk_hw_composite("wdg2", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, true, true, base + 0x10c); + + imx_check_clk_hws(hws, clk_data->num); of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data); for (i = 0; i < ARRAY_SIZE(pcc2_uart_clk_ids); i++) { int index = pcc2_uart_clk_ids[i]; - pcc2_uart_clks[i] = &clks[index]->clk; + pcc2_uart_clks[i] = &hws[index]->clk; } imx_register_uart_clocks(pcc2_uart_clks); @@ -200,7 +201,7 @@ CLK_OF_DECLARE(imx7ulp_clk_pcc2, "fsl,imx7ulp-pcc2", imx7ulp_clk_pcc2_init); static void __init imx7ulp_clk_pcc3_init(struct device_node *np) { struct clk_hw_onecell_data *clk_data; - struct clk_hw **clks; + struct clk_hw **hws; void __iomem *base; int i; @@ -210,41 +211,41 @@ static void __init imx7ulp_clk_pcc3_init(struct device_node *np) return; clk_data->num = IMX7ULP_CLK_PCC3_END; - clks = clk_data->hws; + hws = clk_data->hws; /* PCC3 */ base = of_iomap(np, 0); WARN_ON(!base); - clks[IMX7ULP_CLK_LPTPM6] = imx7ulp_clk_composite("lptpm6", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x84); - clks[IMX7ULP_CLK_LPTPM7] = imx7ulp_clk_composite("lptpm7", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x88); + hws[IMX7ULP_CLK_LPTPM6] = imx7ulp_clk_hw_composite("lptpm6", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x84); + hws[IMX7ULP_CLK_LPTPM7] = imx7ulp_clk_hw_composite("lptpm7", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x88); - clks[IMX7ULP_CLK_MMDC] = clk_hw_register_gate(NULL, "mmdc", "nic1_clk", CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, + hws[IMX7ULP_CLK_MMDC] = clk_hw_register_gate(NULL, "mmdc", "nic1_clk", CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, base + 0xac, 30, 0, &imx_ccm_lock); - clks[IMX7ULP_CLK_LPI2C6] = imx7ulp_clk_composite("lpi2c6", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x90); - clks[IMX7ULP_CLK_LPI2C7] = imx7ulp_clk_composite("lpi2c7", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x94); - clks[IMX7ULP_CLK_LPUART6] = imx7ulp_clk_composite("lpuart6", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x98); - clks[IMX7ULP_CLK_LPUART7] = imx7ulp_clk_composite("lpuart7", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x9c); - clks[IMX7ULP_CLK_DSI] = imx7ulp_clk_composite("dsi", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, true, true, base + 0xa4); - clks[IMX7ULP_CLK_LCDIF] = imx7ulp_clk_composite("lcdif", periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, true, true, base + 0xa8); + hws[IMX7ULP_CLK_LPI2C6] = imx7ulp_clk_hw_composite("lpi2c6", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x90); + hws[IMX7ULP_CLK_LPI2C7] = imx7ulp_clk_hw_composite("lpi2c7", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x94); + hws[IMX7ULP_CLK_LPUART6] = imx7ulp_clk_hw_composite("lpuart6", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x98); + hws[IMX7ULP_CLK_LPUART7] = imx7ulp_clk_hw_composite("lpuart7", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x9c); + hws[IMX7ULP_CLK_DSI] = imx7ulp_clk_hw_composite("dsi", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, true, true, base + 0xa4); + hws[IMX7ULP_CLK_LCDIF] = imx7ulp_clk_hw_composite("lcdif", periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, true, true, base + 0xa8); - clks[IMX7ULP_CLK_VIU] = imx_clk_hw_gate("viu", "nic1_clk", base + 0xa0, 30); - clks[IMX7ULP_CLK_PCTLC] = imx_clk_hw_gate("pctlc", "nic1_bus_clk", base + 0xb8, 30); - clks[IMX7ULP_CLK_PCTLD] = imx_clk_hw_gate("pctld", "nic1_bus_clk", base + 0xbc, 30); - clks[IMX7ULP_CLK_PCTLE] = imx_clk_hw_gate("pctle", "nic1_bus_clk", base + 0xc0, 30); - clks[IMX7ULP_CLK_PCTLF] = imx_clk_hw_gate("pctlf", "nic1_bus_clk", base + 0xc4, 30); + hws[IMX7ULP_CLK_VIU] = imx_clk_hw_gate("viu", "nic1_clk", base + 0xa0, 30); + hws[IMX7ULP_CLK_PCTLC] = imx_clk_hw_gate("pctlc", "nic1_bus_clk", base + 0xb8, 30); + hws[IMX7ULP_CLK_PCTLD] = imx_clk_hw_gate("pctld", "nic1_bus_clk", base + 0xbc, 30); + hws[IMX7ULP_CLK_PCTLE] = imx_clk_hw_gate("pctle", "nic1_bus_clk", base + 0xc0, 30); + hws[IMX7ULP_CLK_PCTLF] = imx_clk_hw_gate("pctlf", "nic1_bus_clk", base + 0xc4, 30); - clks[IMX7ULP_CLK_GPU3D] = imx7ulp_clk_composite("gpu3d", periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, false, true, base + 0x140); - clks[IMX7ULP_CLK_GPU2D] = imx7ulp_clk_composite("gpu2d", periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, false, true, base + 0x144); + hws[IMX7ULP_CLK_GPU3D] = imx7ulp_clk_hw_composite("gpu3d", periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, false, true, base + 0x140); + hws[IMX7ULP_CLK_GPU2D] = imx7ulp_clk_hw_composite("gpu2d", periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, false, true, base + 0x144); - imx_check_clk_hws(clks, clk_data->num); + imx_check_clk_hws(hws, clk_data->num); of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data); for (i = 0; i < ARRAY_SIZE(pcc3_uart_clk_ids); i++) { int index = pcc3_uart_clk_ids[i]; - pcc3_uart_clks[i] = &clks[index]->clk; + pcc3_uart_clks[i] = &hws[index]->clk; } imx_register_uart_clocks(pcc3_uart_clks); @@ -254,7 +255,7 @@ CLK_OF_DECLARE(imx7ulp_clk_pcc3, "fsl,imx7ulp-pcc3", imx7ulp_clk_pcc3_init); static void __init imx7ulp_clk_smc1_init(struct device_node *np) { struct clk_hw_onecell_data *clk_data; - struct clk_hw **clks; + struct clk_hw **hws; void __iomem *base; clk_data = kzalloc(struct_size(clk_data, hws, IMX7ULP_CLK_SMC1_END), @@ -263,15 +264,15 @@ static void __init imx7ulp_clk_smc1_init(struct device_node *np) return; clk_data->num = IMX7ULP_CLK_SMC1_END; - clks = clk_data->hws; + hws = clk_data->hws; /* SMC1 */ base = of_iomap(np, 0); WARN_ON(!base); - clks[IMX7ULP_CLK_ARM] = imx_clk_hw_mux_flags("arm", base + 0x10, 8, 2, arm_sels, ARRAY_SIZE(arm_sels), CLK_IS_CRITICAL); + hws[IMX7ULP_CLK_ARM] = imx_clk_hw_mux_flags("arm", base + 0x10, 8, 2, arm_sels, ARRAY_SIZE(arm_sels), CLK_IS_CRITICAL); - imx_check_clk_hws(clks, clk_data->num); + imx_check_clk_hws(hws, clk_data->num); of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data); } diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c index 030b15d7c0ce..2ed93fc25087 100644 --- a/drivers/clk/imx/clk-imx8mm.c +++ b/drivers/clk/imx/clk-imx8mm.c @@ -12,6 +12,7 @@ #include <linux/of.h> #include <linux/of_address.h> #include <linux/platform_device.h> +#include <linux/slab.h> #include <linux/types.h> #include "clk.h" @@ -285,118 +286,126 @@ static const char *imx8mm_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", } static const char *imx8mm_clko1_sels[] = {"osc_24m", "sys_pll1_800m", "osc_27m", "sys_pll1_200m", "audio_pll2_out", "vpu_pll", "sys_pll1_80m", }; -static struct clk *clks[IMX8MM_CLK_END]; -static struct clk_onecell_data clk_data; +static struct clk_hw_onecell_data *clk_hw_data; +static struct clk_hw **hws; -static struct clk ** const uart_clks[] = { - &clks[IMX8MM_CLK_UART1_ROOT], - &clks[IMX8MM_CLK_UART2_ROOT], - &clks[IMX8MM_CLK_UART3_ROOT], - &clks[IMX8MM_CLK_UART4_ROOT], - NULL +static const int uart_clk_ids[] = { + IMX8MM_CLK_UART1_ROOT, + IMX8MM_CLK_UART2_ROOT, + IMX8MM_CLK_UART3_ROOT, + IMX8MM_CLK_UART4_ROOT, }; +static struct clk **uart_hws[ARRAY_SIZE(uart_clk_ids) + 1]; static int imx8mm_clocks_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; void __iomem *base; - int ret; + int ret, i; - clks[IMX8MM_CLK_DUMMY] = imx_clk_fixed("dummy", 0); - clks[IMX8MM_CLK_24M] = of_clk_get_by_name(np, "osc_24m"); - clks[IMX8MM_CLK_32K] = of_clk_get_by_name(np, "osc_32k"); - clks[IMX8MM_CLK_EXT1] = of_clk_get_by_name(np, "clk_ext1"); - clks[IMX8MM_CLK_EXT2] = of_clk_get_by_name(np, "clk_ext2"); - clks[IMX8MM_CLK_EXT3] = of_clk_get_by_name(np, "clk_ext3"); - clks[IMX8MM_CLK_EXT4] = of_clk_get_by_name(np, "clk_ext4"); + clk_hw_data = kzalloc(struct_size(clk_hw_data, hws, + IMX8MM_CLK_END), GFP_KERNEL); + if (WARN_ON(!clk_hw_data)) + return -ENOMEM; + + clk_hw_data->num = IMX8MM_CLK_END; + hws = clk_hw_data->hws; + + hws[IMX8MM_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0); + hws[IMX8MM_CLK_24M] = imx_obtain_fixed_clk_hw(np, "osc_24m"); + hws[IMX8MM_CLK_32K] = imx_obtain_fixed_clk_hw(np, "osc_32k"); + hws[IMX8MM_CLK_EXT1] = imx_obtain_fixed_clk_hw(np, "clk_ext1"); + hws[IMX8MM_CLK_EXT2] = imx_obtain_fixed_clk_hw(np, "clk_ext2"); + hws[IMX8MM_CLK_EXT3] = imx_obtain_fixed_clk_hw(np, "clk_ext3"); + hws[IMX8MM_CLK_EXT4] = imx_obtain_fixed_clk_hw(np, "clk_ext4"); np = of_find_compatible_node(NULL, NULL, "fsl,imx8mm-anatop"); base = of_iomap(np, 0); if (WARN_ON(!base)) return -ENOMEM; - clks[IMX8MM_AUDIO_PLL1_REF_SEL] = imx_clk_mux("audio_pll1_ref_sel", base + 0x0, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); - clks[IMX8MM_AUDIO_PLL2_REF_SEL] = imx_clk_mux("audio_pll2_ref_sel", base + 0x14, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); - clks[IMX8MM_VIDEO_PLL1_REF_SEL] = imx_clk_mux("video_pll1_ref_sel", base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); - clks[IMX8MM_DRAM_PLL_REF_SEL] = imx_clk_mux("dram_pll_ref_sel", base + 0x50, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); - clks[IMX8MM_GPU_PLL_REF_SEL] = imx_clk_mux("gpu_pll_ref_sel", base + 0x64, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); - clks[IMX8MM_VPU_PLL_REF_SEL] = imx_clk_mux("vpu_pll_ref_sel", base + 0x74, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); - clks[IMX8MM_ARM_PLL_REF_SEL] = imx_clk_mux("arm_pll_ref_sel", base + 0x84, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); - clks[IMX8MM_SYS_PLL3_REF_SEL] = imx_clk_mux("sys_pll3_ref_sel", base + 0x114, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); - - clks[IMX8MM_AUDIO_PLL1] = imx_clk_pll14xx("audio_pll1", "audio_pll1_ref_sel", base, &imx_1443x_pll); - clks[IMX8MM_AUDIO_PLL2] = imx_clk_pll14xx("audio_pll2", "audio_pll2_ref_sel", base + 0x14, &imx_1443x_pll); - clks[IMX8MM_VIDEO_PLL1] = imx_clk_pll14xx("video_pll1", "video_pll1_ref_sel", base + 0x28, &imx_1443x_pll); - clks[IMX8MM_DRAM_PLL] = imx_clk_pll14xx("dram_pll", "dram_pll_ref_sel", base + 0x50, &imx_1443x_pll); - clks[IMX8MM_GPU_PLL] = imx_clk_pll14xx("gpu_pll", "gpu_pll_ref_sel", base + 0x64, &imx_1416x_pll); - clks[IMX8MM_VPU_PLL] = imx_clk_pll14xx("vpu_pll", "vpu_pll_ref_sel", base + 0x74, &imx_1416x_pll); - clks[IMX8MM_ARM_PLL] = imx_clk_pll14xx("arm_pll", "arm_pll_ref_sel", base + 0x84, &imx_1416x_pll); - clks[IMX8MM_SYS_PLL1] = imx_clk_fixed("sys_pll1", 800000000); - clks[IMX8MM_SYS_PLL2] = imx_clk_fixed("sys_pll2", 1000000000); - clks[IMX8MM_SYS_PLL3] = imx_clk_pll14xx("sys_pll3", "sys_pll3_ref_sel", base + 0x114, &imx_1416x_pll); + hws[IMX8MM_AUDIO_PLL1_REF_SEL] = imx_clk_hw_mux("audio_pll1_ref_sel", base + 0x0, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MM_AUDIO_PLL2_REF_SEL] = imx_clk_hw_mux("audio_pll2_ref_sel", base + 0x14, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MM_VIDEO_PLL1_REF_SEL] = imx_clk_hw_mux("video_pll1_ref_sel", base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MM_DRAM_PLL_REF_SEL] = imx_clk_hw_mux("dram_pll_ref_sel", base + 0x50, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MM_GPU_PLL_REF_SEL] = imx_clk_hw_mux("gpu_pll_ref_sel", base + 0x64, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MM_VPU_PLL_REF_SEL] = imx_clk_hw_mux("vpu_pll_ref_sel", base + 0x74, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MM_ARM_PLL_REF_SEL] = imx_clk_hw_mux("arm_pll_ref_sel", base + 0x84, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MM_SYS_PLL3_REF_SEL] = imx_clk_hw_mux("sys_pll3_ref_sel", base + 0x114, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + + hws[IMX8MM_AUDIO_PLL1] = imx_clk_hw_pll14xx("audio_pll1", "audio_pll1_ref_sel", base, &imx_1443x_pll); + hws[IMX8MM_AUDIO_PLL2] = imx_clk_hw_pll14xx("audio_pll2", "audio_pll2_ref_sel", base + 0x14, &imx_1443x_pll); + hws[IMX8MM_VIDEO_PLL1] = imx_clk_hw_pll14xx("video_pll1", "video_pll1_ref_sel", base + 0x28, &imx_1443x_pll); + hws[IMX8MM_DRAM_PLL] = imx_clk_hw_pll14xx("dram_pll", "dram_pll_ref_sel", base + 0x50, &imx_1443x_dram_pll); + hws[IMX8MM_GPU_PLL] = imx_clk_hw_pll14xx("gpu_pll", "gpu_pll_ref_sel", base + 0x64, &imx_1416x_pll); + hws[IMX8MM_VPU_PLL] = imx_clk_hw_pll14xx("vpu_pll", "vpu_pll_ref_sel", base + 0x74, &imx_1416x_pll); + hws[IMX8MM_ARM_PLL] = imx_clk_hw_pll14xx("arm_pll", "arm_pll_ref_sel", base + 0x84, &imx_1416x_pll); + hws[IMX8MM_SYS_PLL1] = imx_clk_hw_fixed("sys_pll1", 800000000); + hws[IMX8MM_SYS_PLL2] = imx_clk_hw_fixed("sys_pll2", 1000000000); + hws[IMX8MM_SYS_PLL3] = imx_clk_hw_pll14xx("sys_pll3", "sys_pll3_ref_sel", base + 0x114, &imx_1416x_pll); /* PLL bypass out */ - clks[IMX8MM_AUDIO_PLL1_BYPASS] = imx_clk_mux_flags("audio_pll1_bypass", base, 16, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT); - clks[IMX8MM_AUDIO_PLL2_BYPASS] = imx_clk_mux_flags("audio_pll2_bypass", base + 0x14, 16, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels), CLK_SET_RATE_PARENT); - clks[IMX8MM_VIDEO_PLL1_BYPASS] = imx_clk_mux_flags("video_pll1_bypass", base + 0x28, 16, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels), CLK_SET_RATE_PARENT); - clks[IMX8MM_DRAM_PLL_BYPASS] = imx_clk_mux_flags("dram_pll_bypass", base + 0x50, 16, 1, dram_pll_bypass_sels, ARRAY_SIZE(dram_pll_bypass_sels), CLK_SET_RATE_PARENT); - clks[IMX8MM_GPU_PLL_BYPASS] = imx_clk_mux_flags("gpu_pll_bypass", base + 0x64, 28, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT); - clks[IMX8MM_VPU_PLL_BYPASS] = imx_clk_mux_flags("vpu_pll_bypass", base + 0x74, 28, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels), CLK_SET_RATE_PARENT); - clks[IMX8MM_ARM_PLL_BYPASS] = imx_clk_mux_flags("arm_pll_bypass", base + 0x84, 28, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT); - clks[IMX8MM_SYS_PLL3_BYPASS] = imx_clk_mux_flags("sys_pll3_bypass", base + 0x114, 28, 1, sys_pll3_bypass_sels, ARRAY_SIZE(sys_pll3_bypass_sels), CLK_SET_RATE_PARENT); + hws[IMX8MM_AUDIO_PLL1_BYPASS] = imx_clk_hw_mux_flags("audio_pll1_bypass", base, 16, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT); + hws[IMX8MM_AUDIO_PLL2_BYPASS] = imx_clk_hw_mux_flags("audio_pll2_bypass", base + 0x14, 16, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels), CLK_SET_RATE_PARENT); + hws[IMX8MM_VIDEO_PLL1_BYPASS] = imx_clk_hw_mux_flags("video_pll1_bypass", base + 0x28, 16, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels), CLK_SET_RATE_PARENT); + hws[IMX8MM_DRAM_PLL_BYPASS] = imx_clk_hw_mux_flags("dram_pll_bypass", base + 0x50, 16, 1, dram_pll_bypass_sels, ARRAY_SIZE(dram_pll_bypass_sels), CLK_SET_RATE_PARENT); + hws[IMX8MM_GPU_PLL_BYPASS] = imx_clk_hw_mux_flags("gpu_pll_bypass", base + 0x64, 28, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT); + hws[IMX8MM_VPU_PLL_BYPASS] = imx_clk_hw_mux_flags("vpu_pll_bypass", base + 0x74, 28, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels), CLK_SET_RATE_PARENT); + hws[IMX8MM_ARM_PLL_BYPASS] = imx_clk_hw_mux_flags("arm_pll_bypass", base + 0x84, 28, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT); + hws[IMX8MM_SYS_PLL3_BYPASS] = imx_clk_hw_mux_flags("sys_pll3_bypass", base + 0x114, 28, 1, sys_pll3_bypass_sels, ARRAY_SIZE(sys_pll3_bypass_sels), CLK_SET_RATE_PARENT); /* PLL out gate */ - clks[IMX8MM_AUDIO_PLL1_OUT] = imx_clk_gate("audio_pll1_out", "audio_pll1_bypass", base, 13); - clks[IMX8MM_AUDIO_PLL2_OUT] = imx_clk_gate("audio_pll2_out", "audio_pll2_bypass", base + 0x14, 13); - clks[IMX8MM_VIDEO_PLL1_OUT] = imx_clk_gate("video_pll1_out", "video_pll1_bypass", base + 0x28, 13); - clks[IMX8MM_DRAM_PLL_OUT] = imx_clk_gate("dram_pll_out", "dram_pll_bypass", base + 0x50, 13); - clks[IMX8MM_GPU_PLL_OUT] = imx_clk_gate("gpu_pll_out", "gpu_pll_bypass", base + 0x64, 11); - clks[IMX8MM_VPU_PLL_OUT] = imx_clk_gate("vpu_pll_out", "vpu_pll_bypass", base + 0x74, 11); - clks[IMX8MM_ARM_PLL_OUT] = imx_clk_gate("arm_pll_out", "arm_pll_bypass", base + 0x84, 11); - clks[IMX8MM_SYS_PLL3_OUT] = imx_clk_gate("sys_pll3_out", "sys_pll3_bypass", base + 0x114, 11); + hws[IMX8MM_AUDIO_PLL1_OUT] = imx_clk_hw_gate("audio_pll1_out", "audio_pll1_bypass", base, 13); + hws[IMX8MM_AUDIO_PLL2_OUT] = imx_clk_hw_gate("audio_pll2_out", "audio_pll2_bypass", base + 0x14, 13); + hws[IMX8MM_VIDEO_PLL1_OUT] = imx_clk_hw_gate("video_pll1_out", "video_pll1_bypass", base + 0x28, 13); + hws[IMX8MM_DRAM_PLL_OUT] = imx_clk_hw_gate("dram_pll_out", "dram_pll_bypass", base + 0x50, 13); + hws[IMX8MM_GPU_PLL_OUT] = imx_clk_hw_gate("gpu_pll_out", "gpu_pll_bypass", base + 0x64, 11); + hws[IMX8MM_VPU_PLL_OUT] = imx_clk_hw_gate("vpu_pll_out", "vpu_pll_bypass", base + 0x74, 11); + hws[IMX8MM_ARM_PLL_OUT] = imx_clk_hw_gate("arm_pll_out", "arm_pll_bypass", base + 0x84, 11); + hws[IMX8MM_SYS_PLL3_OUT] = imx_clk_hw_gate("sys_pll3_out", "sys_pll3_bypass", base + 0x114, 11); /* SYS PLL1 fixed output */ - clks[IMX8MM_SYS_PLL1_40M_CG] = imx_clk_gate("sys_pll1_40m_cg", "sys_pll1", base + 0x94, 27); - clks[IMX8MM_SYS_PLL1_80M_CG] = imx_clk_gate("sys_pll1_80m_cg", "sys_pll1", base + 0x94, 25); - clks[IMX8MM_SYS_PLL1_100M_CG] = imx_clk_gate("sys_pll1_100m_cg", "sys_pll1", base + 0x94, 23); - clks[IMX8MM_SYS_PLL1_133M_CG] = imx_clk_gate("sys_pll1_133m_cg", "sys_pll1", base + 0x94, 21); - clks[IMX8MM_SYS_PLL1_160M_CG] = imx_clk_gate("sys_pll1_160m_cg", "sys_pll1", base + 0x94, 19); - clks[IMX8MM_SYS_PLL1_200M_CG] = imx_clk_gate("sys_pll1_200m_cg", "sys_pll1", base + 0x94, 17); - clks[IMX8MM_SYS_PLL1_266M_CG] = imx_clk_gate("sys_pll1_266m_cg", "sys_pll1", base + 0x94, 15); - clks[IMX8MM_SYS_PLL1_400M_CG] = imx_clk_gate("sys_pll1_400m_cg", "sys_pll1", base + 0x94, 13); - clks[IMX8MM_SYS_PLL1_OUT] = imx_clk_gate("sys_pll1_out", "sys_pll1", base + 0x94, 11); - - clks[IMX8MM_SYS_PLL1_40M] = imx_clk_fixed_factor("sys_pll1_40m", "sys_pll1_40m_cg", 1, 20); - clks[IMX8MM_SYS_PLL1_80M] = imx_clk_fixed_factor("sys_pll1_80m", "sys_pll1_80m_cg", 1, 10); - clks[IMX8MM_SYS_PLL1_100M] = imx_clk_fixed_factor("sys_pll1_100m", "sys_pll1_100m_cg", 1, 8); - clks[IMX8MM_SYS_PLL1_133M] = imx_clk_fixed_factor("sys_pll1_133m", "sys_pll1_133m_cg", 1, 6); - clks[IMX8MM_SYS_PLL1_160M] = imx_clk_fixed_factor("sys_pll1_160m", "sys_pll1_160m_cg", 1, 5); - clks[IMX8MM_SYS_PLL1_200M] = imx_clk_fixed_factor("sys_pll1_200m", "sys_pll1_200m_cg", 1, 4); - clks[IMX8MM_SYS_PLL1_266M] = imx_clk_fixed_factor("sys_pll1_266m", "sys_pll1_266m_cg", 1, 3); - clks[IMX8MM_SYS_PLL1_400M] = imx_clk_fixed_factor("sys_pll1_400m", "sys_pll1_400m_cg", 1, 2); - clks[IMX8MM_SYS_PLL1_800M] = imx_clk_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1, 1); + hws[IMX8MM_SYS_PLL1_40M_CG] = imx_clk_hw_gate("sys_pll1_40m_cg", "sys_pll1", base + 0x94, 27); + hws[IMX8MM_SYS_PLL1_80M_CG] = imx_clk_hw_gate("sys_pll1_80m_cg", "sys_pll1", base + 0x94, 25); + hws[IMX8MM_SYS_PLL1_100M_CG] = imx_clk_hw_gate("sys_pll1_100m_cg", "sys_pll1", base + 0x94, 23); + hws[IMX8MM_SYS_PLL1_133M_CG] = imx_clk_hw_gate("sys_pll1_133m_cg", "sys_pll1", base + 0x94, 21); + hws[IMX8MM_SYS_PLL1_160M_CG] = imx_clk_hw_gate("sys_pll1_160m_cg", "sys_pll1", base + 0x94, 19); + hws[IMX8MM_SYS_PLL1_200M_CG] = imx_clk_hw_gate("sys_pll1_200m_cg", "sys_pll1", base + 0x94, 17); + hws[IMX8MM_SYS_PLL1_266M_CG] = imx_clk_hw_gate("sys_pll1_266m_cg", "sys_pll1", base + 0x94, 15); + hws[IMX8MM_SYS_PLL1_400M_CG] = imx_clk_hw_gate("sys_pll1_400m_cg", "sys_pll1", base + 0x94, 13); + hws[IMX8MM_SYS_PLL1_OUT] = imx_clk_hw_gate("sys_pll1_out", "sys_pll1", base + 0x94, 11); + + hws[IMX8MM_SYS_PLL1_40M] = imx_clk_hw_fixed_factor("sys_pll1_40m", "sys_pll1_40m_cg", 1, 20); + hws[IMX8MM_SYS_PLL1_80M] = imx_clk_hw_fixed_factor("sys_pll1_80m", "sys_pll1_80m_cg", 1, 10); + hws[IMX8MM_SYS_PLL1_100M] = imx_clk_hw_fixed_factor("sys_pll1_100m", "sys_pll1_100m_cg", 1, 8); + hws[IMX8MM_SYS_PLL1_133M] = imx_clk_hw_fixed_factor("sys_pll1_133m", "sys_pll1_133m_cg", 1, 6); + hws[IMX8MM_SYS_PLL1_160M] = imx_clk_hw_fixed_factor("sys_pll1_160m", "sys_pll1_160m_cg", 1, 5); + hws[IMX8MM_SYS_PLL1_200M] = imx_clk_hw_fixed_factor("sys_pll1_200m", "sys_pll1_200m_cg", 1, 4); + hws[IMX8MM_SYS_PLL1_266M] = imx_clk_hw_fixed_factor("sys_pll1_266m", "sys_pll1_266m_cg", 1, 3); + hws[IMX8MM_SYS_PLL1_400M] = imx_clk_hw_fixed_factor("sys_pll1_400m", "sys_pll1_400m_cg", 1, 2); + hws[IMX8MM_SYS_PLL1_800M] = imx_clk_hw_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1, 1); /* SYS PLL2 fixed output */ - clks[IMX8MM_SYS_PLL2_50M_CG] = imx_clk_gate("sys_pll2_50m_cg", "sys_pll2", base + 0x104, 27); - clks[IMX8MM_SYS_PLL2_100M_CG] = imx_clk_gate("sys_pll2_100m_cg", "sys_pll2", base + 0x104, 25); - clks[IMX8MM_SYS_PLL2_125M_CG] = imx_clk_gate("sys_pll2_125m_cg", "sys_pll2", base + 0x104, 23); - clks[IMX8MM_SYS_PLL2_166M_CG] = imx_clk_gate("sys_pll2_166m_cg", "sys_pll2", base + 0x104, 21); - clks[IMX8MM_SYS_PLL2_200M_CG] = imx_clk_gate("sys_pll2_200m_cg", "sys_pll2", base + 0x104, 19); - clks[IMX8MM_SYS_PLL2_250M_CG] = imx_clk_gate("sys_pll2_250m_cg", "sys_pll2", base + 0x104, 17); - clks[IMX8MM_SYS_PLL2_333M_CG] = imx_clk_gate("sys_pll2_333m_cg", "sys_pll2", base + 0x104, 15); - clks[IMX8MM_SYS_PLL2_500M_CG] = imx_clk_gate("sys_pll2_500m_cg", "sys_pll2", base + 0x104, 13); - clks[IMX8MM_SYS_PLL2_OUT] = imx_clk_gate("sys_pll2_out", "sys_pll2", base + 0x104, 11); - - clks[IMX8MM_SYS_PLL2_50M] = imx_clk_fixed_factor("sys_pll2_50m", "sys_pll2_50m_cg", 1, 20); - clks[IMX8MM_SYS_PLL2_100M] = imx_clk_fixed_factor("sys_pll2_100m", "sys_pll2_100m_cg", 1, 10); - clks[IMX8MM_SYS_PLL2_125M] = imx_clk_fixed_factor("sys_pll2_125m", "sys_pll2_125m_cg", 1, 8); - clks[IMX8MM_SYS_PLL2_166M] = imx_clk_fixed_factor("sys_pll2_166m", "sys_pll2_166m_cg", 1, 6); - clks[IMX8MM_SYS_PLL2_200M] = imx_clk_fixed_factor("sys_pll2_200m", "sys_pll2_200m_cg", 1, 5); - clks[IMX8MM_SYS_PLL2_250M] = imx_clk_fixed_factor("sys_pll2_250m", "sys_pll2_250m_cg", 1, 4); - clks[IMX8MM_SYS_PLL2_333M] = imx_clk_fixed_factor("sys_pll2_333m", "sys_pll2_333m_cg", 1, 3); - clks[IMX8MM_SYS_PLL2_500M] = imx_clk_fixed_factor("sys_pll2_500m", "sys_pll2_500m_cg", 1, 2); - clks[IMX8MM_SYS_PLL2_1000M] = imx_clk_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1); + hws[IMX8MM_SYS_PLL2_50M_CG] = imx_clk_hw_gate("sys_pll2_50m_cg", "sys_pll2", base + 0x104, 27); + hws[IMX8MM_SYS_PLL2_100M_CG] = imx_clk_hw_gate("sys_pll2_100m_cg", "sys_pll2", base + 0x104, 25); + hws[IMX8MM_SYS_PLL2_125M_CG] = imx_clk_hw_gate("sys_pll2_125m_cg", "sys_pll2", base + 0x104, 23); + hws[IMX8MM_SYS_PLL2_166M_CG] = imx_clk_hw_gate("sys_pll2_166m_cg", "sys_pll2", base + 0x104, 21); + hws[IMX8MM_SYS_PLL2_200M_CG] = imx_clk_hw_gate("sys_pll2_200m_cg", "sys_pll2", base + 0x104, 19); + hws[IMX8MM_SYS_PLL2_250M_CG] = imx_clk_hw_gate("sys_pll2_250m_cg", "sys_pll2", base + 0x104, 17); + hws[IMX8MM_SYS_PLL2_333M_CG] = imx_clk_hw_gate("sys_pll2_333m_cg", "sys_pll2", base + 0x104, 15); + hws[IMX8MM_SYS_PLL2_500M_CG] = imx_clk_hw_gate("sys_pll2_500m_cg", "sys_pll2", base + 0x104, 13); + hws[IMX8MM_SYS_PLL2_OUT] = imx_clk_hw_gate("sys_pll2_out", "sys_pll2", base + 0x104, 11); + + hws[IMX8MM_SYS_PLL2_50M] = imx_clk_hw_fixed_factor("sys_pll2_50m", "sys_pll2_50m_cg", 1, 20); + hws[IMX8MM_SYS_PLL2_100M] = imx_clk_hw_fixed_factor("sys_pll2_100m", "sys_pll2_100m_cg", 1, 10); + hws[IMX8MM_SYS_PLL2_125M] = imx_clk_hw_fixed_factor("sys_pll2_125m", "sys_pll2_125m_cg", 1, 8); + hws[IMX8MM_SYS_PLL2_166M] = imx_clk_hw_fixed_factor("sys_pll2_166m", "sys_pll2_166m_cg", 1, 6); + hws[IMX8MM_SYS_PLL2_200M] = imx_clk_hw_fixed_factor("sys_pll2_200m", "sys_pll2_200m_cg", 1, 5); + hws[IMX8MM_SYS_PLL2_250M] = imx_clk_hw_fixed_factor("sys_pll2_250m", "sys_pll2_250m_cg", 1, 4); + hws[IMX8MM_SYS_PLL2_333M] = imx_clk_hw_fixed_factor("sys_pll2_333m", "sys_pll2_333m_cg", 1, 3); + hws[IMX8MM_SYS_PLL2_500M] = imx_clk_hw_fixed_factor("sys_pll2_500m", "sys_pll2_500m_cg", 1, 2); + hws[IMX8MM_SYS_PLL2_1000M] = imx_clk_hw_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1); np = dev->of_node; base = devm_platform_ioremap_resource(pdev, 0); @@ -404,204 +413,213 @@ static int imx8mm_clocks_probe(struct platform_device *pdev) return PTR_ERR(base); /* Core Slice */ - clks[IMX8MM_CLK_A53_SRC] = imx_clk_mux2("arm_a53_src", base + 0x8000, 24, 3, imx8mm_a53_sels, ARRAY_SIZE(imx8mm_a53_sels)); - clks[IMX8MM_CLK_M4_SRC] = imx_clk_mux2("arm_m4_src", base + 0x8080, 24, 3, imx8mm_m4_sels, ARRAY_SIZE(imx8mm_m4_sels)); - clks[IMX8MM_CLK_VPU_SRC] = imx_clk_mux2("vpu_src", base + 0x8100, 24, 3, imx8mm_vpu_sels, ARRAY_SIZE(imx8mm_vpu_sels)); - clks[IMX8MM_CLK_GPU3D_SRC] = imx_clk_mux2("gpu3d_src", base + 0x8180, 24, 3, imx8mm_gpu3d_sels, ARRAY_SIZE(imx8mm_gpu3d_sels)); - clks[IMX8MM_CLK_GPU2D_SRC] = imx_clk_mux2("gpu2d_src", base + 0x8200, 24, 3, imx8mm_gpu2d_sels, ARRAY_SIZE(imx8mm_gpu2d_sels)); - clks[IMX8MM_CLK_A53_CG] = imx_clk_gate3("arm_a53_cg", "arm_a53_src", base + 0x8000, 28); - clks[IMX8MM_CLK_M4_CG] = imx_clk_gate3("arm_m4_cg", "arm_m4_src", base + 0x8080, 28); - clks[IMX8MM_CLK_VPU_CG] = imx_clk_gate3("vpu_cg", "vpu_src", base + 0x8100, 28); - clks[IMX8MM_CLK_GPU3D_CG] = imx_clk_gate3("gpu3d_cg", "gpu3d_src", base + 0x8180, 28); - clks[IMX8MM_CLK_GPU2D_CG] = imx_clk_gate3("gpu2d_cg", "gpu2d_src", base + 0x8200, 28); - clks[IMX8MM_CLK_A53_DIV] = imx_clk_divider2("arm_a53_div", "arm_a53_cg", base + 0x8000, 0, 3); - clks[IMX8MM_CLK_M4_DIV] = imx_clk_divider2("arm_m4_div", "arm_m4_cg", base + 0x8080, 0, 3); - clks[IMX8MM_CLK_VPU_DIV] = imx_clk_divider2("vpu_div", "vpu_cg", base + 0x8100, 0, 3); - clks[IMX8MM_CLK_GPU3D_DIV] = imx_clk_divider2("gpu3d_div", "gpu3d_cg", base + 0x8180, 0, 3); - clks[IMX8MM_CLK_GPU2D_DIV] = imx_clk_divider2("gpu2d_div", "gpu2d_cg", base + 0x8200, 0, 3); + hws[IMX8MM_CLK_A53_SRC] = imx_clk_hw_mux2("arm_a53_src", base + 0x8000, 24, 3, imx8mm_a53_sels, ARRAY_SIZE(imx8mm_a53_sels)); + hws[IMX8MM_CLK_M4_SRC] = imx_clk_hw_mux2("arm_m4_src", base + 0x8080, 24, 3, imx8mm_m4_sels, ARRAY_SIZE(imx8mm_m4_sels)); + hws[IMX8MM_CLK_VPU_SRC] = imx_clk_hw_mux2("vpu_src", base + 0x8100, 24, 3, imx8mm_vpu_sels, ARRAY_SIZE(imx8mm_vpu_sels)); + hws[IMX8MM_CLK_GPU3D_SRC] = imx_clk_hw_mux2("gpu3d_src", base + 0x8180, 24, 3, imx8mm_gpu3d_sels, ARRAY_SIZE(imx8mm_gpu3d_sels)); + hws[IMX8MM_CLK_GPU2D_SRC] = imx_clk_hw_mux2("gpu2d_src", base + 0x8200, 24, 3, imx8mm_gpu2d_sels, ARRAY_SIZE(imx8mm_gpu2d_sels)); + hws[IMX8MM_CLK_A53_CG] = imx_clk_hw_gate3("arm_a53_cg", "arm_a53_src", base + 0x8000, 28); + hws[IMX8MM_CLK_M4_CG] = imx_clk_hw_gate3("arm_m4_cg", "arm_m4_src", base + 0x8080, 28); + hws[IMX8MM_CLK_VPU_CG] = imx_clk_hw_gate3("vpu_cg", "vpu_src", base + 0x8100, 28); + hws[IMX8MM_CLK_GPU3D_CG] = imx_clk_hw_gate3("gpu3d_cg", "gpu3d_src", base + 0x8180, 28); + hws[IMX8MM_CLK_GPU2D_CG] = imx_clk_hw_gate3("gpu2d_cg", "gpu2d_src", base + 0x8200, 28); + hws[IMX8MM_CLK_A53_DIV] = imx_clk_hw_divider2("arm_a53_div", "arm_a53_cg", base + 0x8000, 0, 3); + hws[IMX8MM_CLK_M4_DIV] = imx_clk_hw_divider2("arm_m4_div", "arm_m4_cg", base + 0x8080, 0, 3); + hws[IMX8MM_CLK_VPU_DIV] = imx_clk_hw_divider2("vpu_div", "vpu_cg", base + 0x8100, 0, 3); + hws[IMX8MM_CLK_GPU3D_DIV] = imx_clk_hw_divider2("gpu3d_div", "gpu3d_cg", base + 0x8180, 0, 3); + hws[IMX8MM_CLK_GPU2D_DIV] = imx_clk_hw_divider2("gpu2d_div", "gpu2d_cg", base + 0x8200, 0, 3); /* BUS */ - clks[IMX8MM_CLK_MAIN_AXI] = imx8m_clk_composite_critical("main_axi", imx8mm_main_axi_sels, base + 0x8800); - clks[IMX8MM_CLK_ENET_AXI] = imx8m_clk_composite("enet_axi", imx8mm_enet_axi_sels, base + 0x8880); - clks[IMX8MM_CLK_NAND_USDHC_BUS] = imx8m_clk_composite_critical("nand_usdhc_bus", imx8mm_nand_usdhc_sels, base + 0x8900); - clks[IMX8MM_CLK_VPU_BUS] = imx8m_clk_composite("vpu_bus", imx8mm_vpu_bus_sels, base + 0x8980); - clks[IMX8MM_CLK_DISP_AXI] = imx8m_clk_composite("disp_axi", imx8mm_disp_axi_sels, base + 0x8a00); - clks[IMX8MM_CLK_DISP_APB] = imx8m_clk_composite("disp_apb", imx8mm_disp_apb_sels, base + 0x8a80); - clks[IMX8MM_CLK_DISP_RTRM] = imx8m_clk_composite("disp_rtrm", imx8mm_disp_rtrm_sels, base + 0x8b00); - clks[IMX8MM_CLK_USB_BUS] = imx8m_clk_composite("usb_bus", imx8mm_usb_bus_sels, base + 0x8b80); - clks[IMX8MM_CLK_GPU_AXI] = imx8m_clk_composite("gpu_axi", imx8mm_gpu_axi_sels, base + 0x8c00); - clks[IMX8MM_CLK_GPU_AHB] = imx8m_clk_composite("gpu_ahb", imx8mm_gpu_ahb_sels, base + 0x8c80); - clks[IMX8MM_CLK_NOC] = imx8m_clk_composite_critical("noc", imx8mm_noc_sels, base + 0x8d00); - clks[IMX8MM_CLK_NOC_APB] = imx8m_clk_composite_critical("noc_apb", imx8mm_noc_apb_sels, base + 0x8d80); + hws[IMX8MM_CLK_MAIN_AXI] = imx8m_clk_hw_composite_critical("main_axi", imx8mm_main_axi_sels, base + 0x8800); + hws[IMX8MM_CLK_ENET_AXI] = imx8m_clk_hw_composite("enet_axi", imx8mm_enet_axi_sels, base + 0x8880); + hws[IMX8MM_CLK_NAND_USDHC_BUS] = imx8m_clk_hw_composite_critical("nand_usdhc_bus", imx8mm_nand_usdhc_sels, base + 0x8900); + hws[IMX8MM_CLK_VPU_BUS] = imx8m_clk_hw_composite("vpu_bus", imx8mm_vpu_bus_sels, base + 0x8980); + hws[IMX8MM_CLK_DISP_AXI] = imx8m_clk_hw_composite("disp_axi", imx8mm_disp_axi_sels, base + 0x8a00); + hws[IMX8MM_CLK_DISP_APB] = imx8m_clk_hw_composite("disp_apb", imx8mm_disp_apb_sels, base + 0x8a80); + hws[IMX8MM_CLK_DISP_RTRM] = imx8m_clk_hw_composite("disp_rtrm", imx8mm_disp_rtrm_sels, base + 0x8b00); + hws[IMX8MM_CLK_USB_BUS] = imx8m_clk_hw_composite("usb_bus", imx8mm_usb_bus_sels, base + 0x8b80); + hws[IMX8MM_CLK_GPU_AXI] = imx8m_clk_hw_composite("gpu_axi", imx8mm_gpu_axi_sels, base + 0x8c00); + hws[IMX8MM_CLK_GPU_AHB] = imx8m_clk_hw_composite("gpu_ahb", imx8mm_gpu_ahb_sels, base + 0x8c80); + hws[IMX8MM_CLK_NOC] = imx8m_clk_hw_composite_critical("noc", imx8mm_noc_sels, base + 0x8d00); + hws[IMX8MM_CLK_NOC_APB] = imx8m_clk_hw_composite_critical("noc_apb", imx8mm_noc_apb_sels, base + 0x8d80); /* AHB */ - clks[IMX8MM_CLK_AHB] = imx8m_clk_composite_critical("ahb", imx8mm_ahb_sels, base + 0x9000); - clks[IMX8MM_CLK_AUDIO_AHB] = imx8m_clk_composite("audio_ahb", imx8mm_audio_ahb_sels, base + 0x9100); + hws[IMX8MM_CLK_AHB] = imx8m_clk_hw_composite_critical("ahb", imx8mm_ahb_sels, base + 0x9000); + hws[IMX8MM_CLK_AUDIO_AHB] = imx8m_clk_hw_composite("audio_ahb", imx8mm_audio_ahb_sels, base + 0x9100); /* IPG */ - clks[IMX8MM_CLK_IPG_ROOT] = imx_clk_divider2("ipg_root", "ahb", base + 0x9080, 0, 1); - clks[IMX8MM_CLK_IPG_AUDIO_ROOT] = imx_clk_divider2("ipg_audio_root", "audio_ahb", base + 0x9180, 0, 1); + hws[IMX8MM_CLK_IPG_ROOT] = imx_clk_hw_divider2("ipg_root", "ahb", base + 0x9080, 0, 1); + hws[IMX8MM_CLK_IPG_AUDIO_ROOT] = imx_clk_hw_divider2("ipg_audio_root", "audio_ahb", base + 0x9180, 0, 1); + + /* + * DRAM clocks are manipulated from TF-A outside clock framework. + * Mark with GET_RATE_NOCACHE to always read div value from hardware + */ + hws[IMX8MM_CLK_DRAM_ALT] = __imx8m_clk_hw_composite("dram_alt", imx8mm_dram_alt_sels, base + 0xa000, CLK_GET_RATE_NOCACHE); + hws[IMX8MM_CLK_DRAM_APB] = __imx8m_clk_hw_composite("dram_apb", imx8mm_dram_apb_sels, base + 0xa080, CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE); /* IP */ - clks[IMX8MM_CLK_DRAM_ALT] = imx8m_clk_composite("dram_alt", imx8mm_dram_alt_sels, base + 0xa000); - clks[IMX8MM_CLK_DRAM_APB] = imx8m_clk_composite_critical("dram_apb", imx8mm_dram_apb_sels, base + 0xa080); - clks[IMX8MM_CLK_VPU_G1] = imx8m_clk_composite("vpu_g1", imx8mm_vpu_g1_sels, base + 0xa100); - clks[IMX8MM_CLK_VPU_G2] = imx8m_clk_composite("vpu_g2", imx8mm_vpu_g2_sels, base + 0xa180); - clks[IMX8MM_CLK_DISP_DTRC] = imx8m_clk_composite("disp_dtrc", imx8mm_disp_dtrc_sels, base + 0xa200); - clks[IMX8MM_CLK_DISP_DC8000] = imx8m_clk_composite("disp_dc8000", imx8mm_disp_dc8000_sels, base + 0xa280); - clks[IMX8MM_CLK_PCIE1_CTRL] = imx8m_clk_composite("pcie1_ctrl", imx8mm_pcie1_ctrl_sels, base + 0xa300); - clks[IMX8MM_CLK_PCIE1_PHY] = imx8m_clk_composite("pcie1_phy", imx8mm_pcie1_phy_sels, base + 0xa380); - clks[IMX8MM_CLK_PCIE1_AUX] = imx8m_clk_composite("pcie1_aux", imx8mm_pcie1_aux_sels, base + 0xa400); - clks[IMX8MM_CLK_DC_PIXEL] = imx8m_clk_composite("dc_pixel", imx8mm_dc_pixel_sels, base + 0xa480); - clks[IMX8MM_CLK_LCDIF_PIXEL] = imx8m_clk_composite("lcdif_pixel", imx8mm_lcdif_pixel_sels, base + 0xa500); - clks[IMX8MM_CLK_SAI1] = imx8m_clk_composite("sai1", imx8mm_sai1_sels, base + 0xa580); - clks[IMX8MM_CLK_SAI2] = imx8m_clk_composite("sai2", imx8mm_sai2_sels, base + 0xa600); - clks[IMX8MM_CLK_SAI3] = imx8m_clk_composite("sai3", imx8mm_sai3_sels, base + 0xa680); - clks[IMX8MM_CLK_SAI4] = imx8m_clk_composite("sai4", imx8mm_sai4_sels, base + 0xa700); - clks[IMX8MM_CLK_SAI5] = imx8m_clk_composite("sai5", imx8mm_sai5_sels, base + 0xa780); - clks[IMX8MM_CLK_SAI6] = imx8m_clk_composite("sai6", imx8mm_sai6_sels, base + 0xa800); - clks[IMX8MM_CLK_SPDIF1] = imx8m_clk_composite("spdif1", imx8mm_spdif1_sels, base + 0xa880); - clks[IMX8MM_CLK_SPDIF2] = imx8m_clk_composite("spdif2", imx8mm_spdif2_sels, base + 0xa900); - clks[IMX8MM_CLK_ENET_REF] = imx8m_clk_composite("enet_ref", imx8mm_enet_ref_sels, base + 0xa980); - clks[IMX8MM_CLK_ENET_TIMER] = imx8m_clk_composite("enet_timer", imx8mm_enet_timer_sels, base + 0xaa00); - clks[IMX8MM_CLK_ENET_PHY_REF] = imx8m_clk_composite("enet_phy", imx8mm_enet_phy_sels, base + 0xaa80); - clks[IMX8MM_CLK_NAND] = imx8m_clk_composite("nand", imx8mm_nand_sels, base + 0xab00); - clks[IMX8MM_CLK_QSPI] = imx8m_clk_composite("qspi", imx8mm_qspi_sels, base + 0xab80); - clks[IMX8MM_CLK_USDHC1] = imx8m_clk_composite("usdhc1", imx8mm_usdhc1_sels, base + 0xac00); - clks[IMX8MM_CLK_USDHC2] = imx8m_clk_composite("usdhc2", imx8mm_usdhc2_sels, base + 0xac80); - clks[IMX8MM_CLK_I2C1] = imx8m_clk_composite("i2c1", imx8mm_i2c1_sels, base + 0xad00); - clks[IMX8MM_CLK_I2C2] = imx8m_clk_composite("i2c2", imx8mm_i2c2_sels, base + 0xad80); - clks[IMX8MM_CLK_I2C3] = imx8m_clk_composite("i2c3", imx8mm_i2c3_sels, base + 0xae00); - clks[IMX8MM_CLK_I2C4] = imx8m_clk_composite("i2c4", imx8mm_i2c4_sels, base + 0xae80); - clks[IMX8MM_CLK_UART1] = imx8m_clk_composite("uart1", imx8mm_uart1_sels, base + 0xaf00); - clks[IMX8MM_CLK_UART2] = imx8m_clk_composite("uart2", imx8mm_uart2_sels, base + 0xaf80); - clks[IMX8MM_CLK_UART3] = imx8m_clk_composite("uart3", imx8mm_uart3_sels, base + 0xb000); - clks[IMX8MM_CLK_UART4] = imx8m_clk_composite("uart4", imx8mm_uart4_sels, base + 0xb080); - clks[IMX8MM_CLK_USB_CORE_REF] = imx8m_clk_composite("usb_core_ref", imx8mm_usb_core_sels, base + 0xb100); - clks[IMX8MM_CLK_USB_PHY_REF] = imx8m_clk_composite("usb_phy_ref", imx8mm_usb_phy_sels, base + 0xb180); - clks[IMX8MM_CLK_GIC] = imx8m_clk_composite_critical("gic", imx8mm_gic_sels, base + 0xb200); - clks[IMX8MM_CLK_ECSPI1] = imx8m_clk_composite("ecspi1", imx8mm_ecspi1_sels, base + 0xb280); - clks[IMX8MM_CLK_ECSPI2] = imx8m_clk_composite("ecspi2", imx8mm_ecspi2_sels, base + 0xb300); - clks[IMX8MM_CLK_PWM1] = imx8m_clk_composite("pwm1", imx8mm_pwm1_sels, base + 0xb380); - clks[IMX8MM_CLK_PWM2] = imx8m_clk_composite("pwm2", imx8mm_pwm2_sels, base + 0xb400); - clks[IMX8MM_CLK_PWM3] = imx8m_clk_composite("pwm3", imx8mm_pwm3_sels, base + 0xb480); - clks[IMX8MM_CLK_PWM4] = imx8m_clk_composite("pwm4", imx8mm_pwm4_sels, base + 0xb500); - clks[IMX8MM_CLK_GPT1] = imx8m_clk_composite("gpt1", imx8mm_gpt1_sels, base + 0xb580); - clks[IMX8MM_CLK_WDOG] = imx8m_clk_composite("wdog", imx8mm_wdog_sels, base + 0xb900); - clks[IMX8MM_CLK_WRCLK] = imx8m_clk_composite("wrclk", imx8mm_wrclk_sels, base + 0xb980); - clks[IMX8MM_CLK_CLKO1] = imx8m_clk_composite("clko1", imx8mm_clko1_sels, base + 0xba00); - clks[IMX8MM_CLK_DSI_CORE] = imx8m_clk_composite("dsi_core", imx8mm_dsi_core_sels, base + 0xbb00); - clks[IMX8MM_CLK_DSI_PHY_REF] = imx8m_clk_composite("dsi_phy_ref", imx8mm_dsi_phy_sels, base + 0xbb80); - clks[IMX8MM_CLK_DSI_DBI] = imx8m_clk_composite("dsi_dbi", imx8mm_dsi_dbi_sels, base + 0xbc00); - clks[IMX8MM_CLK_USDHC3] = imx8m_clk_composite("usdhc3", imx8mm_usdhc3_sels, base + 0xbc80); - clks[IMX8MM_CLK_CSI1_CORE] = imx8m_clk_composite("csi1_core", imx8mm_csi1_core_sels, base + 0xbd00); - clks[IMX8MM_CLK_CSI1_PHY_REF] = imx8m_clk_composite("csi1_phy_ref", imx8mm_csi1_phy_sels, base + 0xbd80); - clks[IMX8MM_CLK_CSI1_ESC] = imx8m_clk_composite("csi1_esc", imx8mm_csi1_esc_sels, base + 0xbe00); - clks[IMX8MM_CLK_CSI2_CORE] = imx8m_clk_composite("csi2_core", imx8mm_csi2_core_sels, base + 0xbe80); - clks[IMX8MM_CLK_CSI2_PHY_REF] = imx8m_clk_composite("csi2_phy_ref", imx8mm_csi2_phy_sels, base + 0xbf00); - clks[IMX8MM_CLK_CSI2_ESC] = imx8m_clk_composite("csi2_esc", imx8mm_csi2_esc_sels, base + 0xbf80); - clks[IMX8MM_CLK_PCIE2_CTRL] = imx8m_clk_composite("pcie2_ctrl", imx8mm_pcie2_ctrl_sels, base + 0xc000); - clks[IMX8MM_CLK_PCIE2_PHY] = imx8m_clk_composite("pcie2_phy", imx8mm_pcie2_phy_sels, base + 0xc080); - clks[IMX8MM_CLK_PCIE2_AUX] = imx8m_clk_composite("pcie2_aux", imx8mm_pcie2_aux_sels, base + 0xc100); - clks[IMX8MM_CLK_ECSPI3] = imx8m_clk_composite("ecspi3", imx8mm_ecspi3_sels, base + 0xc180); - clks[IMX8MM_CLK_PDM] = imx8m_clk_composite("pdm", imx8mm_pdm_sels, base + 0xc200); - clks[IMX8MM_CLK_VPU_H1] = imx8m_clk_composite("vpu_h1", imx8mm_vpu_h1_sels, base + 0xc280); + hws[IMX8MM_CLK_VPU_G1] = imx8m_clk_hw_composite("vpu_g1", imx8mm_vpu_g1_sels, base + 0xa100); + hws[IMX8MM_CLK_VPU_G2] = imx8m_clk_hw_composite("vpu_g2", imx8mm_vpu_g2_sels, base + 0xa180); + hws[IMX8MM_CLK_DISP_DTRC] = imx8m_clk_hw_composite("disp_dtrc", imx8mm_disp_dtrc_sels, base + 0xa200); + hws[IMX8MM_CLK_DISP_DC8000] = imx8m_clk_hw_composite("disp_dc8000", imx8mm_disp_dc8000_sels, base + 0xa280); + hws[IMX8MM_CLK_PCIE1_CTRL] = imx8m_clk_hw_composite("pcie1_ctrl", imx8mm_pcie1_ctrl_sels, base + 0xa300); + hws[IMX8MM_CLK_PCIE1_PHY] = imx8m_clk_hw_composite("pcie1_phy", imx8mm_pcie1_phy_sels, base + 0xa380); + hws[IMX8MM_CLK_PCIE1_AUX] = imx8m_clk_hw_composite("pcie1_aux", imx8mm_pcie1_aux_sels, base + 0xa400); + hws[IMX8MM_CLK_DC_PIXEL] = imx8m_clk_hw_composite("dc_pixel", imx8mm_dc_pixel_sels, base + 0xa480); + hws[IMX8MM_CLK_LCDIF_PIXEL] = imx8m_clk_hw_composite("lcdif_pixel", imx8mm_lcdif_pixel_sels, base + 0xa500); + hws[IMX8MM_CLK_SAI1] = imx8m_clk_hw_composite("sai1", imx8mm_sai1_sels, base + 0xa580); + hws[IMX8MM_CLK_SAI2] = imx8m_clk_hw_composite("sai2", imx8mm_sai2_sels, base + 0xa600); + hws[IMX8MM_CLK_SAI3] = imx8m_clk_hw_composite("sai3", imx8mm_sai3_sels, base + 0xa680); + hws[IMX8MM_CLK_SAI4] = imx8m_clk_hw_composite("sai4", imx8mm_sai4_sels, base + 0xa700); + hws[IMX8MM_CLK_SAI5] = imx8m_clk_hw_composite("sai5", imx8mm_sai5_sels, base + 0xa780); + hws[IMX8MM_CLK_SAI6] = imx8m_clk_hw_composite("sai6", imx8mm_sai6_sels, base + 0xa800); + hws[IMX8MM_CLK_SPDIF1] = imx8m_clk_hw_composite("spdif1", imx8mm_spdif1_sels, base + 0xa880); + hws[IMX8MM_CLK_SPDIF2] = imx8m_clk_hw_composite("spdif2", imx8mm_spdif2_sels, base + 0xa900); + hws[IMX8MM_CLK_ENET_REF] = imx8m_clk_hw_composite("enet_ref", imx8mm_enet_ref_sels, base + 0xa980); + hws[IMX8MM_CLK_ENET_TIMER] = imx8m_clk_hw_composite("enet_timer", imx8mm_enet_timer_sels, base + 0xaa00); + hws[IMX8MM_CLK_ENET_PHY_REF] = imx8m_clk_hw_composite("enet_phy", imx8mm_enet_phy_sels, base + 0xaa80); + hws[IMX8MM_CLK_NAND] = imx8m_clk_hw_composite("nand", imx8mm_nand_sels, base + 0xab00); + hws[IMX8MM_CLK_QSPI] = imx8m_clk_hw_composite("qspi", imx8mm_qspi_sels, base + 0xab80); + hws[IMX8MM_CLK_USDHC1] = imx8m_clk_hw_composite("usdhc1", imx8mm_usdhc1_sels, base + 0xac00); + hws[IMX8MM_CLK_USDHC2] = imx8m_clk_hw_composite("usdhc2", imx8mm_usdhc2_sels, base + 0xac80); + hws[IMX8MM_CLK_I2C1] = imx8m_clk_hw_composite("i2c1", imx8mm_i2c1_sels, base + 0xad00); + hws[IMX8MM_CLK_I2C2] = imx8m_clk_hw_composite("i2c2", imx8mm_i2c2_sels, base + 0xad80); + hws[IMX8MM_CLK_I2C3] = imx8m_clk_hw_composite("i2c3", imx8mm_i2c3_sels, base + 0xae00); + hws[IMX8MM_CLK_I2C4] = imx8m_clk_hw_composite("i2c4", imx8mm_i2c4_sels, base + 0xae80); + hws[IMX8MM_CLK_UART1] = imx8m_clk_hw_composite("uart1", imx8mm_uart1_sels, base + 0xaf00); + hws[IMX8MM_CLK_UART2] = imx8m_clk_hw_composite("uart2", imx8mm_uart2_sels, base + 0xaf80); + hws[IMX8MM_CLK_UART3] = imx8m_clk_hw_composite("uart3", imx8mm_uart3_sels, base + 0xb000); + hws[IMX8MM_CLK_UART4] = imx8m_clk_hw_composite("uart4", imx8mm_uart4_sels, base + 0xb080); + hws[IMX8MM_CLK_USB_CORE_REF] = imx8m_clk_hw_composite("usb_core_ref", imx8mm_usb_core_sels, base + 0xb100); + hws[IMX8MM_CLK_USB_PHY_REF] = imx8m_clk_hw_composite("usb_phy_ref", imx8mm_usb_phy_sels, base + 0xb180); + hws[IMX8MM_CLK_GIC] = imx8m_clk_hw_composite_critical("gic", imx8mm_gic_sels, base + 0xb200); + hws[IMX8MM_CLK_ECSPI1] = imx8m_clk_hw_composite("ecspi1", imx8mm_ecspi1_sels, base + 0xb280); + hws[IMX8MM_CLK_ECSPI2] = imx8m_clk_hw_composite("ecspi2", imx8mm_ecspi2_sels, base + 0xb300); + hws[IMX8MM_CLK_PWM1] = imx8m_clk_hw_composite("pwm1", imx8mm_pwm1_sels, base + 0xb380); + hws[IMX8MM_CLK_PWM2] = imx8m_clk_hw_composite("pwm2", imx8mm_pwm2_sels, base + 0xb400); + hws[IMX8MM_CLK_PWM3] = imx8m_clk_hw_composite("pwm3", imx8mm_pwm3_sels, base + 0xb480); + hws[IMX8MM_CLK_PWM4] = imx8m_clk_hw_composite("pwm4", imx8mm_pwm4_sels, base + 0xb500); + hws[IMX8MM_CLK_GPT1] = imx8m_clk_hw_composite("gpt1", imx8mm_gpt1_sels, base + 0xb580); + hws[IMX8MM_CLK_WDOG] = imx8m_clk_hw_composite("wdog", imx8mm_wdog_sels, base + 0xb900); + hws[IMX8MM_CLK_WRCLK] = imx8m_clk_hw_composite("wrclk", imx8mm_wrclk_sels, base + 0xb980); + hws[IMX8MM_CLK_CLKO1] = imx8m_clk_hw_composite("clko1", imx8mm_clko1_sels, base + 0xba00); + hws[IMX8MM_CLK_DSI_CORE] = imx8m_clk_hw_composite("dsi_core", imx8mm_dsi_core_sels, base + 0xbb00); + hws[IMX8MM_CLK_DSI_PHY_REF] = imx8m_clk_hw_composite("dsi_phy_ref", imx8mm_dsi_phy_sels, base + 0xbb80); + hws[IMX8MM_CLK_DSI_DBI] = imx8m_clk_hw_composite("dsi_dbi", imx8mm_dsi_dbi_sels, base + 0xbc00); + hws[IMX8MM_CLK_USDHC3] = imx8m_clk_hw_composite("usdhc3", imx8mm_usdhc3_sels, base + 0xbc80); + hws[IMX8MM_CLK_CSI1_CORE] = imx8m_clk_hw_composite("csi1_core", imx8mm_csi1_core_sels, base + 0xbd00); + hws[IMX8MM_CLK_CSI1_PHY_REF] = imx8m_clk_hw_composite("csi1_phy_ref", imx8mm_csi1_phy_sels, base + 0xbd80); + hws[IMX8MM_CLK_CSI1_ESC] = imx8m_clk_hw_composite("csi1_esc", imx8mm_csi1_esc_sels, base + 0xbe00); + hws[IMX8MM_CLK_CSI2_CORE] = imx8m_clk_hw_composite("csi2_core", imx8mm_csi2_core_sels, base + 0xbe80); + hws[IMX8MM_CLK_CSI2_PHY_REF] = imx8m_clk_hw_composite("csi2_phy_ref", imx8mm_csi2_phy_sels, base + 0xbf00); + hws[IMX8MM_CLK_CSI2_ESC] = imx8m_clk_hw_composite("csi2_esc", imx8mm_csi2_esc_sels, base + 0xbf80); + hws[IMX8MM_CLK_PCIE2_CTRL] = imx8m_clk_hw_composite("pcie2_ctrl", imx8mm_pcie2_ctrl_sels, base + 0xc000); + hws[IMX8MM_CLK_PCIE2_PHY] = imx8m_clk_hw_composite("pcie2_phy", imx8mm_pcie2_phy_sels, base + 0xc080); + hws[IMX8MM_CLK_PCIE2_AUX] = imx8m_clk_hw_composite("pcie2_aux", imx8mm_pcie2_aux_sels, base + 0xc100); + hws[IMX8MM_CLK_ECSPI3] = imx8m_clk_hw_composite("ecspi3", imx8mm_ecspi3_sels, base + 0xc180); + hws[IMX8MM_CLK_PDM] = imx8m_clk_hw_composite("pdm", imx8mm_pdm_sels, base + 0xc200); + hws[IMX8MM_CLK_VPU_H1] = imx8m_clk_hw_composite("vpu_h1", imx8mm_vpu_h1_sels, base + 0xc280); /* CCGR */ - clks[IMX8MM_CLK_ECSPI1_ROOT] = imx_clk_gate4("ecspi1_root_clk", "ecspi1", base + 0x4070, 0); - clks[IMX8MM_CLK_ECSPI2_ROOT] = imx_clk_gate4("ecspi2_root_clk", "ecspi2", base + 0x4080, 0); - clks[IMX8MM_CLK_ECSPI3_ROOT] = imx_clk_gate4("ecspi3_root_clk", "ecspi3", base + 0x4090, 0); - clks[IMX8MM_CLK_ENET1_ROOT] = imx_clk_gate4("enet1_root_clk", "enet_axi", base + 0x40a0, 0); - clks[IMX8MM_CLK_GPIO1_ROOT] = imx_clk_gate4("gpio1_root_clk", "ipg_root", base + 0x40b0, 0); - clks[IMX8MM_CLK_GPIO2_ROOT] = imx_clk_gate4("gpio2_root_clk", "ipg_root", base + 0x40c0, 0); - clks[IMX8MM_CLK_GPIO3_ROOT] = imx_clk_gate4("gpio3_root_clk", "ipg_root", base + 0x40d0, 0); - clks[IMX8MM_CLK_GPIO4_ROOT] = imx_clk_gate4("gpio4_root_clk", "ipg_root", base + 0x40e0, 0); - clks[IMX8MM_CLK_GPIO5_ROOT] = imx_clk_gate4("gpio5_root_clk", "ipg_root", base + 0x40f0, 0); - clks[IMX8MM_CLK_GPT1_ROOT] = imx_clk_gate4("gpt1_root_clk", "gpt1", base + 0x4100, 0); - clks[IMX8MM_CLK_I2C1_ROOT] = imx_clk_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0); - clks[IMX8MM_CLK_I2C2_ROOT] = imx_clk_gate4("i2c2_root_clk", "i2c2", base + 0x4180, 0); - clks[IMX8MM_CLK_I2C3_ROOT] = imx_clk_gate4("i2c3_root_clk", "i2c3", base + 0x4190, 0); - clks[IMX8MM_CLK_I2C4_ROOT] = imx_clk_gate4("i2c4_root_clk", "i2c4", base + 0x41a0, 0); - clks[IMX8MM_CLK_MU_ROOT] = imx_clk_gate4("mu_root_clk", "ipg_root", base + 0x4210, 0); - clks[IMX8MM_CLK_OCOTP_ROOT] = imx_clk_gate4("ocotp_root_clk", "ipg_root", base + 0x4220, 0); - clks[IMX8MM_CLK_PCIE1_ROOT] = imx_clk_gate4("pcie1_root_clk", "pcie1_ctrl", base + 0x4250, 0); - clks[IMX8MM_CLK_PWM1_ROOT] = imx_clk_gate4("pwm1_root_clk", "pwm1", base + 0x4280, 0); - clks[IMX8MM_CLK_PWM2_ROOT] = imx_clk_gate4("pwm2_root_clk", "pwm2", base + 0x4290, 0); - clks[IMX8MM_CLK_PWM3_ROOT] = imx_clk_gate4("pwm3_root_clk", "pwm3", base + 0x42a0, 0); - clks[IMX8MM_CLK_PWM4_ROOT] = imx_clk_gate4("pwm4_root_clk", "pwm4", base + 0x42b0, 0); - clks[IMX8MM_CLK_QSPI_ROOT] = imx_clk_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0); - clks[IMX8MM_CLK_NAND_ROOT] = imx_clk_gate2_shared2("nand_root_clk", "nand", base + 0x4300, 0, &share_count_nand); - clks[IMX8MM_CLK_NAND_USDHC_BUS_RAWNAND_CLK] = imx_clk_gate2_shared2("nand_usdhc_rawnand_clk", "nand_usdhc_bus", base + 0x4300, 0, &share_count_nand); - clks[IMX8MM_CLK_SAI1_ROOT] = imx_clk_gate2_shared2("sai1_root_clk", "sai1", base + 0x4330, 0, &share_count_sai1); - clks[IMX8MM_CLK_SAI1_IPG] = imx_clk_gate2_shared2("sai1_ipg_clk", "ipg_audio_root", base + 0x4330, 0, &share_count_sai1); - clks[IMX8MM_CLK_SAI2_ROOT] = imx_clk_gate2_shared2("sai2_root_clk", "sai2", base + 0x4340, 0, &share_count_sai2); - clks[IMX8MM_CLK_SAI2_IPG] = imx_clk_gate2_shared2("sai2_ipg_clk", "ipg_audio_root", base + 0x4340, 0, &share_count_sai2); - clks[IMX8MM_CLK_SAI3_ROOT] = imx_clk_gate2_shared2("sai3_root_clk", "sai3", base + 0x4350, 0, &share_count_sai3); - clks[IMX8MM_CLK_SAI3_IPG] = imx_clk_gate2_shared2("sai3_ipg_clk", "ipg_audio_root", base + 0x4350, 0, &share_count_sai3); - clks[IMX8MM_CLK_SAI4_ROOT] = imx_clk_gate2_shared2("sai4_root_clk", "sai4", base + 0x4360, 0, &share_count_sai4); - clks[IMX8MM_CLK_SAI4_IPG] = imx_clk_gate2_shared2("sai4_ipg_clk", "ipg_audio_root", base + 0x4360, 0, &share_count_sai4); - clks[IMX8MM_CLK_SAI5_ROOT] = imx_clk_gate2_shared2("sai5_root_clk", "sai5", base + 0x4370, 0, &share_count_sai5); - clks[IMX8MM_CLK_SAI5_IPG] = imx_clk_gate2_shared2("sai5_ipg_clk", "ipg_audio_root", base + 0x4370, 0, &share_count_sai5); - clks[IMX8MM_CLK_SAI6_ROOT] = imx_clk_gate2_shared2("sai6_root_clk", "sai6", base + 0x4380, 0, &share_count_sai6); - clks[IMX8MM_CLK_SAI6_IPG] = imx_clk_gate2_shared2("sai6_ipg_clk", "ipg_audio_root", base + 0x4380, 0, &share_count_sai6); - clks[IMX8MM_CLK_SNVS_ROOT] = imx_clk_gate4("snvs_root_clk", "ipg_root", base + 0x4470, 0); - clks[IMX8MM_CLK_UART1_ROOT] = imx_clk_gate4("uart1_root_clk", "uart1", base + 0x4490, 0); - clks[IMX8MM_CLK_UART2_ROOT] = imx_clk_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0); - clks[IMX8MM_CLK_UART3_ROOT] = imx_clk_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0); - clks[IMX8MM_CLK_UART4_ROOT] = imx_clk_gate4("uart4_root_clk", "uart4", base + 0x44c0, 0); - clks[IMX8MM_CLK_USB1_CTRL_ROOT] = imx_clk_gate4("usb1_ctrl_root_clk", "usb_bus", base + 0x44d0, 0); - clks[IMX8MM_CLK_GPU3D_ROOT] = imx_clk_gate4("gpu3d_root_clk", "gpu3d_div", base + 0x44f0, 0); - clks[IMX8MM_CLK_USDHC1_ROOT] = imx_clk_gate4("usdhc1_root_clk", "usdhc1", base + 0x4510, 0); - clks[IMX8MM_CLK_USDHC2_ROOT] = imx_clk_gate4("usdhc2_root_clk", "usdhc2", base + 0x4520, 0); - clks[IMX8MM_CLK_WDOG1_ROOT] = imx_clk_gate4("wdog1_root_clk", "wdog", base + 0x4530, 0); - clks[IMX8MM_CLK_WDOG2_ROOT] = imx_clk_gate4("wdog2_root_clk", "wdog", base + 0x4540, 0); - clks[IMX8MM_CLK_WDOG3_ROOT] = imx_clk_gate4("wdog3_root_clk", "wdog", base + 0x4550, 0); - clks[IMX8MM_CLK_VPU_G1_ROOT] = imx_clk_gate4("vpu_g1_root_clk", "vpu_g1", base + 0x4560, 0); - clks[IMX8MM_CLK_GPU_BUS_ROOT] = imx_clk_gate4("gpu_root_clk", "gpu_axi", base + 0x4570, 0); - clks[IMX8MM_CLK_VPU_H1_ROOT] = imx_clk_gate4("vpu_h1_root_clk", "vpu_h1", base + 0x4590, 0); - clks[IMX8MM_CLK_VPU_G2_ROOT] = imx_clk_gate4("vpu_g2_root_clk", "vpu_g2", base + 0x45a0, 0); - clks[IMX8MM_CLK_PDM_ROOT] = imx_clk_gate2_shared2("pdm_root_clk", "pdm", base + 0x45b0, 0, &share_count_pdm); - clks[IMX8MM_CLK_PDM_IPG] = imx_clk_gate2_shared2("pdm_ipg_clk", "ipg_audio_root", base + 0x45b0, 0, &share_count_pdm); - clks[IMX8MM_CLK_DISP_ROOT] = imx_clk_gate2_shared2("disp_root_clk", "disp_dc8000", base + 0x45d0, 0, &share_count_disp); - clks[IMX8MM_CLK_DISP_AXI_ROOT] = imx_clk_gate2_shared2("disp_axi_root_clk", "disp_axi", base + 0x45d0, 0, &share_count_disp); - clks[IMX8MM_CLK_DISP_APB_ROOT] = imx_clk_gate2_shared2("disp_apb_root_clk", "disp_apb", base + 0x45d0, 0, &share_count_disp); - clks[IMX8MM_CLK_DISP_RTRM_ROOT] = imx_clk_gate2_shared2("disp_rtrm_root_clk", "disp_rtrm", base + 0x45d0, 0, &share_count_disp); - clks[IMX8MM_CLK_USDHC3_ROOT] = imx_clk_gate4("usdhc3_root_clk", "usdhc3", base + 0x45e0, 0); - clks[IMX8MM_CLK_TMU_ROOT] = imx_clk_gate4("tmu_root_clk", "ipg_root", base + 0x4620, 0); - clks[IMX8MM_CLK_VPU_DEC_ROOT] = imx_clk_gate4("vpu_dec_root_clk", "vpu_bus", base + 0x4630, 0); - clks[IMX8MM_CLK_SDMA1_ROOT] = imx_clk_gate4("sdma1_clk", "ipg_root", base + 0x43a0, 0); - clks[IMX8MM_CLK_SDMA2_ROOT] = imx_clk_gate4("sdma2_clk", "ipg_audio_root", base + 0x43b0, 0); - clks[IMX8MM_CLK_SDMA3_ROOT] = imx_clk_gate4("sdma3_clk", "ipg_audio_root", base + 0x45f0, 0); - clks[IMX8MM_CLK_GPU2D_ROOT] = imx_clk_gate4("gpu2d_root_clk", "gpu2d_div", base + 0x4660, 0); - clks[IMX8MM_CLK_CSI1_ROOT] = imx_clk_gate4("csi1_root_clk", "csi1_core", base + 0x4650, 0); - - clks[IMX8MM_CLK_GPT_3M] = imx_clk_fixed_factor("gpt_3m", "osc_24m", 1, 8); - - clks[IMX8MM_CLK_DRAM_ALT_ROOT] = imx_clk_fixed_factor("dram_alt_root", "dram_alt", 1, 4); - clks[IMX8MM_CLK_DRAM_CORE] = imx_clk_mux2_flags("dram_core_clk", base + 0x9800, 24, 1, imx8mm_dram_core_sels, ARRAY_SIZE(imx8mm_dram_core_sels), CLK_IS_CRITICAL); - - clks[IMX8MM_CLK_ARM] = imx_clk_cpu("arm", "arm_a53_div", - clks[IMX8MM_CLK_A53_DIV], - clks[IMX8MM_CLK_A53_SRC], - clks[IMX8MM_ARM_PLL_OUT], - clks[IMX8MM_SYS_PLL1_800M]); - - imx_check_clocks(clks, ARRAY_SIZE(clks)); - - clk_data.clks = clks; - clk_data.clk_num = ARRAY_SIZE(clks); - ret = of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); + hws[IMX8MM_CLK_ECSPI1_ROOT] = imx_clk_hw_gate4("ecspi1_root_clk", "ecspi1", base + 0x4070, 0); + hws[IMX8MM_CLK_ECSPI2_ROOT] = imx_clk_hw_gate4("ecspi2_root_clk", "ecspi2", base + 0x4080, 0); + hws[IMX8MM_CLK_ECSPI3_ROOT] = imx_clk_hw_gate4("ecspi3_root_clk", "ecspi3", base + 0x4090, 0); + hws[IMX8MM_CLK_ENET1_ROOT] = imx_clk_hw_gate4("enet1_root_clk", "enet_axi", base + 0x40a0, 0); + hws[IMX8MM_CLK_GPIO1_ROOT] = imx_clk_hw_gate4("gpio1_root_clk", "ipg_root", base + 0x40b0, 0); + hws[IMX8MM_CLK_GPIO2_ROOT] = imx_clk_hw_gate4("gpio2_root_clk", "ipg_root", base + 0x40c0, 0); + hws[IMX8MM_CLK_GPIO3_ROOT] = imx_clk_hw_gate4("gpio3_root_clk", "ipg_root", base + 0x40d0, 0); + hws[IMX8MM_CLK_GPIO4_ROOT] = imx_clk_hw_gate4("gpio4_root_clk", "ipg_root", base + 0x40e0, 0); + hws[IMX8MM_CLK_GPIO5_ROOT] = imx_clk_hw_gate4("gpio5_root_clk", "ipg_root", base + 0x40f0, 0); + hws[IMX8MM_CLK_GPT1_ROOT] = imx_clk_hw_gate4("gpt1_root_clk", "gpt1", base + 0x4100, 0); + hws[IMX8MM_CLK_I2C1_ROOT] = imx_clk_hw_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0); + hws[IMX8MM_CLK_I2C2_ROOT] = imx_clk_hw_gate4("i2c2_root_clk", "i2c2", base + 0x4180, 0); + hws[IMX8MM_CLK_I2C3_ROOT] = imx_clk_hw_gate4("i2c3_root_clk", "i2c3", base + 0x4190, 0); + hws[IMX8MM_CLK_I2C4_ROOT] = imx_clk_hw_gate4("i2c4_root_clk", "i2c4", base + 0x41a0, 0); + hws[IMX8MM_CLK_MU_ROOT] = imx_clk_hw_gate4("mu_root_clk", "ipg_root", base + 0x4210, 0); + hws[IMX8MM_CLK_OCOTP_ROOT] = imx_clk_hw_gate4("ocotp_root_clk", "ipg_root", base + 0x4220, 0); + hws[IMX8MM_CLK_PCIE1_ROOT] = imx_clk_hw_gate4("pcie1_root_clk", "pcie1_ctrl", base + 0x4250, 0); + hws[IMX8MM_CLK_PWM1_ROOT] = imx_clk_hw_gate4("pwm1_root_clk", "pwm1", base + 0x4280, 0); + hws[IMX8MM_CLK_PWM2_ROOT] = imx_clk_hw_gate4("pwm2_root_clk", "pwm2", base + 0x4290, 0); + hws[IMX8MM_CLK_PWM3_ROOT] = imx_clk_hw_gate4("pwm3_root_clk", "pwm3", base + 0x42a0, 0); + hws[IMX8MM_CLK_PWM4_ROOT] = imx_clk_hw_gate4("pwm4_root_clk", "pwm4", base + 0x42b0, 0); + hws[IMX8MM_CLK_QSPI_ROOT] = imx_clk_hw_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0); + hws[IMX8MM_CLK_NAND_ROOT] = imx_clk_hw_gate2_shared2("nand_root_clk", "nand", base + 0x4300, 0, &share_count_nand); + hws[IMX8MM_CLK_NAND_USDHC_BUS_RAWNAND_CLK] = imx_clk_hw_gate2_shared2("nand_usdhc_rawnand_clk", "nand_usdhc_bus", base + 0x4300, 0, &share_count_nand); + hws[IMX8MM_CLK_SAI1_ROOT] = imx_clk_hw_gate2_shared2("sai1_root_clk", "sai1", base + 0x4330, 0, &share_count_sai1); + hws[IMX8MM_CLK_SAI1_IPG] = imx_clk_hw_gate2_shared2("sai1_ipg_clk", "ipg_audio_root", base + 0x4330, 0, &share_count_sai1); + hws[IMX8MM_CLK_SAI2_ROOT] = imx_clk_hw_gate2_shared2("sai2_root_clk", "sai2", base + 0x4340, 0, &share_count_sai2); + hws[IMX8MM_CLK_SAI2_IPG] = imx_clk_hw_gate2_shared2("sai2_ipg_clk", "ipg_audio_root", base + 0x4340, 0, &share_count_sai2); + hws[IMX8MM_CLK_SAI3_ROOT] = imx_clk_hw_gate2_shared2("sai3_root_clk", "sai3", base + 0x4350, 0, &share_count_sai3); + hws[IMX8MM_CLK_SAI3_IPG] = imx_clk_hw_gate2_shared2("sai3_ipg_clk", "ipg_audio_root", base + 0x4350, 0, &share_count_sai3); + hws[IMX8MM_CLK_SAI4_ROOT] = imx_clk_hw_gate2_shared2("sai4_root_clk", "sai4", base + 0x4360, 0, &share_count_sai4); + hws[IMX8MM_CLK_SAI4_IPG] = imx_clk_hw_gate2_shared2("sai4_ipg_clk", "ipg_audio_root", base + 0x4360, 0, &share_count_sai4); + hws[IMX8MM_CLK_SAI5_ROOT] = imx_clk_hw_gate2_shared2("sai5_root_clk", "sai5", base + 0x4370, 0, &share_count_sai5); + hws[IMX8MM_CLK_SAI5_IPG] = imx_clk_hw_gate2_shared2("sai5_ipg_clk", "ipg_audio_root", base + 0x4370, 0, &share_count_sai5); + hws[IMX8MM_CLK_SAI6_ROOT] = imx_clk_hw_gate2_shared2("sai6_root_clk", "sai6", base + 0x4380, 0, &share_count_sai6); + hws[IMX8MM_CLK_SAI6_IPG] = imx_clk_hw_gate2_shared2("sai6_ipg_clk", "ipg_audio_root", base + 0x4380, 0, &share_count_sai6); + hws[IMX8MM_CLK_SNVS_ROOT] = imx_clk_hw_gate4("snvs_root_clk", "ipg_root", base + 0x4470, 0); + hws[IMX8MM_CLK_UART1_ROOT] = imx_clk_hw_gate4("uart1_root_clk", "uart1", base + 0x4490, 0); + hws[IMX8MM_CLK_UART2_ROOT] = imx_clk_hw_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0); + hws[IMX8MM_CLK_UART3_ROOT] = imx_clk_hw_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0); + hws[IMX8MM_CLK_UART4_ROOT] = imx_clk_hw_gate4("uart4_root_clk", "uart4", base + 0x44c0, 0); + hws[IMX8MM_CLK_USB1_CTRL_ROOT] = imx_clk_hw_gate4("usb1_ctrl_root_clk", "usb_bus", base + 0x44d0, 0); + hws[IMX8MM_CLK_GPU3D_ROOT] = imx_clk_hw_gate4("gpu3d_root_clk", "gpu3d_div", base + 0x44f0, 0); + hws[IMX8MM_CLK_USDHC1_ROOT] = imx_clk_hw_gate4("usdhc1_root_clk", "usdhc1", base + 0x4510, 0); + hws[IMX8MM_CLK_USDHC2_ROOT] = imx_clk_hw_gate4("usdhc2_root_clk", "usdhc2", base + 0x4520, 0); + hws[IMX8MM_CLK_WDOG1_ROOT] = imx_clk_hw_gate4("wdog1_root_clk", "wdog", base + 0x4530, 0); + hws[IMX8MM_CLK_WDOG2_ROOT] = imx_clk_hw_gate4("wdog2_root_clk", "wdog", base + 0x4540, 0); + hws[IMX8MM_CLK_WDOG3_ROOT] = imx_clk_hw_gate4("wdog3_root_clk", "wdog", base + 0x4550, 0); + hws[IMX8MM_CLK_VPU_G1_ROOT] = imx_clk_hw_gate4("vpu_g1_root_clk", "vpu_g1", base + 0x4560, 0); + hws[IMX8MM_CLK_GPU_BUS_ROOT] = imx_clk_hw_gate4("gpu_root_clk", "gpu_axi", base + 0x4570, 0); + hws[IMX8MM_CLK_VPU_H1_ROOT] = imx_clk_hw_gate4("vpu_h1_root_clk", "vpu_h1", base + 0x4590, 0); + hws[IMX8MM_CLK_VPU_G2_ROOT] = imx_clk_hw_gate4("vpu_g2_root_clk", "vpu_g2", base + 0x45a0, 0); + hws[IMX8MM_CLK_PDM_ROOT] = imx_clk_hw_gate2_shared2("pdm_root_clk", "pdm", base + 0x45b0, 0, &share_count_pdm); + hws[IMX8MM_CLK_PDM_IPG] = imx_clk_hw_gate2_shared2("pdm_ipg_clk", "ipg_audio_root", base + 0x45b0, 0, &share_count_pdm); + hws[IMX8MM_CLK_DISP_ROOT] = imx_clk_hw_gate2_shared2("disp_root_clk", "disp_dc8000", base + 0x45d0, 0, &share_count_disp); + hws[IMX8MM_CLK_DISP_AXI_ROOT] = imx_clk_hw_gate2_shared2("disp_axi_root_clk", "disp_axi", base + 0x45d0, 0, &share_count_disp); + hws[IMX8MM_CLK_DISP_APB_ROOT] = imx_clk_hw_gate2_shared2("disp_apb_root_clk", "disp_apb", base + 0x45d0, 0, &share_count_disp); + hws[IMX8MM_CLK_DISP_RTRM_ROOT] = imx_clk_hw_gate2_shared2("disp_rtrm_root_clk", "disp_rtrm", base + 0x45d0, 0, &share_count_disp); + hws[IMX8MM_CLK_USDHC3_ROOT] = imx_clk_hw_gate4("usdhc3_root_clk", "usdhc3", base + 0x45e0, 0); + hws[IMX8MM_CLK_TMU_ROOT] = imx_clk_hw_gate4("tmu_root_clk", "ipg_root", base + 0x4620, 0); + hws[IMX8MM_CLK_VPU_DEC_ROOT] = imx_clk_hw_gate4("vpu_dec_root_clk", "vpu_bus", base + 0x4630, 0); + hws[IMX8MM_CLK_SDMA1_ROOT] = imx_clk_hw_gate4("sdma1_clk", "ipg_root", base + 0x43a0, 0); + hws[IMX8MM_CLK_SDMA2_ROOT] = imx_clk_hw_gate4("sdma2_clk", "ipg_audio_root", base + 0x43b0, 0); + hws[IMX8MM_CLK_SDMA3_ROOT] = imx_clk_hw_gate4("sdma3_clk", "ipg_audio_root", base + 0x45f0, 0); + hws[IMX8MM_CLK_GPU2D_ROOT] = imx_clk_hw_gate4("gpu2d_root_clk", "gpu2d_div", base + 0x4660, 0); + hws[IMX8MM_CLK_CSI1_ROOT] = imx_clk_hw_gate4("csi1_root_clk", "csi1_core", base + 0x4650, 0); + + hws[IMX8MM_CLK_GPT_3M] = imx_clk_hw_fixed_factor("gpt_3m", "osc_24m", 1, 8); + + hws[IMX8MM_CLK_DRAM_ALT_ROOT] = imx_clk_hw_fixed_factor("dram_alt_root", "dram_alt", 1, 4); + hws[IMX8MM_CLK_DRAM_CORE] = imx_clk_hw_mux2_flags("dram_core_clk", base + 0x9800, 24, 1, imx8mm_dram_core_sels, ARRAY_SIZE(imx8mm_dram_core_sels), CLK_IS_CRITICAL); + + hws[IMX8MM_CLK_ARM] = imx_clk_hw_cpu("arm", "arm_a53_div", + hws[IMX8MM_CLK_A53_DIV]->clk, + hws[IMX8MM_CLK_A53_SRC]->clk, + hws[IMX8MM_ARM_PLL_OUT]->clk, + hws[IMX8MM_SYS_PLL1_800M]->clk); + + imx_check_clk_hws(hws, IMX8MM_CLK_END); + + ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data); if (ret < 0) { - pr_err("failed to register clks for i.MX8MM\n"); - goto unregister_clks; + dev_err(dev, "failed to register clks for i.MX8MM\n"); + goto unregister_hws; + } + + for (i = 0; i < ARRAY_SIZE(uart_clk_ids); i++) { + int index = uart_clk_ids[i]; + + uart_hws[i] = &hws[index]->clk; } - imx_register_uart_clocks(uart_clks); + imx_register_uart_clocks(uart_hws); return 0; -unregister_clks: - imx_unregister_clocks(clks, ARRAY_SIZE(clks)); +unregister_hws: + imx_unregister_hw_clocks(hws, IMX8MM_CLK_END); return ret; } @@ -616,6 +634,11 @@ static struct platform_driver imx8mm_clk_driver = { .probe = imx8mm_clocks_probe, .driver = { .name = "imx8mm-ccm", + /* + * Disable bind attributes: clocks are not removed and + * reloading the driver will crash or break devices. + */ + .suppress_bind_attrs = true, .of_match_table = of_match_ptr(imx8mm_clk_of_match), }, }; diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c index 9f5a5a56b45e..c5e7316b4c66 100644 --- a/drivers/clk/imx/clk-imx8mn.c +++ b/drivers/clk/imx/clk-imx8mn.c @@ -12,6 +12,7 @@ #include <linux/of.h> #include <linux/of_address.h> #include <linux/platform_device.h> +#include <linux/slab.h> #include <linux/types.h> #include "clk.h" @@ -280,284 +281,302 @@ static const char * const imx8mn_clko2_sels[] = {"osc_24m", "sys_pll2_200m", "sy "sys_pll2_166m", "sys_pll3_out", "audio_pll1_out", "video_pll1_out", "osc_32k", }; -static struct clk *clks[IMX8MN_CLK_END]; -static struct clk_onecell_data clk_data; +static struct clk_hw_onecell_data *clk_hw_data; +static struct clk_hw **hws; -static struct clk ** const uart_clks[] = { - &clks[IMX8MN_CLK_UART1_ROOT], - &clks[IMX8MN_CLK_UART2_ROOT], - &clks[IMX8MN_CLK_UART3_ROOT], - &clks[IMX8MN_CLK_UART4_ROOT], - NULL +static const int uart_clk_ids[] = { + IMX8MN_CLK_UART1_ROOT, + IMX8MN_CLK_UART2_ROOT, + IMX8MN_CLK_UART3_ROOT, + IMX8MN_CLK_UART4_ROOT, }; +static struct clk **uart_hws[ARRAY_SIZE(uart_clk_ids) + 1]; static int imx8mn_clocks_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; void __iomem *base; - int ret; + int ret, i; - clks[IMX8MN_CLK_DUMMY] = imx_clk_fixed("dummy", 0); - clks[IMX8MN_CLK_24M] = of_clk_get_by_name(np, "osc_24m"); - clks[IMX8MN_CLK_32K] = of_clk_get_by_name(np, "osc_32k"); - clks[IMX8MN_CLK_EXT1] = of_clk_get_by_name(np, "clk_ext1"); - clks[IMX8MN_CLK_EXT2] = of_clk_get_by_name(np, "clk_ext2"); - clks[IMX8MN_CLK_EXT3] = of_clk_get_by_name(np, "clk_ext3"); - clks[IMX8MN_CLK_EXT4] = of_clk_get_by_name(np, "clk_ext4"); + clk_hw_data = kzalloc(struct_size(clk_hw_data, hws, + IMX8MN_CLK_END), GFP_KERNEL); + if (WARN_ON(!clk_hw_data)) + return -ENOMEM; + + clk_hw_data->num = IMX8MN_CLK_END; + hws = clk_hw_data->hws; + + hws[IMX8MN_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0); + hws[IMX8MN_CLK_24M] = imx_obtain_fixed_clk_hw(np, "osc_24m"); + hws[IMX8MN_CLK_32K] = imx_obtain_fixed_clk_hw(np, "osc_32k"); + hws[IMX8MN_CLK_EXT1] = imx_obtain_fixed_clk_hw(np, "clk_ext1"); + hws[IMX8MN_CLK_EXT2] = imx_obtain_fixed_clk_hw(np, "clk_ext2"); + hws[IMX8MN_CLK_EXT3] = imx_obtain_fixed_clk_hw(np, "clk_ext3"); + hws[IMX8MN_CLK_EXT4] = imx_obtain_fixed_clk_hw(np, "clk_ext4"); np = of_find_compatible_node(NULL, NULL, "fsl,imx8mn-anatop"); base = of_iomap(np, 0); if (WARN_ON(!base)) { ret = -ENOMEM; - goto unregister_clks; + goto unregister_hws; } - clks[IMX8MN_AUDIO_PLL1_REF_SEL] = imx_clk_mux("audio_pll1_ref_sel", base + 0x0, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); - clks[IMX8MN_AUDIO_PLL2_REF_SEL] = imx_clk_mux("audio_pll2_ref_sel", base + 0x14, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); - clks[IMX8MN_VIDEO_PLL1_REF_SEL] = imx_clk_mux("video_pll1_ref_sel", base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); - clks[IMX8MN_DRAM_PLL_REF_SEL] = imx_clk_mux("dram_pll_ref_sel", base + 0x50, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); - clks[IMX8MN_GPU_PLL_REF_SEL] = imx_clk_mux("gpu_pll_ref_sel", base + 0x64, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); - clks[IMX8MN_VPU_PLL_REF_SEL] = imx_clk_mux("vpu_pll_ref_sel", base + 0x74, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); - clks[IMX8MN_ARM_PLL_REF_SEL] = imx_clk_mux("arm_pll_ref_sel", base + 0x84, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); - clks[IMX8MN_SYS_PLL3_REF_SEL] = imx_clk_mux("sys_pll3_ref_sel", base + 0x114, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); - - clks[IMX8MN_AUDIO_PLL1] = imx_clk_pll14xx("audio_pll1", "audio_pll1_ref_sel", base, &imx_1443x_pll); - clks[IMX8MN_AUDIO_PLL2] = imx_clk_pll14xx("audio_pll2", "audio_pll2_ref_sel", base + 0x14, &imx_1443x_pll); - clks[IMX8MN_VIDEO_PLL1] = imx_clk_pll14xx("video_pll1", "video_pll1_ref_sel", base + 0x28, &imx_1443x_pll); - clks[IMX8MN_DRAM_PLL] = imx_clk_pll14xx("dram_pll", "dram_pll_ref_sel", base + 0x50, &imx_1443x_pll); - clks[IMX8MN_GPU_PLL] = imx_clk_pll14xx("gpu_pll", "gpu_pll_ref_sel", base + 0x64, &imx_1416x_pll); - clks[IMX8MN_VPU_PLL] = imx_clk_pll14xx("vpu_pll", "vpu_pll_ref_sel", base + 0x74, &imx_1416x_pll); - clks[IMX8MN_ARM_PLL] = imx_clk_pll14xx("arm_pll", "arm_pll_ref_sel", base + 0x84, &imx_1416x_pll); - clks[IMX8MN_SYS_PLL1] = imx_clk_fixed("sys_pll1", 800000000); - clks[IMX8MN_SYS_PLL2] = imx_clk_fixed("sys_pll2", 1000000000); - clks[IMX8MN_SYS_PLL3] = imx_clk_pll14xx("sys_pll3", "sys_pll3_ref_sel", base + 0x114, &imx_1416x_pll); + hws[IMX8MN_AUDIO_PLL1_REF_SEL] = imx_clk_hw_mux("audio_pll1_ref_sel", base + 0x0, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MN_AUDIO_PLL2_REF_SEL] = imx_clk_hw_mux("audio_pll2_ref_sel", base + 0x14, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MN_VIDEO_PLL1_REF_SEL] = imx_clk_hw_mux("video_pll1_ref_sel", base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MN_DRAM_PLL_REF_SEL] = imx_clk_hw_mux("dram_pll_ref_sel", base + 0x50, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MN_GPU_PLL_REF_SEL] = imx_clk_hw_mux("gpu_pll_ref_sel", base + 0x64, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MN_VPU_PLL_REF_SEL] = imx_clk_hw_mux("vpu_pll_ref_sel", base + 0x74, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MN_ARM_PLL_REF_SEL] = imx_clk_hw_mux("arm_pll_ref_sel", base + 0x84, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MN_SYS_PLL3_REF_SEL] = imx_clk_hw_mux("sys_pll3_ref_sel", base + 0x114, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + + hws[IMX8MN_AUDIO_PLL1] = imx_clk_hw_pll14xx("audio_pll1", "audio_pll1_ref_sel", base, &imx_1443x_pll); + hws[IMX8MN_AUDIO_PLL2] = imx_clk_hw_pll14xx("audio_pll2", "audio_pll2_ref_sel", base + 0x14, &imx_1443x_pll); + hws[IMX8MN_VIDEO_PLL1] = imx_clk_hw_pll14xx("video_pll1", "video_pll1_ref_sel", base + 0x28, &imx_1443x_pll); + hws[IMX8MN_DRAM_PLL] = imx_clk_hw_pll14xx("dram_pll", "dram_pll_ref_sel", base + 0x50, &imx_1443x_dram_pll); + hws[IMX8MN_GPU_PLL] = imx_clk_hw_pll14xx("gpu_pll", "gpu_pll_ref_sel", base + 0x64, &imx_1416x_pll); + hws[IMX8MN_VPU_PLL] = imx_clk_hw_pll14xx("vpu_pll", "vpu_pll_ref_sel", base + 0x74, &imx_1416x_pll); + hws[IMX8MN_ARM_PLL] = imx_clk_hw_pll14xx("arm_pll", "arm_pll_ref_sel", base + 0x84, &imx_1416x_pll); + hws[IMX8MN_SYS_PLL1] = imx_clk_hw_fixed("sys_pll1", 800000000); + hws[IMX8MN_SYS_PLL2] = imx_clk_hw_fixed("sys_pll2", 1000000000); + hws[IMX8MN_SYS_PLL3] = imx_clk_hw_pll14xx("sys_pll3", "sys_pll3_ref_sel", base + 0x114, &imx_1416x_pll); /* PLL bypass out */ - clks[IMX8MN_AUDIO_PLL1_BYPASS] = imx_clk_mux_flags("audio_pll1_bypass", base, 16, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT); - clks[IMX8MN_AUDIO_PLL2_BYPASS] = imx_clk_mux_flags("audio_pll2_bypass", base + 0x14, 16, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels), CLK_SET_RATE_PARENT); - clks[IMX8MN_VIDEO_PLL1_BYPASS] = imx_clk_mux_flags("video_pll1_bypass", base + 0x28, 16, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels), CLK_SET_RATE_PARENT); - clks[IMX8MN_DRAM_PLL_BYPASS] = imx_clk_mux_flags("dram_pll_bypass", base + 0x50, 16, 1, dram_pll_bypass_sels, ARRAY_SIZE(dram_pll_bypass_sels), CLK_SET_RATE_PARENT); - clks[IMX8MN_GPU_PLL_BYPASS] = imx_clk_mux_flags("gpu_pll_bypass", base + 0x64, 28, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT); - clks[IMX8MN_VPU_PLL_BYPASS] = imx_clk_mux_flags("vpu_pll_bypass", base + 0x74, 28, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels), CLK_SET_RATE_PARENT); - clks[IMX8MN_ARM_PLL_BYPASS] = imx_clk_mux_flags("arm_pll_bypass", base + 0x84, 28, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT); - clks[IMX8MN_SYS_PLL3_BYPASS] = imx_clk_mux_flags("sys_pll3_bypass", base + 0x114, 28, 1, sys_pll3_bypass_sels, ARRAY_SIZE(sys_pll3_bypass_sels), CLK_SET_RATE_PARENT); + hws[IMX8MN_AUDIO_PLL1_BYPASS] = imx_clk_hw_mux_flags("audio_pll1_bypass", base, 16, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT); + hws[IMX8MN_AUDIO_PLL2_BYPASS] = imx_clk_hw_mux_flags("audio_pll2_bypass", base + 0x14, 16, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels), CLK_SET_RATE_PARENT); + hws[IMX8MN_VIDEO_PLL1_BYPASS] = imx_clk_hw_mux_flags("video_pll1_bypass", base + 0x28, 16, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels), CLK_SET_RATE_PARENT); + hws[IMX8MN_DRAM_PLL_BYPASS] = imx_clk_hw_mux_flags("dram_pll_bypass", base + 0x50, 16, 1, dram_pll_bypass_sels, ARRAY_SIZE(dram_pll_bypass_sels), CLK_SET_RATE_PARENT); + hws[IMX8MN_GPU_PLL_BYPASS] = imx_clk_hw_mux_flags("gpu_pll_bypass", base + 0x64, 28, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT); + hws[IMX8MN_VPU_PLL_BYPASS] = imx_clk_hw_mux_flags("vpu_pll_bypass", base + 0x74, 28, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels), CLK_SET_RATE_PARENT); + hws[IMX8MN_ARM_PLL_BYPASS] = imx_clk_hw_mux_flags("arm_pll_bypass", base + 0x84, 28, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT); + hws[IMX8MN_SYS_PLL3_BYPASS] = imx_clk_hw_mux_flags("sys_pll3_bypass", base + 0x114, 28, 1, sys_pll3_bypass_sels, ARRAY_SIZE(sys_pll3_bypass_sels), CLK_SET_RATE_PARENT); /* PLL out gate */ - clks[IMX8MN_AUDIO_PLL1_OUT] = imx_clk_gate("audio_pll1_out", "audio_pll1_bypass", base, 13); - clks[IMX8MN_AUDIO_PLL2_OUT] = imx_clk_gate("audio_pll2_out", "audio_pll2_bypass", base + 0x14, 13); - clks[IMX8MN_VIDEO_PLL1_OUT] = imx_clk_gate("video_pll1_out", "video_pll1_bypass", base + 0x28, 13); - clks[IMX8MN_DRAM_PLL_OUT] = imx_clk_gate("dram_pll_out", "dram_pll_bypass", base + 0x50, 13); - clks[IMX8MN_GPU_PLL_OUT] = imx_clk_gate("gpu_pll_out", "gpu_pll_bypass", base + 0x64, 11); - clks[IMX8MN_VPU_PLL_OUT] = imx_clk_gate("vpu_pll_out", "vpu_pll_bypass", base + 0x74, 11); - clks[IMX8MN_ARM_PLL_OUT] = imx_clk_gate("arm_pll_out", "arm_pll_bypass", base + 0x84, 11); - clks[IMX8MN_SYS_PLL3_OUT] = imx_clk_gate("sys_pll3_out", "sys_pll3_bypass", base + 0x114, 11); + hws[IMX8MN_AUDIO_PLL1_OUT] = imx_clk_hw_gate("audio_pll1_out", "audio_pll1_bypass", base, 13); + hws[IMX8MN_AUDIO_PLL2_OUT] = imx_clk_hw_gate("audio_pll2_out", "audio_pll2_bypass", base + 0x14, 13); + hws[IMX8MN_VIDEO_PLL1_OUT] = imx_clk_hw_gate("video_pll1_out", "video_pll1_bypass", base + 0x28, 13); + hws[IMX8MN_DRAM_PLL_OUT] = imx_clk_hw_gate("dram_pll_out", "dram_pll_bypass", base + 0x50, 13); + hws[IMX8MN_GPU_PLL_OUT] = imx_clk_hw_gate("gpu_pll_out", "gpu_pll_bypass", base + 0x64, 11); + hws[IMX8MN_VPU_PLL_OUT] = imx_clk_hw_gate("vpu_pll_out", "vpu_pll_bypass", base + 0x74, 11); + hws[IMX8MN_ARM_PLL_OUT] = imx_clk_hw_gate("arm_pll_out", "arm_pll_bypass", base + 0x84, 11); + hws[IMX8MN_SYS_PLL3_OUT] = imx_clk_hw_gate("sys_pll3_out", "sys_pll3_bypass", base + 0x114, 11); /* SYS PLL1 fixed output */ - clks[IMX8MN_SYS_PLL1_40M_CG] = imx_clk_gate("sys_pll1_40m_cg", "sys_pll1", base + 0x94, 27); - clks[IMX8MN_SYS_PLL1_80M_CG] = imx_clk_gate("sys_pll1_80m_cg", "sys_pll1", base + 0x94, 25); - clks[IMX8MN_SYS_PLL1_100M_CG] = imx_clk_gate("sys_pll1_100m_cg", "sys_pll1", base + 0x94, 23); - clks[IMX8MN_SYS_PLL1_133M_CG] = imx_clk_gate("sys_pll1_133m_cg", "sys_pll1", base + 0x94, 21); - clks[IMX8MN_SYS_PLL1_160M_CG] = imx_clk_gate("sys_pll1_160m_cg", "sys_pll1", base + 0x94, 19); - clks[IMX8MN_SYS_PLL1_200M_CG] = imx_clk_gate("sys_pll1_200m_cg", "sys_pll1", base + 0x94, 17); - clks[IMX8MN_SYS_PLL1_266M_CG] = imx_clk_gate("sys_pll1_266m_cg", "sys_pll1", base + 0x94, 15); - clks[IMX8MN_SYS_PLL1_400M_CG] = imx_clk_gate("sys_pll1_400m_cg", "sys_pll1", base + 0x94, 13); - clks[IMX8MN_SYS_PLL1_OUT] = imx_clk_gate("sys_pll1_out", "sys_pll1", base + 0x94, 11); - - clks[IMX8MN_SYS_PLL1_40M] = imx_clk_fixed_factor("sys_pll1_40m", "sys_pll1_40m_cg", 1, 20); - clks[IMX8MN_SYS_PLL1_80M] = imx_clk_fixed_factor("sys_pll1_80m", "sys_pll1_80m_cg", 1, 10); - clks[IMX8MN_SYS_PLL1_100M] = imx_clk_fixed_factor("sys_pll1_100m", "sys_pll1_100m_cg", 1, 8); - clks[IMX8MN_SYS_PLL1_133M] = imx_clk_fixed_factor("sys_pll1_133m", "sys_pll1_133m_cg", 1, 6); - clks[IMX8MN_SYS_PLL1_160M] = imx_clk_fixed_factor("sys_pll1_160m", "sys_pll1_160m_cg", 1, 5); - clks[IMX8MN_SYS_PLL1_200M] = imx_clk_fixed_factor("sys_pll1_200m", "sys_pll1_200m_cg", 1, 4); - clks[IMX8MN_SYS_PLL1_266M] = imx_clk_fixed_factor("sys_pll1_266m", "sys_pll1_266m_cg", 1, 3); - clks[IMX8MN_SYS_PLL1_400M] = imx_clk_fixed_factor("sys_pll1_400m", "sys_pll1_400m_cg", 1, 2); - clks[IMX8MN_SYS_PLL1_800M] = imx_clk_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1, 1); + hws[IMX8MN_SYS_PLL1_40M_CG] = imx_clk_hw_gate("sys_pll1_40m_cg", "sys_pll1", base + 0x94, 27); + hws[IMX8MN_SYS_PLL1_80M_CG] = imx_clk_hw_gate("sys_pll1_80m_cg", "sys_pll1", base + 0x94, 25); + hws[IMX8MN_SYS_PLL1_100M_CG] = imx_clk_hw_gate("sys_pll1_100m_cg", "sys_pll1", base + 0x94, 23); + hws[IMX8MN_SYS_PLL1_133M_CG] = imx_clk_hw_gate("sys_pll1_133m_cg", "sys_pll1", base + 0x94, 21); + hws[IMX8MN_SYS_PLL1_160M_CG] = imx_clk_hw_gate("sys_pll1_160m_cg", "sys_pll1", base + 0x94, 19); + hws[IMX8MN_SYS_PLL1_200M_CG] = imx_clk_hw_gate("sys_pll1_200m_cg", "sys_pll1", base + 0x94, 17); + hws[IMX8MN_SYS_PLL1_266M_CG] = imx_clk_hw_gate("sys_pll1_266m_cg", "sys_pll1", base + 0x94, 15); + hws[IMX8MN_SYS_PLL1_400M_CG] = imx_clk_hw_gate("sys_pll1_400m_cg", "sys_pll1", base + 0x94, 13); + hws[IMX8MN_SYS_PLL1_OUT] = imx_clk_hw_gate("sys_pll1_out", "sys_pll1", base + 0x94, 11); + + hws[IMX8MN_SYS_PLL1_40M] = imx_clk_hw_fixed_factor("sys_pll1_40m", "sys_pll1_40m_cg", 1, 20); + hws[IMX8MN_SYS_PLL1_80M] = imx_clk_hw_fixed_factor("sys_pll1_80m", "sys_pll1_80m_cg", 1, 10); + hws[IMX8MN_SYS_PLL1_100M] = imx_clk_hw_fixed_factor("sys_pll1_100m", "sys_pll1_100m_cg", 1, 8); + hws[IMX8MN_SYS_PLL1_133M] = imx_clk_hw_fixed_factor("sys_pll1_133m", "sys_pll1_133m_cg", 1, 6); + hws[IMX8MN_SYS_PLL1_160M] = imx_clk_hw_fixed_factor("sys_pll1_160m", "sys_pll1_160m_cg", 1, 5); + hws[IMX8MN_SYS_PLL1_200M] = imx_clk_hw_fixed_factor("sys_pll1_200m", "sys_pll1_200m_cg", 1, 4); + hws[IMX8MN_SYS_PLL1_266M] = imx_clk_hw_fixed_factor("sys_pll1_266m", "sys_pll1_266m_cg", 1, 3); + hws[IMX8MN_SYS_PLL1_400M] = imx_clk_hw_fixed_factor("sys_pll1_400m", "sys_pll1_400m_cg", 1, 2); + hws[IMX8MN_SYS_PLL1_800M] = imx_clk_hw_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1, 1); /* SYS PLL2 fixed output */ - clks[IMX8MN_SYS_PLL2_50M_CG] = imx_clk_gate("sys_pll2_50m_cg", "sys_pll2", base + 0x104, 27); - clks[IMX8MN_SYS_PLL2_100M_CG] = imx_clk_gate("sys_pll2_100m_cg", "sys_pll2", base + 0x104, 25); - clks[IMX8MN_SYS_PLL2_125M_CG] = imx_clk_gate("sys_pll2_125m_cg", "sys_pll2", base + 0x104, 23); - clks[IMX8MN_SYS_PLL2_166M_CG] = imx_clk_gate("sys_pll2_166m_cg", "sys_pll2", base + 0x104, 21); - clks[IMX8MN_SYS_PLL2_200M_CG] = imx_clk_gate("sys_pll2_200m_cg", "sys_pll2", base + 0x104, 19); - clks[IMX8MN_SYS_PLL2_250M_CG] = imx_clk_gate("sys_pll2_250m_cg", "sys_pll2", base + 0x104, 17); - clks[IMX8MN_SYS_PLL2_333M_CG] = imx_clk_gate("sys_pll2_333m_cg", "sys_pll2", base + 0x104, 15); - clks[IMX8MN_SYS_PLL2_500M_CG] = imx_clk_gate("sys_pll2_500m_cg", "sys_pll2", base + 0x104, 13); - clks[IMX8MN_SYS_PLL2_OUT] = imx_clk_gate("sys_pll2_out", "sys_pll2", base + 0x104, 11); - - clks[IMX8MN_SYS_PLL2_50M] = imx_clk_fixed_factor("sys_pll2_50m", "sys_pll2_50m_cg", 1, 20); - clks[IMX8MN_SYS_PLL2_100M] = imx_clk_fixed_factor("sys_pll2_100m", "sys_pll2_100m_cg", 1, 10); - clks[IMX8MN_SYS_PLL2_125M] = imx_clk_fixed_factor("sys_pll2_125m", "sys_pll2_125m_cg", 1, 8); - clks[IMX8MN_SYS_PLL2_166M] = imx_clk_fixed_factor("sys_pll2_166m", "sys_pll2_166m_cg", 1, 6); - clks[IMX8MN_SYS_PLL2_200M] = imx_clk_fixed_factor("sys_pll2_200m", "sys_pll2_200m_cg", 1, 5); - clks[IMX8MN_SYS_PLL2_250M] = imx_clk_fixed_factor("sys_pll2_250m", "sys_pll2_250m_cg", 1, 4); - clks[IMX8MN_SYS_PLL2_333M] = imx_clk_fixed_factor("sys_pll2_333m", "sys_pll2_333m_cg", 1, 3); - clks[IMX8MN_SYS_PLL2_500M] = imx_clk_fixed_factor("sys_pll2_500m", "sys_pll2_500m_cg", 1, 2); - clks[IMX8MN_SYS_PLL2_1000M] = imx_clk_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1); + hws[IMX8MN_SYS_PLL2_50M_CG] = imx_clk_hw_gate("sys_pll2_50m_cg", "sys_pll2", base + 0x104, 27); + hws[IMX8MN_SYS_PLL2_100M_CG] = imx_clk_hw_gate("sys_pll2_100m_cg", "sys_pll2", base + 0x104, 25); + hws[IMX8MN_SYS_PLL2_125M_CG] = imx_clk_hw_gate("sys_pll2_125m_cg", "sys_pll2", base + 0x104, 23); + hws[IMX8MN_SYS_PLL2_166M_CG] = imx_clk_hw_gate("sys_pll2_166m_cg", "sys_pll2", base + 0x104, 21); + hws[IMX8MN_SYS_PLL2_200M_CG] = imx_clk_hw_gate("sys_pll2_200m_cg", "sys_pll2", base + 0x104, 19); + hws[IMX8MN_SYS_PLL2_250M_CG] = imx_clk_hw_gate("sys_pll2_250m_cg", "sys_pll2", base + 0x104, 17); + hws[IMX8MN_SYS_PLL2_333M_CG] = imx_clk_hw_gate("sys_pll2_333m_cg", "sys_pll2", base + 0x104, 15); + hws[IMX8MN_SYS_PLL2_500M_CG] = imx_clk_hw_gate("sys_pll2_500m_cg", "sys_pll2", base + 0x104, 13); + hws[IMX8MN_SYS_PLL2_OUT] = imx_clk_hw_gate("sys_pll2_out", "sys_pll2", base + 0x104, 11); + + hws[IMX8MN_SYS_PLL2_50M] = imx_clk_hw_fixed_factor("sys_pll2_50m", "sys_pll2_50m_cg", 1, 20); + hws[IMX8MN_SYS_PLL2_100M] = imx_clk_hw_fixed_factor("sys_pll2_100m", "sys_pll2_100m_cg", 1, 10); + hws[IMX8MN_SYS_PLL2_125M] = imx_clk_hw_fixed_factor("sys_pll2_125m", "sys_pll2_125m_cg", 1, 8); + hws[IMX8MN_SYS_PLL2_166M] = imx_clk_hw_fixed_factor("sys_pll2_166m", "sys_pll2_166m_cg", 1, 6); + hws[IMX8MN_SYS_PLL2_200M] = imx_clk_hw_fixed_factor("sys_pll2_200m", "sys_pll2_200m_cg", 1, 5); + hws[IMX8MN_SYS_PLL2_250M] = imx_clk_hw_fixed_factor("sys_pll2_250m", "sys_pll2_250m_cg", 1, 4); + hws[IMX8MN_SYS_PLL2_333M] = imx_clk_hw_fixed_factor("sys_pll2_333m", "sys_pll2_333m_cg", 1, 3); + hws[IMX8MN_SYS_PLL2_500M] = imx_clk_hw_fixed_factor("sys_pll2_500m", "sys_pll2_500m_cg", 1, 2); + hws[IMX8MN_SYS_PLL2_1000M] = imx_clk_hw_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1); np = dev->of_node; base = devm_platform_ioremap_resource(pdev, 0); if (WARN_ON(IS_ERR(base))) { ret = PTR_ERR(base); - goto unregister_clks; + goto unregister_hws; } /* CORE */ - clks[IMX8MN_CLK_A53_SRC] = imx_clk_mux2("arm_a53_src", base + 0x8000, 24, 3, imx8mn_a53_sels, ARRAY_SIZE(imx8mn_a53_sels)); - clks[IMX8MN_CLK_GPU_CORE_SRC] = imx_clk_mux2("gpu_core_src", base + 0x8180, 24, 3, imx8mn_gpu_core_sels, ARRAY_SIZE(imx8mn_gpu_core_sels)); - clks[IMX8MN_CLK_GPU_SHADER_SRC] = imx_clk_mux2("gpu_shader_src", base + 0x8200, 24, 3, imx8mn_gpu_shader_sels, ARRAY_SIZE(imx8mn_gpu_shader_sels)); - clks[IMX8MN_CLK_A53_CG] = imx_clk_gate3("arm_a53_cg", "arm_a53_src", base + 0x8000, 28); - clks[IMX8MN_CLK_GPU_CORE_CG] = imx_clk_gate3("gpu_core_cg", "gpu_core_src", base + 0x8180, 28); - clks[IMX8MN_CLK_GPU_SHADER_CG] = imx_clk_gate3("gpu_shader_cg", "gpu_shader_src", base + 0x8200, 28); + hws[IMX8MN_CLK_A53_SRC] = imx_clk_hw_mux2("arm_a53_src", base + 0x8000, 24, 3, imx8mn_a53_sels, ARRAY_SIZE(imx8mn_a53_sels)); + hws[IMX8MN_CLK_GPU_CORE_SRC] = imx_clk_hw_mux2("gpu_core_src", base + 0x8180, 24, 3, imx8mn_gpu_core_sels, ARRAY_SIZE(imx8mn_gpu_core_sels)); + hws[IMX8MN_CLK_GPU_SHADER_SRC] = imx_clk_hw_mux2("gpu_shader_src", base + 0x8200, 24, 3, imx8mn_gpu_shader_sels, ARRAY_SIZE(imx8mn_gpu_shader_sels)); + hws[IMX8MN_CLK_A53_CG] = imx_clk_hw_gate3("arm_a53_cg", "arm_a53_src", base + 0x8000, 28); + hws[IMX8MN_CLK_GPU_CORE_CG] = imx_clk_hw_gate3("gpu_core_cg", "gpu_core_src", base + 0x8180, 28); + hws[IMX8MN_CLK_GPU_SHADER_CG] = imx_clk_hw_gate3("gpu_shader_cg", "gpu_shader_src", base + 0x8200, 28); - clks[IMX8MN_CLK_A53_DIV] = imx_clk_divider2("arm_a53_div", "arm_a53_cg", base + 0x8000, 0, 3); - clks[IMX8MN_CLK_GPU_CORE_DIV] = imx_clk_divider2("gpu_core_div", "gpu_core_cg", base + 0x8180, 0, 3); - clks[IMX8MN_CLK_GPU_SHADER_DIV] = imx_clk_divider2("gpu_shader_div", "gpu_shader_cg", base + 0x8200, 0, 3); + hws[IMX8MN_CLK_A53_DIV] = imx_clk_hw_divider2("arm_a53_div", "arm_a53_cg", base + 0x8000, 0, 3); + hws[IMX8MN_CLK_GPU_CORE_DIV] = imx_clk_hw_divider2("gpu_core_div", "gpu_core_cg", base + 0x8180, 0, 3); + hws[IMX8MN_CLK_GPU_SHADER_DIV] = imx_clk_hw_divider2("gpu_shader_div", "gpu_shader_cg", base + 0x8200, 0, 3); /* BUS */ - clks[IMX8MN_CLK_MAIN_AXI] = imx8m_clk_composite_critical("main_axi", imx8mn_main_axi_sels, base + 0x8800); - clks[IMX8MN_CLK_ENET_AXI] = imx8m_clk_composite("enet_axi", imx8mn_enet_axi_sels, base + 0x8880); - clks[IMX8MN_CLK_NAND_USDHC_BUS] = imx8m_clk_composite("nand_usdhc_bus", imx8mn_nand_usdhc_sels, base + 0x8900); - clks[IMX8MN_CLK_DISP_AXI] = imx8m_clk_composite("disp_axi", imx8mn_disp_axi_sels, base + 0x8a00); - clks[IMX8MN_CLK_DISP_APB] = imx8m_clk_composite("disp_apb", imx8mn_disp_apb_sels, base + 0x8a80); - clks[IMX8MN_CLK_USB_BUS] = imx8m_clk_composite("usb_bus", imx8mn_usb_bus_sels, base + 0x8b80); - clks[IMX8MN_CLK_GPU_AXI] = imx8m_clk_composite("gpu_axi", imx8mn_gpu_axi_sels, base + 0x8c00); - clks[IMX8MN_CLK_GPU_AHB] = imx8m_clk_composite("gpu_ahb", imx8mn_gpu_ahb_sels, base + 0x8c80); - clks[IMX8MN_CLK_NOC] = imx8m_clk_composite_critical("noc", imx8mn_noc_sels, base + 0x8d00); - - clks[IMX8MN_CLK_AHB] = imx8m_clk_composite_critical("ahb", imx8mn_ahb_sels, base + 0x9000); - clks[IMX8MN_CLK_AUDIO_AHB] = imx8m_clk_composite("audio_ahb", imx8mn_audio_ahb_sels, base + 0x9100); - clks[IMX8MN_CLK_IPG_ROOT] = imx_clk_divider2("ipg_root", "ahb", base + 0x9080, 0, 1); - clks[IMX8MN_CLK_IPG_AUDIO_ROOT] = imx_clk_divider2("ipg_audio_root", "audio_ahb", base + 0x9180, 0, 1); - clks[IMX8MN_CLK_DRAM_CORE] = imx_clk_mux2_flags("dram_core_clk", base + 0x9800, 24, 1, imx8mn_dram_core_sels, ARRAY_SIZE(imx8mn_dram_core_sels), CLK_IS_CRITICAL); - clks[IMX8MN_CLK_DRAM_ALT] = imx8m_clk_composite("dram_alt", imx8mn_dram_alt_sels, base + 0xa000); - clks[IMX8MN_CLK_DRAM_APB] = imx8m_clk_composite_critical("dram_apb", imx8mn_dram_apb_sels, base + 0xa080); - clks[IMX8MN_CLK_DISP_PIXEL] = imx8m_clk_composite("disp_pixel", imx8mn_disp_pixel_sels, base + 0xa500); - clks[IMX8MN_CLK_SAI2] = imx8m_clk_composite("sai2", imx8mn_sai2_sels, base + 0xa600); - clks[IMX8MN_CLK_SAI3] = imx8m_clk_composite("sai3", imx8mn_sai3_sels, base + 0xa680); - clks[IMX8MN_CLK_SAI5] = imx8m_clk_composite("sai5", imx8mn_sai5_sels, base + 0xa780); - clks[IMX8MN_CLK_SAI6] = imx8m_clk_composite("sai6", imx8mn_sai6_sels, base + 0xa800); - clks[IMX8MN_CLK_SPDIF1] = imx8m_clk_composite("spdif1", imx8mn_spdif1_sels, base + 0xa880); - clks[IMX8MN_CLK_ENET_REF] = imx8m_clk_composite("enet_ref", imx8mn_enet_ref_sels, base + 0xa980); - clks[IMX8MN_CLK_ENET_TIMER] = imx8m_clk_composite("enet_timer", imx8mn_enet_timer_sels, base + 0xaa00); - clks[IMX8MN_CLK_ENET_PHY_REF] = imx8m_clk_composite("enet_phy", imx8mn_enet_phy_sels, base + 0xaa80); - clks[IMX8MN_CLK_NAND] = imx8m_clk_composite("nand", imx8mn_nand_sels, base + 0xab00); - clks[IMX8MN_CLK_QSPI] = imx8m_clk_composite("qspi", imx8mn_qspi_sels, base + 0xab80); - clks[IMX8MN_CLK_USDHC1] = imx8m_clk_composite("usdhc1", imx8mn_usdhc1_sels, base + 0xac00); - clks[IMX8MN_CLK_USDHC2] = imx8m_clk_composite("usdhc2", imx8mn_usdhc2_sels, base + 0xac80); - clks[IMX8MN_CLK_I2C1] = imx8m_clk_composite("i2c1", imx8mn_i2c1_sels, base + 0xad00); - clks[IMX8MN_CLK_I2C2] = imx8m_clk_composite("i2c2", imx8mn_i2c2_sels, base + 0xad80); - clks[IMX8MN_CLK_I2C3] = imx8m_clk_composite("i2c3", imx8mn_i2c3_sels, base + 0xae00); - clks[IMX8MN_CLK_I2C4] = imx8m_clk_composite("i2c4", imx8mn_i2c4_sels, base + 0xae80); - clks[IMX8MN_CLK_UART1] = imx8m_clk_composite("uart1", imx8mn_uart1_sels, base + 0xaf00); - clks[IMX8MN_CLK_UART2] = imx8m_clk_composite("uart2", imx8mn_uart2_sels, base + 0xaf80); - clks[IMX8MN_CLK_UART3] = imx8m_clk_composite("uart3", imx8mn_uart3_sels, base + 0xb000); - clks[IMX8MN_CLK_UART4] = imx8m_clk_composite("uart4", imx8mn_uart4_sels, base + 0xb080); - clks[IMX8MN_CLK_USB_CORE_REF] = imx8m_clk_composite("usb_core_ref", imx8mn_usb_core_sels, base + 0xb100); - clks[IMX8MN_CLK_USB_PHY_REF] = imx8m_clk_composite("usb_phy_ref", imx8mn_usb_phy_sels, base + 0xb180); - clks[IMX8MN_CLK_GIC] = imx8m_clk_composite_critical("gic", imx8mn_gic_sels, base + 0xb200); - clks[IMX8MN_CLK_ECSPI1] = imx8m_clk_composite("ecspi1", imx8mn_ecspi1_sels, base + 0xb280); - clks[IMX8MN_CLK_ECSPI2] = imx8m_clk_composite("ecspi2", imx8mn_ecspi2_sels, base + 0xb300); - clks[IMX8MN_CLK_PWM1] = imx8m_clk_composite("pwm1", imx8mn_pwm1_sels, base + 0xb380); - clks[IMX8MN_CLK_PWM2] = imx8m_clk_composite("pwm2", imx8mn_pwm2_sels, base + 0xb400); - clks[IMX8MN_CLK_PWM3] = imx8m_clk_composite("pwm3", imx8mn_pwm3_sels, base + 0xb480); - clks[IMX8MN_CLK_PWM4] = imx8m_clk_composite("pwm4", imx8mn_pwm4_sels, base + 0xb500); - clks[IMX8MN_CLK_WDOG] = imx8m_clk_composite("wdog", imx8mn_wdog_sels, base + 0xb900); - clks[IMX8MN_CLK_WRCLK] = imx8m_clk_composite("wrclk", imx8mn_wrclk_sels, base + 0xb980); - clks[IMX8MN_CLK_CLKO1] = imx8m_clk_composite("clko1", imx8mn_clko1_sels, base + 0xba00); - clks[IMX8MN_CLK_CLKO2] = imx8m_clk_composite("clko2", imx8mn_clko2_sels, base + 0xba80); - clks[IMX8MN_CLK_DSI_CORE] = imx8m_clk_composite("dsi_core", imx8mn_dsi_core_sels, base + 0xbb00); - clks[IMX8MN_CLK_DSI_PHY_REF] = imx8m_clk_composite("dsi_phy_ref", imx8mn_dsi_phy_sels, base + 0xbb80); - clks[IMX8MN_CLK_DSI_DBI] = imx8m_clk_composite("dsi_dbi", imx8mn_dsi_dbi_sels, base + 0xbc00); - clks[IMX8MN_CLK_USDHC3] = imx8m_clk_composite("usdhc3", imx8mn_usdhc3_sels, base + 0xbc80); - clks[IMX8MN_CLK_CAMERA_PIXEL] = imx8m_clk_composite("camera_pixel", imx8mn_camera_pixel_sels, base + 0xbd00); - clks[IMX8MN_CLK_CSI1_PHY_REF] = imx8m_clk_composite("csi1_phy_ref", imx8mn_csi1_phy_sels, base + 0xbd80); - clks[IMX8MN_CLK_CSI2_PHY_REF] = imx8m_clk_composite("csi2_phy_ref", imx8mn_csi2_phy_sels, base + 0xbf00); - clks[IMX8MN_CLK_CSI2_ESC] = imx8m_clk_composite("csi2_esc", imx8mn_csi2_esc_sels, base + 0xbf80); - clks[IMX8MN_CLK_ECSPI3] = imx8m_clk_composite("ecspi3", imx8mn_ecspi3_sels, base + 0xc180); - clks[IMX8MN_CLK_PDM] = imx8m_clk_composite("pdm", imx8mn_pdm_sels, base + 0xc200); - clks[IMX8MN_CLK_SAI7] = imx8m_clk_composite("sai7", imx8mn_sai7_sels, base + 0xc300); - - clks[IMX8MN_CLK_ECSPI1_ROOT] = imx_clk_gate4("ecspi1_root_clk", "ecspi1", base + 0x4070, 0); - clks[IMX8MN_CLK_ECSPI2_ROOT] = imx_clk_gate4("ecspi2_root_clk", "ecspi2", base + 0x4080, 0); - clks[IMX8MN_CLK_ECSPI3_ROOT] = imx_clk_gate4("ecspi3_root_clk", "ecspi3", base + 0x4090, 0); - clks[IMX8MN_CLK_ENET1_ROOT] = imx_clk_gate4("enet1_root_clk", "enet_axi", base + 0x40a0, 0); - clks[IMX8MN_CLK_GPIO1_ROOT] = imx_clk_gate4("gpio1_root_clk", "ipg_root", base + 0x40b0, 0); - clks[IMX8MN_CLK_GPIO2_ROOT] = imx_clk_gate4("gpio2_root_clk", "ipg_root", base + 0x40c0, 0); - clks[IMX8MN_CLK_GPIO3_ROOT] = imx_clk_gate4("gpio3_root_clk", "ipg_root", base + 0x40d0, 0); - clks[IMX8MN_CLK_GPIO4_ROOT] = imx_clk_gate4("gpio4_root_clk", "ipg_root", base + 0x40e0, 0); - clks[IMX8MN_CLK_GPIO5_ROOT] = imx_clk_gate4("gpio5_root_clk", "ipg_root", base + 0x40f0, 0); - clks[IMX8MN_CLK_I2C1_ROOT] = imx_clk_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0); - clks[IMX8MN_CLK_I2C2_ROOT] = imx_clk_gate4("i2c2_root_clk", "i2c2", base + 0x4180, 0); - clks[IMX8MN_CLK_I2C3_ROOT] = imx_clk_gate4("i2c3_root_clk", "i2c3", base + 0x4190, 0); - clks[IMX8MN_CLK_I2C4_ROOT] = imx_clk_gate4("i2c4_root_clk", "i2c4", base + 0x41a0, 0); - clks[IMX8MN_CLK_MU_ROOT] = imx_clk_gate4("mu_root_clk", "ipg_root", base + 0x4210, 0); - clks[IMX8MN_CLK_OCOTP_ROOT] = imx_clk_gate4("ocotp_root_clk", "ipg_root", base + 0x4220, 0); - clks[IMX8MN_CLK_PWM1_ROOT] = imx_clk_gate4("pwm1_root_clk", "pwm1", base + 0x4280, 0); - clks[IMX8MN_CLK_PWM2_ROOT] = imx_clk_gate4("pwm2_root_clk", "pwm2", base + 0x4290, 0); - clks[IMX8MN_CLK_PWM3_ROOT] = imx_clk_gate4("pwm3_root_clk", "pwm3", base + 0x42a0, 0); - clks[IMX8MN_CLK_PWM4_ROOT] = imx_clk_gate4("pwm4_root_clk", "pwm4", base + 0x42b0, 0); - clks[IMX8MN_CLK_QSPI_ROOT] = imx_clk_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0); - clks[IMX8MN_CLK_NAND_ROOT] = imx_clk_gate2_shared2("nand_root_clk", "nand", base + 0x4300, 0, &share_count_nand); - clks[IMX8MN_CLK_NAND_USDHC_BUS_RAWNAND_CLK] = imx_clk_gate2_shared2("nand_usdhc_rawnand_clk", "nand_usdhc_bus", base + 0x4300, 0, &share_count_nand); - clks[IMX8MN_CLK_SAI2_ROOT] = imx_clk_gate2_shared2("sai2_root_clk", "sai2", base + 0x4340, 0, &share_count_sai2); - clks[IMX8MN_CLK_SAI2_IPG] = imx_clk_gate2_shared2("sai2_ipg_clk", "ipg_audio_root", base + 0x4340, 0, &share_count_sai2); - clks[IMX8MN_CLK_SAI3_ROOT] = imx_clk_gate2_shared2("sai3_root_clk", "sai3", base + 0x4350, 0, &share_count_sai3); - clks[IMX8MN_CLK_SAI3_IPG] = imx_clk_gate2_shared2("sai3_ipg_clk", "ipg_audio_root", base + 0x4350, 0, &share_count_sai3); - clks[IMX8MN_CLK_SAI5_ROOT] = imx_clk_gate2_shared2("sai5_root_clk", "sai5", base + 0x4370, 0, &share_count_sai5); - clks[IMX8MN_CLK_SAI5_IPG] = imx_clk_gate2_shared2("sai5_ipg_clk", "ipg_audio_root", base + 0x4370, 0, &share_count_sai5); - clks[IMX8MN_CLK_SAI6_ROOT] = imx_clk_gate2_shared2("sai6_root_clk", "sai6", base + 0x4380, 0, &share_count_sai6); - clks[IMX8MN_CLK_SAI6_IPG] = imx_clk_gate2_shared2("sai6_ipg_clk", "ipg_audio_root", base + 0x4380, 0, &share_count_sai6); - clks[IMX8MN_CLK_UART1_ROOT] = imx_clk_gate4("uart1_root_clk", "uart1", base + 0x4490, 0); - clks[IMX8MN_CLK_UART2_ROOT] = imx_clk_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0); - clks[IMX8MN_CLK_UART3_ROOT] = imx_clk_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0); - clks[IMX8MN_CLK_UART4_ROOT] = imx_clk_gate4("uart4_root_clk", "uart4", base + 0x44c0, 0); - clks[IMX8MN_CLK_USB1_CTRL_ROOT] = imx_clk_gate4("usb1_ctrl_root_clk", "usb_core_ref", base + 0x44d0, 0); - clks[IMX8MN_CLK_GPU_CORE_ROOT] = imx_clk_gate4("gpu_core_root_clk", "gpu_core_div", base + 0x44f0, 0); - clks[IMX8MN_CLK_USDHC1_ROOT] = imx_clk_gate4("usdhc1_root_clk", "usdhc1", base + 0x4510, 0); - clks[IMX8MN_CLK_USDHC2_ROOT] = imx_clk_gate4("usdhc2_root_clk", "usdhc2", base + 0x4520, 0); - clks[IMX8MN_CLK_WDOG1_ROOT] = imx_clk_gate4("wdog1_root_clk", "wdog", base + 0x4530, 0); - clks[IMX8MN_CLK_WDOG2_ROOT] = imx_clk_gate4("wdog2_root_clk", "wdog", base + 0x4540, 0); - clks[IMX8MN_CLK_WDOG3_ROOT] = imx_clk_gate4("wdog3_root_clk", "wdog", base + 0x4550, 0); - clks[IMX8MN_CLK_GPU_BUS_ROOT] = imx_clk_gate4("gpu_root_clk", "gpu_axi", base + 0x4570, 0); - clks[IMX8MN_CLK_ASRC_ROOT] = imx_clk_gate4("asrc_root_clk", "audio_ahb", base + 0x4580, 0); - clks[IMX8MN_CLK_PDM_ROOT] = imx_clk_gate2_shared2("pdm_root_clk", "pdm", base + 0x45b0, 0, &share_count_pdm); - clks[IMX8MN_CLK_PDM_IPG] = imx_clk_gate2_shared2("pdm_ipg_clk", "ipg_audio_root", base + 0x45b0, 0, &share_count_pdm); - clks[IMX8MN_CLK_DISP_AXI_ROOT] = imx_clk_gate2_shared2("disp_axi_root_clk", "disp_axi", base + 0x45d0, 0, &share_count_disp); - clks[IMX8MN_CLK_DISP_APB_ROOT] = imx_clk_gate2_shared2("disp_apb_root_clk", "disp_apb", base + 0x45d0, 0, &share_count_disp); - clks[IMX8MN_CLK_CAMERA_PIXEL_ROOT] = imx_clk_gate2_shared2("camera_pixel_clk", "camera_pixel", base + 0x45d0, 0, &share_count_disp); - clks[IMX8MN_CLK_DISP_PIXEL_ROOT] = imx_clk_gate2_shared2("disp_pixel_clk", "disp_pixel", base + 0x45d0, 0, &share_count_disp); - clks[IMX8MN_CLK_USDHC3_ROOT] = imx_clk_gate4("usdhc3_root_clk", "usdhc3", base + 0x45e0, 0); - clks[IMX8MN_CLK_TMU_ROOT] = imx_clk_gate4("tmu_root_clk", "ipg_root", base + 0x4620, 0); - clks[IMX8MN_CLK_SDMA1_ROOT] = imx_clk_gate4("sdma1_clk", "ipg_root", base + 0x43a0, 0); - clks[IMX8MN_CLK_SDMA2_ROOT] = imx_clk_gate4("sdma2_clk", "ipg_audio_root", base + 0x43b0, 0); - clks[IMX8MN_CLK_SDMA3_ROOT] = imx_clk_gate4("sdma3_clk", "ipg_audio_root", base + 0x45f0, 0); - clks[IMX8MN_CLK_SAI7_ROOT] = imx_clk_gate2_shared2("sai7_root_clk", "sai7", base + 0x4650, 0, &share_count_sai7); - - clks[IMX8MN_CLK_DRAM_ALT_ROOT] = imx_clk_fixed_factor("dram_alt_root", "dram_alt", 1, 4); - - clks[IMX8MN_CLK_ARM] = imx_clk_cpu("arm", "arm_a53_div", - clks[IMX8MN_CLK_A53_DIV], - clks[IMX8MN_CLK_A53_SRC], - clks[IMX8MN_ARM_PLL_OUT], - clks[IMX8MN_SYS_PLL1_800M]); - - imx_check_clocks(clks, ARRAY_SIZE(clks)); - - clk_data.clks = clks; - clk_data.clk_num = ARRAY_SIZE(clks); - ret = of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); + hws[IMX8MN_CLK_MAIN_AXI] = imx8m_clk_hw_composite_critical("main_axi", imx8mn_main_axi_sels, base + 0x8800); + hws[IMX8MN_CLK_ENET_AXI] = imx8m_clk_hw_composite("enet_axi", imx8mn_enet_axi_sels, base + 0x8880); + hws[IMX8MN_CLK_NAND_USDHC_BUS] = imx8m_clk_hw_composite("nand_usdhc_bus", imx8mn_nand_usdhc_sels, base + 0x8900); + hws[IMX8MN_CLK_DISP_AXI] = imx8m_clk_hw_composite("disp_axi", imx8mn_disp_axi_sels, base + 0x8a00); + hws[IMX8MN_CLK_DISP_APB] = imx8m_clk_hw_composite("disp_apb", imx8mn_disp_apb_sels, base + 0x8a80); + hws[IMX8MN_CLK_USB_BUS] = imx8m_clk_hw_composite("usb_bus", imx8mn_usb_bus_sels, base + 0x8b80); + hws[IMX8MN_CLK_GPU_AXI] = imx8m_clk_hw_composite("gpu_axi", imx8mn_gpu_axi_sels, base + 0x8c00); + hws[IMX8MN_CLK_GPU_AHB] = imx8m_clk_hw_composite("gpu_ahb", imx8mn_gpu_ahb_sels, base + 0x8c80); + hws[IMX8MN_CLK_NOC] = imx8m_clk_hw_composite_critical("noc", imx8mn_noc_sels, base + 0x8d00); + + hws[IMX8MN_CLK_AHB] = imx8m_clk_hw_composite_critical("ahb", imx8mn_ahb_sels, base + 0x9000); + hws[IMX8MN_CLK_AUDIO_AHB] = imx8m_clk_hw_composite("audio_ahb", imx8mn_audio_ahb_sels, base + 0x9100); + hws[IMX8MN_CLK_IPG_ROOT] = imx_clk_hw_divider2("ipg_root", "ahb", base + 0x9080, 0, 1); + hws[IMX8MN_CLK_IPG_AUDIO_ROOT] = imx_clk_hw_divider2("ipg_audio_root", "audio_ahb", base + 0x9180, 0, 1); + hws[IMX8MN_CLK_DRAM_CORE] = imx_clk_hw_mux2_flags("dram_core_clk", base + 0x9800, 24, 1, imx8mn_dram_core_sels, ARRAY_SIZE(imx8mn_dram_core_sels), CLK_IS_CRITICAL); + + /* + * DRAM clocks are manipulated from TF-A outside clock framework. + * Mark with GET_RATE_NOCACHE to always read div value from hardware + */ + hws[IMX8MN_CLK_DRAM_ALT] = __imx8m_clk_hw_composite("dram_alt", imx8mn_dram_alt_sels, base + 0xa000, CLK_GET_RATE_NOCACHE); + hws[IMX8MN_CLK_DRAM_APB] = __imx8m_clk_hw_composite("dram_apb", imx8mn_dram_apb_sels, base + 0xa080, CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE); + + hws[IMX8MN_CLK_DISP_PIXEL] = imx8m_clk_hw_composite("disp_pixel", imx8mn_disp_pixel_sels, base + 0xa500); + hws[IMX8MN_CLK_SAI2] = imx8m_clk_hw_composite("sai2", imx8mn_sai2_sels, base + 0xa600); + hws[IMX8MN_CLK_SAI3] = imx8m_clk_hw_composite("sai3", imx8mn_sai3_sels, base + 0xa680); + hws[IMX8MN_CLK_SAI5] = imx8m_clk_hw_composite("sai5", imx8mn_sai5_sels, base + 0xa780); + hws[IMX8MN_CLK_SAI6] = imx8m_clk_hw_composite("sai6", imx8mn_sai6_sels, base + 0xa800); + hws[IMX8MN_CLK_SPDIF1] = imx8m_clk_hw_composite("spdif1", imx8mn_spdif1_sels, base + 0xa880); + hws[IMX8MN_CLK_ENET_REF] = imx8m_clk_hw_composite("enet_ref", imx8mn_enet_ref_sels, base + 0xa980); + hws[IMX8MN_CLK_ENET_TIMER] = imx8m_clk_hw_composite("enet_timer", imx8mn_enet_timer_sels, base + 0xaa00); + hws[IMX8MN_CLK_ENET_PHY_REF] = imx8m_clk_hw_composite("enet_phy", imx8mn_enet_phy_sels, base + 0xaa80); + hws[IMX8MN_CLK_NAND] = imx8m_clk_hw_composite("nand", imx8mn_nand_sels, base + 0xab00); + hws[IMX8MN_CLK_QSPI] = imx8m_clk_hw_composite("qspi", imx8mn_qspi_sels, base + 0xab80); + hws[IMX8MN_CLK_USDHC1] = imx8m_clk_hw_composite("usdhc1", imx8mn_usdhc1_sels, base + 0xac00); + hws[IMX8MN_CLK_USDHC2] = imx8m_clk_hw_composite("usdhc2", imx8mn_usdhc2_sels, base + 0xac80); + hws[IMX8MN_CLK_I2C1] = imx8m_clk_hw_composite("i2c1", imx8mn_i2c1_sels, base + 0xad00); + hws[IMX8MN_CLK_I2C2] = imx8m_clk_hw_composite("i2c2", imx8mn_i2c2_sels, base + 0xad80); + hws[IMX8MN_CLK_I2C3] = imx8m_clk_hw_composite("i2c3", imx8mn_i2c3_sels, base + 0xae00); + hws[IMX8MN_CLK_I2C4] = imx8m_clk_hw_composite("i2c4", imx8mn_i2c4_sels, base + 0xae80); + hws[IMX8MN_CLK_UART1] = imx8m_clk_hw_composite("uart1", imx8mn_uart1_sels, base + 0xaf00); + hws[IMX8MN_CLK_UART2] = imx8m_clk_hw_composite("uart2", imx8mn_uart2_sels, base + 0xaf80); + hws[IMX8MN_CLK_UART3] = imx8m_clk_hw_composite("uart3", imx8mn_uart3_sels, base + 0xb000); + hws[IMX8MN_CLK_UART4] = imx8m_clk_hw_composite("uart4", imx8mn_uart4_sels, base + 0xb080); + hws[IMX8MN_CLK_USB_CORE_REF] = imx8m_clk_hw_composite("usb_core_ref", imx8mn_usb_core_sels, base + 0xb100); + hws[IMX8MN_CLK_USB_PHY_REF] = imx8m_clk_hw_composite("usb_phy_ref", imx8mn_usb_phy_sels, base + 0xb180); + hws[IMX8MN_CLK_GIC] = imx8m_clk_hw_composite_critical("gic", imx8mn_gic_sels, base + 0xb200); + hws[IMX8MN_CLK_ECSPI1] = imx8m_clk_hw_composite("ecspi1", imx8mn_ecspi1_sels, base + 0xb280); + hws[IMX8MN_CLK_ECSPI2] = imx8m_clk_hw_composite("ecspi2", imx8mn_ecspi2_sels, base + 0xb300); + hws[IMX8MN_CLK_PWM1] = imx8m_clk_hw_composite("pwm1", imx8mn_pwm1_sels, base + 0xb380); + hws[IMX8MN_CLK_PWM2] = imx8m_clk_hw_composite("pwm2", imx8mn_pwm2_sels, base + 0xb400); + hws[IMX8MN_CLK_PWM3] = imx8m_clk_hw_composite("pwm3", imx8mn_pwm3_sels, base + 0xb480); + hws[IMX8MN_CLK_PWM4] = imx8m_clk_hw_composite("pwm4", imx8mn_pwm4_sels, base + 0xb500); + hws[IMX8MN_CLK_WDOG] = imx8m_clk_hw_composite("wdog", imx8mn_wdog_sels, base + 0xb900); + hws[IMX8MN_CLK_WRCLK] = imx8m_clk_hw_composite("wrclk", imx8mn_wrclk_sels, base + 0xb980); + hws[IMX8MN_CLK_CLKO1] = imx8m_clk_hw_composite("clko1", imx8mn_clko1_sels, base + 0xba00); + hws[IMX8MN_CLK_CLKO2] = imx8m_clk_hw_composite("clko2", imx8mn_clko2_sels, base + 0xba80); + hws[IMX8MN_CLK_DSI_CORE] = imx8m_clk_hw_composite("dsi_core", imx8mn_dsi_core_sels, base + 0xbb00); + hws[IMX8MN_CLK_DSI_PHY_REF] = imx8m_clk_hw_composite("dsi_phy_ref", imx8mn_dsi_phy_sels, base + 0xbb80); + hws[IMX8MN_CLK_DSI_DBI] = imx8m_clk_hw_composite("dsi_dbi", imx8mn_dsi_dbi_sels, base + 0xbc00); + hws[IMX8MN_CLK_USDHC3] = imx8m_clk_hw_composite("usdhc3", imx8mn_usdhc3_sels, base + 0xbc80); + hws[IMX8MN_CLK_CAMERA_PIXEL] = imx8m_clk_hw_composite("camera_pixel", imx8mn_camera_pixel_sels, base + 0xbd00); + hws[IMX8MN_CLK_CSI1_PHY_REF] = imx8m_clk_hw_composite("csi1_phy_ref", imx8mn_csi1_phy_sels, base + 0xbd80); + hws[IMX8MN_CLK_CSI2_PHY_REF] = imx8m_clk_hw_composite("csi2_phy_ref", imx8mn_csi2_phy_sels, base + 0xbf00); + hws[IMX8MN_CLK_CSI2_ESC] = imx8m_clk_hw_composite("csi2_esc", imx8mn_csi2_esc_sels, base + 0xbf80); + hws[IMX8MN_CLK_ECSPI3] = imx8m_clk_hw_composite("ecspi3", imx8mn_ecspi3_sels, base + 0xc180); + hws[IMX8MN_CLK_PDM] = imx8m_clk_hw_composite("pdm", imx8mn_pdm_sels, base + 0xc200); + hws[IMX8MN_CLK_SAI7] = imx8m_clk_hw_composite("sai7", imx8mn_sai7_sels, base + 0xc300); + + hws[IMX8MN_CLK_ECSPI1_ROOT] = imx_clk_hw_gate4("ecspi1_root_clk", "ecspi1", base + 0x4070, 0); + hws[IMX8MN_CLK_ECSPI2_ROOT] = imx_clk_hw_gate4("ecspi2_root_clk", "ecspi2", base + 0x4080, 0); + hws[IMX8MN_CLK_ECSPI3_ROOT] = imx_clk_hw_gate4("ecspi3_root_clk", "ecspi3", base + 0x4090, 0); + hws[IMX8MN_CLK_ENET1_ROOT] = imx_clk_hw_gate4("enet1_root_clk", "enet_axi", base + 0x40a0, 0); + hws[IMX8MN_CLK_GPIO1_ROOT] = imx_clk_hw_gate4("gpio1_root_clk", "ipg_root", base + 0x40b0, 0); + hws[IMX8MN_CLK_GPIO2_ROOT] = imx_clk_hw_gate4("gpio2_root_clk", "ipg_root", base + 0x40c0, 0); + hws[IMX8MN_CLK_GPIO3_ROOT] = imx_clk_hw_gate4("gpio3_root_clk", "ipg_root", base + 0x40d0, 0); + hws[IMX8MN_CLK_GPIO4_ROOT] = imx_clk_hw_gate4("gpio4_root_clk", "ipg_root", base + 0x40e0, 0); + hws[IMX8MN_CLK_GPIO5_ROOT] = imx_clk_hw_gate4("gpio5_root_clk", "ipg_root", base + 0x40f0, 0); + hws[IMX8MN_CLK_I2C1_ROOT] = imx_clk_hw_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0); + hws[IMX8MN_CLK_I2C2_ROOT] = imx_clk_hw_gate4("i2c2_root_clk", "i2c2", base + 0x4180, 0); + hws[IMX8MN_CLK_I2C3_ROOT] = imx_clk_hw_gate4("i2c3_root_clk", "i2c3", base + 0x4190, 0); + hws[IMX8MN_CLK_I2C4_ROOT] = imx_clk_hw_gate4("i2c4_root_clk", "i2c4", base + 0x41a0, 0); + hws[IMX8MN_CLK_MU_ROOT] = imx_clk_hw_gate4("mu_root_clk", "ipg_root", base + 0x4210, 0); + hws[IMX8MN_CLK_OCOTP_ROOT] = imx_clk_hw_gate4("ocotp_root_clk", "ipg_root", base + 0x4220, 0); + hws[IMX8MN_CLK_PWM1_ROOT] = imx_clk_hw_gate4("pwm1_root_clk", "pwm1", base + 0x4280, 0); + hws[IMX8MN_CLK_PWM2_ROOT] = imx_clk_hw_gate4("pwm2_root_clk", "pwm2", base + 0x4290, 0); + hws[IMX8MN_CLK_PWM3_ROOT] = imx_clk_hw_gate4("pwm3_root_clk", "pwm3", base + 0x42a0, 0); + hws[IMX8MN_CLK_PWM4_ROOT] = imx_clk_hw_gate4("pwm4_root_clk", "pwm4", base + 0x42b0, 0); + hws[IMX8MN_CLK_QSPI_ROOT] = imx_clk_hw_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0); + hws[IMX8MN_CLK_NAND_ROOT] = imx_clk_hw_gate2_shared2("nand_root_clk", "nand", base + 0x4300, 0, &share_count_nand); + hws[IMX8MN_CLK_NAND_USDHC_BUS_RAWNAND_CLK] = imx_clk_hw_gate2_shared2("nand_usdhc_rawnand_clk", "nand_usdhc_bus", base + 0x4300, 0, &share_count_nand); + hws[IMX8MN_CLK_SAI2_ROOT] = imx_clk_hw_gate2_shared2("sai2_root_clk", "sai2", base + 0x4340, 0, &share_count_sai2); + hws[IMX8MN_CLK_SAI2_IPG] = imx_clk_hw_gate2_shared2("sai2_ipg_clk", "ipg_audio_root", base + 0x4340, 0, &share_count_sai2); + hws[IMX8MN_CLK_SAI3_ROOT] = imx_clk_hw_gate2_shared2("sai3_root_clk", "sai3", base + 0x4350, 0, &share_count_sai3); + hws[IMX8MN_CLK_SAI3_IPG] = imx_clk_hw_gate2_shared2("sai3_ipg_clk", "ipg_audio_root", base + 0x4350, 0, &share_count_sai3); + hws[IMX8MN_CLK_SAI5_ROOT] = imx_clk_hw_gate2_shared2("sai5_root_clk", "sai5", base + 0x4370, 0, &share_count_sai5); + hws[IMX8MN_CLK_SAI5_IPG] = imx_clk_hw_gate2_shared2("sai5_ipg_clk", "ipg_audio_root", base + 0x4370, 0, &share_count_sai5); + hws[IMX8MN_CLK_SAI6_ROOT] = imx_clk_hw_gate2_shared2("sai6_root_clk", "sai6", base + 0x4380, 0, &share_count_sai6); + hws[IMX8MN_CLK_SAI6_IPG] = imx_clk_hw_gate2_shared2("sai6_ipg_clk", "ipg_audio_root", base + 0x4380, 0, &share_count_sai6); + hws[IMX8MN_CLK_UART1_ROOT] = imx_clk_hw_gate4("uart1_root_clk", "uart1", base + 0x4490, 0); + hws[IMX8MN_CLK_UART2_ROOT] = imx_clk_hw_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0); + hws[IMX8MN_CLK_UART3_ROOT] = imx_clk_hw_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0); + hws[IMX8MN_CLK_UART4_ROOT] = imx_clk_hw_gate4("uart4_root_clk", "uart4", base + 0x44c0, 0); + hws[IMX8MN_CLK_USB1_CTRL_ROOT] = imx_clk_hw_gate4("usb1_ctrl_root_clk", "usb_bus", base + 0x44d0, 0); + hws[IMX8MN_CLK_GPU_CORE_ROOT] = imx_clk_hw_gate4("gpu_core_root_clk", "gpu_core_div", base + 0x44f0, 0); + hws[IMX8MN_CLK_USDHC1_ROOT] = imx_clk_hw_gate4("usdhc1_root_clk", "usdhc1", base + 0x4510, 0); + hws[IMX8MN_CLK_USDHC2_ROOT] = imx_clk_hw_gate4("usdhc2_root_clk", "usdhc2", base + 0x4520, 0); + hws[IMX8MN_CLK_WDOG1_ROOT] = imx_clk_hw_gate4("wdog1_root_clk", "wdog", base + 0x4530, 0); + hws[IMX8MN_CLK_WDOG2_ROOT] = imx_clk_hw_gate4("wdog2_root_clk", "wdog", base + 0x4540, 0); + hws[IMX8MN_CLK_WDOG3_ROOT] = imx_clk_hw_gate4("wdog3_root_clk", "wdog", base + 0x4550, 0); + hws[IMX8MN_CLK_GPU_BUS_ROOT] = imx_clk_hw_gate4("gpu_root_clk", "gpu_axi", base + 0x4570, 0); + hws[IMX8MN_CLK_ASRC_ROOT] = imx_clk_hw_gate4("asrc_root_clk", "audio_ahb", base + 0x4580, 0); + hws[IMX8MN_CLK_PDM_ROOT] = imx_clk_hw_gate2_shared2("pdm_root_clk", "pdm", base + 0x45b0, 0, &share_count_pdm); + hws[IMX8MN_CLK_PDM_IPG] = imx_clk_hw_gate2_shared2("pdm_ipg_clk", "ipg_audio_root", base + 0x45b0, 0, &share_count_pdm); + hws[IMX8MN_CLK_DISP_AXI_ROOT] = imx_clk_hw_gate2_shared2("disp_axi_root_clk", "disp_axi", base + 0x45d0, 0, &share_count_disp); + hws[IMX8MN_CLK_DISP_APB_ROOT] = imx_clk_hw_gate2_shared2("disp_apb_root_clk", "disp_apb", base + 0x45d0, 0, &share_count_disp); + hws[IMX8MN_CLK_CAMERA_PIXEL_ROOT] = imx_clk_hw_gate2_shared2("camera_pixel_clk", "camera_pixel", base + 0x45d0, 0, &share_count_disp); + hws[IMX8MN_CLK_DISP_PIXEL_ROOT] = imx_clk_hw_gate2_shared2("disp_pixel_clk", "disp_pixel", base + 0x45d0, 0, &share_count_disp); + hws[IMX8MN_CLK_USDHC3_ROOT] = imx_clk_hw_gate4("usdhc3_root_clk", "usdhc3", base + 0x45e0, 0); + hws[IMX8MN_CLK_TMU_ROOT] = imx_clk_hw_gate4("tmu_root_clk", "ipg_root", base + 0x4620, 0); + hws[IMX8MN_CLK_SDMA1_ROOT] = imx_clk_hw_gate4("sdma1_clk", "ipg_root", base + 0x43a0, 0); + hws[IMX8MN_CLK_SDMA2_ROOT] = imx_clk_hw_gate4("sdma2_clk", "ipg_audio_root", base + 0x43b0, 0); + hws[IMX8MN_CLK_SDMA3_ROOT] = imx_clk_hw_gate4("sdma3_clk", "ipg_audio_root", base + 0x45f0, 0); + hws[IMX8MN_CLK_SAI7_ROOT] = imx_clk_hw_gate2_shared2("sai7_root_clk", "sai7", base + 0x4650, 0, &share_count_sai7); + + hws[IMX8MN_CLK_DRAM_ALT_ROOT] = imx_clk_hw_fixed_factor("dram_alt_root", "dram_alt", 1, 4); + + hws[IMX8MN_CLK_ARM] = imx_clk_hw_cpu("arm", "arm_a53_div", + hws[IMX8MN_CLK_A53_DIV]->clk, + hws[IMX8MN_CLK_A53_SRC]->clk, + hws[IMX8MN_ARM_PLL_OUT]->clk, + hws[IMX8MN_SYS_PLL1_800M]->clk); + + imx_check_clk_hws(hws, IMX8MN_CLK_END); + + ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data); if (ret < 0) { - dev_err(dev, "failed to register clks for i.MX8MN\n"); - goto unregister_clks; + dev_err(dev, "failed to register hws for i.MX8MN\n"); + goto unregister_hws; + } + + for (i = 0; i < ARRAY_SIZE(uart_clk_ids); i++) { + int index = uart_clk_ids[i]; + + uart_hws[i] = &hws[index]->clk; } - imx_register_uart_clocks(uart_clks); + imx_register_uart_clocks(uart_hws); return 0; -unregister_clks: - imx_unregister_clocks(clks, ARRAY_SIZE(clks)); +unregister_hws: + imx_unregister_hw_clocks(hws, IMX8MN_CLK_END); return ret; } @@ -572,6 +591,11 @@ static struct platform_driver imx8mn_clk_driver = { .probe = imx8mn_clocks_probe, .driver = { .name = "imx8mn-ccm", + /* + * Disable bind attributes: clocks are not removed and + * reloading the driver will crash or break devices. + */ + .suppress_bind_attrs = true, .of_match_table = of_match_ptr(imx8mn_clk_of_match), }, }; diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c new file mode 100644 index 000000000000..f6c120cca0d4 --- /dev/null +++ b/drivers/clk/imx/clk-imx8mp.c @@ -0,0 +1,764 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2019 NXP. + */ + +#include <dt-bindings/clock/imx8mp-clock.h> +#include <linux/clkdev.h> +#include <linux/clk-provider.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/of_address.h> +#include <linux/platform_device.h> +#include <linux/types.h> + +#include "clk.h" + +static u32 share_count_nand; +static u32 share_count_media; + +static const char * const pll_ref_sels[] = { "osc_24m", "dummy", "dummy", "dummy", }; +static const char * const audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ref_sel", }; +static const char * const audio_pll2_bypass_sels[] = {"audio_pll2", "audio_pll2_ref_sel", }; +static const char * const video_pll1_bypass_sels[] = {"video_pll1", "video_pll1_ref_sel", }; +static const char * const dram_pll_bypass_sels[] = {"dram_pll", "dram_pll_ref_sel", }; +static const char * const gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", }; +static const char * const vpu_pll_bypass_sels[] = {"vpu_pll", "vpu_pll_ref_sel", }; +static const char * const arm_pll_bypass_sels[] = {"arm_pll", "arm_pll_ref_sel", }; +static const char * const sys_pll1_bypass_sels[] = {"sys_pll1", "sys_pll1_ref_sel", }; +static const char * const sys_pll2_bypass_sels[] = {"sys_pll2", "sys_pll2_ref_sel", }; +static const char * const sys_pll3_bypass_sels[] = {"sys_pll3", "sys_pll3_ref_sel", }; + +static const char * const imx8mp_a53_sels[] = {"osc_24m", "arm_pll_out", "sys_pll2_500m", + "sys_pll2_1000m", "sys_pll1_800m", "sys_pll1_400m", + "audio_pll1_out", "sys_pll3_out", }; + +static const char * const imx8mp_m7_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_250m", + "vpu_pll_out", "sys_pll1_800m", "audio_pll1_out", + "video_pll1_out", "sys_pll3_out", }; + +static const char * const imx8mp_ml_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m", + "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out", + "video_pll1_out", "audio_pll2_out", }; + +static const char * const imx8mp_gpu3d_core_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m", + "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out", + "video_pll1_out", "audio_pll2_out", }; + +static const char * const imx8mp_gpu3d_shader_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m", + "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out", + "video_pll1_out", "audio_pll2_out", }; + +static const char * const imx8mp_gpu2d_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m", + "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out", + "video_pll1_out", "audio_pll2_out", }; + +static const char * const imx8mp_audio_axi_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m", + "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out", + "video_pll1_out", "audio_pll2_out", }; + +static const char * const imx8mp_hsio_axi_sels[] = {"osc_24m", "sys_pll2_500m", "sys_pll1_800m", + "sys_pll2_100m", "sys_pll2_200m", "clk_ext2", + "clk_ext4", "audio_pll2_out", }; + +static const char * const imx8mp_media_isp_sels[] = {"osc_24m", "sys_pll2_1000m", "sys_pll1_800m", + "sys_pll3_out", "sys_pll1_400m", "audio_pll2_out", + "clk_ext1", "sys_pll2_500m", }; + +static const char * const imx8mp_main_axi_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll1_800m", + "sys_pll2_250m", "sys_pll2_1000m", "audio_pll1_out", + "video_pll1_out", "sys_pll1_100m",}; + +static const char * const imx8mp_enet_axi_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll1_800m", + "sys_pll2_250m", "sys_pll2_200m", "audio_pll1_out", + "video_pll1_out", "sys_pll3_out", }; + +static const char * const imx8mp_nand_usdhc_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll1_800m", + "sys_pll2_200m", "sys_pll1_133m", "sys_pll3_out", + "sys_pll2_250m", "audio_pll1_out", }; + +static const char * const imx8mp_vpu_bus_sels[] = {"osc_24m", "sys_pll1_800m", "vpu_pll_out", + "audio_pll2_out", "sys_pll3_out", "sys_pll2_1000m", + "sys_pll2_200m", "sys_pll1_100m", }; + +static const char * const imx8mp_media_axi_sels[] = {"osc_24m", "sys_pll2_1000m", "sys_pll1_800m", + "sys_pll3_out", "sys_pll1_40m", "audio_pll2_out", + "clk_ext1", "sys_pll2_500m", }; + +static const char * const imx8mp_media_apb_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll1_800m", + "sys_pll3_out", "sys_pll1_40m", "audio_pll2_out", + "clk_ext1", "sys_pll1_133m", }; + +static const char * const imx8mp_gpu_axi_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out", + "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out", + "video_pll1_out", "audio_pll2_out", }; + +static const char * const imx8mp_gpu_ahb_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out", + "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out", + "video_pll1_out", "audio_pll2_out", }; + +static const char * const imx8mp_noc_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll3_out", + "sys_pll2_1000m", "sys_pll2_500m", "audio_pll1_out", + "video_pll1_out", "audio_pll2_out", }; + +static const char * const imx8mp_noc_io_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll3_out", + "sys_pll2_1000m", "sys_pll2_500m", "audio_pll1_out", + "video_pll1_out", "audio_pll2_out", }; + +static const char * const imx8mp_ml_axi_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out", + "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out", + "video_pll1_out", "audio_pll2_out", }; + +static const char * const imx8mp_ml_ahb_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out", + "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out", + "video_pll1_out", "audio_pll2_out", }; + +static const char * const imx8mp_ahb_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_800m", + "sys_pll1_400m", "sys_pll2_125m", "sys_pll3_out", + "audio_pll1_out", "video_pll1_out", }; + +static const char * const imx8mp_audio_ahb_sels[] = {"osc_24m", "sys_pll2_500m", "sys_pll1_800m", + "sys_pll2_1000m", "sys_pll2_166m", "sys_pll3_out", + "audio_pll1_out", "video_pll1_out", }; + +static const char * const imx8mp_mipi_dsi_esc_rx_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_80m", + "sys_pll1_800m", "sys_pll2_1000m", + "sys_pll3_out", "clk_ext3", "audio_pll2_out", }; + +static const char * const imx8mp_dram_alt_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll1_100m", + "sys_pll2_500m", "sys_pll2_1000m", "sys_pll3_out", + "audio_pll1_out", "sys_pll1_266m", }; + +static const char * const imx8mp_dram_apb_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m", + "sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out", + "sys_pll2_250m", "audio_pll2_out", }; + +static const char * const imx8mp_vpu_g1_sels[] = {"osc_24m", "vpu_pll_out", "sys_pll1_800m", + "sys_pll2_1000m", "sys_pll1_100m", "sys_pll2_125m", + "sys_pll3_out", "audio_pll1_out", }; + +static const char * const imx8mp_vpu_g2_sels[] = {"osc_24m", "vpu_pll_out", "sys_pll1_800m", + "sys_pll2_1000m", "sys_pll1_100m", "sys_pll2_125m", + "sys_pll3_out", "audio_pll1_out", }; + +static const char * const imx8mp_can1_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m", + "sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out", + "sys_pll2_250m", "audio_pll2_out", }; + +static const char * const imx8mp_can2_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m", + "sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out", + "sys_pll2_250m", "audio_pll2_out", }; + +static const char * const imx8mp_memrepair_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", + "sys_pll3_out", "audio_pll1_out", "video_pll1_out", + "audio_pll2_out", "sys_pll1_133m", }; + +static const char * const imx8mp_pcie_phy_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll2_500m", + "clk_ext1", "clk_ext2", "clk_ext3", + "clk_ext4", "sys_pll1_400m", }; + +static const char * const imx8mp_pcie_aux_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_50m", + "sys_pll3_out", "sys_pll2_100m", "sys_pll1_80m", + "sys_pll1_160m", "sys_pll1_200m", }; + +static const char * const imx8mp_i2c5_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", + "sys_pll3_out", "audio_pll1_out", "video_pll1_out", + "audio_pll2_out", "sys_pll1_133m", }; + +static const char * const imx8mp_i2c6_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", + "sys_pll3_out", "audio_pll1_out", "video_pll1_out", + "audio_pll2_out", "sys_pll1_133m", }; + +static const char * const imx8mp_sai1_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", + "video_pll1_out", "sys_pll1_133m", "osc_hdmi", + "clk_ext1", "clk_ext2", }; + +static const char * const imx8mp_sai2_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", + "video_pll1_out", "sys_pll1_133m", "osc_hdmi", + "clk_ext2", "clk_ext3", }; + +static const char * const imx8mp_sai3_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", + "video_pll1_out", "sys_pll1_133m", "osc_hdmi", + "clk_ext3", "clk_ext4", }; + +static const char * const imx8mp_sai4_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", + "video_pll1_out", "sys_pll1_133m", "osc_hdmi", + "clk_ext1", "clk_ext2", }; + +static const char * const imx8mp_sai5_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", + "video_pll1_out", "sys_pll1_133m", "osc_hdmi", + "clk_ext2", "clk_ext3", }; + +static const char * const imx8mp_sai6_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", + "video_pll1_out", "sys_pll1_133m", "osc_hdmi", + "clk_ext3", "clk_ext4", }; + +static const char * const imx8mp_enet_qos_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll2_50m", + "sys_pll2_100m", "sys_pll1_160m", "audio_pll1_out", + "video_pll1_out", "clk_ext4", }; + +static const char * const imx8mp_enet_qos_timer_sels[] = {"osc_24m", "sys_pll2_100m", "audio_pll1_out", + "clk_ext1", "clk_ext2", "clk_ext3", + "clk_ext4", "video_pll1_out", }; + +static const char * const imx8mp_enet_ref_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll2_50m", + "sys_pll2_100m", "sys_pll1_160m", "audio_pll1_out", + "video_pll1_out", "clk_ext4", }; + +static const char * const imx8mp_enet_timer_sels[] = {"osc_24m", "sys_pll2_100m", "audio_pll1_out", + "clk_ext1", "clk_ext2", "clk_ext3", + "clk_ext4", "video_pll1_out", }; + +static const char * const imx8mp_enet_phy_ref_sels[] = {"osc_24m", "sys_pll2_50m", "sys_pll2_125m", + "sys_pll2_200m", "sys_pll2_500m", "audio_pll1_out", + "video_pll1_out", "audio_pll2_out", }; + +static const char * const imx8mp_nand_sels[] = {"osc_24m", "sys_pll2_500m", "audio_pll1_out", + "sys_pll1_400m", "audio_pll2_out", "sys_pll3_out", + "sys_pll2_250m", "video_pll1_out", }; + +static const char * const imx8mp_qspi_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll2_333m", + "sys_pll2_500m", "audio_pll2_out", "sys_pll1_266m", + "sys_pll3_out", "sys_pll1_100m", }; + +static const char * const imx8mp_usdhc1_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m", + "sys_pll2_500m", "sys_pll3_out", "sys_pll1_266m", + "audio_pll2_out", "sys_pll1_100m", }; + +static const char * const imx8mp_usdhc2_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m", + "sys_pll2_500m", "sys_pll3_out", "sys_pll1_266m", + "audio_pll2_out", "sys_pll1_100m", }; + +static const char * const imx8mp_i2c1_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", + "sys_pll3_out", "audio_pll1_out", "video_pll1_out", + "audio_pll2_out", "sys_pll1_133m", }; + +static const char * const imx8mp_i2c2_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", + "sys_pll3_out", "audio_pll1_out", "video_pll1_out", + "audio_pll2_out", "sys_pll1_133m", }; + +static const char * const imx8mp_i2c3_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", + "sys_pll3_out", "audio_pll1_out", "video_pll1_out", + "audio_pll2_out", "sys_pll1_133m", }; + +static const char * const imx8mp_i2c4_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", + "sys_pll3_out", "audio_pll1_out", "video_pll1_out", + "audio_pll2_out", "sys_pll1_133m", }; + +static const char * const imx8mp_uart1_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m", + "sys_pll2_100m", "sys_pll3_out", "clk_ext2", + "clk_ext4", "audio_pll2_out", }; + +static const char * const imx8mp_uart2_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m", + "sys_pll2_100m", "sys_pll3_out", "clk_ext2", + "clk_ext3", "audio_pll2_out", }; + +static const char * const imx8mp_uart3_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m", + "sys_pll2_100m", "sys_pll3_out", "clk_ext2", + "clk_ext4", "audio_pll2_out", }; + +static const char * const imx8mp_uart4_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m", + "sys_pll2_100m", "sys_pll3_out", "clk_ext2", + "clk_ext3", "audio_pll2_out", }; + +static const char * const imx8mp_usb_core_ref_sels[] = {"osc_24m", "sys_pll1_100m", "sys_pll1_40m", + "sys_pll2_100m", "sys_pll2_200m", "clk_ext2", + "clk_ext3", "audio_pll2_out", }; + +static const char * const imx8mp_usb_phy_ref_sels[] = {"osc_24m", "sys_pll1_100m", "sys_pll1_40m", + "sys_pll2_100m", "sys_pll2_200m", "clk_ext2", + "clk_ext3", "audio_pll2_out", }; + +static const char * const imx8mp_gic_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m", + "sys_pll2_100m", "sys_pll1_800m", + "sys_pll2_500m", "clk_ext4", "audio_pll2_out" }; + +static const char * const imx8mp_ecspi1_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m", + "sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out", + "sys_pll2_250m", "audio_pll2_out", }; + +static const char * const imx8mp_ecspi2_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m", + "sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out", + "sys_pll2_250m", "audio_pll2_out", }; + +static const char * const imx8mp_pwm1_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", + "sys_pll1_40m", "sys_pll3_out", "clk_ext1", + "sys_pll1_80m", "video_pll1_out", }; + +static const char * const imx8mp_pwm2_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", + "sys_pll1_40m", "sys_pll3_out", "clk_ext1", + "sys_pll1_80m", "video_pll1_out", }; + +static const char * const imx8mp_pwm3_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", + "sys_pll1_40m", "sys_pll3_out", "clk_ext2", + "sys_pll1_80m", "video_pll1_out", }; + +static const char * const imx8mp_pwm4_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", + "sys_pll1_40m", "sys_pll3_out", "clk_ext2", + "sys_pll1_80m", "video_pll1_out", }; + +static const char * const imx8mp_gpt1_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m", + "sys_pll1_40m", "video_pll1_out", "sys_pll1_80m", + "audio_pll1_out", "clk_ext1" }; + +static const char * const imx8mp_gpt2_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m", + "sys_pll1_40m", "video_pll1_out", "sys_pll1_80m", + "audio_pll1_out", "clk_ext2" }; + +static const char * const imx8mp_gpt3_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m", + "sys_pll1_40m", "video_pll1_out", "sys_pll1_80m", + "audio_pll1_out", "clk_ext3" }; + +static const char * const imx8mp_gpt4_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m", + "sys_pll1_40m", "video_pll1_out", "sys_pll1_80m", + "audio_pll1_out", "clk_ext1" }; + +static const char * const imx8mp_gpt5_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m", + "sys_pll1_40m", "video_pll1_out", "sys_pll1_80m", + "audio_pll1_out", "clk_ext2" }; + +static const char * const imx8mp_gpt6_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m", + "sys_pll1_40m", "video_pll1_out", "sys_pll1_80m", + "audio_pll1_out", "clk_ext3" }; + +static const char * const imx8mp_wdog_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_160m", + "vpu_pll_out", "sys_pll2_125m", "sys_pll3_out", + "sys_pll1_80m", "sys_pll2_166m" }; + +static const char * const imx8mp_wrclk_sels[] = {"osc_24m", "sys_pll1_40m", "vpu_pll_out", + "sys_pll3_out", "sys_pll2_200m", "sys_pll1_266m", + "sys_pll2_500m", "sys_pll1_100m" }; + +static const char * const imx8mp_ipp_do_clko1_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll1_133m", + "sys_pll1_200m", "audio_pll2_out", "sys_pll2_500m", + "vpu_pll_out", "sys_pll1_80m" }; + +static const char * const imx8mp_ipp_do_clko2_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_400m", + "sys_pll1_166m", "sys_pll3_out", "audio_pll1_out", + "video_pll1_out", "osc_32k" }; + +static const char * const imx8mp_hdmi_fdcc_tst_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m", + "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out", + "audio_pll2_out", "video_pll1_out", }; + +static const char * const imx8mp_hdmi_27m_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", + "sys_pll3_out", "audio_pll1_out", "video_pll1_out", + "audio_pll2_out", "sys_pll1_133m", }; + +static const char * const imx8mp_hdmi_ref_266m_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll3_out", + "sys_pll2_333m", "sys_pll1_266m", "sys_pll2_200m", + "audio_pll1_out", "video_pll1_out", }; + +static const char * const imx8mp_usdhc3_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m", + "sys_pll2_500m", "sys_pll3_out", "sys_pll1_266m", + "audio_pll2_out", "sys_pll1_100m", }; + +static const char * const imx8mp_media_cam1_pix_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m", + "sys_pll1_800m", "sys_pll2_1000m", + "sys_pll3_out", "audio_pll2_out", + "video_pll1_out", }; + +static const char * const imx8mp_media_mipi_phy1_ref_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll2_100m", + "sys_pll1_800m", "sys_pll2_1000m", + "clk_ext2", "audio_pll2_out", + "video_pll1_out", }; + +static const char * const imx8mp_media_disp1_pix_sels[] = {"osc_24m", "video_pll1_out", "audio_pll2_out", + "audio_pll1_out", "sys_pll1_800m", + "sys_pll2_1000m", "sys_pll3_out", "clk_ext4", }; + +static const char * const imx8mp_media_cam2_pix_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m", + "sys_pll1_800m", "sys_pll2_1000m", + "sys_pll3_out", "audio_pll2_out", + "video_pll1_out", }; + +static const char * const imx8mp_media_mipi_phy2_ref_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll2_100m", + "sys_pll1_800m", "sys_pll2_1000m", + "clk_ext2", "audio_pll2_out", + "video_pll1_out", }; + +static const char * const imx8mp_media_mipi_csi2_esc_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_80m", + "sys_pll1_800m", "sys_pll2_1000m", + "sys_pll3_out", "clk_ext3", + "audio_pll2_out", }; + +static const char * const imx8mp_pcie2_ctrl_sels[] = {"osc_24m", "sys_pll2_250m", "sys_pll2_200m", + "sys_pll1_266m", "sys_pll1_800m", "sys_pll2_500m", + "sys_pll2_333m", "sys_pll3_out", }; + +static const char * const imx8mp_pcie2_phy_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll2_500m", + "clk_ext1", "clk_ext2", "clk_ext3", + "clk_ext4", "sys_pll1_400m", }; + +static const char * const imx8mp_media_mipi_test_byte_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_50m", + "sys_pll3_out", "sys_pll2_100m", + "sys_pll1_80m", "sys_pll1_160m", + "sys_pll1_200m", }; + +static const char * const imx8mp_ecspi3_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m", + "sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out", + "sys_pll2_250m", "audio_pll2_out", }; + +static const char * const imx8mp_pdm_sels[] = {"osc_24m", "sys_pll2_100m", "audio_pll1_out", + "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out", + "clk_ext3", "audio_pll2_out", }; + +static const char * const imx8mp_vpu_vc8000e_sels[] = {"osc_24m", "vpu_pll_out", "sys_pll1_800m", + "sys_pll2_1000m", "audio_pll2_out", "sys_pll2_125m", + "sys_pll3_out", "audio_pll1_out", }; + +static const char * const imx8mp_sai7_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", + "video_pll1_out", "sys_pll1_133m", "osc_hdmi", + "clk_ext3", "clk_ext4", }; + +static const char * const imx8mp_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", }; + +static struct clk_hw **hws; +static struct clk_hw_onecell_data *clk_hw_data; + +static const int uart_clk_ids[] = { + IMX8MP_CLK_UART1_ROOT, + IMX8MP_CLK_UART2_ROOT, + IMX8MP_CLK_UART3_ROOT, + IMX8MP_CLK_UART4_ROOT, +}; +static struct clk **uart_clks[ARRAY_SIZE(uart_clk_ids) + 1]; + +static int imx8mp_clocks_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + void __iomem *anatop_base, *ccm_base; + int i; + + np = of_find_compatible_node(NULL, NULL, "fsl,imx8mp-anatop"); + anatop_base = of_iomap(np, 0); + if (WARN_ON(!anatop_base)) + return -ENOMEM; + + np = dev->of_node; + ccm_base = devm_platform_ioremap_resource(pdev, 0); + if (WARN_ON(IS_ERR(ccm_base))) { + iounmap(anatop_base); + return PTR_ERR(ccm_base); + } + + clk_hw_data = kzalloc(struct_size(clk_hw_data, hws, IMX8MP_CLK_END), GFP_KERNEL); + if (WARN_ON(!clk_hw_data)) { + iounmap(anatop_base); + return -ENOMEM; + } + + clk_hw_data->num = IMX8MP_CLK_END; + hws = clk_hw_data->hws; + + hws[IMX8MP_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0); + hws[IMX8MP_CLK_24M] = imx_obtain_fixed_clk_hw(np, "osc_24m"); + hws[IMX8MP_CLK_32K] = imx_obtain_fixed_clk_hw(np, "osc_32k"); + hws[IMX8MP_CLK_EXT1] = imx_obtain_fixed_clk_hw(np, "clk_ext1"); + hws[IMX8MP_CLK_EXT2] = imx_obtain_fixed_clk_hw(np, "clk_ext2"); + hws[IMX8MP_CLK_EXT3] = imx_obtain_fixed_clk_hw(np, "clk_ext3"); + hws[IMX8MP_CLK_EXT4] = imx_obtain_fixed_clk_hw(np, "clk_ext4"); + + hws[IMX8MP_AUDIO_PLL1_REF_SEL] = imx_clk_hw_mux("audio_pll1_ref_sel", anatop_base + 0x0, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MP_AUDIO_PLL2_REF_SEL] = imx_clk_hw_mux("audio_pll2_ref_sel", anatop_base + 0x14, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MP_VIDEO_PLL1_REF_SEL] = imx_clk_hw_mux("video_pll1_ref_sel", anatop_base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MP_DRAM_PLL_REF_SEL] = imx_clk_hw_mux("dram_pll_ref_sel", anatop_base + 0x50, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MP_GPU_PLL_REF_SEL] = imx_clk_hw_mux("gpu_pll_ref_sel", anatop_base + 0x64, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MP_VPU_PLL_REF_SEL] = imx_clk_hw_mux("vpu_pll_ref_sel", anatop_base + 0x74, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MP_ARM_PLL_REF_SEL] = imx_clk_hw_mux("arm_pll_ref_sel", anatop_base + 0x84, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MP_SYS_PLL1_REF_SEL] = imx_clk_hw_mux("sys_pll1_ref_sel", anatop_base + 0x94, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MP_SYS_PLL2_REF_SEL] = imx_clk_hw_mux("sys_pll2_ref_sel", anatop_base + 0x104, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MP_SYS_PLL3_REF_SEL] = imx_clk_hw_mux("sys_pll3_ref_sel", anatop_base + 0x114, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + + hws[IMX8MP_AUDIO_PLL1] = imx_clk_hw_pll14xx("audio_pll1", "audio_pll1_ref_sel", anatop_base, &imx_1443x_pll); + hws[IMX8MP_AUDIO_PLL2] = imx_clk_hw_pll14xx("audio_pll2", "audio_pll2_ref_sel", anatop_base + 0x14, &imx_1443x_pll); + hws[IMX8MP_VIDEO_PLL1] = imx_clk_hw_pll14xx("video_pll1", "video_pll1_ref_sel", anatop_base + 0x28, &imx_1443x_pll); + hws[IMX8MP_DRAM_PLL] = imx_clk_hw_pll14xx("dram_pll", "dram_pll_ref_sel", anatop_base + 0x50, &imx_1443x_dram_pll); + hws[IMX8MP_GPU_PLL] = imx_clk_hw_pll14xx("gpu_pll", "gpu_pll_ref_sel", anatop_base + 0x64, &imx_1416x_pll); + hws[IMX8MP_VPU_PLL] = imx_clk_hw_pll14xx("vpu_pll", "vpu_pll_ref_sel", anatop_base + 0x74, &imx_1416x_pll); + hws[IMX8MP_ARM_PLL] = imx_clk_hw_pll14xx("arm_pll", "arm_pll_ref_sel", anatop_base + 0x84, &imx_1416x_pll); + hws[IMX8MP_SYS_PLL1] = imx_clk_hw_pll14xx("sys_pll1", "sys_pll1_ref_sel", anatop_base + 0x94, &imx_1416x_pll); + hws[IMX8MP_SYS_PLL2] = imx_clk_hw_pll14xx("sys_pll2", "sys_pll2_ref_sel", anatop_base + 0x104, &imx_1416x_pll); + hws[IMX8MP_SYS_PLL3] = imx_clk_hw_pll14xx("sys_pll3", "sys_pll3_ref_sel", anatop_base + 0x114, &imx_1416x_pll); + + hws[IMX8MP_AUDIO_PLL1_BYPASS] = imx_clk_hw_mux_flags("audio_pll1_bypass", anatop_base, 4, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT); + hws[IMX8MP_AUDIO_PLL2_BYPASS] = imx_clk_hw_mux_flags("audio_pll2_bypass", anatop_base + 0x14, 4, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels), CLK_SET_RATE_PARENT); + hws[IMX8MP_VIDEO_PLL1_BYPASS] = imx_clk_hw_mux_flags("video_pll1_bypass", anatop_base + 0x28, 4, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels), CLK_SET_RATE_PARENT); + hws[IMX8MP_DRAM_PLL_BYPASS] = imx_clk_hw_mux_flags("dram_pll_bypass", anatop_base + 0x50, 4, 1, dram_pll_bypass_sels, ARRAY_SIZE(dram_pll_bypass_sels), CLK_SET_RATE_PARENT); + hws[IMX8MP_GPU_PLL_BYPASS] = imx_clk_hw_mux_flags("gpu_pll_bypass", anatop_base + 0x64, 4, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT); + hws[IMX8MP_VPU_PLL_BYPASS] = imx_clk_hw_mux_flags("vpu_pll_bypass", anatop_base + 0x74, 4, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels), CLK_SET_RATE_PARENT); + hws[IMX8MP_ARM_PLL_BYPASS] = imx_clk_hw_mux_flags("arm_pll_bypass", anatop_base + 0x84, 4, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT); + hws[IMX8MP_SYS_PLL1_BYPASS] = imx_clk_hw_mux_flags("sys_pll1_bypass", anatop_base + 0x94, 4, 1, sys_pll1_bypass_sels, ARRAY_SIZE(sys_pll1_bypass_sels), CLK_SET_RATE_PARENT); + hws[IMX8MP_SYS_PLL2_BYPASS] = imx_clk_hw_mux_flags("sys_pll2_bypass", anatop_base + 0x104, 4, 1, sys_pll2_bypass_sels, ARRAY_SIZE(sys_pll2_bypass_sels), CLK_SET_RATE_PARENT); + hws[IMX8MP_SYS_PLL3_BYPASS] = imx_clk_hw_mux_flags("sys_pll3_bypass", anatop_base + 0x114, 4, 1, sys_pll3_bypass_sels, ARRAY_SIZE(sys_pll3_bypass_sels), CLK_SET_RATE_PARENT); + + hws[IMX8MP_AUDIO_PLL1_OUT] = imx_clk_hw_gate("audio_pll1_out", "audio_pll1_bypass", anatop_base, 13); + hws[IMX8MP_AUDIO_PLL2_OUT] = imx_clk_hw_gate("audio_pll2_out", "audio_pll2_bypass", anatop_base + 0x14, 13); + hws[IMX8MP_VIDEO_PLL1_OUT] = imx_clk_hw_gate("video_pll1_out", "video_pll1_bypass", anatop_base + 0x28, 13); + hws[IMX8MP_DRAM_PLL_OUT] = imx_clk_hw_gate("dram_pll_out", "dram_pll_bypass", anatop_base + 0x50, 13); + hws[IMX8MP_GPU_PLL_OUT] = imx_clk_hw_gate("gpu_pll_out", "gpu_pll_bypass", anatop_base + 0x64, 11); + hws[IMX8MP_VPU_PLL_OUT] = imx_clk_hw_gate("vpu_pll_out", "vpu_pll_bypass", anatop_base + 0x74, 11); + hws[IMX8MP_ARM_PLL_OUT] = imx_clk_hw_gate("arm_pll_out", "arm_pll_bypass", anatop_base + 0x84, 11); + hws[IMX8MP_SYS_PLL1_OUT] = imx_clk_hw_gate("sys_pll1_out", "sys_pll1_bypass", anatop_base + 0x94, 11); + hws[IMX8MP_SYS_PLL2_OUT] = imx_clk_hw_gate("sys_pll2_out", "sys_pll2_bypass", anatop_base + 0x104, 11); + hws[IMX8MP_SYS_PLL3_OUT] = imx_clk_hw_gate("sys_pll3_out", "sys_pll3_bypass", anatop_base + 0x114, 11); + + hws[IMX8MP_SYS_PLL1_40M] = imx_clk_hw_fixed_factor("sys_pll1_40m", "sys_pll1_out", 1, 20); + hws[IMX8MP_SYS_PLL1_80M] = imx_clk_hw_fixed_factor("sys_pll1_80m", "sys_pll1_out", 1, 10); + hws[IMX8MP_SYS_PLL1_100M] = imx_clk_hw_fixed_factor("sys_pll1_100m", "sys_pll1_out", 1, 8); + hws[IMX8MP_SYS_PLL1_133M] = imx_clk_hw_fixed_factor("sys_pll1_133m", "sys_pll1_out", 1, 6); + hws[IMX8MP_SYS_PLL1_160M] = imx_clk_hw_fixed_factor("sys_pll1_160m", "sys_pll1_out", 1, 5); + hws[IMX8MP_SYS_PLL1_200M] = imx_clk_hw_fixed_factor("sys_pll1_200m", "sys_pll1_out", 1, 4); + hws[IMX8MP_SYS_PLL1_266M] = imx_clk_hw_fixed_factor("sys_pll1_266m", "sys_pll1_out", 1, 3); + hws[IMX8MP_SYS_PLL1_400M] = imx_clk_hw_fixed_factor("sys_pll1_400m", "sys_pll1_out", 1, 2); + hws[IMX8MP_SYS_PLL1_800M] = imx_clk_hw_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1, 1); + + hws[IMX8MP_SYS_PLL2_50M] = imx_clk_hw_fixed_factor("sys_pll2_50m", "sys_pll2_out", 1, 20); + hws[IMX8MP_SYS_PLL2_100M] = imx_clk_hw_fixed_factor("sys_pll2_100m", "sys_pll2_out", 1, 10); + hws[IMX8MP_SYS_PLL2_125M] = imx_clk_hw_fixed_factor("sys_pll2_125m", "sys_pll2_out", 1, 8); + hws[IMX8MP_SYS_PLL2_166M] = imx_clk_hw_fixed_factor("sys_pll2_166m", "sys_pll2_out", 1, 6); + hws[IMX8MP_SYS_PLL2_200M] = imx_clk_hw_fixed_factor("sys_pll2_200m", "sys_pll2_out", 1, 5); + hws[IMX8MP_SYS_PLL2_250M] = imx_clk_hw_fixed_factor("sys_pll2_250m", "sys_pll2_out", 1, 4); + hws[IMX8MP_SYS_PLL2_333M] = imx_clk_hw_fixed_factor("sys_pll2_333m", "sys_pll2_out", 1, 3); + hws[IMX8MP_SYS_PLL2_500M] = imx_clk_hw_fixed_factor("sys_pll2_500m", "sys_pll2_out", 1, 2); + hws[IMX8MP_SYS_PLL2_1000M] = imx_clk_hw_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1); + + hws[IMX8MP_CLK_A53_SRC] = imx_clk_hw_mux2("arm_a53_src", ccm_base + 0x8000, 24, 3, imx8mp_a53_sels, ARRAY_SIZE(imx8mp_a53_sels)); + hws[IMX8MP_CLK_M7_SRC] = imx_clk_hw_mux2("arm_m7_src", ccm_base + 0x8080, 24, 3, imx8mp_m7_sels, ARRAY_SIZE(imx8mp_m7_sels)); + hws[IMX8MP_CLK_ML_SRC] = imx_clk_hw_mux2("ml_src", ccm_base + 0x8100, 24, 3, imx8mp_ml_sels, ARRAY_SIZE(imx8mp_ml_sels)); + hws[IMX8MP_CLK_GPU3D_CORE_SRC] = imx_clk_hw_mux2("gpu3d_core_src", ccm_base + 0x8180, 24, 3, imx8mp_gpu3d_core_sels, ARRAY_SIZE(imx8mp_gpu3d_core_sels)); + hws[IMX8MP_CLK_GPU3D_SHADER_SRC] = imx_clk_hw_mux2("gpu3d_shader_src", ccm_base + 0x8200, 24, 3, imx8mp_gpu3d_shader_sels, ARRAY_SIZE(imx8mp_gpu3d_shader_sels)); + hws[IMX8MP_CLK_GPU2D_SRC] = imx_clk_hw_mux2("gpu2d_src", ccm_base + 0x8280, 24, 3, imx8mp_gpu2d_sels, ARRAY_SIZE(imx8mp_gpu2d_sels)); + hws[IMX8MP_CLK_AUDIO_AXI_SRC] = imx_clk_hw_mux2("audio_axi_src", ccm_base + 0x8300, 24, 3, imx8mp_audio_axi_sels, ARRAY_SIZE(imx8mp_audio_axi_sels)); + hws[IMX8MP_CLK_HSIO_AXI_SRC] = imx_clk_hw_mux2("hsio_axi_src", ccm_base + 0x8380, 24, 3, imx8mp_hsio_axi_sels, ARRAY_SIZE(imx8mp_hsio_axi_sels)); + hws[IMX8MP_CLK_MEDIA_ISP_SRC] = imx_clk_hw_mux2("media_isp_src", ccm_base + 0x8400, 24, 3, imx8mp_media_isp_sels, ARRAY_SIZE(imx8mp_media_isp_sels)); + hws[IMX8MP_CLK_A53_CG] = imx_clk_hw_gate3("arm_a53_cg", "arm_a53_src", ccm_base + 0x8000, 28); + hws[IMX8MP_CLK_M4_CG] = imx_clk_hw_gate3("arm_m7_cg", "arm_m7_src", ccm_base + 0x8080, 28); + hws[IMX8MP_CLK_ML_CG] = imx_clk_hw_gate3("ml_cg", "ml_src", ccm_base + 0x8100, 28); + hws[IMX8MP_CLK_GPU3D_CORE_CG] = imx_clk_hw_gate3("gpu3d_core_cg", "gpu3d_core_src", ccm_base + 0x8180, 28); + hws[IMX8MP_CLK_GPU3D_SHADER_CG] = imx_clk_hw_gate3("gpu3d_shader_cg", "gpu3d_shader_src", ccm_base + 0x8200, 28); + hws[IMX8MP_CLK_GPU2D_CG] = imx_clk_hw_gate3("gpu2d_cg", "gpu2d_src", ccm_base + 0x8280, 28); + hws[IMX8MP_CLK_AUDIO_AXI_CG] = imx_clk_hw_gate3("audio_axi_cg", "audio_axi_src", ccm_base + 0x8300, 28); + hws[IMX8MP_CLK_HSIO_AXI_CG] = imx_clk_hw_gate3("hsio_axi_cg", "hsio_axi_src", ccm_base + 0x8380, 28); + hws[IMX8MP_CLK_MEDIA_ISP_CG] = imx_clk_hw_gate3("media_isp_cg", "media_isp_src", ccm_base + 0x8400, 28); + hws[IMX8MP_CLK_A53_DIV] = imx_clk_hw_divider2("arm_a53_div", "arm_a53_cg", ccm_base + 0x8000, 0, 3); + hws[IMX8MP_CLK_M7_DIV] = imx_clk_hw_divider2("arm_m7_div", "arm_m7_cg", ccm_base + 0x8080, 0, 3); + hws[IMX8MP_CLK_ML_DIV] = imx_clk_hw_divider2("ml_div", "ml_cg", ccm_base + 0x8100, 0, 3); + hws[IMX8MP_CLK_GPU3D_CORE_DIV] = imx_clk_hw_divider2("gpu3d_core_div", "gpu3d_core_cg", ccm_base + 0x8180, 0, 3); + hws[IMX8MP_CLK_GPU3D_SHADER_DIV] = imx_clk_hw_divider2("gpu3d_shader_div", "gpu3d_shader_cg", ccm_base + 0x8200, 0, 3); + hws[IMX8MP_CLK_GPU2D_DIV] = imx_clk_hw_divider2("gpu2d_div", "gpu2d_cg", ccm_base + 0x8280, 0, 3); + hws[IMX8MP_CLK_AUDIO_AXI_DIV] = imx_clk_hw_divider2("audio_axi_div", "audio_axi_cg", ccm_base + 0x8300, 0, 3); + hws[IMX8MP_CLK_HSIO_AXI_DIV] = imx_clk_hw_divider2("hsio_axi_div", "hsio_axi_cg", ccm_base + 0x8380, 0, 3); + hws[IMX8MP_CLK_MEDIA_ISP_DIV] = imx_clk_hw_divider2("media_isp_div", "media_isp_cg", ccm_base + 0x8400, 0, 3); + + hws[IMX8MP_CLK_MAIN_AXI] = imx8m_clk_hw_composite_critical("main_axi", imx8mp_main_axi_sels, ccm_base + 0x8800); + hws[IMX8MP_CLK_ENET_AXI] = imx8m_clk_hw_composite("enet_axi", imx8mp_enet_axi_sels, ccm_base + 0x8880); + hws[IMX8MP_CLK_NAND_USDHC_BUS] = imx8m_clk_hw_composite_critical("nand_usdhc_bus", imx8mp_nand_usdhc_sels, ccm_base + 0x8900); + hws[IMX8MP_CLK_VPU_BUS] = imx8m_clk_hw_composite("vpu_bus", imx8mp_vpu_bus_sels, ccm_base + 0x8980); + hws[IMX8MP_CLK_MEDIA_AXI] = imx8m_clk_hw_composite("media_axi", imx8mp_media_axi_sels, ccm_base + 0x8a00); + hws[IMX8MP_CLK_MEDIA_APB] = imx8m_clk_hw_composite("media_apb", imx8mp_media_apb_sels, ccm_base + 0x8a80); + hws[IMX8MP_CLK_HDMI_APB] = imx8m_clk_hw_composite("hdmi_apb", imx8mp_media_apb_sels, ccm_base + 0x8b00); + hws[IMX8MP_CLK_HDMI_AXI] = imx8m_clk_hw_composite("hdmi_axi", imx8mp_media_apb_sels, ccm_base + 0x8b80); + hws[IMX8MP_CLK_GPU_AXI] = imx8m_clk_hw_composite("gpu_axi", imx8mp_gpu_axi_sels, ccm_base + 0x8c00); + hws[IMX8MP_CLK_GPU_AHB] = imx8m_clk_hw_composite("gpu_ahb", imx8mp_gpu_ahb_sels, ccm_base + 0x8c80); + hws[IMX8MP_CLK_NOC] = imx8m_clk_hw_composite_critical("noc", imx8mp_noc_sels, ccm_base + 0x8d00); + hws[IMX8MP_CLK_NOC_IO] = imx8m_clk_hw_composite_critical("noc_io", imx8mp_noc_io_sels, ccm_base + 0x8d80); + hws[IMX8MP_CLK_ML_AXI] = imx8m_clk_hw_composite("ml_axi", imx8mp_ml_axi_sels, ccm_base + 0x8e00); + hws[IMX8MP_CLK_ML_AHB] = imx8m_clk_hw_composite("ml_ahb", imx8mp_ml_ahb_sels, ccm_base + 0x8e80); + + hws[IMX8MP_CLK_AHB] = imx8m_clk_hw_composite_critical("ahb_root", imx8mp_ahb_sels, ccm_base + 0x9000); + hws[IMX8MP_CLK_AUDIO_AHB] = imx8m_clk_hw_composite("audio_ahb", imx8mp_audio_ahb_sels, ccm_base + 0x9100); + hws[IMX8MP_CLK_MIPI_DSI_ESC_RX] = imx8m_clk_hw_composite("mipi_dsi_esc_rx", imx8mp_mipi_dsi_esc_rx_sels, ccm_base + 0x9200); + + hws[IMX8MP_CLK_IPG_ROOT] = imx_clk_hw_divider2("ipg_root", "ahb_root", ccm_base + 0x9080, 0, 1); + hws[IMX8MP_CLK_IPG_AUDIO_ROOT] = imx_clk_hw_divider2("ipg_audio_root", "audio_ahb", ccm_base + 0x9180, 0, 1); + + hws[IMX8MP_CLK_DRAM_ALT] = imx8m_clk_hw_composite("dram_alt", imx8mp_dram_alt_sels, ccm_base + 0xa000); + hws[IMX8MP_CLK_DRAM_APB] = imx8m_clk_hw_composite_critical("dram_apb", imx8mp_dram_apb_sels, ccm_base + 0xa080); + hws[IMX8MP_CLK_VPU_G1] = imx8m_clk_hw_composite("vpu_g1", imx8mp_vpu_g1_sels, ccm_base + 0xa100); + hws[IMX8MP_CLK_VPU_G2] = imx8m_clk_hw_composite("vpu_g2", imx8mp_vpu_g2_sels, ccm_base + 0xa180); + hws[IMX8MP_CLK_CAN1] = imx8m_clk_hw_composite("can1", imx8mp_can1_sels, ccm_base + 0xa200); + hws[IMX8MP_CLK_CAN2] = imx8m_clk_hw_composite("can2", imx8mp_can2_sels, ccm_base + 0xa280); + hws[IMX8MP_CLK_MEMREPAIR] = imx8m_clk_hw_composite("memrepair", imx8mp_memrepair_sels, ccm_base + 0xa300); + hws[IMX8MP_CLK_PCIE_PHY] = imx8m_clk_hw_composite("pcie_phy", imx8mp_pcie_phy_sels, ccm_base + 0xa380); + hws[IMX8MP_CLK_PCIE_AUX] = imx8m_clk_hw_composite("pcie_aux", imx8mp_pcie_aux_sels, ccm_base + 0xa400); + hws[IMX8MP_CLK_I2C5] = imx8m_clk_hw_composite("i2c5", imx8mp_i2c5_sels, ccm_base + 0xa480); + hws[IMX8MP_CLK_I2C6] = imx8m_clk_hw_composite("i2c6", imx8mp_i2c6_sels, ccm_base + 0xa500); + hws[IMX8MP_CLK_SAI1] = imx8m_clk_hw_composite("sai1", imx8mp_sai1_sels, ccm_base + 0xa580); + hws[IMX8MP_CLK_SAI2] = imx8m_clk_hw_composite("sai2", imx8mp_sai2_sels, ccm_base + 0xa600); + hws[IMX8MP_CLK_SAI3] = imx8m_clk_hw_composite("sai3", imx8mp_sai3_sels, ccm_base + 0xa680); + hws[IMX8MP_CLK_SAI4] = imx8m_clk_hw_composite("sai4", imx8mp_sai4_sels, ccm_base + 0xa700); + hws[IMX8MP_CLK_SAI5] = imx8m_clk_hw_composite("sai5", imx8mp_sai5_sels, ccm_base + 0xa780); + hws[IMX8MP_CLK_SAI6] = imx8m_clk_hw_composite("sai6", imx8mp_sai6_sels, ccm_base + 0xa800); + hws[IMX8MP_CLK_ENET_QOS] = imx8m_clk_hw_composite("enet_qos", imx8mp_enet_qos_sels, ccm_base + 0xa880); + hws[IMX8MP_CLK_ENET_QOS_TIMER] = imx8m_clk_hw_composite("enet_qos_timer", imx8mp_enet_qos_timer_sels, ccm_base + 0xa900); + hws[IMX8MP_CLK_ENET_REF] = imx8m_clk_hw_composite("enet_ref", imx8mp_enet_ref_sels, ccm_base + 0xa980); + hws[IMX8MP_CLK_ENET_TIMER] = imx8m_clk_hw_composite("enet_timer", imx8mp_enet_timer_sels, ccm_base + 0xaa00); + hws[IMX8MP_CLK_ENET_PHY_REF] = imx8m_clk_hw_composite("enet_phy_ref", imx8mp_enet_phy_ref_sels, ccm_base + 0xaa80); + hws[IMX8MP_CLK_NAND] = imx8m_clk_hw_composite("nand", imx8mp_nand_sels, ccm_base + 0xab00); + hws[IMX8MP_CLK_QSPI] = imx8m_clk_hw_composite("qspi", imx8mp_qspi_sels, ccm_base + 0xab80); + hws[IMX8MP_CLK_USDHC1] = imx8m_clk_hw_composite("usdhc1", imx8mp_usdhc1_sels, ccm_base + 0xac00); + hws[IMX8MP_CLK_USDHC2] = imx8m_clk_hw_composite("usdhc2", imx8mp_usdhc2_sels, ccm_base + 0xac80); + hws[IMX8MP_CLK_I2C1] = imx8m_clk_hw_composite("i2c1", imx8mp_i2c1_sels, ccm_base + 0xad00); + hws[IMX8MP_CLK_I2C2] = imx8m_clk_hw_composite("i2c2", imx8mp_i2c2_sels, ccm_base + 0xad80); + hws[IMX8MP_CLK_I2C3] = imx8m_clk_hw_composite("i2c3", imx8mp_i2c3_sels, ccm_base + 0xae00); + hws[IMX8MP_CLK_I2C4] = imx8m_clk_hw_composite("i2c4", imx8mp_i2c4_sels, ccm_base + 0xae80); + + hws[IMX8MP_CLK_UART1] = imx8m_clk_hw_composite("uart1", imx8mp_uart1_sels, ccm_base + 0xaf00); + hws[IMX8MP_CLK_UART2] = imx8m_clk_hw_composite("uart2", imx8mp_uart2_sels, ccm_base + 0xaf80); + hws[IMX8MP_CLK_UART3] = imx8m_clk_hw_composite("uart3", imx8mp_uart3_sels, ccm_base + 0xb000); + hws[IMX8MP_CLK_UART4] = imx8m_clk_hw_composite("uart4", imx8mp_uart4_sels, ccm_base + 0xb080); + hws[IMX8MP_CLK_USB_CORE_REF] = imx8m_clk_hw_composite("usb_core_ref", imx8mp_usb_core_ref_sels, ccm_base + 0xb100); + hws[IMX8MP_CLK_USB_PHY_REF] = imx8m_clk_hw_composite("usb_phy_ref", imx8mp_usb_phy_ref_sels, ccm_base + 0xb180); + hws[IMX8MP_CLK_GIC] = imx8m_clk_hw_composite_critical("gic", imx8mp_gic_sels, ccm_base + 0xb200); + hws[IMX8MP_CLK_ECSPI1] = imx8m_clk_hw_composite("ecspi1", imx8mp_ecspi1_sels, ccm_base + 0xb280); + hws[IMX8MP_CLK_ECSPI2] = imx8m_clk_hw_composite("ecspi2", imx8mp_ecspi2_sels, ccm_base + 0xb300); + hws[IMX8MP_CLK_PWM1] = imx8m_clk_hw_composite("pwm1", imx8mp_pwm1_sels, ccm_base + 0xb380); + hws[IMX8MP_CLK_PWM2] = imx8m_clk_hw_composite("pwm2", imx8mp_pwm2_sels, ccm_base + 0xb400); + hws[IMX8MP_CLK_PWM3] = imx8m_clk_hw_composite("pwm3", imx8mp_pwm3_sels, ccm_base + 0xb480); + hws[IMX8MP_CLK_PWM4] = imx8m_clk_hw_composite("pwm4", imx8mp_pwm4_sels, ccm_base + 0xb500); + + hws[IMX8MP_CLK_GPT1] = imx8m_clk_hw_composite("gpt1", imx8mp_gpt1_sels, ccm_base + 0xb580); + hws[IMX8MP_CLK_GPT2] = imx8m_clk_hw_composite("gpt2", imx8mp_gpt2_sels, ccm_base + 0xb600); + hws[IMX8MP_CLK_GPT3] = imx8m_clk_hw_composite("gpt3", imx8mp_gpt3_sels, ccm_base + 0xb680); + hws[IMX8MP_CLK_GPT4] = imx8m_clk_hw_composite("gpt4", imx8mp_gpt4_sels, ccm_base + 0xb700); + hws[IMX8MP_CLK_GPT5] = imx8m_clk_hw_composite("gpt5", imx8mp_gpt5_sels, ccm_base + 0xb780); + hws[IMX8MP_CLK_GPT6] = imx8m_clk_hw_composite("gpt6", imx8mp_gpt6_sels, ccm_base + 0xb800); + hws[IMX8MP_CLK_WDOG] = imx8m_clk_hw_composite("wdog", imx8mp_wdog_sels, ccm_base + 0xb900); + hws[IMX8MP_CLK_WRCLK] = imx8m_clk_hw_composite("wrclk", imx8mp_wrclk_sels, ccm_base + 0xb980); + hws[IMX8MP_CLK_IPP_DO_CLKO1] = imx8m_clk_hw_composite("ipp_do_clko1", imx8mp_ipp_do_clko1_sels, ccm_base + 0xba00); + hws[IMX8MP_CLK_IPP_DO_CLKO2] = imx8m_clk_hw_composite("ipp_do_clko2", imx8mp_ipp_do_clko2_sels, ccm_base + 0xba80); + hws[IMX8MP_CLK_HDMI_FDCC_TST] = imx8m_clk_hw_composite("hdmi_fdcc_tst", imx8mp_hdmi_fdcc_tst_sels, ccm_base + 0xbb00); + hws[IMX8MP_CLK_HDMI_27M] = imx8m_clk_hw_composite("hdmi_27m", imx8mp_hdmi_27m_sels, ccm_base + 0xbb80); + hws[IMX8MP_CLK_HDMI_REF_266M] = imx8m_clk_hw_composite("hdmi_ref_266m", imx8mp_hdmi_ref_266m_sels, ccm_base + 0xbc00); + hws[IMX8MP_CLK_USDHC3] = imx8m_clk_hw_composite("usdhc3", imx8mp_usdhc3_sels, ccm_base + 0xbc80); + hws[IMX8MP_CLK_MEDIA_CAM1_PIX] = imx8m_clk_hw_composite("media_cam1_pix", imx8mp_media_cam1_pix_sels, ccm_base + 0xbd00); + hws[IMX8MP_CLK_MEDIA_MIPI_PHY1_REF] = imx8m_clk_hw_composite("media_mipi_phy1_ref", imx8mp_media_mipi_phy1_ref_sels, ccm_base + 0xbd80); + hws[IMX8MP_CLK_MEDIA_DISP1_PIX] = imx8m_clk_hw_composite("media_disp1_pix", imx8mp_media_disp1_pix_sels, ccm_base + 0xbe00); + hws[IMX8MP_CLK_MEDIA_CAM2_PIX] = imx8m_clk_hw_composite("media_cam2_pix", imx8mp_media_cam2_pix_sels, ccm_base + 0xbe80); + hws[IMX8MP_CLK_MEDIA_MIPI_PHY2_REF] = imx8m_clk_hw_composite("media_mipi_phy2_ref", imx8mp_media_mipi_phy2_ref_sels, ccm_base + 0xbf00); + hws[IMX8MP_CLK_MEDIA_MIPI_CSI2_ESC] = imx8m_clk_hw_composite("media_mipi_csi2_esc", imx8mp_media_mipi_csi2_esc_sels, ccm_base + 0xbf80); + hws[IMX8MP_CLK_PCIE2_CTRL] = imx8m_clk_hw_composite("pcie2_ctrl", imx8mp_pcie2_ctrl_sels, ccm_base + 0xc000); + hws[IMX8MP_CLK_PCIE2_PHY] = imx8m_clk_hw_composite("pcie2_phy", imx8mp_pcie2_phy_sels, ccm_base + 0xc080); + hws[IMX8MP_CLK_MEDIA_MIPI_TEST_BYTE] = imx8m_clk_hw_composite("media_mipi_test_byte", imx8mp_media_mipi_test_byte_sels, ccm_base + 0xc100); + hws[IMX8MP_CLK_ECSPI3] = imx8m_clk_hw_composite("ecspi3", imx8mp_ecspi3_sels, ccm_base + 0xc180); + hws[IMX8MP_CLK_PDM] = imx8m_clk_hw_composite("pdm", imx8mp_pdm_sels, ccm_base + 0xc200); + hws[IMX8MP_CLK_VPU_VC8000E] = imx8m_clk_hw_composite("vpu_vc8000e", imx8mp_vpu_vc8000e_sels, ccm_base + 0xc280); + hws[IMX8MP_CLK_SAI7] = imx8m_clk_hw_composite("sai7", imx8mp_sai7_sels, ccm_base + 0xc300); + + hws[IMX8MP_CLK_DRAM_ALT_ROOT] = imx_clk_hw_fixed_factor("dram_alt_root", "dram_alt", 1, 4); + hws[IMX8MP_CLK_DRAM_CORE] = imx_clk_hw_mux2_flags("dram_core_clk", ccm_base + 0x9800, 24, 1, imx8mp_dram_core_sels, ARRAY_SIZE(imx8mp_dram_core_sels), CLK_IS_CRITICAL); + + hws[IMX8MP_CLK_DRAM1_ROOT] = imx_clk_hw_gate4_flags("dram1_root_clk", "dram_core_clk", ccm_base + 0x4050, 0, CLK_IS_CRITICAL); + hws[IMX8MP_CLK_ECSPI1_ROOT] = imx_clk_hw_gate4("ecspi1_root_clk", "ecspi1", ccm_base + 0x4070, 0); + hws[IMX8MP_CLK_ECSPI2_ROOT] = imx_clk_hw_gate4("ecspi2_root_clk", "ecspi2", ccm_base + 0x4080, 0); + hws[IMX8MP_CLK_ECSPI3_ROOT] = imx_clk_hw_gate4("ecspi3_root_clk", "ecspi3", ccm_base + 0x4090, 0); + hws[IMX8MP_CLK_ENET1_ROOT] = imx_clk_hw_gate4("enet1_root_clk", "enet_axi", ccm_base + 0x40a0, 0); + hws[IMX8MP_CLK_GPIO1_ROOT] = imx_clk_hw_gate4("gpio1_root_clk", "ipg_root", ccm_base + 0x40b0, 0); + hws[IMX8MP_CLK_GPIO2_ROOT] = imx_clk_hw_gate4("gpio2_root_clk", "ipg_root", ccm_base + 0x40c0, 0); + hws[IMX8MP_CLK_GPIO3_ROOT] = imx_clk_hw_gate4("gpio3_root_clk", "ipg_root", ccm_base + 0x40d0, 0); + hws[IMX8MP_CLK_GPIO4_ROOT] = imx_clk_hw_gate4("gpio4_root_clk", "ipg_root", ccm_base + 0x40e0, 0); + hws[IMX8MP_CLK_GPIO5_ROOT] = imx_clk_hw_gate4("gpio5_root_clk", "ipg_root", ccm_base + 0x40f0, 0); + hws[IMX8MP_CLK_GPT1_ROOT] = imx_clk_hw_gate4("gpt1_root_clk", "gpt1", ccm_base + 0x4100, 0); + hws[IMX8MP_CLK_GPT2_ROOT] = imx_clk_hw_gate4("gpt2_root_clk", "gpt2", ccm_base + 0x4110, 0); + hws[IMX8MP_CLK_GPT3_ROOT] = imx_clk_hw_gate4("gpt3_root_clk", "gpt3", ccm_base + 0x4120, 0); + hws[IMX8MP_CLK_GPT4_ROOT] = imx_clk_hw_gate4("gpt4_root_clk", "gpt4", ccm_base + 0x4130, 0); + hws[IMX8MP_CLK_GPT5_ROOT] = imx_clk_hw_gate4("gpt5_root_clk", "gpt5", ccm_base + 0x4140, 0); + hws[IMX8MP_CLK_GPT6_ROOT] = imx_clk_hw_gate4("gpt6_root_clk", "gpt6", ccm_base + 0x4150, 0); + hws[IMX8MP_CLK_I2C1_ROOT] = imx_clk_hw_gate4("i2c1_root_clk", "i2c1", ccm_base + 0x4170, 0); + hws[IMX8MP_CLK_I2C2_ROOT] = imx_clk_hw_gate4("i2c2_root_clk", "i2c2", ccm_base + 0x4180, 0); + hws[IMX8MP_CLK_I2C3_ROOT] = imx_clk_hw_gate4("i2c3_root_clk", "i2c3", ccm_base + 0x4190, 0); + hws[IMX8MP_CLK_I2C4_ROOT] = imx_clk_hw_gate4("i2c4_root_clk", "i2c4", ccm_base + 0x41a0, 0); + hws[IMX8MP_CLK_PCIE_ROOT] = imx_clk_hw_gate4("pcie_root_clk", "pcie_aux", ccm_base + 0x4250, 0); + hws[IMX8MP_CLK_PWM1_ROOT] = imx_clk_hw_gate4("pwm1_root_clk", "pwm1", ccm_base + 0x4280, 0); + hws[IMX8MP_CLK_PWM2_ROOT] = imx_clk_hw_gate4("pwm2_root_clk", "pwm2", ccm_base + 0x4290, 0); + hws[IMX8MP_CLK_PWM3_ROOT] = imx_clk_hw_gate4("pwm3_root_clk", "pwm3", ccm_base + 0x42a0, 0); + hws[IMX8MP_CLK_PWM4_ROOT] = imx_clk_hw_gate4("pwm4_root_clk", "pwm4", ccm_base + 0x42b0, 0); + hws[IMX8MP_CLK_QOS_ROOT] = imx_clk_hw_gate4("qos_root_clk", "ipg_root", ccm_base + 0x42c0, 0); + hws[IMX8MP_CLK_QOS_ENET_ROOT] = imx_clk_hw_gate4("qos_enet_root_clk", "ipg_root", ccm_base + 0x42e0, 0); + hws[IMX8MP_CLK_QSPI_ROOT] = imx_clk_hw_gate4("qspi_root_clk", "qspi", ccm_base + 0x42f0, 0); + hws[IMX8MP_CLK_NAND_ROOT] = imx_clk_hw_gate2_shared2("nand_root_clk", "nand", ccm_base + 0x4300, 0, &share_count_nand); + hws[IMX8MP_CLK_NAND_USDHC_BUS_RAWNAND_CLK] = imx_clk_hw_gate2_shared2("nand_usdhc_rawnand_clk", "nand_usdhc_bus", ccm_base + 0x4300, 0, &share_count_nand); + hws[IMX8MP_CLK_I2C5_ROOT] = imx_clk_hw_gate2("i2c5_root_clk", "i2c5", ccm_base + 0x4330, 0); + hws[IMX8MP_CLK_I2C6_ROOT] = imx_clk_hw_gate2("i2c6_root_clk", "i2c6", ccm_base + 0x4340, 0); + hws[IMX8MP_CLK_CAN1_ROOT] = imx_clk_hw_gate2("can1_root_clk", "can1", ccm_base + 0x4350, 0); + hws[IMX8MP_CLK_CAN2_ROOT] = imx_clk_hw_gate2("can2_root_clk", "can2", ccm_base + 0x4360, 0); + hws[IMX8MP_CLK_SDMA1_ROOT] = imx_clk_hw_gate4("sdma1_root_clk", "ipg_root", ccm_base + 0x43a0, 0); + hws[IMX8MP_CLK_ENET_QOS_ROOT] = imx_clk_hw_gate4("enet_qos_root_clk", "enet_axi", ccm_base + 0x43b0, 0); + hws[IMX8MP_CLK_SIM_ENET_ROOT] = imx_clk_hw_gate4("sim_enet_root_clk", "enet_axi", ccm_base + 0x4400, 0); + hws[IMX8MP_CLK_GPU2D_ROOT] = imx_clk_hw_gate4("gpu2d_root_clk", "gpu2d_div", ccm_base + 0x4450, 0); + hws[IMX8MP_CLK_GPU3D_ROOT] = imx_clk_hw_gate4("gpu3d_root_clk", "gpu3d_core_div", ccm_base + 0x4460, 0); + hws[IMX8MP_CLK_SNVS_ROOT] = imx_clk_hw_gate4("snvs_root_clk", "ipg_root", ccm_base + 0x4470, 0); + hws[IMX8MP_CLK_UART1_ROOT] = imx_clk_hw_gate4("uart1_root_clk", "uart1", ccm_base + 0x4490, 0); + hws[IMX8MP_CLK_UART2_ROOT] = imx_clk_hw_gate4("uart2_root_clk", "uart2", ccm_base + 0x44a0, 0); + hws[IMX8MP_CLK_UART3_ROOT] = imx_clk_hw_gate4("uart3_root_clk", "uart3", ccm_base + 0x44b0, 0); + hws[IMX8MP_CLK_UART4_ROOT] = imx_clk_hw_gate4("uart4_root_clk", "uart4", ccm_base + 0x44c0, 0); + hws[IMX8MP_CLK_USB_ROOT] = imx_clk_hw_gate4("usb_root_clk", "osc_32k", ccm_base + 0x44d0, 0); + hws[IMX8MP_CLK_USB_PHY_ROOT] = imx_clk_hw_gate4("usb_phy_root_clk", "usb_phy_ref", ccm_base + 0x44f0, 0); + hws[IMX8MP_CLK_USDHC1_ROOT] = imx_clk_hw_gate4("usdhc1_root_clk", "usdhc1", ccm_base + 0x4510, 0); + hws[IMX8MP_CLK_USDHC2_ROOT] = imx_clk_hw_gate4("usdhc2_root_clk", "usdhc2", ccm_base + 0x4520, 0); + hws[IMX8MP_CLK_WDOG1_ROOT] = imx_clk_hw_gate4("wdog1_root_clk", "wdog", ccm_base + 0x4530, 0); + hws[IMX8MP_CLK_WDOG2_ROOT] = imx_clk_hw_gate4("wdog2_root_clk", "wdog", ccm_base + 0x4540, 0); + hws[IMX8MP_CLK_WDOG3_ROOT] = imx_clk_hw_gate4("wdog3_root_clk", "wdog", ccm_base + 0x4550, 0); + hws[IMX8MP_CLK_VPU_G1_ROOT] = imx_clk_hw_gate4("vpu_g1_root_clk", "vpu_g1", ccm_base + 0x4560, 0); + hws[IMX8MP_CLK_GPU_ROOT] = imx_clk_hw_gate4("gpu_root_clk", "gpu_axi", ccm_base + 0x4570, 0); + hws[IMX8MP_CLK_VPU_VC8KE_ROOT] = imx_clk_hw_gate4("vpu_vc8ke_root_clk", "vpu_vc8000e", ccm_base + 0x4590, 0); + hws[IMX8MP_CLK_VPU_G2_ROOT] = imx_clk_hw_gate4("vpu_g2_root_clk", "vpu_g2", ccm_base + 0x45a0, 0); + hws[IMX8MP_CLK_NPU_ROOT] = imx_clk_hw_gate4("npu_root_clk", "ml_div", ccm_base + 0x45b0, 0); + hws[IMX8MP_CLK_HSIO_ROOT] = imx_clk_hw_gate4("hsio_root_clk", "ipg_root", ccm_base + 0x45c0, 0); + hws[IMX8MP_CLK_MEDIA_APB_ROOT] = imx_clk_hw_gate2_shared2("media_apb_root_clk", "media_apb", ccm_base + 0x45d0, 0, &share_count_media); + hws[IMX8MP_CLK_MEDIA_AXI_ROOT] = imx_clk_hw_gate2_shared2("media_axi_root_clk", "media_axi", ccm_base + 0x45d0, 0, &share_count_media); + hws[IMX8MP_CLK_MEDIA_CAM1_PIX_ROOT] = imx_clk_hw_gate2_shared2("media_cam1_pix_root_clk", "media_cam1_pix", ccm_base + 0x45d0, 0, &share_count_media); + hws[IMX8MP_CLK_MEDIA_CAM2_PIX_ROOT] = imx_clk_hw_gate2_shared2("media_cam2_pix_root_clk", "media_cam2_pix", ccm_base + 0x45d0, 0, &share_count_media); + hws[IMX8MP_CLK_MEDIA_DISP1_PIX_ROOT] = imx_clk_hw_gate2_shared2("media_disp1_pix_root_clk", "media_disp1_pix", ccm_base + 0x45d0, 0, &share_count_media); + hws[IMX8MP_CLK_MEDIA_DISP2_PIX_ROOT] = imx_clk_hw_gate2_shared2("media_disp2_pix_root_clk", "media_disp2_pix", ccm_base + 0x45d0, 0, &share_count_media); + hws[IMX8MP_CLK_MEDIA_ISP_ROOT] = imx_clk_hw_gate2_shared2("media_isp_root_clk", "media_isp_div", ccm_base + 0x45d0, 0, &share_count_media); + + hws[IMX8MP_CLK_USDHC3_ROOT] = imx_clk_hw_gate4("usdhc3_root_clk", "usdhc3", ccm_base + 0x45e0, 0); + hws[IMX8MP_CLK_HDMI_ROOT] = imx_clk_hw_gate4("hdmi_root_clk", "hdmi_axi", ccm_base + 0x45f0, 0); + hws[IMX8MP_CLK_TSENSOR_ROOT] = imx_clk_hw_gate4("tsensor_root_clk", "ipg_root", ccm_base + 0x4620, 0); + hws[IMX8MP_CLK_VPU_ROOT] = imx_clk_hw_gate4("vpu_root_clk", "vpu_bus", ccm_base + 0x4630, 0); + hws[IMX8MP_CLK_AUDIO_ROOT] = imx_clk_hw_gate4("audio_root_clk", "ipg_root", ccm_base + 0x4650, 0); + + hws[IMX8MP_CLK_ARM] = imx_clk_hw_cpu("arm", "arm_a53_div", + hws[IMX8MP_CLK_A53_DIV]->clk, + hws[IMX8MP_CLK_A53_SRC]->clk, + hws[IMX8MP_ARM_PLL_OUT]->clk, + hws[IMX8MP_SYS_PLL1_800M]->clk); + + imx_check_clk_hws(hws, IMX8MP_CLK_END); + + of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data); + + for (i = 0; i < ARRAY_SIZE(uart_clk_ids); i++) { + int index = uart_clk_ids[i]; + + uart_clks[i] = &hws[index]->clk; + } + + imx_register_uart_clocks(uart_clks); + + return 0; +} + +static const struct of_device_id imx8mp_clk_of_match[] = { + { .compatible = "fsl,imx8mp-ccm" }, + { /* Sentinel */ } +}; +MODULE_DEVICE_TABLE(of, imx8mp_clk_of_match); + +static struct platform_driver imx8mp_clk_driver = { + .probe = imx8mp_clocks_probe, + .driver = { + .name = "imx8mp-ccm", + /* + * Disable bind attributes: clocks are not removed and + * reloading the driver will crash or break devices. + */ + .suppress_bind_attrs = true, + .of_match_table = of_match_ptr(imx8mp_clk_of_match), + }, +}; +module_platform_driver(imx8mp_clk_driver); diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c index 5f10a606d836..4c0edca1a6d0 100644 --- a/drivers/clk/imx/clk-imx8mq.c +++ b/drivers/clk/imx/clk-imx8mq.c @@ -11,6 +11,7 @@ #include <linux/module.h> #include <linux/of_address.h> #include <linux/types.h> +#include <linux/slab.h> #include <linux/platform_device.h> #include "clk.h" @@ -24,8 +25,6 @@ static u32 share_count_sai6; static u32 share_count_dcss; static u32 share_count_nand; -static struct clk *clks[IMX8MQ_CLK_END]; - static const char * const pll_ref_sels[] = { "osc_25m", "osc_27m", "dummy", "dummy", }; static const char * const arm_pll_bypass_sels[] = {"arm_pll", "arm_pll_ref_sel", }; static const char * const gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", }; @@ -269,124 +268,133 @@ static const char * const imx8mq_clko1_sels[] = {"osc_25m", "sys1_pll_800m", "os static const char * const imx8mq_clko2_sels[] = {"osc_25m", "sys2_pll_200m", "sys1_pll_400m", "sys2_pll_166m", "sys3_pll_out", "audio_pll1_out", "video_pll1_out", "ckil", }; -static struct clk_onecell_data clk_data; +static struct clk_hw_onecell_data *clk_hw_data; +static struct clk_hw **hws; -static struct clk ** const uart_clks[] = { - &clks[IMX8MQ_CLK_UART1_ROOT], - &clks[IMX8MQ_CLK_UART2_ROOT], - &clks[IMX8MQ_CLK_UART3_ROOT], - &clks[IMX8MQ_CLK_UART4_ROOT], - NULL +static const int uart_clk_ids[] = { + IMX8MQ_CLK_UART1_ROOT, + IMX8MQ_CLK_UART2_ROOT, + IMX8MQ_CLK_UART3_ROOT, + IMX8MQ_CLK_UART4_ROOT, }; +static struct clk **uart_hws[ARRAY_SIZE(uart_clk_ids) + 1]; static int imx8mq_clocks_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; void __iomem *base; - int err; + int err, i; + + clk_hw_data = kzalloc(struct_size(clk_hw_data, hws, + IMX8MQ_CLK_END), GFP_KERNEL); + if (WARN_ON(!clk_hw_data)) + return -ENOMEM; + + clk_hw_data->num = IMX8MQ_CLK_END; + hws = clk_hw_data->hws; - clks[IMX8MQ_CLK_DUMMY] = imx_clk_fixed("dummy", 0); - clks[IMX8MQ_CLK_32K] = of_clk_get_by_name(np, "ckil"); - clks[IMX8MQ_CLK_25M] = of_clk_get_by_name(np, "osc_25m"); - clks[IMX8MQ_CLK_27M] = of_clk_get_by_name(np, "osc_27m"); - clks[IMX8MQ_CLK_EXT1] = of_clk_get_by_name(np, "clk_ext1"); - clks[IMX8MQ_CLK_EXT2] = of_clk_get_by_name(np, "clk_ext2"); - clks[IMX8MQ_CLK_EXT3] = of_clk_get_by_name(np, "clk_ext3"); - clks[IMX8MQ_CLK_EXT4] = of_clk_get_by_name(np, "clk_ext4"); + hws[IMX8MQ_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0); + hws[IMX8MQ_CLK_32K] = imx_obtain_fixed_clk_hw(np, "ckil"); + hws[IMX8MQ_CLK_25M] = imx_obtain_fixed_clk_hw(np, "osc_25m"); + hws[IMX8MQ_CLK_27M] = imx_obtain_fixed_clk_hw(np, "osc_27m"); + hws[IMX8MQ_CLK_EXT1] = imx_obtain_fixed_clk_hw(np, "clk_ext1"); + hws[IMX8MQ_CLK_EXT2] = imx_obtain_fixed_clk_hw(np, "clk_ext2"); + hws[IMX8MQ_CLK_EXT3] = imx_obtain_fixed_clk_hw(np, "clk_ext3"); + hws[IMX8MQ_CLK_EXT4] = imx_obtain_fixed_clk_hw(np, "clk_ext4"); np = of_find_compatible_node(NULL, NULL, "fsl,imx8mq-anatop"); base = of_iomap(np, 0); if (WARN_ON(!base)) return -ENOMEM; - clks[IMX8MQ_ARM_PLL_REF_SEL] = imx_clk_mux("arm_pll_ref_sel", base + 0x28, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); - clks[IMX8MQ_GPU_PLL_REF_SEL] = imx_clk_mux("gpu_pll_ref_sel", base + 0x18, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); - clks[IMX8MQ_VPU_PLL_REF_SEL] = imx_clk_mux("vpu_pll_ref_sel", base + 0x20, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); - clks[IMX8MQ_AUDIO_PLL1_REF_SEL] = imx_clk_mux("audio_pll1_ref_sel", base + 0x0, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); - clks[IMX8MQ_AUDIO_PLL2_REF_SEL] = imx_clk_mux("audio_pll2_ref_sel", base + 0x8, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); - clks[IMX8MQ_VIDEO_PLL1_REF_SEL] = imx_clk_mux("video_pll1_ref_sel", base + 0x10, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); - clks[IMX8MQ_SYS3_PLL1_REF_SEL] = imx_clk_mux("sys3_pll1_ref_sel", base + 0x48, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); - clks[IMX8MQ_DRAM_PLL1_REF_SEL] = imx_clk_mux("dram_pll1_ref_sel", base + 0x60, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); - clks[IMX8MQ_VIDEO2_PLL1_REF_SEL] = imx_clk_mux("video2_pll1_ref_sel", base + 0x54, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); - - clks[IMX8MQ_ARM_PLL_REF_DIV] = imx_clk_divider("arm_pll_ref_div", "arm_pll_ref_sel", base + 0x28, 5, 6); - clks[IMX8MQ_GPU_PLL_REF_DIV] = imx_clk_divider("gpu_pll_ref_div", "gpu_pll_ref_sel", base + 0x18, 5, 6); - clks[IMX8MQ_VPU_PLL_REF_DIV] = imx_clk_divider("vpu_pll_ref_div", "vpu_pll_ref_sel", base + 0x20, 5, 6); - clks[IMX8MQ_AUDIO_PLL1_REF_DIV] = imx_clk_divider("audio_pll1_ref_div", "audio_pll1_ref_sel", base + 0x0, 5, 6); - clks[IMX8MQ_AUDIO_PLL2_REF_DIV] = imx_clk_divider("audio_pll2_ref_div", "audio_pll2_ref_sel", base + 0x8, 5, 6); - clks[IMX8MQ_VIDEO_PLL1_REF_DIV] = imx_clk_divider("video_pll1_ref_div", "video_pll1_ref_sel", base + 0x10, 5, 6); - - clks[IMX8MQ_ARM_PLL] = imx_clk_frac_pll("arm_pll", "arm_pll_ref_div", base + 0x28); - clks[IMX8MQ_GPU_PLL] = imx_clk_frac_pll("gpu_pll", "gpu_pll_ref_div", base + 0x18); - clks[IMX8MQ_VPU_PLL] = imx_clk_frac_pll("vpu_pll", "vpu_pll_ref_div", base + 0x20); - clks[IMX8MQ_AUDIO_PLL1] = imx_clk_frac_pll("audio_pll1", "audio_pll1_ref_div", base + 0x0); - clks[IMX8MQ_AUDIO_PLL2] = imx_clk_frac_pll("audio_pll2", "audio_pll2_ref_div", base + 0x8); - clks[IMX8MQ_VIDEO_PLL1] = imx_clk_frac_pll("video_pll1", "video_pll1_ref_div", base + 0x10); + hws[IMX8MQ_ARM_PLL_REF_SEL] = imx_clk_hw_mux("arm_pll_ref_sel", base + 0x28, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MQ_GPU_PLL_REF_SEL] = imx_clk_hw_mux("gpu_pll_ref_sel", base + 0x18, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MQ_VPU_PLL_REF_SEL] = imx_clk_hw_mux("vpu_pll_ref_sel", base + 0x20, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MQ_AUDIO_PLL1_REF_SEL] = imx_clk_hw_mux("audio_pll1_ref_sel", base + 0x0, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MQ_AUDIO_PLL2_REF_SEL] = imx_clk_hw_mux("audio_pll2_ref_sel", base + 0x8, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MQ_VIDEO_PLL1_REF_SEL] = imx_clk_hw_mux("video_pll1_ref_sel", base + 0x10, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MQ_SYS3_PLL1_REF_SEL] = imx_clk_hw_mux("sys3_pll1_ref_sel", base + 0x48, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MQ_DRAM_PLL1_REF_SEL] = imx_clk_hw_mux("dram_pll1_ref_sel", base + 0x60, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MQ_VIDEO2_PLL1_REF_SEL] = imx_clk_hw_mux("video2_pll1_ref_sel", base + 0x54, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + + hws[IMX8MQ_ARM_PLL_REF_DIV] = imx_clk_hw_divider("arm_pll_ref_div", "arm_pll_ref_sel", base + 0x28, 5, 6); + hws[IMX8MQ_GPU_PLL_REF_DIV] = imx_clk_hw_divider("gpu_pll_ref_div", "gpu_pll_ref_sel", base + 0x18, 5, 6); + hws[IMX8MQ_VPU_PLL_REF_DIV] = imx_clk_hw_divider("vpu_pll_ref_div", "vpu_pll_ref_sel", base + 0x20, 5, 6); + hws[IMX8MQ_AUDIO_PLL1_REF_DIV] = imx_clk_hw_divider("audio_pll1_ref_div", "audio_pll1_ref_sel", base + 0x0, 5, 6); + hws[IMX8MQ_AUDIO_PLL2_REF_DIV] = imx_clk_hw_divider("audio_pll2_ref_div", "audio_pll2_ref_sel", base + 0x8, 5, 6); + hws[IMX8MQ_VIDEO_PLL1_REF_DIV] = imx_clk_hw_divider("video_pll1_ref_div", "video_pll1_ref_sel", base + 0x10, 5, 6); + + hws[IMX8MQ_ARM_PLL] = imx_clk_hw_frac_pll("arm_pll", "arm_pll_ref_div", base + 0x28); + hws[IMX8MQ_GPU_PLL] = imx_clk_hw_frac_pll("gpu_pll", "gpu_pll_ref_div", base + 0x18); + hws[IMX8MQ_VPU_PLL] = imx_clk_hw_frac_pll("vpu_pll", "vpu_pll_ref_div", base + 0x20); + hws[IMX8MQ_AUDIO_PLL1] = imx_clk_hw_frac_pll("audio_pll1", "audio_pll1_ref_div", base + 0x0); + hws[IMX8MQ_AUDIO_PLL2] = imx_clk_hw_frac_pll("audio_pll2", "audio_pll2_ref_div", base + 0x8); + hws[IMX8MQ_VIDEO_PLL1] = imx_clk_hw_frac_pll("video_pll1", "video_pll1_ref_div", base + 0x10); /* PLL bypass out */ - clks[IMX8MQ_ARM_PLL_BYPASS] = imx_clk_mux_flags("arm_pll_bypass", base + 0x28, 14, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT); - clks[IMX8MQ_GPU_PLL_BYPASS] = imx_clk_mux("gpu_pll_bypass", base + 0x18, 14, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels)); - clks[IMX8MQ_VPU_PLL_BYPASS] = imx_clk_mux("vpu_pll_bypass", base + 0x20, 14, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels)); - clks[IMX8MQ_AUDIO_PLL1_BYPASS] = imx_clk_mux("audio_pll1_bypass", base + 0x0, 14, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels)); - clks[IMX8MQ_AUDIO_PLL2_BYPASS] = imx_clk_mux("audio_pll2_bypass", base + 0x8, 14, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels)); - clks[IMX8MQ_VIDEO_PLL1_BYPASS] = imx_clk_mux("video_pll1_bypass", base + 0x10, 14, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels)); + hws[IMX8MQ_ARM_PLL_BYPASS] = imx_clk_hw_mux_flags("arm_pll_bypass", base + 0x28, 14, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT); + hws[IMX8MQ_GPU_PLL_BYPASS] = imx_clk_hw_mux("gpu_pll_bypass", base + 0x18, 14, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels)); + hws[IMX8MQ_VPU_PLL_BYPASS] = imx_clk_hw_mux("vpu_pll_bypass", base + 0x20, 14, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels)); + hws[IMX8MQ_AUDIO_PLL1_BYPASS] = imx_clk_hw_mux("audio_pll1_bypass", base + 0x0, 14, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels)); + hws[IMX8MQ_AUDIO_PLL2_BYPASS] = imx_clk_hw_mux("audio_pll2_bypass", base + 0x8, 14, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels)); + hws[IMX8MQ_VIDEO_PLL1_BYPASS] = imx_clk_hw_mux("video_pll1_bypass", base + 0x10, 14, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels)); /* PLL OUT GATE */ - clks[IMX8MQ_ARM_PLL_OUT] = imx_clk_gate("arm_pll_out", "arm_pll_bypass", base + 0x28, 21); - clks[IMX8MQ_GPU_PLL_OUT] = imx_clk_gate("gpu_pll_out", "gpu_pll_bypass", base + 0x18, 21); - clks[IMX8MQ_VPU_PLL_OUT] = imx_clk_gate("vpu_pll_out", "vpu_pll_bypass", base + 0x20, 21); - clks[IMX8MQ_AUDIO_PLL1_OUT] = imx_clk_gate("audio_pll1_out", "audio_pll1_bypass", base + 0x0, 21); - clks[IMX8MQ_AUDIO_PLL2_OUT] = imx_clk_gate("audio_pll2_out", "audio_pll2_bypass", base + 0x8, 21); - clks[IMX8MQ_VIDEO_PLL1_OUT] = imx_clk_gate("video_pll1_out", "video_pll1_bypass", base + 0x10, 21); - - clks[IMX8MQ_SYS1_PLL_OUT] = imx_clk_fixed("sys1_pll_out", 800000000); - clks[IMX8MQ_SYS2_PLL_OUT] = imx_clk_fixed("sys2_pll_out", 1000000000); - clks[IMX8MQ_SYS3_PLL_OUT] = imx_clk_sccg_pll("sys3_pll_out", sys3_pll_out_sels, ARRAY_SIZE(sys3_pll_out_sels), 0, 0, 0, base + 0x48, CLK_IS_CRITICAL); - clks[IMX8MQ_DRAM_PLL_OUT] = imx_clk_sccg_pll("dram_pll_out", dram_pll_out_sels, ARRAY_SIZE(dram_pll_out_sels), 0, 0, 0, base + 0x60, CLK_IS_CRITICAL); - clks[IMX8MQ_VIDEO2_PLL_OUT] = imx_clk_sccg_pll("video2_pll_out", video2_pll_out_sels, ARRAY_SIZE(video2_pll_out_sels), 0, 0, 0, base + 0x54, 0); + hws[IMX8MQ_ARM_PLL_OUT] = imx_clk_hw_gate("arm_pll_out", "arm_pll_bypass", base + 0x28, 21); + hws[IMX8MQ_GPU_PLL_OUT] = imx_clk_hw_gate("gpu_pll_out", "gpu_pll_bypass", base + 0x18, 21); + hws[IMX8MQ_VPU_PLL_OUT] = imx_clk_hw_gate("vpu_pll_out", "vpu_pll_bypass", base + 0x20, 21); + hws[IMX8MQ_AUDIO_PLL1_OUT] = imx_clk_hw_gate("audio_pll1_out", "audio_pll1_bypass", base + 0x0, 21); + hws[IMX8MQ_AUDIO_PLL2_OUT] = imx_clk_hw_gate("audio_pll2_out", "audio_pll2_bypass", base + 0x8, 21); + hws[IMX8MQ_VIDEO_PLL1_OUT] = imx_clk_hw_gate("video_pll1_out", "video_pll1_bypass", base + 0x10, 21); + + hws[IMX8MQ_SYS1_PLL_OUT] = imx_clk_hw_fixed("sys1_pll_out", 800000000); + hws[IMX8MQ_SYS2_PLL_OUT] = imx_clk_hw_fixed("sys2_pll_out", 1000000000); + hws[IMX8MQ_SYS3_PLL_OUT] = imx_clk_hw_sscg_pll("sys3_pll_out", sys3_pll_out_sels, ARRAY_SIZE(sys3_pll_out_sels), 0, 0, 0, base + 0x48, CLK_IS_CRITICAL); + hws[IMX8MQ_DRAM_PLL_OUT] = imx_clk_hw_sscg_pll("dram_pll_out", dram_pll_out_sels, ARRAY_SIZE(dram_pll_out_sels), 0, 0, 0, base + 0x60, CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE); + hws[IMX8MQ_VIDEO2_PLL_OUT] = imx_clk_hw_sscg_pll("video2_pll_out", video2_pll_out_sels, ARRAY_SIZE(video2_pll_out_sels), 0, 0, 0, base + 0x54, 0); /* SYS PLL1 fixed output */ - clks[IMX8MQ_SYS1_PLL_40M_CG] = imx_clk_gate("sys1_pll_40m_cg", "sys1_pll_out", base + 0x30, 9); - clks[IMX8MQ_SYS1_PLL_80M_CG] = imx_clk_gate("sys1_pll_80m_cg", "sys1_pll_out", base + 0x30, 11); - clks[IMX8MQ_SYS1_PLL_100M_CG] = imx_clk_gate("sys1_pll_100m_cg", "sys1_pll_out", base + 0x30, 13); - clks[IMX8MQ_SYS1_PLL_133M_CG] = imx_clk_gate("sys1_pll_133m_cg", "sys1_pll_out", base + 0x30, 15); - clks[IMX8MQ_SYS1_PLL_160M_CG] = imx_clk_gate("sys1_pll_160m_cg", "sys1_pll_out", base + 0x30, 17); - clks[IMX8MQ_SYS1_PLL_200M_CG] = imx_clk_gate("sys1_pll_200m_cg", "sys1_pll_out", base + 0x30, 19); - clks[IMX8MQ_SYS1_PLL_266M_CG] = imx_clk_gate("sys1_pll_266m_cg", "sys1_pll_out", base + 0x30, 21); - clks[IMX8MQ_SYS1_PLL_400M_CG] = imx_clk_gate("sys1_pll_400m_cg", "sys1_pll_out", base + 0x30, 23); - clks[IMX8MQ_SYS1_PLL_800M_CG] = imx_clk_gate("sys1_pll_800m_cg", "sys1_pll_out", base + 0x30, 25); - - clks[IMX8MQ_SYS1_PLL_40M] = imx_clk_fixed_factor("sys1_pll_40m", "sys1_pll_40m_cg", 1, 20); - clks[IMX8MQ_SYS1_PLL_80M] = imx_clk_fixed_factor("sys1_pll_80m", "sys1_pll_80m_cg", 1, 10); - clks[IMX8MQ_SYS1_PLL_100M] = imx_clk_fixed_factor("sys1_pll_100m", "sys1_pll_100m_cg", 1, 8); - clks[IMX8MQ_SYS1_PLL_133M] = imx_clk_fixed_factor("sys1_pll_133m", "sys1_pll_133m_cg", 1, 6); - clks[IMX8MQ_SYS1_PLL_160M] = imx_clk_fixed_factor("sys1_pll_160m", "sys1_pll_160m_cg", 1, 5); - clks[IMX8MQ_SYS1_PLL_200M] = imx_clk_fixed_factor("sys1_pll_200m", "sys1_pll_200m_cg", 1, 4); - clks[IMX8MQ_SYS1_PLL_266M] = imx_clk_fixed_factor("sys1_pll_266m", "sys1_pll_266m_cg", 1, 3); - clks[IMX8MQ_SYS1_PLL_400M] = imx_clk_fixed_factor("sys1_pll_400m", "sys1_pll_400m_cg", 1, 2); - clks[IMX8MQ_SYS1_PLL_800M] = imx_clk_fixed_factor("sys1_pll_800m", "sys1_pll_800m_cg", 1, 1); + hws[IMX8MQ_SYS1_PLL_40M_CG] = imx_clk_hw_gate("sys1_pll_40m_cg", "sys1_pll_out", base + 0x30, 9); + hws[IMX8MQ_SYS1_PLL_80M_CG] = imx_clk_hw_gate("sys1_pll_80m_cg", "sys1_pll_out", base + 0x30, 11); + hws[IMX8MQ_SYS1_PLL_100M_CG] = imx_clk_hw_gate("sys1_pll_100m_cg", "sys1_pll_out", base + 0x30, 13); + hws[IMX8MQ_SYS1_PLL_133M_CG] = imx_clk_hw_gate("sys1_pll_133m_cg", "sys1_pll_out", base + 0x30, 15); + hws[IMX8MQ_SYS1_PLL_160M_CG] = imx_clk_hw_gate("sys1_pll_160m_cg", "sys1_pll_out", base + 0x30, 17); + hws[IMX8MQ_SYS1_PLL_200M_CG] = imx_clk_hw_gate("sys1_pll_200m_cg", "sys1_pll_out", base + 0x30, 19); + hws[IMX8MQ_SYS1_PLL_266M_CG] = imx_clk_hw_gate("sys1_pll_266m_cg", "sys1_pll_out", base + 0x30, 21); + hws[IMX8MQ_SYS1_PLL_400M_CG] = imx_clk_hw_gate("sys1_pll_400m_cg", "sys1_pll_out", base + 0x30, 23); + hws[IMX8MQ_SYS1_PLL_800M_CG] = imx_clk_hw_gate("sys1_pll_800m_cg", "sys1_pll_out", base + 0x30, 25); + + hws[IMX8MQ_SYS1_PLL_40M] = imx_clk_hw_fixed_factor("sys1_pll_40m", "sys1_pll_40m_cg", 1, 20); + hws[IMX8MQ_SYS1_PLL_80M] = imx_clk_hw_fixed_factor("sys1_pll_80m", "sys1_pll_80m_cg", 1, 10); + hws[IMX8MQ_SYS1_PLL_100M] = imx_clk_hw_fixed_factor("sys1_pll_100m", "sys1_pll_100m_cg", 1, 8); + hws[IMX8MQ_SYS1_PLL_133M] = imx_clk_hw_fixed_factor("sys1_pll_133m", "sys1_pll_133m_cg", 1, 6); + hws[IMX8MQ_SYS1_PLL_160M] = imx_clk_hw_fixed_factor("sys1_pll_160m", "sys1_pll_160m_cg", 1, 5); + hws[IMX8MQ_SYS1_PLL_200M] = imx_clk_hw_fixed_factor("sys1_pll_200m", "sys1_pll_200m_cg", 1, 4); + hws[IMX8MQ_SYS1_PLL_266M] = imx_clk_hw_fixed_factor("sys1_pll_266m", "sys1_pll_266m_cg", 1, 3); + hws[IMX8MQ_SYS1_PLL_400M] = imx_clk_hw_fixed_factor("sys1_pll_400m", "sys1_pll_400m_cg", 1, 2); + hws[IMX8MQ_SYS1_PLL_800M] = imx_clk_hw_fixed_factor("sys1_pll_800m", "sys1_pll_800m_cg", 1, 1); /* SYS PLL2 fixed output */ - clks[IMX8MQ_SYS2_PLL_50M_CG] = imx_clk_gate("sys2_pll_50m_cg", "sys2_pll_out", base + 0x3c, 9); - clks[IMX8MQ_SYS2_PLL_100M_CG] = imx_clk_gate("sys2_pll_100m_cg", "sys2_pll_out", base + 0x3c, 11); - clks[IMX8MQ_SYS2_PLL_125M_CG] = imx_clk_gate("sys2_pll_125m_cg", "sys2_pll_out", base + 0x3c, 13); - clks[IMX8MQ_SYS2_PLL_166M_CG] = imx_clk_gate("sys2_pll_166m_cg", "sys2_pll_out", base + 0x3c, 15); - clks[IMX8MQ_SYS2_PLL_200M_CG] = imx_clk_gate("sys2_pll_200m_cg", "sys2_pll_out", base + 0x3c, 17); - clks[IMX8MQ_SYS2_PLL_250M_CG] = imx_clk_gate("sys2_pll_250m_cg", "sys2_pll_out", base + 0x3c, 19); - clks[IMX8MQ_SYS2_PLL_333M_CG] = imx_clk_gate("sys2_pll_333m_cg", "sys2_pll_out", base + 0x3c, 21); - clks[IMX8MQ_SYS2_PLL_500M_CG] = imx_clk_gate("sys2_pll_500m_cg", "sys2_pll_out", base + 0x3c, 23); - clks[IMX8MQ_SYS2_PLL_1000M_CG] = imx_clk_gate("sys2_pll_1000m_cg", "sys2_pll_out", base + 0x3c, 25); - - clks[IMX8MQ_SYS2_PLL_50M] = imx_clk_fixed_factor("sys2_pll_50m", "sys2_pll_50m_cg", 1, 20); - clks[IMX8MQ_SYS2_PLL_100M] = imx_clk_fixed_factor("sys2_pll_100m", "sys2_pll_100m_cg", 1, 10); - clks[IMX8MQ_SYS2_PLL_125M] = imx_clk_fixed_factor("sys2_pll_125m", "sys2_pll_125m_cg", 1, 8); - clks[IMX8MQ_SYS2_PLL_166M] = imx_clk_fixed_factor("sys2_pll_166m", "sys2_pll_166m_cg", 1, 6); - clks[IMX8MQ_SYS2_PLL_200M] = imx_clk_fixed_factor("sys2_pll_200m", "sys2_pll_200m_cg", 1, 5); - clks[IMX8MQ_SYS2_PLL_250M] = imx_clk_fixed_factor("sys2_pll_250m", "sys2_pll_250m_cg", 1, 4); - clks[IMX8MQ_SYS2_PLL_333M] = imx_clk_fixed_factor("sys2_pll_333m", "sys2_pll_333m_cg", 1, 3); - clks[IMX8MQ_SYS2_PLL_500M] = imx_clk_fixed_factor("sys2_pll_500m", "sys2_pll_500m_cg", 1, 2); - clks[IMX8MQ_SYS2_PLL_1000M] = imx_clk_fixed_factor("sys2_pll_1000m", "sys2_pll_1000m_cg", 1, 1); + hws[IMX8MQ_SYS2_PLL_50M_CG] = imx_clk_hw_gate("sys2_pll_50m_cg", "sys2_pll_out", base + 0x3c, 9); + hws[IMX8MQ_SYS2_PLL_100M_CG] = imx_clk_hw_gate("sys2_pll_100m_cg", "sys2_pll_out", base + 0x3c, 11); + hws[IMX8MQ_SYS2_PLL_125M_CG] = imx_clk_hw_gate("sys2_pll_125m_cg", "sys2_pll_out", base + 0x3c, 13); + hws[IMX8MQ_SYS2_PLL_166M_CG] = imx_clk_hw_gate("sys2_pll_166m_cg", "sys2_pll_out", base + 0x3c, 15); + hws[IMX8MQ_SYS2_PLL_200M_CG] = imx_clk_hw_gate("sys2_pll_200m_cg", "sys2_pll_out", base + 0x3c, 17); + hws[IMX8MQ_SYS2_PLL_250M_CG] = imx_clk_hw_gate("sys2_pll_250m_cg", "sys2_pll_out", base + 0x3c, 19); + hws[IMX8MQ_SYS2_PLL_333M_CG] = imx_clk_hw_gate("sys2_pll_333m_cg", "sys2_pll_out", base + 0x3c, 21); + hws[IMX8MQ_SYS2_PLL_500M_CG] = imx_clk_hw_gate("sys2_pll_500m_cg", "sys2_pll_out", base + 0x3c, 23); + hws[IMX8MQ_SYS2_PLL_1000M_CG] = imx_clk_hw_gate("sys2_pll_1000m_cg", "sys2_pll_out", base + 0x3c, 25); + + hws[IMX8MQ_SYS2_PLL_50M] = imx_clk_hw_fixed_factor("sys2_pll_50m", "sys2_pll_50m_cg", 1, 20); + hws[IMX8MQ_SYS2_PLL_100M] = imx_clk_hw_fixed_factor("sys2_pll_100m", "sys2_pll_100m_cg", 1, 10); + hws[IMX8MQ_SYS2_PLL_125M] = imx_clk_hw_fixed_factor("sys2_pll_125m", "sys2_pll_125m_cg", 1, 8); + hws[IMX8MQ_SYS2_PLL_166M] = imx_clk_hw_fixed_factor("sys2_pll_166m", "sys2_pll_166m_cg", 1, 6); + hws[IMX8MQ_SYS2_PLL_200M] = imx_clk_hw_fixed_factor("sys2_pll_200m", "sys2_pll_200m_cg", 1, 5); + hws[IMX8MQ_SYS2_PLL_250M] = imx_clk_hw_fixed_factor("sys2_pll_250m", "sys2_pll_250m_cg", 1, 4); + hws[IMX8MQ_SYS2_PLL_333M] = imx_clk_hw_fixed_factor("sys2_pll_333m", "sys2_pll_333m_cg", 1, 3); + hws[IMX8MQ_SYS2_PLL_500M] = imx_clk_hw_fixed_factor("sys2_pll_500m", "sys2_pll_500m_cg", 1, 2); + hws[IMX8MQ_SYS2_PLL_1000M] = imx_clk_hw_fixed_factor("sys2_pll_1000m", "sys2_pll_1000m_cg", 1, 1); np = dev->of_node; base = devm_platform_ioremap_resource(pdev, 0); @@ -394,206 +402,213 @@ static int imx8mq_clocks_probe(struct platform_device *pdev) return PTR_ERR(base); /* CORE */ - clks[IMX8MQ_CLK_A53_SRC] = imx_clk_mux2("arm_a53_src", base + 0x8000, 24, 3, imx8mq_a53_sels, ARRAY_SIZE(imx8mq_a53_sels)); - clks[IMX8MQ_CLK_M4_SRC] = imx_clk_mux2("arm_m4_src", base + 0x8080, 24, 3, imx8mq_arm_m4_sels, ARRAY_SIZE(imx8mq_arm_m4_sels)); - clks[IMX8MQ_CLK_VPU_SRC] = imx_clk_mux2("vpu_src", base + 0x8100, 24, 3, imx8mq_vpu_sels, ARRAY_SIZE(imx8mq_vpu_sels)); - clks[IMX8MQ_CLK_GPU_CORE_SRC] = imx_clk_mux2("gpu_core_src", base + 0x8180, 24, 3, imx8mq_gpu_core_sels, ARRAY_SIZE(imx8mq_gpu_core_sels)); - clks[IMX8MQ_CLK_GPU_SHADER_SRC] = imx_clk_mux2("gpu_shader_src", base + 0x8200, 24, 3, imx8mq_gpu_shader_sels, ARRAY_SIZE(imx8mq_gpu_shader_sels)); - - clks[IMX8MQ_CLK_A53_CG] = imx_clk_gate3_flags("arm_a53_cg", "arm_a53_src", base + 0x8000, 28, CLK_IS_CRITICAL); - clks[IMX8MQ_CLK_M4_CG] = imx_clk_gate3("arm_m4_cg", "arm_m4_src", base + 0x8080, 28); - clks[IMX8MQ_CLK_VPU_CG] = imx_clk_gate3("vpu_cg", "vpu_src", base + 0x8100, 28); - clks[IMX8MQ_CLK_GPU_CORE_CG] = imx_clk_gate3("gpu_core_cg", "gpu_core_src", base + 0x8180, 28); - clks[IMX8MQ_CLK_GPU_SHADER_CG] = imx_clk_gate3("gpu_shader_cg", "gpu_shader_src", base + 0x8200, 28); - - clks[IMX8MQ_CLK_A53_DIV] = imx_clk_divider2("arm_a53_div", "arm_a53_cg", base + 0x8000, 0, 3); - clks[IMX8MQ_CLK_M4_DIV] = imx_clk_divider2("arm_m4_div", "arm_m4_cg", base + 0x8080, 0, 3); - clks[IMX8MQ_CLK_VPU_DIV] = imx_clk_divider2("vpu_div", "vpu_cg", base + 0x8100, 0, 3); - clks[IMX8MQ_CLK_GPU_CORE_DIV] = imx_clk_divider2("gpu_core_div", "gpu_core_cg", base + 0x8180, 0, 3); - clks[IMX8MQ_CLK_GPU_SHADER_DIV] = imx_clk_divider2("gpu_shader_div", "gpu_shader_cg", base + 0x8200, 0, 3); + hws[IMX8MQ_CLK_A53_SRC] = imx_clk_hw_mux2("arm_a53_src", base + 0x8000, 24, 3, imx8mq_a53_sels, ARRAY_SIZE(imx8mq_a53_sels)); + hws[IMX8MQ_CLK_M4_SRC] = imx_clk_hw_mux2("arm_m4_src", base + 0x8080, 24, 3, imx8mq_arm_m4_sels, ARRAY_SIZE(imx8mq_arm_m4_sels)); + hws[IMX8MQ_CLK_VPU_SRC] = imx_clk_hw_mux2("vpu_src", base + 0x8100, 24, 3, imx8mq_vpu_sels, ARRAY_SIZE(imx8mq_vpu_sels)); + hws[IMX8MQ_CLK_GPU_CORE_SRC] = imx_clk_hw_mux2("gpu_core_src", base + 0x8180, 24, 3, imx8mq_gpu_core_sels, ARRAY_SIZE(imx8mq_gpu_core_sels)); + hws[IMX8MQ_CLK_GPU_SHADER_SRC] = imx_clk_hw_mux2("gpu_shader_src", base + 0x8200, 24, 3, imx8mq_gpu_shader_sels, ARRAY_SIZE(imx8mq_gpu_shader_sels)); + + hws[IMX8MQ_CLK_A53_CG] = imx_clk_hw_gate3_flags("arm_a53_cg", "arm_a53_src", base + 0x8000, 28, CLK_IS_CRITICAL); + hws[IMX8MQ_CLK_M4_CG] = imx_clk_hw_gate3("arm_m4_cg", "arm_m4_src", base + 0x8080, 28); + hws[IMX8MQ_CLK_VPU_CG] = imx_clk_hw_gate3("vpu_cg", "vpu_src", base + 0x8100, 28); + hws[IMX8MQ_CLK_GPU_CORE_CG] = imx_clk_hw_gate3("gpu_core_cg", "gpu_core_src", base + 0x8180, 28); + hws[IMX8MQ_CLK_GPU_SHADER_CG] = imx_clk_hw_gate3("gpu_shader_cg", "gpu_shader_src", base + 0x8200, 28); + + hws[IMX8MQ_CLK_A53_DIV] = imx_clk_hw_divider2("arm_a53_div", "arm_a53_cg", base + 0x8000, 0, 3); + hws[IMX8MQ_CLK_M4_DIV] = imx_clk_hw_divider2("arm_m4_div", "arm_m4_cg", base + 0x8080, 0, 3); + hws[IMX8MQ_CLK_VPU_DIV] = imx_clk_hw_divider2("vpu_div", "vpu_cg", base + 0x8100, 0, 3); + hws[IMX8MQ_CLK_GPU_CORE_DIV] = imx_clk_hw_divider2("gpu_core_div", "gpu_core_cg", base + 0x8180, 0, 3); + hws[IMX8MQ_CLK_GPU_SHADER_DIV] = imx_clk_hw_divider2("gpu_shader_div", "gpu_shader_cg", base + 0x8200, 0, 3); /* BUS */ - clks[IMX8MQ_CLK_MAIN_AXI] = imx8m_clk_composite_critical("main_axi", imx8mq_main_axi_sels, base + 0x8800); - clks[IMX8MQ_CLK_ENET_AXI] = imx8m_clk_composite("enet_axi", imx8mq_enet_axi_sels, base + 0x8880); - clks[IMX8MQ_CLK_NAND_USDHC_BUS] = imx8m_clk_composite("nand_usdhc_bus", imx8mq_nand_usdhc_sels, base + 0x8900); - clks[IMX8MQ_CLK_VPU_BUS] = imx8m_clk_composite("vpu_bus", imx8mq_vpu_bus_sels, base + 0x8980); - clks[IMX8MQ_CLK_DISP_AXI] = imx8m_clk_composite("disp_axi", imx8mq_disp_axi_sels, base + 0x8a00); - clks[IMX8MQ_CLK_DISP_APB] = imx8m_clk_composite("disp_apb", imx8mq_disp_apb_sels, base + 0x8a80); - clks[IMX8MQ_CLK_DISP_RTRM] = imx8m_clk_composite("disp_rtrm", imx8mq_disp_rtrm_sels, base + 0x8b00); - clks[IMX8MQ_CLK_USB_BUS] = imx8m_clk_composite("usb_bus", imx8mq_usb_bus_sels, base + 0x8b80); - clks[IMX8MQ_CLK_GPU_AXI] = imx8m_clk_composite("gpu_axi", imx8mq_gpu_axi_sels, base + 0x8c00); - clks[IMX8MQ_CLK_GPU_AHB] = imx8m_clk_composite("gpu_ahb", imx8mq_gpu_ahb_sels, base + 0x8c80); - clks[IMX8MQ_CLK_NOC] = imx8m_clk_composite_critical("noc", imx8mq_noc_sels, base + 0x8d00); - clks[IMX8MQ_CLK_NOC_APB] = imx8m_clk_composite_critical("noc_apb", imx8mq_noc_apb_sels, base + 0x8d80); + hws[IMX8MQ_CLK_MAIN_AXI] = imx8m_clk_hw_composite_critical("main_axi", imx8mq_main_axi_sels, base + 0x8800); + hws[IMX8MQ_CLK_ENET_AXI] = imx8m_clk_hw_composite("enet_axi", imx8mq_enet_axi_sels, base + 0x8880); + hws[IMX8MQ_CLK_NAND_USDHC_BUS] = imx8m_clk_hw_composite("nand_usdhc_bus", imx8mq_nand_usdhc_sels, base + 0x8900); + hws[IMX8MQ_CLK_VPU_BUS] = imx8m_clk_hw_composite("vpu_bus", imx8mq_vpu_bus_sels, base + 0x8980); + hws[IMX8MQ_CLK_DISP_AXI] = imx8m_clk_hw_composite("disp_axi", imx8mq_disp_axi_sels, base + 0x8a00); + hws[IMX8MQ_CLK_DISP_APB] = imx8m_clk_hw_composite("disp_apb", imx8mq_disp_apb_sels, base + 0x8a80); + hws[IMX8MQ_CLK_DISP_RTRM] = imx8m_clk_hw_composite("disp_rtrm", imx8mq_disp_rtrm_sels, base + 0x8b00); + hws[IMX8MQ_CLK_USB_BUS] = imx8m_clk_hw_composite("usb_bus", imx8mq_usb_bus_sels, base + 0x8b80); + hws[IMX8MQ_CLK_GPU_AXI] = imx8m_clk_hw_composite("gpu_axi", imx8mq_gpu_axi_sels, base + 0x8c00); + hws[IMX8MQ_CLK_GPU_AHB] = imx8m_clk_hw_composite("gpu_ahb", imx8mq_gpu_ahb_sels, base + 0x8c80); + hws[IMX8MQ_CLK_NOC] = imx8m_clk_hw_composite_critical("noc", imx8mq_noc_sels, base + 0x8d00); + hws[IMX8MQ_CLK_NOC_APB] = imx8m_clk_hw_composite_critical("noc_apb", imx8mq_noc_apb_sels, base + 0x8d80); /* AHB */ /* AHB clock is used by the AHB bus therefore marked as critical */ - clks[IMX8MQ_CLK_AHB] = imx8m_clk_composite_critical("ahb", imx8mq_ahb_sels, base + 0x9000); - clks[IMX8MQ_CLK_AUDIO_AHB] = imx8m_clk_composite("audio_ahb", imx8mq_audio_ahb_sels, base + 0x9100); + hws[IMX8MQ_CLK_AHB] = imx8m_clk_hw_composite_critical("ahb", imx8mq_ahb_sels, base + 0x9000); + hws[IMX8MQ_CLK_AUDIO_AHB] = imx8m_clk_hw_composite("audio_ahb", imx8mq_audio_ahb_sels, base + 0x9100); /* IPG */ - clks[IMX8MQ_CLK_IPG_ROOT] = imx_clk_divider2("ipg_root", "ahb", base + 0x9080, 0, 1); - clks[IMX8MQ_CLK_IPG_AUDIO_ROOT] = imx_clk_divider2("ipg_audio_root", "audio_ahb", base + 0x9180, 0, 1); + hws[IMX8MQ_CLK_IPG_ROOT] = imx_clk_hw_divider2("ipg_root", "ahb", base + 0x9080, 0, 1); + hws[IMX8MQ_CLK_IPG_AUDIO_ROOT] = imx_clk_hw_divider2("ipg_audio_root", "audio_ahb", base + 0x9180, 0, 1); + + /* + * DRAM clocks are manipulated from TF-A outside clock framework. + * Mark with GET_RATE_NOCACHE to always read div value from hardware + */ + hws[IMX8MQ_CLK_DRAM_CORE] = imx_clk_hw_mux2_flags("dram_core_clk", base + 0x9800, 24, 1, imx8mq_dram_core_sels, ARRAY_SIZE(imx8mq_dram_core_sels), CLK_IS_CRITICAL); + hws[IMX8MQ_CLK_DRAM_ALT] = __imx8m_clk_hw_composite("dram_alt", imx8mq_dram_alt_sels, base + 0xa000, CLK_GET_RATE_NOCACHE); + hws[IMX8MQ_CLK_DRAM_APB] = __imx8m_clk_hw_composite("dram_apb", imx8mq_dram_apb_sels, base + 0xa080, CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE); /* IP */ - clks[IMX8MQ_CLK_DRAM_CORE] = imx_clk_mux2_flags("dram_core_clk", base + 0x9800, 24, 1, imx8mq_dram_core_sels, ARRAY_SIZE(imx8mq_dram_core_sels), CLK_IS_CRITICAL); - - clks[IMX8MQ_CLK_DRAM_ALT] = imx8m_clk_composite("dram_alt", imx8mq_dram_alt_sels, base + 0xa000); - clks[IMX8MQ_CLK_DRAM_APB] = imx8m_clk_composite_critical("dram_apb", imx8mq_dram_apb_sels, base + 0xa080); - clks[IMX8MQ_CLK_VPU_G1] = imx8m_clk_composite("vpu_g1", imx8mq_vpu_g1_sels, base + 0xa100); - clks[IMX8MQ_CLK_VPU_G2] = imx8m_clk_composite("vpu_g2", imx8mq_vpu_g2_sels, base + 0xa180); - clks[IMX8MQ_CLK_DISP_DTRC] = imx8m_clk_composite("disp_dtrc", imx8mq_disp_dtrc_sels, base + 0xa200); - clks[IMX8MQ_CLK_DISP_DC8000] = imx8m_clk_composite("disp_dc8000", imx8mq_disp_dc8000_sels, base + 0xa280); - clks[IMX8MQ_CLK_PCIE1_CTRL] = imx8m_clk_composite("pcie1_ctrl", imx8mq_pcie1_ctrl_sels, base + 0xa300); - clks[IMX8MQ_CLK_PCIE1_PHY] = imx8m_clk_composite("pcie1_phy", imx8mq_pcie1_phy_sels, base + 0xa380); - clks[IMX8MQ_CLK_PCIE1_AUX] = imx8m_clk_composite("pcie1_aux", imx8mq_pcie1_aux_sels, base + 0xa400); - clks[IMX8MQ_CLK_DC_PIXEL] = imx8m_clk_composite("dc_pixel", imx8mq_dc_pixel_sels, base + 0xa480); - clks[IMX8MQ_CLK_LCDIF_PIXEL] = imx8m_clk_composite("lcdif_pixel", imx8mq_lcdif_pixel_sels, base + 0xa500); - clks[IMX8MQ_CLK_SAI1] = imx8m_clk_composite("sai1", imx8mq_sai1_sels, base + 0xa580); - clks[IMX8MQ_CLK_SAI2] = imx8m_clk_composite("sai2", imx8mq_sai2_sels, base + 0xa600); - clks[IMX8MQ_CLK_SAI3] = imx8m_clk_composite("sai3", imx8mq_sai3_sels, base + 0xa680); - clks[IMX8MQ_CLK_SAI4] = imx8m_clk_composite("sai4", imx8mq_sai4_sels, base + 0xa700); - clks[IMX8MQ_CLK_SAI5] = imx8m_clk_composite("sai5", imx8mq_sai5_sels, base + 0xa780); - clks[IMX8MQ_CLK_SAI6] = imx8m_clk_composite("sai6", imx8mq_sai6_sels, base + 0xa800); - clks[IMX8MQ_CLK_SPDIF1] = imx8m_clk_composite("spdif1", imx8mq_spdif1_sels, base + 0xa880); - clks[IMX8MQ_CLK_SPDIF2] = imx8m_clk_composite("spdif2", imx8mq_spdif2_sels, base + 0xa900); - clks[IMX8MQ_CLK_ENET_REF] = imx8m_clk_composite("enet_ref", imx8mq_enet_ref_sels, base + 0xa980); - clks[IMX8MQ_CLK_ENET_TIMER] = imx8m_clk_composite("enet_timer", imx8mq_enet_timer_sels, base + 0xaa00); - clks[IMX8MQ_CLK_ENET_PHY_REF] = imx8m_clk_composite("enet_phy", imx8mq_enet_phy_sels, base + 0xaa80); - clks[IMX8MQ_CLK_NAND] = imx8m_clk_composite("nand", imx8mq_nand_sels, base + 0xab00); - clks[IMX8MQ_CLK_QSPI] = imx8m_clk_composite("qspi", imx8mq_qspi_sels, base + 0xab80); - clks[IMX8MQ_CLK_USDHC1] = imx8m_clk_composite("usdhc1", imx8mq_usdhc1_sels, base + 0xac00); - clks[IMX8MQ_CLK_USDHC2] = imx8m_clk_composite("usdhc2", imx8mq_usdhc2_sels, base + 0xac80); - clks[IMX8MQ_CLK_I2C1] = imx8m_clk_composite("i2c1", imx8mq_i2c1_sels, base + 0xad00); - clks[IMX8MQ_CLK_I2C2] = imx8m_clk_composite("i2c2", imx8mq_i2c2_sels, base + 0xad80); - clks[IMX8MQ_CLK_I2C3] = imx8m_clk_composite("i2c3", imx8mq_i2c3_sels, base + 0xae00); - clks[IMX8MQ_CLK_I2C4] = imx8m_clk_composite("i2c4", imx8mq_i2c4_sels, base + 0xae80); - clks[IMX8MQ_CLK_UART1] = imx8m_clk_composite("uart1", imx8mq_uart1_sels, base + 0xaf00); - clks[IMX8MQ_CLK_UART2] = imx8m_clk_composite("uart2", imx8mq_uart2_sels, base + 0xaf80); - clks[IMX8MQ_CLK_UART3] = imx8m_clk_composite("uart3", imx8mq_uart3_sels, base + 0xb000); - clks[IMX8MQ_CLK_UART4] = imx8m_clk_composite("uart4", imx8mq_uart4_sels, base + 0xb080); - clks[IMX8MQ_CLK_USB_CORE_REF] = imx8m_clk_composite("usb_core_ref", imx8mq_usb_core_sels, base + 0xb100); - clks[IMX8MQ_CLK_USB_PHY_REF] = imx8m_clk_composite("usb_phy_ref", imx8mq_usb_phy_sels, base + 0xb180); - clks[IMX8MQ_CLK_GIC] = imx8m_clk_composite_critical("gic", imx8mq_gic_sels, base + 0xb200); - clks[IMX8MQ_CLK_ECSPI1] = imx8m_clk_composite("ecspi1", imx8mq_ecspi1_sels, base + 0xb280); - clks[IMX8MQ_CLK_ECSPI2] = imx8m_clk_composite("ecspi2", imx8mq_ecspi2_sels, base + 0xb300); - clks[IMX8MQ_CLK_PWM1] = imx8m_clk_composite("pwm1", imx8mq_pwm1_sels, base + 0xb380); - clks[IMX8MQ_CLK_PWM2] = imx8m_clk_composite("pwm2", imx8mq_pwm2_sels, base + 0xb400); - clks[IMX8MQ_CLK_PWM3] = imx8m_clk_composite("pwm3", imx8mq_pwm3_sels, base + 0xb480); - clks[IMX8MQ_CLK_PWM4] = imx8m_clk_composite("pwm4", imx8mq_pwm4_sels, base + 0xb500); - clks[IMX8MQ_CLK_GPT1] = imx8m_clk_composite("gpt1", imx8mq_gpt1_sels, base + 0xb580); - clks[IMX8MQ_CLK_WDOG] = imx8m_clk_composite("wdog", imx8mq_wdog_sels, base + 0xb900); - clks[IMX8MQ_CLK_WRCLK] = imx8m_clk_composite("wrclk", imx8mq_wrclk_sels, base + 0xb980); - clks[IMX8MQ_CLK_CLKO1] = imx8m_clk_composite("clko1", imx8mq_clko1_sels, base + 0xba00); - clks[IMX8MQ_CLK_CLKO2] = imx8m_clk_composite("clko2", imx8mq_clko2_sels, base + 0xba80); - clks[IMX8MQ_CLK_DSI_CORE] = imx8m_clk_composite("dsi_core", imx8mq_dsi_core_sels, base + 0xbb00); - clks[IMX8MQ_CLK_DSI_PHY_REF] = imx8m_clk_composite("dsi_phy_ref", imx8mq_dsi_phy_sels, base + 0xbb80); - clks[IMX8MQ_CLK_DSI_DBI] = imx8m_clk_composite("dsi_dbi", imx8mq_dsi_dbi_sels, base + 0xbc00); - clks[IMX8MQ_CLK_DSI_ESC] = imx8m_clk_composite("dsi_esc", imx8mq_dsi_esc_sels, base + 0xbc80); - clks[IMX8MQ_CLK_DSI_AHB] = imx8m_clk_composite("dsi_ahb", imx8mq_dsi_ahb_sels, base + 0x9200); - clks[IMX8MQ_CLK_DSI_IPG_DIV] = imx_clk_divider2("dsi_ipg_div", "dsi_ahb", base + 0x9280, 0, 6); - clks[IMX8MQ_CLK_CSI1_CORE] = imx8m_clk_composite("csi1_core", imx8mq_csi1_core_sels, base + 0xbd00); - clks[IMX8MQ_CLK_CSI1_PHY_REF] = imx8m_clk_composite("csi1_phy_ref", imx8mq_csi1_phy_sels, base + 0xbd80); - clks[IMX8MQ_CLK_CSI1_ESC] = imx8m_clk_composite("csi1_esc", imx8mq_csi1_esc_sels, base + 0xbe00); - clks[IMX8MQ_CLK_CSI2_CORE] = imx8m_clk_composite("csi2_core", imx8mq_csi2_core_sels, base + 0xbe80); - clks[IMX8MQ_CLK_CSI2_PHY_REF] = imx8m_clk_composite("csi2_phy_ref", imx8mq_csi2_phy_sels, base + 0xbf00); - clks[IMX8MQ_CLK_CSI2_ESC] = imx8m_clk_composite("csi2_esc", imx8mq_csi2_esc_sels, base + 0xbf80); - clks[IMX8MQ_CLK_PCIE2_CTRL] = imx8m_clk_composite("pcie2_ctrl", imx8mq_pcie2_ctrl_sels, base + 0xc000); - clks[IMX8MQ_CLK_PCIE2_PHY] = imx8m_clk_composite("pcie2_phy", imx8mq_pcie2_phy_sels, base + 0xc080); - clks[IMX8MQ_CLK_PCIE2_AUX] = imx8m_clk_composite("pcie2_aux", imx8mq_pcie2_aux_sels, base + 0xc100); - clks[IMX8MQ_CLK_ECSPI3] = imx8m_clk_composite("ecspi3", imx8mq_ecspi3_sels, base + 0xc180); - - clks[IMX8MQ_CLK_ECSPI1_ROOT] = imx_clk_gate4("ecspi1_root_clk", "ecspi1", base + 0x4070, 0); - clks[IMX8MQ_CLK_ECSPI2_ROOT] = imx_clk_gate4("ecspi2_root_clk", "ecspi2", base + 0x4080, 0); - clks[IMX8MQ_CLK_ECSPI3_ROOT] = imx_clk_gate4("ecspi3_root_clk", "ecspi3", base + 0x4090, 0); - clks[IMX8MQ_CLK_ENET1_ROOT] = imx_clk_gate4("enet1_root_clk", "enet_axi", base + 0x40a0, 0); - clks[IMX8MQ_CLK_GPIO1_ROOT] = imx_clk_gate4("gpio1_root_clk", "ipg_root", base + 0x40b0, 0); - clks[IMX8MQ_CLK_GPIO2_ROOT] = imx_clk_gate4("gpio2_root_clk", "ipg_root", base + 0x40c0, 0); - clks[IMX8MQ_CLK_GPIO3_ROOT] = imx_clk_gate4("gpio3_root_clk", "ipg_root", base + 0x40d0, 0); - clks[IMX8MQ_CLK_GPIO4_ROOT] = imx_clk_gate4("gpio4_root_clk", "ipg_root", base + 0x40e0, 0); - clks[IMX8MQ_CLK_GPIO5_ROOT] = imx_clk_gate4("gpio5_root_clk", "ipg_root", base + 0x40f0, 0); - clks[IMX8MQ_CLK_GPT1_ROOT] = imx_clk_gate4("gpt1_root_clk", "gpt1", base + 0x4100, 0); - clks[IMX8MQ_CLK_I2C1_ROOT] = imx_clk_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0); - clks[IMX8MQ_CLK_I2C2_ROOT] = imx_clk_gate4("i2c2_root_clk", "i2c2", base + 0x4180, 0); - clks[IMX8MQ_CLK_I2C3_ROOT] = imx_clk_gate4("i2c3_root_clk", "i2c3", base + 0x4190, 0); - clks[IMX8MQ_CLK_I2C4_ROOT] = imx_clk_gate4("i2c4_root_clk", "i2c4", base + 0x41a0, 0); - clks[IMX8MQ_CLK_MU_ROOT] = imx_clk_gate4("mu_root_clk", "ipg_root", base + 0x4210, 0); - clks[IMX8MQ_CLK_OCOTP_ROOT] = imx_clk_gate4("ocotp_root_clk", "ipg_root", base + 0x4220, 0); - clks[IMX8MQ_CLK_PCIE1_ROOT] = imx_clk_gate4("pcie1_root_clk", "pcie1_ctrl", base + 0x4250, 0); - clks[IMX8MQ_CLK_PCIE2_ROOT] = imx_clk_gate4("pcie2_root_clk", "pcie2_ctrl", base + 0x4640, 0); - clks[IMX8MQ_CLK_PWM1_ROOT] = imx_clk_gate4("pwm1_root_clk", "pwm1", base + 0x4280, 0); - clks[IMX8MQ_CLK_PWM2_ROOT] = imx_clk_gate4("pwm2_root_clk", "pwm2", base + 0x4290, 0); - clks[IMX8MQ_CLK_PWM3_ROOT] = imx_clk_gate4("pwm3_root_clk", "pwm3", base + 0x42a0, 0); - clks[IMX8MQ_CLK_PWM4_ROOT] = imx_clk_gate4("pwm4_root_clk", "pwm4", base + 0x42b0, 0); - clks[IMX8MQ_CLK_QSPI_ROOT] = imx_clk_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0); - clks[IMX8MQ_CLK_RAWNAND_ROOT] = imx_clk_gate2_shared2("nand_root_clk", "nand", base + 0x4300, 0, &share_count_nand); - clks[IMX8MQ_CLK_NAND_USDHC_BUS_RAWNAND_CLK] = imx_clk_gate2_shared2("nand_usdhc_rawnand_clk", "nand_usdhc_bus", base + 0x4300, 0, &share_count_nand); - clks[IMX8MQ_CLK_SAI1_ROOT] = imx_clk_gate2_shared2("sai1_root_clk", "sai1", base + 0x4330, 0, &share_count_sai1); - clks[IMX8MQ_CLK_SAI1_IPG] = imx_clk_gate2_shared2("sai1_ipg_clk", "ipg_audio_root", base + 0x4330, 0, &share_count_sai1); - clks[IMX8MQ_CLK_SAI2_ROOT] = imx_clk_gate2_shared2("sai2_root_clk", "sai2", base + 0x4340, 0, &share_count_sai2); - clks[IMX8MQ_CLK_SAI2_IPG] = imx_clk_gate2_shared2("sai2_ipg_clk", "ipg_root", base + 0x4340, 0, &share_count_sai2); - clks[IMX8MQ_CLK_SAI3_ROOT] = imx_clk_gate2_shared2("sai3_root_clk", "sai3", base + 0x4350, 0, &share_count_sai3); - clks[IMX8MQ_CLK_SAI3_IPG] = imx_clk_gate2_shared2("sai3_ipg_clk", "ipg_root", base + 0x4350, 0, &share_count_sai3); - clks[IMX8MQ_CLK_SAI4_ROOT] = imx_clk_gate2_shared2("sai4_root_clk", "sai4", base + 0x4360, 0, &share_count_sai4); - clks[IMX8MQ_CLK_SAI4_IPG] = imx_clk_gate2_shared2("sai4_ipg_clk", "ipg_audio_root", base + 0x4360, 0, &share_count_sai4); - clks[IMX8MQ_CLK_SAI5_ROOT] = imx_clk_gate2_shared2("sai5_root_clk", "sai5", base + 0x4370, 0, &share_count_sai5); - clks[IMX8MQ_CLK_SAI5_IPG] = imx_clk_gate2_shared2("sai5_ipg_clk", "ipg_audio_root", base + 0x4370, 0, &share_count_sai5); - clks[IMX8MQ_CLK_SAI6_ROOT] = imx_clk_gate2_shared2("sai6_root_clk", "sai6", base + 0x4380, 0, &share_count_sai6); - clks[IMX8MQ_CLK_SAI6_IPG] = imx_clk_gate2_shared2("sai6_ipg_clk", "ipg_audio_root", base + 0x4380, 0, &share_count_sai6); - clks[IMX8MQ_CLK_SNVS_ROOT] = imx_clk_gate4("snvs_root_clk", "ipg_root", base + 0x4470, 0); - clks[IMX8MQ_CLK_UART1_ROOT] = imx_clk_gate4("uart1_root_clk", "uart1", base + 0x4490, 0); - clks[IMX8MQ_CLK_UART2_ROOT] = imx_clk_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0); - clks[IMX8MQ_CLK_UART3_ROOT] = imx_clk_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0); - clks[IMX8MQ_CLK_UART4_ROOT] = imx_clk_gate4("uart4_root_clk", "uart4", base + 0x44c0, 0); - clks[IMX8MQ_CLK_USB1_CTRL_ROOT] = imx_clk_gate4("usb1_ctrl_root_clk", "usb_bus", base + 0x44d0, 0); - clks[IMX8MQ_CLK_USB2_CTRL_ROOT] = imx_clk_gate4("usb2_ctrl_root_clk", "usb_bus", base + 0x44e0, 0); - clks[IMX8MQ_CLK_USB1_PHY_ROOT] = imx_clk_gate4("usb1_phy_root_clk", "usb_phy_ref", base + 0x44f0, 0); - clks[IMX8MQ_CLK_USB2_PHY_ROOT] = imx_clk_gate4("usb2_phy_root_clk", "usb_phy_ref", base + 0x4500, 0); - clks[IMX8MQ_CLK_USDHC1_ROOT] = imx_clk_gate4("usdhc1_root_clk", "usdhc1", base + 0x4510, 0); - clks[IMX8MQ_CLK_USDHC2_ROOT] = imx_clk_gate4("usdhc2_root_clk", "usdhc2", base + 0x4520, 0); - clks[IMX8MQ_CLK_WDOG1_ROOT] = imx_clk_gate4("wdog1_root_clk", "wdog", base + 0x4530, 0); - clks[IMX8MQ_CLK_WDOG2_ROOT] = imx_clk_gate4("wdog2_root_clk", "wdog", base + 0x4540, 0); - clks[IMX8MQ_CLK_WDOG3_ROOT] = imx_clk_gate4("wdog3_root_clk", "wdog", base + 0x4550, 0); - clks[IMX8MQ_CLK_VPU_G1_ROOT] = imx_clk_gate2_flags("vpu_g1_root_clk", "vpu_g1", base + 0x4560, 0, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE); - clks[IMX8MQ_CLK_GPU_ROOT] = imx_clk_gate4("gpu_root_clk", "gpu_core_div", base + 0x4570, 0); - clks[IMX8MQ_CLK_VPU_G2_ROOT] = imx_clk_gate2_flags("vpu_g2_root_clk", "vpu_g2", base + 0x45a0, 0, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE); - clks[IMX8MQ_CLK_DISP_ROOT] = imx_clk_gate2_shared2("disp_root_clk", "disp_dc8000", base + 0x45d0, 0, &share_count_dcss); - clks[IMX8MQ_CLK_DISP_AXI_ROOT] = imx_clk_gate2_shared2("disp_axi_root_clk", "disp_axi", base + 0x45d0, 0, &share_count_dcss); - clks[IMX8MQ_CLK_DISP_APB_ROOT] = imx_clk_gate2_shared2("disp_apb_root_clk", "disp_apb", base + 0x45d0, 0, &share_count_dcss); - clks[IMX8MQ_CLK_DISP_RTRM_ROOT] = imx_clk_gate2_shared2("disp_rtrm_root_clk", "disp_rtrm", base + 0x45d0, 0, &share_count_dcss); - clks[IMX8MQ_CLK_TMU_ROOT] = imx_clk_gate4("tmu_root_clk", "ipg_root", base + 0x4620, 0); - clks[IMX8MQ_CLK_VPU_DEC_ROOT] = imx_clk_gate2_flags("vpu_dec_root_clk", "vpu_bus", base + 0x4630, 0, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE); - clks[IMX8MQ_CLK_CSI1_ROOT] = imx_clk_gate4("csi1_root_clk", "csi1_core", base + 0x4650, 0); - clks[IMX8MQ_CLK_CSI2_ROOT] = imx_clk_gate4("csi2_root_clk", "csi2_core", base + 0x4660, 0); - clks[IMX8MQ_CLK_SDMA1_ROOT] = imx_clk_gate4("sdma1_clk", "ipg_root", base + 0x43a0, 0); - clks[IMX8MQ_CLK_SDMA2_ROOT] = imx_clk_gate4("sdma2_clk", "ipg_audio_root", base + 0x43b0, 0); - - clks[IMX8MQ_GPT_3M_CLK] = imx_clk_fixed_factor("gpt_3m", "osc_25m", 1, 8); - clks[IMX8MQ_CLK_DRAM_ALT_ROOT] = imx_clk_fixed_factor("dram_alt_root", "dram_alt", 1, 4); - - clks[IMX8MQ_CLK_ARM] = imx_clk_cpu("arm", "arm_a53_div", - clks[IMX8MQ_CLK_A53_DIV], - clks[IMX8MQ_CLK_A53_SRC], - clks[IMX8MQ_ARM_PLL_OUT], - clks[IMX8MQ_SYS1_PLL_800M]); - - imx_check_clocks(clks, ARRAY_SIZE(clks)); - - clk_data.clks = clks; - clk_data.clk_num = ARRAY_SIZE(clks); - - err = of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); + hws[IMX8MQ_CLK_VPU_G1] = imx8m_clk_hw_composite("vpu_g1", imx8mq_vpu_g1_sels, base + 0xa100); + hws[IMX8MQ_CLK_VPU_G2] = imx8m_clk_hw_composite("vpu_g2", imx8mq_vpu_g2_sels, base + 0xa180); + hws[IMX8MQ_CLK_DISP_DTRC] = imx8m_clk_hw_composite("disp_dtrc", imx8mq_disp_dtrc_sels, base + 0xa200); + hws[IMX8MQ_CLK_DISP_DC8000] = imx8m_clk_hw_composite("disp_dc8000", imx8mq_disp_dc8000_sels, base + 0xa280); + hws[IMX8MQ_CLK_PCIE1_CTRL] = imx8m_clk_hw_composite("pcie1_ctrl", imx8mq_pcie1_ctrl_sels, base + 0xa300); + hws[IMX8MQ_CLK_PCIE1_PHY] = imx8m_clk_hw_composite("pcie1_phy", imx8mq_pcie1_phy_sels, base + 0xa380); + hws[IMX8MQ_CLK_PCIE1_AUX] = imx8m_clk_hw_composite("pcie1_aux", imx8mq_pcie1_aux_sels, base + 0xa400); + hws[IMX8MQ_CLK_DC_PIXEL] = imx8m_clk_hw_composite("dc_pixel", imx8mq_dc_pixel_sels, base + 0xa480); + hws[IMX8MQ_CLK_LCDIF_PIXEL] = imx8m_clk_hw_composite("lcdif_pixel", imx8mq_lcdif_pixel_sels, base + 0xa500); + hws[IMX8MQ_CLK_SAI1] = imx8m_clk_hw_composite("sai1", imx8mq_sai1_sels, base + 0xa580); + hws[IMX8MQ_CLK_SAI2] = imx8m_clk_hw_composite("sai2", imx8mq_sai2_sels, base + 0xa600); + hws[IMX8MQ_CLK_SAI3] = imx8m_clk_hw_composite("sai3", imx8mq_sai3_sels, base + 0xa680); + hws[IMX8MQ_CLK_SAI4] = imx8m_clk_hw_composite("sai4", imx8mq_sai4_sels, base + 0xa700); + hws[IMX8MQ_CLK_SAI5] = imx8m_clk_hw_composite("sai5", imx8mq_sai5_sels, base + 0xa780); + hws[IMX8MQ_CLK_SAI6] = imx8m_clk_hw_composite("sai6", imx8mq_sai6_sels, base + 0xa800); + hws[IMX8MQ_CLK_SPDIF1] = imx8m_clk_hw_composite("spdif1", imx8mq_spdif1_sels, base + 0xa880); + hws[IMX8MQ_CLK_SPDIF2] = imx8m_clk_hw_composite("spdif2", imx8mq_spdif2_sels, base + 0xa900); + hws[IMX8MQ_CLK_ENET_REF] = imx8m_clk_hw_composite("enet_ref", imx8mq_enet_ref_sels, base + 0xa980); + hws[IMX8MQ_CLK_ENET_TIMER] = imx8m_clk_hw_composite("enet_timer", imx8mq_enet_timer_sels, base + 0xaa00); + hws[IMX8MQ_CLK_ENET_PHY_REF] = imx8m_clk_hw_composite("enet_phy", imx8mq_enet_phy_sels, base + 0xaa80); + hws[IMX8MQ_CLK_NAND] = imx8m_clk_hw_composite("nand", imx8mq_nand_sels, base + 0xab00); + hws[IMX8MQ_CLK_QSPI] = imx8m_clk_hw_composite("qspi", imx8mq_qspi_sels, base + 0xab80); + hws[IMX8MQ_CLK_USDHC1] = imx8m_clk_hw_composite("usdhc1", imx8mq_usdhc1_sels, base + 0xac00); + hws[IMX8MQ_CLK_USDHC2] = imx8m_clk_hw_composite("usdhc2", imx8mq_usdhc2_sels, base + 0xac80); + hws[IMX8MQ_CLK_I2C1] = imx8m_clk_hw_composite("i2c1", imx8mq_i2c1_sels, base + 0xad00); + hws[IMX8MQ_CLK_I2C2] = imx8m_clk_hw_composite("i2c2", imx8mq_i2c2_sels, base + 0xad80); + hws[IMX8MQ_CLK_I2C3] = imx8m_clk_hw_composite("i2c3", imx8mq_i2c3_sels, base + 0xae00); + hws[IMX8MQ_CLK_I2C4] = imx8m_clk_hw_composite("i2c4", imx8mq_i2c4_sels, base + 0xae80); + hws[IMX8MQ_CLK_UART1] = imx8m_clk_hw_composite("uart1", imx8mq_uart1_sels, base + 0xaf00); + hws[IMX8MQ_CLK_UART2] = imx8m_clk_hw_composite("uart2", imx8mq_uart2_sels, base + 0xaf80); + hws[IMX8MQ_CLK_UART3] = imx8m_clk_hw_composite("uart3", imx8mq_uart3_sels, base + 0xb000); + hws[IMX8MQ_CLK_UART4] = imx8m_clk_hw_composite("uart4", imx8mq_uart4_sels, base + 0xb080); + hws[IMX8MQ_CLK_USB_CORE_REF] = imx8m_clk_hw_composite("usb_core_ref", imx8mq_usb_core_sels, base + 0xb100); + hws[IMX8MQ_CLK_USB_PHY_REF] = imx8m_clk_hw_composite("usb_phy_ref", imx8mq_usb_phy_sels, base + 0xb180); + hws[IMX8MQ_CLK_GIC] = imx8m_clk_hw_composite_critical("gic", imx8mq_gic_sels, base + 0xb200); + hws[IMX8MQ_CLK_ECSPI1] = imx8m_clk_hw_composite("ecspi1", imx8mq_ecspi1_sels, base + 0xb280); + hws[IMX8MQ_CLK_ECSPI2] = imx8m_clk_hw_composite("ecspi2", imx8mq_ecspi2_sels, base + 0xb300); + hws[IMX8MQ_CLK_PWM1] = imx8m_clk_hw_composite("pwm1", imx8mq_pwm1_sels, base + 0xb380); + hws[IMX8MQ_CLK_PWM2] = imx8m_clk_hw_composite("pwm2", imx8mq_pwm2_sels, base + 0xb400); + hws[IMX8MQ_CLK_PWM3] = imx8m_clk_hw_composite("pwm3", imx8mq_pwm3_sels, base + 0xb480); + hws[IMX8MQ_CLK_PWM4] = imx8m_clk_hw_composite("pwm4", imx8mq_pwm4_sels, base + 0xb500); + hws[IMX8MQ_CLK_GPT1] = imx8m_clk_hw_composite("gpt1", imx8mq_gpt1_sels, base + 0xb580); + hws[IMX8MQ_CLK_WDOG] = imx8m_clk_hw_composite("wdog", imx8mq_wdog_sels, base + 0xb900); + hws[IMX8MQ_CLK_WRCLK] = imx8m_clk_hw_composite("wrclk", imx8mq_wrclk_sels, base + 0xb980); + hws[IMX8MQ_CLK_CLKO1] = imx8m_clk_hw_composite("clko1", imx8mq_clko1_sels, base + 0xba00); + hws[IMX8MQ_CLK_CLKO2] = imx8m_clk_hw_composite("clko2", imx8mq_clko2_sels, base + 0xba80); + hws[IMX8MQ_CLK_DSI_CORE] = imx8m_clk_hw_composite("dsi_core", imx8mq_dsi_core_sels, base + 0xbb00); + hws[IMX8MQ_CLK_DSI_PHY_REF] = imx8m_clk_hw_composite("dsi_phy_ref", imx8mq_dsi_phy_sels, base + 0xbb80); + hws[IMX8MQ_CLK_DSI_DBI] = imx8m_clk_hw_composite("dsi_dbi", imx8mq_dsi_dbi_sels, base + 0xbc00); + hws[IMX8MQ_CLK_DSI_ESC] = imx8m_clk_hw_composite("dsi_esc", imx8mq_dsi_esc_sels, base + 0xbc80); + hws[IMX8MQ_CLK_DSI_AHB] = imx8m_clk_hw_composite("dsi_ahb", imx8mq_dsi_ahb_sels, base + 0x9200); + hws[IMX8MQ_CLK_DSI_IPG_DIV] = imx_clk_hw_divider2("dsi_ipg_div", "dsi_ahb", base + 0x9280, 0, 6); + hws[IMX8MQ_CLK_CSI1_CORE] = imx8m_clk_hw_composite("csi1_core", imx8mq_csi1_core_sels, base + 0xbd00); + hws[IMX8MQ_CLK_CSI1_PHY_REF] = imx8m_clk_hw_composite("csi1_phy_ref", imx8mq_csi1_phy_sels, base + 0xbd80); + hws[IMX8MQ_CLK_CSI1_ESC] = imx8m_clk_hw_composite("csi1_esc", imx8mq_csi1_esc_sels, base + 0xbe00); + hws[IMX8MQ_CLK_CSI2_CORE] = imx8m_clk_hw_composite("csi2_core", imx8mq_csi2_core_sels, base + 0xbe80); + hws[IMX8MQ_CLK_CSI2_PHY_REF] = imx8m_clk_hw_composite("csi2_phy_ref", imx8mq_csi2_phy_sels, base + 0xbf00); + hws[IMX8MQ_CLK_CSI2_ESC] = imx8m_clk_hw_composite("csi2_esc", imx8mq_csi2_esc_sels, base + 0xbf80); + hws[IMX8MQ_CLK_PCIE2_CTRL] = imx8m_clk_hw_composite("pcie2_ctrl", imx8mq_pcie2_ctrl_sels, base + 0xc000); + hws[IMX8MQ_CLK_PCIE2_PHY] = imx8m_clk_hw_composite("pcie2_phy", imx8mq_pcie2_phy_sels, base + 0xc080); + hws[IMX8MQ_CLK_PCIE2_AUX] = imx8m_clk_hw_composite("pcie2_aux", imx8mq_pcie2_aux_sels, base + 0xc100); + hws[IMX8MQ_CLK_ECSPI3] = imx8m_clk_hw_composite("ecspi3", imx8mq_ecspi3_sels, base + 0xc180); + + hws[IMX8MQ_CLK_ECSPI1_ROOT] = imx_clk_hw_gate4("ecspi1_root_clk", "ecspi1", base + 0x4070, 0); + hws[IMX8MQ_CLK_ECSPI2_ROOT] = imx_clk_hw_gate4("ecspi2_root_clk", "ecspi2", base + 0x4080, 0); + hws[IMX8MQ_CLK_ECSPI3_ROOT] = imx_clk_hw_gate4("ecspi3_root_clk", "ecspi3", base + 0x4090, 0); + hws[IMX8MQ_CLK_ENET1_ROOT] = imx_clk_hw_gate4("enet1_root_clk", "enet_axi", base + 0x40a0, 0); + hws[IMX8MQ_CLK_GPIO1_ROOT] = imx_clk_hw_gate4("gpio1_root_clk", "ipg_root", base + 0x40b0, 0); + hws[IMX8MQ_CLK_GPIO2_ROOT] = imx_clk_hw_gate4("gpio2_root_clk", "ipg_root", base + 0x40c0, 0); + hws[IMX8MQ_CLK_GPIO3_ROOT] = imx_clk_hw_gate4("gpio3_root_clk", "ipg_root", base + 0x40d0, 0); + hws[IMX8MQ_CLK_GPIO4_ROOT] = imx_clk_hw_gate4("gpio4_root_clk", "ipg_root", base + 0x40e0, 0); + hws[IMX8MQ_CLK_GPIO5_ROOT] = imx_clk_hw_gate4("gpio5_root_clk", "ipg_root", base + 0x40f0, 0); + hws[IMX8MQ_CLK_GPT1_ROOT] = imx_clk_hw_gate4("gpt1_root_clk", "gpt1", base + 0x4100, 0); + hws[IMX8MQ_CLK_I2C1_ROOT] = imx_clk_hw_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0); + hws[IMX8MQ_CLK_I2C2_ROOT] = imx_clk_hw_gate4("i2c2_root_clk", "i2c2", base + 0x4180, 0); + hws[IMX8MQ_CLK_I2C3_ROOT] = imx_clk_hw_gate4("i2c3_root_clk", "i2c3", base + 0x4190, 0); + hws[IMX8MQ_CLK_I2C4_ROOT] = imx_clk_hw_gate4("i2c4_root_clk", "i2c4", base + 0x41a0, 0); + hws[IMX8MQ_CLK_MU_ROOT] = imx_clk_hw_gate4("mu_root_clk", "ipg_root", base + 0x4210, 0); + hws[IMX8MQ_CLK_OCOTP_ROOT] = imx_clk_hw_gate4("ocotp_root_clk", "ipg_root", base + 0x4220, 0); + hws[IMX8MQ_CLK_PCIE1_ROOT] = imx_clk_hw_gate4("pcie1_root_clk", "pcie1_ctrl", base + 0x4250, 0); + hws[IMX8MQ_CLK_PCIE2_ROOT] = imx_clk_hw_gate4("pcie2_root_clk", "pcie2_ctrl", base + 0x4640, 0); + hws[IMX8MQ_CLK_PWM1_ROOT] = imx_clk_hw_gate4("pwm1_root_clk", "pwm1", base + 0x4280, 0); + hws[IMX8MQ_CLK_PWM2_ROOT] = imx_clk_hw_gate4("pwm2_root_clk", "pwm2", base + 0x4290, 0); + hws[IMX8MQ_CLK_PWM3_ROOT] = imx_clk_hw_gate4("pwm3_root_clk", "pwm3", base + 0x42a0, 0); + hws[IMX8MQ_CLK_PWM4_ROOT] = imx_clk_hw_gate4("pwm4_root_clk", "pwm4", base + 0x42b0, 0); + hws[IMX8MQ_CLK_QSPI_ROOT] = imx_clk_hw_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0); + hws[IMX8MQ_CLK_RAWNAND_ROOT] = imx_clk_hw_gate2_shared2("nand_root_clk", "nand", base + 0x4300, 0, &share_count_nand); + hws[IMX8MQ_CLK_NAND_USDHC_BUS_RAWNAND_CLK] = imx_clk_hw_gate2_shared2("nand_usdhc_rawnand_clk", "nand_usdhc_bus", base + 0x4300, 0, &share_count_nand); + hws[IMX8MQ_CLK_SAI1_ROOT] = imx_clk_hw_gate2_shared2("sai1_root_clk", "sai1", base + 0x4330, 0, &share_count_sai1); + hws[IMX8MQ_CLK_SAI1_IPG] = imx_clk_hw_gate2_shared2("sai1_ipg_clk", "ipg_audio_root", base + 0x4330, 0, &share_count_sai1); + hws[IMX8MQ_CLK_SAI2_ROOT] = imx_clk_hw_gate2_shared2("sai2_root_clk", "sai2", base + 0x4340, 0, &share_count_sai2); + hws[IMX8MQ_CLK_SAI2_IPG] = imx_clk_hw_gate2_shared2("sai2_ipg_clk", "ipg_root", base + 0x4340, 0, &share_count_sai2); + hws[IMX8MQ_CLK_SAI3_ROOT] = imx_clk_hw_gate2_shared2("sai3_root_clk", "sai3", base + 0x4350, 0, &share_count_sai3); + hws[IMX8MQ_CLK_SAI3_IPG] = imx_clk_hw_gate2_shared2("sai3_ipg_clk", "ipg_root", base + 0x4350, 0, &share_count_sai3); + hws[IMX8MQ_CLK_SAI4_ROOT] = imx_clk_hw_gate2_shared2("sai4_root_clk", "sai4", base + 0x4360, 0, &share_count_sai4); + hws[IMX8MQ_CLK_SAI4_IPG] = imx_clk_hw_gate2_shared2("sai4_ipg_clk", "ipg_audio_root", base + 0x4360, 0, &share_count_sai4); + hws[IMX8MQ_CLK_SAI5_ROOT] = imx_clk_hw_gate2_shared2("sai5_root_clk", "sai5", base + 0x4370, 0, &share_count_sai5); + hws[IMX8MQ_CLK_SAI5_IPG] = imx_clk_hw_gate2_shared2("sai5_ipg_clk", "ipg_audio_root", base + 0x4370, 0, &share_count_sai5); + hws[IMX8MQ_CLK_SAI6_ROOT] = imx_clk_hw_gate2_shared2("sai6_root_clk", "sai6", base + 0x4380, 0, &share_count_sai6); + hws[IMX8MQ_CLK_SAI6_IPG] = imx_clk_hw_gate2_shared2("sai6_ipg_clk", "ipg_audio_root", base + 0x4380, 0, &share_count_sai6); + hws[IMX8MQ_CLK_SNVS_ROOT] = imx_clk_hw_gate4("snvs_root_clk", "ipg_root", base + 0x4470, 0); + hws[IMX8MQ_CLK_UART1_ROOT] = imx_clk_hw_gate4("uart1_root_clk", "uart1", base + 0x4490, 0); + hws[IMX8MQ_CLK_UART2_ROOT] = imx_clk_hw_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0); + hws[IMX8MQ_CLK_UART3_ROOT] = imx_clk_hw_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0); + hws[IMX8MQ_CLK_UART4_ROOT] = imx_clk_hw_gate4("uart4_root_clk", "uart4", base + 0x44c0, 0); + hws[IMX8MQ_CLK_USB1_CTRL_ROOT] = imx_clk_hw_gate4("usb1_ctrl_root_clk", "usb_bus", base + 0x44d0, 0); + hws[IMX8MQ_CLK_USB2_CTRL_ROOT] = imx_clk_hw_gate4("usb2_ctrl_root_clk", "usb_bus", base + 0x44e0, 0); + hws[IMX8MQ_CLK_USB1_PHY_ROOT] = imx_clk_hw_gate4("usb1_phy_root_clk", "usb_phy_ref", base + 0x44f0, 0); + hws[IMX8MQ_CLK_USB2_PHY_ROOT] = imx_clk_hw_gate4("usb2_phy_root_clk", "usb_phy_ref", base + 0x4500, 0); + hws[IMX8MQ_CLK_USDHC1_ROOT] = imx_clk_hw_gate4("usdhc1_root_clk", "usdhc1", base + 0x4510, 0); + hws[IMX8MQ_CLK_USDHC2_ROOT] = imx_clk_hw_gate4("usdhc2_root_clk", "usdhc2", base + 0x4520, 0); + hws[IMX8MQ_CLK_WDOG1_ROOT] = imx_clk_hw_gate4("wdog1_root_clk", "wdog", base + 0x4530, 0); + hws[IMX8MQ_CLK_WDOG2_ROOT] = imx_clk_hw_gate4("wdog2_root_clk", "wdog", base + 0x4540, 0); + hws[IMX8MQ_CLK_WDOG3_ROOT] = imx_clk_hw_gate4("wdog3_root_clk", "wdog", base + 0x4550, 0); + hws[IMX8MQ_CLK_VPU_G1_ROOT] = imx_clk_hw_gate2_flags("vpu_g1_root_clk", "vpu_g1", base + 0x4560, 0, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE); + hws[IMX8MQ_CLK_GPU_ROOT] = imx_clk_hw_gate4("gpu_root_clk", "gpu_core_div", base + 0x4570, 0); + hws[IMX8MQ_CLK_VPU_G2_ROOT] = imx_clk_hw_gate2_flags("vpu_g2_root_clk", "vpu_g2", base + 0x45a0, 0, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE); + hws[IMX8MQ_CLK_DISP_ROOT] = imx_clk_hw_gate2_shared2("disp_root_clk", "disp_dc8000", base + 0x45d0, 0, &share_count_dcss); + hws[IMX8MQ_CLK_DISP_AXI_ROOT] = imx_clk_hw_gate2_shared2("disp_axi_root_clk", "disp_axi", base + 0x45d0, 0, &share_count_dcss); + hws[IMX8MQ_CLK_DISP_APB_ROOT] = imx_clk_hw_gate2_shared2("disp_apb_root_clk", "disp_apb", base + 0x45d0, 0, &share_count_dcss); + hws[IMX8MQ_CLK_DISP_RTRM_ROOT] = imx_clk_hw_gate2_shared2("disp_rtrm_root_clk", "disp_rtrm", base + 0x45d0, 0, &share_count_dcss); + hws[IMX8MQ_CLK_TMU_ROOT] = imx_clk_hw_gate4("tmu_root_clk", "ipg_root", base + 0x4620, 0); + hws[IMX8MQ_CLK_VPU_DEC_ROOT] = imx_clk_hw_gate2_flags("vpu_dec_root_clk", "vpu_bus", base + 0x4630, 0, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE); + hws[IMX8MQ_CLK_CSI1_ROOT] = imx_clk_hw_gate4("csi1_root_clk", "csi1_core", base + 0x4650, 0); + hws[IMX8MQ_CLK_CSI2_ROOT] = imx_clk_hw_gate4("csi2_root_clk", "csi2_core", base + 0x4660, 0); + hws[IMX8MQ_CLK_SDMA1_ROOT] = imx_clk_hw_gate4("sdma1_clk", "ipg_root", base + 0x43a0, 0); + hws[IMX8MQ_CLK_SDMA2_ROOT] = imx_clk_hw_gate4("sdma2_clk", "ipg_audio_root", base + 0x43b0, 0); + + hws[IMX8MQ_GPT_3M_CLK] = imx_clk_hw_fixed_factor("gpt_3m", "osc_25m", 1, 8); + hws[IMX8MQ_CLK_DRAM_ALT_ROOT] = imx_clk_hw_fixed_factor("dram_alt_root", "dram_alt", 1, 4); + + hws[IMX8MQ_CLK_ARM] = imx_clk_hw_cpu("arm", "arm_a53_div", + hws[IMX8MQ_CLK_A53_DIV]->clk, + hws[IMX8MQ_CLK_A53_SRC]->clk, + hws[IMX8MQ_ARM_PLL_OUT]->clk, + hws[IMX8MQ_SYS1_PLL_800M]->clk); + + imx_check_clk_hws(hws, IMX8MQ_CLK_END); + + err = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data); if (err < 0) { - dev_err(dev, "failed to register clks for i.MX8MQ\n"); - goto unregister_clks; + dev_err(dev, "failed to register hws for i.MX8MQ\n"); + goto unregister_hws; + } + + for (i = 0; i < ARRAY_SIZE(uart_clk_ids); i++) { + int index = uart_clk_ids[i]; + + uart_hws[i] = &hws[index]->clk; } - imx_register_uart_clocks(uart_clks); + imx_register_uart_clocks(uart_hws); return 0; -unregister_clks: - imx_unregister_clocks(clks, ARRAY_SIZE(clks)); +unregister_hws: + imx_unregister_hw_clocks(hws, IMX8MQ_CLK_END); return err; } @@ -609,6 +624,11 @@ static struct platform_driver imx8mq_clk_driver = { .probe = imx8mq_clocks_probe, .driver = { .name = "imx8mq-ccm", + /* + * Disable bind attributes: clocks are not removed and + * reloading the driver will crash or break devices. + */ + .suppress_bind_attrs = true, .of_match_table = of_match_ptr(imx8mq_clk_of_match), }, }; diff --git a/drivers/clk/imx/clk-imx8qxp-lpcg.c b/drivers/clk/imx/clk-imx8qxp-lpcg.c index c0aff7ca6374..04c8ee35e14c 100644 --- a/drivers/clk/imx/clk-imx8qxp-lpcg.c +++ b/drivers/clk/imx/clk-imx8qxp-lpcg.c @@ -173,6 +173,17 @@ static int imx8qxp_lpcg_clk_probe(struct platform_device *pdev) if (!ss_lpcg) return -ENODEV; + /* + * Please don't replace this with devm_platform_ioremap_resource. + * + * devm_platform_ioremap_resource calls devm_ioremap_resource which + * differs from devm_ioremap by also calling devm_request_mem_region + * and preventing other mappings in the same area. + * + * On imx8 the LPCG nodes map entire subsystems and overlap + * peripherals, this means that using devm_platform_ioremap_resource + * will cause many devices to fail to probe including serial ports. + */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) return -EINVAL; diff --git a/drivers/clk/imx/clk-pfdv2.c b/drivers/clk/imx/clk-pfdv2.c index a03bbed662c6..de93ce73101b 100644 --- a/drivers/clk/imx/clk-pfdv2.c +++ b/drivers/clk/imx/clk-pfdv2.c @@ -166,7 +166,7 @@ static const struct clk_ops clk_pfdv2_ops = { .is_enabled = clk_pfdv2_is_enabled, }; -struct clk_hw *imx_clk_pfdv2(const char *name, const char *parent_name, +struct clk_hw *imx_clk_hw_pfdv2(const char *name, const char *parent_name, void __iomem *reg, u8 idx) { struct clk_init_data init; diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c index 5c458199060a..5b0519a81a7a 100644 --- a/drivers/clk/imx/clk-pll14xx.c +++ b/drivers/clk/imx/clk-pll14xx.c @@ -67,6 +67,13 @@ struct imx_pll14xx_clk imx_1443x_pll = { .rate_count = ARRAY_SIZE(imx_pll1443x_tbl), }; +struct imx_pll14xx_clk imx_1443x_dram_pll = { + .type = PLL_1443X, + .rate_table = imx_pll1443x_tbl, + .rate_count = ARRAY_SIZE(imx_pll1443x_tbl), + .flags = CLK_GET_RATE_NOCACHE, +}; + struct imx_pll14xx_clk imx_1416x_pll = { .type = PLL_1416X, .rate_table = imx_pll1416x_tbl, @@ -159,7 +166,7 @@ static int clk_pll14xx_wait_lock(struct clk_pll14xx *pll) { u32 val; - return readl_poll_timeout(pll->base, val, val & LOCK_TIMEOUT_US, 0, + return readl_poll_timeout(pll->base, val, val & LOCK_STATUS, 0, LOCK_TIMEOUT_US); } @@ -369,13 +376,14 @@ static const struct clk_ops clk_pll1443x_ops = { .set_rate = clk_pll1443x_set_rate, }; -struct clk *imx_clk_pll14xx(const char *name, const char *parent_name, - void __iomem *base, - const struct imx_pll14xx_clk *pll_clk) +struct clk_hw *imx_clk_hw_pll14xx(const char *name, const char *parent_name, + void __iomem *base, + const struct imx_pll14xx_clk *pll_clk) { struct clk_pll14xx *pll; - struct clk *clk; + struct clk_hw *hw; struct clk_init_data init; + int ret; u32 val; pll = kzalloc(sizeof(*pll), GFP_KERNEL); @@ -412,12 +420,15 @@ struct clk *imx_clk_pll14xx(const char *name, const char *parent_name, val &= ~BYPASS_MASK; writel_relaxed(val, pll->base + GNRL_CTL); - clk = clk_register(NULL, &pll->hw); - if (IS_ERR(clk)) { - pr_err("%s: failed to register pll %s %lu\n", - __func__, name, PTR_ERR(clk)); + hw = &pll->hw; + + ret = clk_hw_register(NULL, hw); + if (ret) { + pr_err("%s: failed to register pll %s %d\n", + __func__, name, ret); kfree(pll); + return ERR_PTR(ret); } - return clk; + return hw; } diff --git a/drivers/clk/imx/clk-pllv1.c b/drivers/clk/imx/clk-pllv1.c index 4ba9973d4c18..de4f8a41a7d0 100644 --- a/drivers/clk/imx/clk-pllv1.c +++ b/drivers/clk/imx/clk-pllv1.c @@ -111,12 +111,13 @@ static const struct clk_ops clk_pllv1_ops = { .recalc_rate = clk_pllv1_recalc_rate, }; -struct clk *imx_clk_pllv1(enum imx_pllv1_type type, const char *name, +struct clk_hw *imx_clk_hw_pllv1(enum imx_pllv1_type type, const char *name, const char *parent, void __iomem *base) { struct clk_pllv1 *pll; - struct clk *clk; + struct clk_hw *hw; struct clk_init_data init; + int ret; pll = kmalloc(sizeof(*pll), GFP_KERNEL); if (!pll) @@ -132,10 +133,13 @@ struct clk *imx_clk_pllv1(enum imx_pllv1_type type, const char *name, init.num_parents = 1; pll->hw.init = &init; + hw = &pll->hw; - clk = clk_register(NULL, &pll->hw); - if (IS_ERR(clk)) + ret = clk_hw_register(NULL, hw); + if (ret) { kfree(pll); + return ERR_PTR(ret); + } - return clk; + return hw; } diff --git a/drivers/clk/imx/clk-pllv2.c b/drivers/clk/imx/clk-pllv2.c index eeba3cb14e2d..ff17f0664faa 100644 --- a/drivers/clk/imx/clk-pllv2.c +++ b/drivers/clk/imx/clk-pllv2.c @@ -239,12 +239,13 @@ static const struct clk_ops clk_pllv2_ops = { .set_rate = clk_pllv2_set_rate, }; -struct clk *imx_clk_pllv2(const char *name, const char *parent, +struct clk_hw *imx_clk_hw_pllv2(const char *name, const char *parent, void __iomem *base) { struct clk_pllv2 *pll; - struct clk *clk; + struct clk_hw *hw; struct clk_init_data init; + int ret; pll = kzalloc(sizeof(*pll), GFP_KERNEL); if (!pll) @@ -259,10 +260,13 @@ struct clk *imx_clk_pllv2(const char *name, const char *parent, init.num_parents = 1; pll->hw.init = &init; + hw = &pll->hw; - clk = clk_register(NULL, &pll->hw); - if (IS_ERR(clk)) + ret = clk_hw_register(NULL, hw); + if (ret) { kfree(pll); + return ERR_PTR(ret); + } - return clk; + return hw; } diff --git a/drivers/clk/imx/clk-pllv4.c b/drivers/clk/imx/clk-pllv4.c index 8155b12cf0e1..f51a800c268c 100644 --- a/drivers/clk/imx/clk-pllv4.c +++ b/drivers/clk/imx/clk-pllv4.c @@ -206,7 +206,7 @@ static const struct clk_ops clk_pllv4_ops = { .is_enabled = clk_pllv4_is_enabled, }; -struct clk_hw *imx_clk_pllv4(const char *name, const char *parent_name, +struct clk_hw *imx_clk_hw_pllv4(const char *name, const char *parent_name, void __iomem *base) { struct clk_pllv4 *pll; diff --git a/drivers/clk/imx/clk-sccg-pll.c b/drivers/clk/imx/clk-sscg-pll.c index 5d65f65c512e..acd1b9002be6 100644 --- a/drivers/clk/imx/clk-sccg-pll.c +++ b/drivers/clk/imx/clk-sscg-pll.c @@ -67,7 +67,7 @@ #define PLL_SCCG_LOCK_TIMEOUT 70 -struct clk_sccg_pll_setup { +struct clk_sscg_pll_setup { int divr1, divf1; int divr2, divf2; int divq; @@ -83,22 +83,22 @@ struct clk_sccg_pll_setup { int fout_error; }; -struct clk_sccg_pll { +struct clk_sscg_pll { struct clk_hw hw; const struct clk_ops ops; void __iomem *base; - struct clk_sccg_pll_setup setup; + struct clk_sscg_pll_setup setup; u8 parent; u8 bypass1; u8 bypass2; }; -#define to_clk_sccg_pll(_hw) container_of(_hw, struct clk_sccg_pll, hw) +#define to_clk_sscg_pll(_hw) container_of(_hw, struct clk_sscg_pll, hw) -static int clk_sccg_pll_wait_lock(struct clk_sccg_pll *pll) +static int clk_sscg_pll_wait_lock(struct clk_sscg_pll *pll) { u32 val; @@ -112,15 +112,15 @@ static int clk_sccg_pll_wait_lock(struct clk_sccg_pll *pll) return 0; } -static int clk_sccg_pll2_check_match(struct clk_sccg_pll_setup *setup, - struct clk_sccg_pll_setup *temp_setup) +static int clk_sscg_pll2_check_match(struct clk_sscg_pll_setup *setup, + struct clk_sscg_pll_setup *temp_setup) { int new_diff = temp_setup->fout - temp_setup->fout_request; int diff = temp_setup->fout_error; if (abs(diff) > abs(new_diff)) { temp_setup->fout_error = new_diff; - memcpy(setup, temp_setup, sizeof(struct clk_sccg_pll_setup)); + memcpy(setup, temp_setup, sizeof(struct clk_sscg_pll_setup)); if (temp_setup->fout_request == temp_setup->fout) return 0; @@ -128,8 +128,8 @@ static int clk_sccg_pll2_check_match(struct clk_sccg_pll_setup *setup, return -1; } -static int clk_sccg_divq_lookup(struct clk_sccg_pll_setup *setup, - struct clk_sccg_pll_setup *temp_setup) +static int clk_sscg_divq_lookup(struct clk_sscg_pll_setup *setup, + struct clk_sscg_pll_setup *temp_setup) { int ret = -EINVAL; @@ -144,7 +144,7 @@ static int clk_sccg_divq_lookup(struct clk_sccg_pll_setup *setup, temp_setup->fout = temp_setup->vco2; do_div(temp_setup->fout, 2 * (temp_setup->divq + 1)); - ret = clk_sccg_pll2_check_match(setup, temp_setup); + ret = clk_sscg_pll2_check_match(setup, temp_setup); if (!ret) { temp_setup->bypass = PLL_BYPASS1; return ret; @@ -155,14 +155,14 @@ static int clk_sccg_divq_lookup(struct clk_sccg_pll_setup *setup, return ret; } -static int clk_sccg_divf2_lookup(struct clk_sccg_pll_setup *setup, - struct clk_sccg_pll_setup *temp_setup) +static int clk_sscg_divf2_lookup(struct clk_sscg_pll_setup *setup, + struct clk_sscg_pll_setup *temp_setup) { int ret = -EINVAL; for (temp_setup->divf2 = 0; temp_setup->divf2 <= PLL_DIVF2_MAX; temp_setup->divf2++) { - ret = clk_sccg_divq_lookup(setup, temp_setup); + ret = clk_sscg_divq_lookup(setup, temp_setup); if (!ret) return ret; } @@ -170,8 +170,8 @@ static int clk_sccg_divf2_lookup(struct clk_sccg_pll_setup *setup, return ret; } -static int clk_sccg_divr2_lookup(struct clk_sccg_pll_setup *setup, - struct clk_sccg_pll_setup *temp_setup) +static int clk_sscg_divr2_lookup(struct clk_sscg_pll_setup *setup, + struct clk_sscg_pll_setup *temp_setup) { int ret = -EINVAL; @@ -181,7 +181,7 @@ static int clk_sccg_divr2_lookup(struct clk_sccg_pll_setup *setup, do_div(temp_setup->ref_div2, temp_setup->divr2 + 1); if (temp_setup->ref_div2 >= PLL_STAGE2_REF_MIN_FREQ && temp_setup->ref_div2 <= PLL_STAGE2_REF_MAX_FREQ) { - ret = clk_sccg_divf2_lookup(setup, temp_setup); + ret = clk_sscg_divf2_lookup(setup, temp_setup); if (!ret) return ret; } @@ -190,8 +190,8 @@ static int clk_sccg_divr2_lookup(struct clk_sccg_pll_setup *setup, return ret; } -static int clk_sccg_pll2_find_setup(struct clk_sccg_pll_setup *setup, - struct clk_sccg_pll_setup *temp_setup, +static int clk_sscg_pll2_find_setup(struct clk_sscg_pll_setup *setup, + struct clk_sscg_pll_setup *temp_setup, uint64_t ref) { @@ -202,12 +202,12 @@ static int clk_sccg_pll2_find_setup(struct clk_sccg_pll_setup *setup, temp_setup->vco1 = ref; - ret = clk_sccg_divr2_lookup(setup, temp_setup); + ret = clk_sscg_divr2_lookup(setup, temp_setup); return ret; } -static int clk_sccg_divf1_lookup(struct clk_sccg_pll_setup *setup, - struct clk_sccg_pll_setup *temp_setup) +static int clk_sscg_divf1_lookup(struct clk_sscg_pll_setup *setup, + struct clk_sscg_pll_setup *temp_setup) { int ret = -EINVAL; @@ -219,7 +219,7 @@ static int clk_sccg_divf1_lookup(struct clk_sccg_pll_setup *setup, vco1 *= 2; vco1 *= temp_setup->divf1 + 1; - ret = clk_sccg_pll2_find_setup(setup, temp_setup, vco1); + ret = clk_sscg_pll2_find_setup(setup, temp_setup, vco1); if (!ret) { temp_setup->bypass = PLL_BYPASS_NONE; return ret; @@ -229,8 +229,8 @@ static int clk_sccg_divf1_lookup(struct clk_sccg_pll_setup *setup, return ret; } -static int clk_sccg_divr1_lookup(struct clk_sccg_pll_setup *setup, - struct clk_sccg_pll_setup *temp_setup) +static int clk_sscg_divr1_lookup(struct clk_sscg_pll_setup *setup, + struct clk_sscg_pll_setup *temp_setup) { int ret = -EINVAL; @@ -240,7 +240,7 @@ static int clk_sccg_divr1_lookup(struct clk_sccg_pll_setup *setup, do_div(temp_setup->ref_div1, temp_setup->divr1 + 1); if (temp_setup->ref_div1 >= PLL_STAGE1_REF_MIN_FREQ && temp_setup->ref_div1 <= PLL_STAGE1_REF_MAX_FREQ) { - ret = clk_sccg_divf1_lookup(setup, temp_setup); + ret = clk_sscg_divf1_lookup(setup, temp_setup); if (!ret) return ret; } @@ -249,8 +249,8 @@ static int clk_sccg_divr1_lookup(struct clk_sccg_pll_setup *setup, return ret; } -static int clk_sccg_pll1_find_setup(struct clk_sccg_pll_setup *setup, - struct clk_sccg_pll_setup *temp_setup, +static int clk_sscg_pll1_find_setup(struct clk_sscg_pll_setup *setup, + struct clk_sscg_pll_setup *temp_setup, uint64_t ref) { @@ -261,20 +261,20 @@ static int clk_sccg_pll1_find_setup(struct clk_sccg_pll_setup *setup, temp_setup->ref = ref; - ret = clk_sccg_divr1_lookup(setup, temp_setup); + ret = clk_sscg_divr1_lookup(setup, temp_setup); return ret; } -static int clk_sccg_pll_find_setup(struct clk_sccg_pll_setup *setup, +static int clk_sscg_pll_find_setup(struct clk_sscg_pll_setup *setup, uint64_t prate, uint64_t rate, int try_bypass) { - struct clk_sccg_pll_setup temp_setup; + struct clk_sscg_pll_setup temp_setup; int ret = -EINVAL; - memset(&temp_setup, 0, sizeof(struct clk_sccg_pll_setup)); - memset(setup, 0, sizeof(struct clk_sccg_pll_setup)); + memset(&temp_setup, 0, sizeof(struct clk_sscg_pll_setup)); + memset(setup, 0, sizeof(struct clk_sscg_pll_setup)); temp_setup.fout_error = PLL_OUT_MAX_FREQ; temp_setup.fout_request = rate; @@ -290,11 +290,11 @@ static int clk_sccg_pll_find_setup(struct clk_sccg_pll_setup *setup, break; case PLL_BYPASS1: - ret = clk_sccg_pll2_find_setup(setup, &temp_setup, prate); + ret = clk_sscg_pll2_find_setup(setup, &temp_setup, prate); break; case PLL_BYPASS_NONE: - ret = clk_sccg_pll1_find_setup(setup, &temp_setup, prate); + ret = clk_sscg_pll1_find_setup(setup, &temp_setup, prate); break; } @@ -302,30 +302,30 @@ static int clk_sccg_pll_find_setup(struct clk_sccg_pll_setup *setup, } -static int clk_sccg_pll_is_prepared(struct clk_hw *hw) +static int clk_sscg_pll_is_prepared(struct clk_hw *hw) { - struct clk_sccg_pll *pll = to_clk_sccg_pll(hw); + struct clk_sscg_pll *pll = to_clk_sscg_pll(hw); u32 val = readl_relaxed(pll->base + PLL_CFG0); return (val & PLL_PD_MASK) ? 0 : 1; } -static int clk_sccg_pll_prepare(struct clk_hw *hw) +static int clk_sscg_pll_prepare(struct clk_hw *hw) { - struct clk_sccg_pll *pll = to_clk_sccg_pll(hw); + struct clk_sscg_pll *pll = to_clk_sscg_pll(hw); u32 val; val = readl_relaxed(pll->base + PLL_CFG0); val &= ~PLL_PD_MASK; writel_relaxed(val, pll->base + PLL_CFG0); - return clk_sccg_pll_wait_lock(pll); + return clk_sscg_pll_wait_lock(pll); } -static void clk_sccg_pll_unprepare(struct clk_hw *hw) +static void clk_sscg_pll_unprepare(struct clk_hw *hw) { - struct clk_sccg_pll *pll = to_clk_sccg_pll(hw); + struct clk_sscg_pll *pll = to_clk_sscg_pll(hw); u32 val; val = readl_relaxed(pll->base + PLL_CFG0); @@ -333,10 +333,10 @@ static void clk_sccg_pll_unprepare(struct clk_hw *hw) writel_relaxed(val, pll->base + PLL_CFG0); } -static unsigned long clk_sccg_pll_recalc_rate(struct clk_hw *hw, +static unsigned long clk_sscg_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { - struct clk_sccg_pll *pll = to_clk_sccg_pll(hw); + struct clk_sscg_pll *pll = to_clk_sscg_pll(hw); u32 val, divr1, divf1, divr2, divf2, divq; u64 temp64; @@ -364,11 +364,11 @@ static unsigned long clk_sccg_pll_recalc_rate(struct clk_hw *hw, return temp64; } -static int clk_sccg_pll_set_rate(struct clk_hw *hw, unsigned long rate, +static int clk_sscg_pll_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { - struct clk_sccg_pll *pll = to_clk_sccg_pll(hw); - struct clk_sccg_pll_setup *setup = &pll->setup; + struct clk_sscg_pll *pll = to_clk_sscg_pll(hw); + struct clk_sscg_pll_setup *setup = &pll->setup; u32 val; /* set bypass here too since the parent might be the same */ @@ -387,12 +387,12 @@ static int clk_sccg_pll_set_rate(struct clk_hw *hw, unsigned long rate, val |= FIELD_PREP(PLL_DIVQ_MASK, setup->divq); writel_relaxed(val, pll->base + PLL_CFG2); - return clk_sccg_pll_wait_lock(pll); + return clk_sscg_pll_wait_lock(pll); } -static u8 clk_sccg_pll_get_parent(struct clk_hw *hw) +static u8 clk_sscg_pll_get_parent(struct clk_hw *hw) { - struct clk_sccg_pll *pll = to_clk_sccg_pll(hw); + struct clk_sscg_pll *pll = to_clk_sscg_pll(hw); u32 val; u8 ret = pll->parent; @@ -404,9 +404,9 @@ static u8 clk_sccg_pll_get_parent(struct clk_hw *hw) return ret; } -static int clk_sccg_pll_set_parent(struct clk_hw *hw, u8 index) +static int clk_sscg_pll_set_parent(struct clk_hw *hw, u8 index) { - struct clk_sccg_pll *pll = to_clk_sccg_pll(hw); + struct clk_sscg_pll *pll = to_clk_sscg_pll(hw); u32 val; val = readl(pll->base + PLL_CFG0); @@ -414,18 +414,18 @@ static int clk_sccg_pll_set_parent(struct clk_hw *hw, u8 index) val |= FIELD_PREP(SSCG_PLL_BYPASS_MASK, pll->setup.bypass); writel(val, pll->base + PLL_CFG0); - return clk_sccg_pll_wait_lock(pll); + return clk_sscg_pll_wait_lock(pll); } -static int __clk_sccg_pll_determine_rate(struct clk_hw *hw, +static int __clk_sscg_pll_determine_rate(struct clk_hw *hw, struct clk_rate_request *req, uint64_t min, uint64_t max, uint64_t rate, int bypass) { - struct clk_sccg_pll *pll = to_clk_sccg_pll(hw); - struct clk_sccg_pll_setup *setup = &pll->setup; + struct clk_sscg_pll *pll = to_clk_sscg_pll(hw); + struct clk_sscg_pll_setup *setup = &pll->setup; struct clk_hw *parent_hw = NULL; int bypass_parent_index; int ret = -EINVAL; @@ -448,7 +448,7 @@ static int __clk_sccg_pll_determine_rate(struct clk_hw *hw, parent_hw = clk_hw_get_parent_by_index(hw, bypass_parent_index); ret = __clk_determine_rate(parent_hw, req); if (!ret) { - ret = clk_sccg_pll_find_setup(setup, req->rate, + ret = clk_sscg_pll_find_setup(setup, req->rate, rate, bypass); } @@ -459,11 +459,11 @@ static int __clk_sccg_pll_determine_rate(struct clk_hw *hw, return ret; } -static int clk_sccg_pll_determine_rate(struct clk_hw *hw, +static int clk_sscg_pll_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) { - struct clk_sccg_pll *pll = to_clk_sccg_pll(hw); - struct clk_sccg_pll_setup *setup = &pll->setup; + struct clk_sscg_pll *pll = to_clk_sscg_pll(hw); + struct clk_sscg_pll_setup *setup = &pll->setup; uint64_t rate = req->rate; uint64_t min = req->min_rate; uint64_t max = req->max_rate; @@ -472,18 +472,18 @@ static int clk_sccg_pll_determine_rate(struct clk_hw *hw, if (rate < PLL_OUT_MIN_FREQ || rate > PLL_OUT_MAX_FREQ) return ret; - ret = __clk_sccg_pll_determine_rate(hw, req, req->rate, req->rate, + ret = __clk_sscg_pll_determine_rate(hw, req, req->rate, req->rate, rate, PLL_BYPASS2); if (!ret) return ret; - ret = __clk_sccg_pll_determine_rate(hw, req, PLL_STAGE1_REF_MIN_FREQ, + ret = __clk_sscg_pll_determine_rate(hw, req, PLL_STAGE1_REF_MIN_FREQ, PLL_STAGE1_REF_MAX_FREQ, rate, PLL_BYPASS1); if (!ret) return ret; - ret = __clk_sccg_pll_determine_rate(hw, req, PLL_REF_MIN_FREQ, + ret = __clk_sscg_pll_determine_rate(hw, req, PLL_REF_MIN_FREQ, PLL_REF_MAX_FREQ, rate, PLL_BYPASS_NONE); if (!ret) @@ -495,25 +495,25 @@ static int clk_sccg_pll_determine_rate(struct clk_hw *hw, return ret; } -static const struct clk_ops clk_sccg_pll_ops = { - .prepare = clk_sccg_pll_prepare, - .unprepare = clk_sccg_pll_unprepare, - .is_prepared = clk_sccg_pll_is_prepared, - .recalc_rate = clk_sccg_pll_recalc_rate, - .set_rate = clk_sccg_pll_set_rate, - .set_parent = clk_sccg_pll_set_parent, - .get_parent = clk_sccg_pll_get_parent, - .determine_rate = clk_sccg_pll_determine_rate, +static const struct clk_ops clk_sscg_pll_ops = { + .prepare = clk_sscg_pll_prepare, + .unprepare = clk_sscg_pll_unprepare, + .is_prepared = clk_sscg_pll_is_prepared, + .recalc_rate = clk_sscg_pll_recalc_rate, + .set_rate = clk_sscg_pll_set_rate, + .set_parent = clk_sscg_pll_set_parent, + .get_parent = clk_sscg_pll_get_parent, + .determine_rate = clk_sscg_pll_determine_rate, }; -struct clk *imx_clk_sccg_pll(const char *name, +struct clk_hw *imx_clk_hw_sscg_pll(const char *name, const char * const *parent_names, u8 num_parents, u8 parent, u8 bypass1, u8 bypass2, void __iomem *base, unsigned long flags) { - struct clk_sccg_pll *pll; + struct clk_sscg_pll *pll; struct clk_init_data init; struct clk_hw *hw; int ret; @@ -528,7 +528,7 @@ struct clk *imx_clk_sccg_pll(const char *name, pll->base = base; init.name = name; - init.ops = &clk_sccg_pll_ops; + init.ops = &clk_sscg_pll_ops; init.flags = flags; init.parent_names = parent_names; @@ -545,5 +545,5 @@ struct clk *imx_clk_sccg_pll(const char *name, return ERR_PTR(ret); } - return hw->clk; + return hw; } diff --git a/drivers/clk/imx/clk.c b/drivers/clk/imx/clk.c index cfc05e43c343..87ab8db3d282 100644 --- a/drivers/clk/imx/clk.c +++ b/drivers/clk/imx/clk.c @@ -22,6 +22,14 @@ void imx_unregister_clocks(struct clk *clks[], unsigned int count) clk_unregister(clks[i]); } +void imx_unregister_hw_clocks(struct clk_hw *hws[], unsigned int count) +{ + unsigned int i; + + for (i = 0; i < count; i++) + clk_hw_unregister(hws[i]); +} + void __init imx_mmdc_mask_handshake(void __iomem *ccm_base, unsigned int chn) { @@ -94,8 +102,8 @@ struct clk_hw * __init imx_obtain_fixed_clock_hw( return __clk_get_hw(clk); } -struct clk_hw * __init imx_obtain_fixed_clk_hw(struct device_node *np, - const char *name) +struct clk_hw * imx_obtain_fixed_clk_hw(struct device_node *np, + const char *name) { struct clk *clk; diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h index bc5bb6ac8636..b05213b91dcf 100644 --- a/drivers/clk/imx/clk.h +++ b/drivers/clk/imx/clk.h @@ -12,6 +12,7 @@ void imx_check_clk_hws(struct clk_hw *clks[], unsigned int count); void imx_register_uart_clocks(struct clk ** const clks[]); void imx_mmdc_mask_handshake(void __iomem *ccm_base, unsigned int chn); void imx_unregister_clocks(struct clk *clks[], unsigned int count); +void imx_unregister_hw_clocks(struct clk_hw *hws[], unsigned int count); extern void imx_cscmr1_fixup(u32 *val); @@ -24,7 +25,7 @@ enum imx_pllv1_type { IMX_PLLV1_IMX35, }; -enum imx_sccg_pll_type { +enum imx_sscg_pll_type { SCCG_PLL1, SCCG_PLL2, }; @@ -52,64 +53,98 @@ struct imx_pll14xx_clk { extern struct imx_pll14xx_clk imx_1416x_pll; extern struct imx_pll14xx_clk imx_1443x_pll; +extern struct imx_pll14xx_clk imx_1443x_dram_pll; #define imx_clk_cpu(name, parent_name, div, mux, pll, step) \ - imx_clk_hw_cpu(name, parent_name, div, mux, pll, step)->clk + to_clk(imx_clk_hw_cpu(name, parent_name, div, mux, pll, step)) #define clk_register_gate2(dev, name, parent_name, flags, reg, bit_idx, \ cgr_val, clk_gate_flags, lock, share_count) \ - clk_hw_register_gate2(dev, name, parent_name, flags, reg, bit_idx, \ - cgr_val, clk_gate_flags, lock, share_count)->clk + to_clk(clk_hw_register_gate2(dev, name, parent_name, flags, reg, bit_idx, \ + cgr_val, clk_gate_flags, lock, share_count)) #define imx_clk_pllv3(type, name, parent_name, base, div_mask) \ - imx_clk_hw_pllv3(type, name, parent_name, base, div_mask)->clk + to_clk(imx_clk_hw_pllv3(type, name, parent_name, base, div_mask)) #define imx_clk_pfd(name, parent_name, reg, idx) \ - imx_clk_hw_pfd(name, parent_name, reg, idx)->clk + to_clk(imx_clk_hw_pfd(name, parent_name, reg, idx)) #define imx_clk_gate_exclusive(name, parent, reg, shift, exclusive_mask) \ - imx_clk_hw_gate_exclusive(name, parent, reg, shift, exclusive_mask)->clk + to_clk(imx_clk_hw_gate_exclusive(name, parent, reg, shift, exclusive_mask)) + +#define imx_clk_fixed(name, rate) \ + to_clk(imx_clk_hw_fixed(name, rate)) #define imx_clk_fixed_factor(name, parent, mult, div) \ - imx_clk_hw_fixed_factor(name, parent, mult, div)->clk + to_clk(imx_clk_hw_fixed_factor(name, parent, mult, div)) + +#define imx_clk_divider(name, parent, reg, shift, width) \ + to_clk(imx_clk_hw_divider(name, parent, reg, shift, width)) #define imx_clk_divider2(name, parent, reg, shift, width) \ - imx_clk_hw_divider2(name, parent, reg, shift, width)->clk + to_clk(imx_clk_hw_divider2(name, parent, reg, shift, width)) + +#define imx_clk_divider_flags(name, parent, reg, shift, width, flags) \ + to_clk(imx_clk_hw_divider_flags(name, parent, reg, shift, width, flags)) + +#define imx_clk_gate(name, parent, reg, shift) \ + to_clk(imx_clk_hw_gate(name, parent, reg, shift)) #define imx_clk_gate_dis(name, parent, reg, shift) \ - imx_clk_hw_gate_dis(name, parent, reg, shift)->clk + to_clk(imx_clk_hw_gate_dis(name, parent, reg, shift)) #define imx_clk_gate2(name, parent, reg, shift) \ - imx_clk_hw_gate2(name, parent, reg, shift)->clk + to_clk(imx_clk_hw_gate2(name, parent, reg, shift)) #define imx_clk_gate2_flags(name, parent, reg, shift, flags) \ - imx_clk_hw_gate2_flags(name, parent, reg, shift, flags)->clk + to_clk(imx_clk_hw_gate2_flags(name, parent, reg, shift, flags)) #define imx_clk_gate2_shared2(name, parent, reg, shift, share_count) \ - imx_clk_hw_gate2_shared2(name, parent, reg, shift, share_count)->clk + to_clk(imx_clk_hw_gate2_shared2(name, parent, reg, shift, share_count)) #define imx_clk_gate3(name, parent, reg, shift) \ - imx_clk_hw_gate3(name, parent, reg, shift)->clk + to_clk(imx_clk_hw_gate3(name, parent, reg, shift)) #define imx_clk_gate4(name, parent, reg, shift) \ - imx_clk_hw_gate4(name, parent, reg, shift)->clk + to_clk(imx_clk_hw_gate4(name, parent, reg, shift)) #define imx_clk_mux(name, reg, shift, width, parents, num_parents) \ - imx_clk_hw_mux(name, reg, shift, width, parents, num_parents)->clk + to_clk(imx_clk_hw_mux(name, reg, shift, width, parents, num_parents)) + +#define imx_clk_pllv1(type, name, parent, base) \ + to_clk(imx_clk_hw_pllv1(type, name, parent, base)) + +#define imx_clk_pllv2(name, parent, base) \ + to_clk(imx_clk_hw_pllv2(name, parent, base)) + +#define imx_clk_frac_pll(name, parent_name, base) \ + to_clk(imx_clk_hw_frac_pll(name, parent_name, base)) + +#define imx_clk_sscg_pll(name, parent_names, num_parents, parent,\ + bypass1, bypass2, base, flags) \ + to_clk(imx_clk_hw_sscg_pll(name, parent_names, num_parents, parent,\ + bypass1, bypass2, base, flags)) struct clk *imx_clk_pll14xx(const char *name, const char *parent_name, void __iomem *base, const struct imx_pll14xx_clk *pll_clk); -struct clk *imx_clk_pllv1(enum imx_pllv1_type type, const char *name, +#define imx_clk_pll14xx(name, parent_name, base, pll_clk) \ + to_clk(imx_clk_hw_pll14xx(name, parent_name, base, pll_clk)) + +struct clk_hw *imx_clk_hw_pll14xx(const char *name, const char *parent_name, + void __iomem *base, + const struct imx_pll14xx_clk *pll_clk); + +struct clk_hw *imx_clk_hw_pllv1(enum imx_pllv1_type type, const char *name, const char *parent, void __iomem *base); -struct clk *imx_clk_pllv2(const char *name, const char *parent, +struct clk_hw *imx_clk_hw_pllv2(const char *name, const char *parent, void __iomem *base); -struct clk *imx_clk_frac_pll(const char *name, const char *parent_name, +struct clk_hw *imx_clk_hw_frac_pll(const char *name, const char *parent_name, void __iomem *base); -struct clk *imx_clk_sccg_pll(const char *name, +struct clk_hw *imx_clk_hw_sscg_pll(const char *name, const char * const *parent_names, u8 num_parents, u8 parent, u8 bypass1, u8 bypass2, @@ -149,7 +184,7 @@ struct clk_hw *imx_clk_hw_pllv3(enum imx_pllv3_type type, const char *name, .kdiv = (_k), \ } -struct clk_hw *imx_clk_pllv4(const char *name, const char *parent_name, +struct clk_hw *imx_clk_hw_pllv4(const char *name, const char *parent_name, void __iomem *base); struct clk_hw *clk_hw_register_gate2(struct device *dev, const char *name, @@ -173,7 +208,7 @@ struct clk_hw *imx_clk_hw_gate_exclusive(const char *name, const char *parent, struct clk_hw *imx_clk_hw_pfd(const char *name, const char *parent_name, void __iomem *reg, u8 idx); -struct clk_hw *imx_clk_pfdv2(const char *name, const char *parent_name, +struct clk_hw *imx_clk_hw_pfdv2(const char *name, const char *parent_name, void __iomem *reg, u8 idx); struct clk_hw *imx_clk_hw_busy_divider(const char *name, const char *parent_name, @@ -184,7 +219,7 @@ struct clk_hw *imx_clk_hw_busy_mux(const char *name, void __iomem *reg, u8 shift u8 width, void __iomem *busy_reg, u8 busy_shift, const char * const *parent_names, int num_parents); -struct clk_hw *imx7ulp_clk_composite(const char *name, +struct clk_hw *imx7ulp_clk_hw_composite(const char *name, const char * const *parent_names, int num_parents, bool mux_present, bool rate_present, bool gate_present, @@ -198,9 +233,11 @@ struct clk_hw *imx_clk_hw_fixup_mux(const char *name, void __iomem *reg, u8 shift, u8 width, const char * const *parents, int num_parents, void (*fixup)(u32 *val)); -static inline struct clk *imx_clk_fixed(const char *name, int rate) +static inline struct clk *to_clk(struct clk_hw *hw) { - return clk_register_fixed_rate(NULL, name, NULL, 0, rate); + if (IS_ERR_OR_NULL(hw)) + return ERR_CAST(hw); + return hw->clk; } static inline struct clk_hw *imx_clk_hw_fixed(const char *name, int rate) @@ -224,13 +261,6 @@ static inline struct clk_hw *imx_clk_hw_fixed_factor(const char *name, CLK_SET_RATE_PARENT, mult, div); } -static inline struct clk *imx_clk_divider(const char *name, const char *parent, - void __iomem *reg, u8 shift, u8 width) -{ - return clk_register_divider(NULL, name, parent, CLK_SET_RATE_PARENT, - reg, shift, width, 0, &imx_ccm_lock); -} - static inline struct clk_hw *imx_clk_hw_divider(const char *name, const char *parent, void __iomem *reg, u8 shift, @@ -240,14 +270,6 @@ static inline struct clk_hw *imx_clk_hw_divider(const char *name, reg, shift, width, 0, &imx_ccm_lock); } -static inline struct clk *imx_clk_divider_flags(const char *name, - const char *parent, void __iomem *reg, u8 shift, u8 width, - unsigned long flags) -{ - return clk_register_divider(NULL, name, parent, flags, - reg, shift, width, 0, &imx_ccm_lock); -} - static inline struct clk_hw *imx_clk_hw_divider_flags(const char *name, const char *parent, void __iomem *reg, u8 shift, @@ -274,13 +296,6 @@ static inline struct clk *imx_clk_divider2_flags(const char *name, reg, shift, width, 0, &imx_ccm_lock); } -static inline struct clk *imx_clk_gate(const char *name, const char *parent, - void __iomem *reg, u8 shift) -{ - return clk_register_gate(NULL, name, parent, CLK_SET_RATE_PARENT, reg, - shift, 0, &imx_ccm_lock); -} - static inline struct clk_hw *imx_clk_hw_gate_flags(const char *name, const char *parent, void __iomem *reg, u8 shift, unsigned long flags) { @@ -355,15 +370,18 @@ static inline struct clk_hw *imx_clk_hw_gate3(const char *name, const char *pare reg, shift, 0, &imx_ccm_lock); } -static inline struct clk *imx_clk_gate3_flags(const char *name, +static inline struct clk_hw *imx_clk_hw_gate3_flags(const char *name, const char *parent, void __iomem *reg, u8 shift, unsigned long flags) { - return clk_register_gate(NULL, name, parent, + return clk_hw_register_gate(NULL, name, parent, flags | CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, reg, shift, 0, &imx_ccm_lock); } +#define imx_clk_gate3_flags(name, parent, reg, shift, flags) \ + to_clk(imx_clk_hw_gate3_flags(name, parent, reg, shift, flags)) + static inline struct clk_hw *imx_clk_hw_gate4(const char *name, const char *parent, void __iomem *reg, u8 shift) { @@ -372,15 +390,18 @@ static inline struct clk_hw *imx_clk_hw_gate4(const char *name, const char *pare reg, shift, 0x3, 0, &imx_ccm_lock, NULL); } -static inline struct clk *imx_clk_gate4_flags(const char *name, +static inline struct clk_hw *imx_clk_hw_gate4_flags(const char *name, const char *parent, void __iomem *reg, u8 shift, unsigned long flags) { - return clk_register_gate2(NULL, name, parent, + return clk_hw_register_gate2(NULL, name, parent, flags | CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, reg, shift, 0x3, 0, &imx_ccm_lock, NULL); } +#define imx_clk_gate4_flags(name, parent, reg, shift, flags) \ + to_clk(imx_clk_hw_gate4_flags(name, parent, reg, shift, flags)) + static inline struct clk_hw *imx_clk_hw_mux(const char *name, void __iomem *reg, u8 shift, u8 width, const char * const *parents, int num_parents) @@ -420,6 +441,16 @@ static inline struct clk *imx_clk_mux_flags(const char *name, &imx_ccm_lock); } +static inline struct clk_hw *imx_clk_hw_mux2_flags(const char *name, + void __iomem *reg, u8 shift, u8 width, + const char * const *parents, + int num_parents, unsigned long flags) +{ + return clk_hw_register_mux(NULL, name, parents, num_parents, + flags | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE, + reg, shift, width, 0, &imx_ccm_lock); +} + static inline struct clk *imx_clk_mux2_flags(const char *name, void __iomem *reg, u8 shift, u8 width, const char * const *parents, @@ -446,23 +477,38 @@ struct clk_hw *imx_clk_hw_cpu(const char *name, const char *parent_name, struct clk *div, struct clk *mux, struct clk *pll, struct clk *step); -struct clk *imx8m_clk_composite_flags(const char *name, - const char * const *parent_names, - int num_parents, void __iomem *reg, - unsigned long flags); +struct clk_hw *imx8m_clk_hw_composite_flags(const char *name, + const char * const *parent_names, + int num_parents, + void __iomem *reg, + unsigned long flags); -#define __imx8m_clk_composite(name, parent_names, reg, flags) \ - imx8m_clk_composite_flags(name, parent_names, \ +#define imx8m_clk_composite_flags(name, parent_names, num_parents, reg, \ + flags) \ + to_clk(imx8m_clk_hw_composite_flags(name, parent_names, \ + num_parents, reg, flags)) + +#define __imx8m_clk_hw_composite(name, parent_names, reg, flags) \ + imx8m_clk_hw_composite_flags(name, parent_names, \ ARRAY_SIZE(parent_names), reg, \ flags | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE) +#define __imx8m_clk_composite(name, parent_names, reg, flags) \ + to_clk(__imx8m_clk_hw_composite(name, parent_names, reg, flags)) + +#define imx8m_clk_hw_composite(name, parent_names, reg) \ + __imx8m_clk_hw_composite(name, parent_names, reg, 0) + #define imx8m_clk_composite(name, parent_names, reg) \ __imx8m_clk_composite(name, parent_names, reg, 0) +#define imx8m_clk_hw_composite_critical(name, parent_names, reg) \ + __imx8m_clk_hw_composite(name, parent_names, reg, CLK_IS_CRITICAL) + #define imx8m_clk_composite_critical(name, parent_names, reg) \ __imx8m_clk_composite(name, parent_names, reg, CLK_IS_CRITICAL) -struct clk_hw *imx_clk_divider_gate(const char *name, const char *parent_name, +struct clk_hw *imx_clk_hw_divider_gate(const char *name, const char *parent_name, unsigned long flags, void __iomem *reg, u8 shift, u8 width, u8 clk_divider_flags, const struct clk_div_table *table, spinlock_t *lock); diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig index 7efc3617bbd5..ea3c70d1307e 100644 --- a/drivers/clk/mediatek/Kconfig +++ b/drivers/clk/mediatek/Kconfig @@ -174,36 +174,36 @@ config COMMON_CLK_MT6779_AUDSYS This driver supports Mediatek MT6779 audsys clocks. config COMMON_CLK_MT6797 - bool "Clock driver for MediaTek MT6797" - depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST - select COMMON_CLK_MEDIATEK - default ARCH_MEDIATEK && ARM64 - ---help--- - This driver supports MediaTek MT6797 basic clocks. + bool "Clock driver for MediaTek MT6797" + depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST + select COMMON_CLK_MEDIATEK + default ARCH_MEDIATEK && ARM64 + ---help--- + This driver supports MediaTek MT6797 basic clocks. config COMMON_CLK_MT6797_MMSYS - bool "Clock driver for MediaTek MT6797 mmsys" - depends on COMMON_CLK_MT6797 - ---help--- - This driver supports MediaTek MT6797 mmsys clocks. + bool "Clock driver for MediaTek MT6797 mmsys" + depends on COMMON_CLK_MT6797 + ---help--- + This driver supports MediaTek MT6797 mmsys clocks. config COMMON_CLK_MT6797_IMGSYS - bool "Clock driver for MediaTek MT6797 imgsys" - depends on COMMON_CLK_MT6797 - ---help--- - This driver supports MediaTek MT6797 imgsys clocks. + bool "Clock driver for MediaTek MT6797 imgsys" + depends on COMMON_CLK_MT6797 + ---help--- + This driver supports MediaTek MT6797 imgsys clocks. config COMMON_CLK_MT6797_VDECSYS - bool "Clock driver for MediaTek MT6797 vdecsys" - depends on COMMON_CLK_MT6797 - ---help--- - This driver supports MediaTek MT6797 vdecsys clocks. + bool "Clock driver for MediaTek MT6797 vdecsys" + depends on COMMON_CLK_MT6797 + ---help--- + This driver supports MediaTek MT6797 vdecsys clocks. config COMMON_CLK_MT6797_VENCSYS - bool "Clock driver for MediaTek MT6797 vencsys" - depends on COMMON_CLK_MT6797 - ---help--- - This driver supports MediaTek MT6797 vencsys clocks. + bool "Clock driver for MediaTek MT6797 vencsys" + depends on COMMON_CLK_MT6797 + ---help--- + This driver supports MediaTek MT6797 vencsys clocks. config COMMON_CLK_MT7622 bool "Clock driver for MediaTek MT7622" diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile index 3939f218587a..6eca2a406ee3 100644 --- a/drivers/clk/meson/Makefile +++ b/drivers/clk/meson/Makefile @@ -18,4 +18,4 @@ obj-$(CONFIG_COMMON_CLK_AXG) += axg.o axg-aoclk.o obj-$(CONFIG_COMMON_CLK_AXG_AUDIO) += axg-audio.o obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o obj-$(CONFIG_COMMON_CLK_G12A) += g12a.o g12a-aoclk.o -obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o +obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o meson8-ddr.o diff --git a/drivers/clk/meson/clk-mpll.c b/drivers/clk/meson/clk-mpll.c index 2d39a8bc367c..fc9df4860872 100644 --- a/drivers/clk/meson/clk-mpll.c +++ b/drivers/clk/meson/clk-mpll.c @@ -129,7 +129,7 @@ static int mpll_set_rate(struct clk_hw *hw, return 0; } -static void mpll_init(struct clk_hw *hw) +static int mpll_init(struct clk_hw *hw) { struct clk_regmap *clk = to_clk_regmap(hw); struct meson_clk_mpll_data *mpll = meson_clk_mpll_data(clk); @@ -151,6 +151,8 @@ static void mpll_init(struct clk_hw *hw) /* Set the magic misc bit if required */ if (MESON_PARM_APPLICABLE(&mpll->misc)) meson_parm_write(clk->map, &mpll->misc, 1); + + return 0; } const struct clk_ops meson_clk_mpll_ro_ops = { diff --git a/drivers/clk/meson/clk-phase.c b/drivers/clk/meson/clk-phase.c index 80c3ada193a4..fe22e171121a 100644 --- a/drivers/clk/meson/clk-phase.c +++ b/drivers/clk/meson/clk-phase.c @@ -78,7 +78,7 @@ meson_clk_triphase_data(struct clk_regmap *clk) return (struct meson_clk_triphase_data *)clk->data; } -static void meson_clk_triphase_sync(struct clk_hw *hw) +static int meson_clk_triphase_sync(struct clk_hw *hw) { struct clk_regmap *clk = to_clk_regmap(hw); struct meson_clk_triphase_data *tph = meson_clk_triphase_data(clk); @@ -88,6 +88,8 @@ static void meson_clk_triphase_sync(struct clk_hw *hw) val = meson_parm_read(clk->map, &tph->ph0); meson_parm_write(clk->map, &tph->ph1, val); meson_parm_write(clk->map, &tph->ph2, val); + + return 0; } static int meson_clk_triphase_get_phase(struct clk_hw *hw) diff --git a/drivers/clk/meson/clk-pll.c b/drivers/clk/meson/clk-pll.c index ddb1e5634739..b17a13e9337c 100644 --- a/drivers/clk/meson/clk-pll.c +++ b/drivers/clk/meson/clk-pll.c @@ -77,6 +77,15 @@ static unsigned long meson_clk_pll_recalc_rate(struct clk_hw *hw, unsigned int m, n, frac; n = meson_parm_read(clk->map, &pll->n); + + /* + * On some HW, N is set to zero on init. This value is invalid as + * it would result in a division by zero. The rate can't be + * calculated in this case + */ + if (n == 0) + return 0; + m = meson_parm_read(clk->map, &pll->m); frac = MESON_PARM_APPLICABLE(&pll->frac) ? @@ -277,7 +286,7 @@ static int meson_clk_pll_wait_lock(struct clk_hw *hw) return -ETIMEDOUT; } -static void meson_clk_pll_init(struct clk_hw *hw) +static int meson_clk_pll_init(struct clk_hw *hw) { struct clk_regmap *clk = to_clk_regmap(hw); struct meson_clk_pll_data *pll = meson_clk_pll_data(clk); @@ -288,6 +297,8 @@ static void meson_clk_pll_init(struct clk_hw *hw) pll->init_count); meson_parm_write(clk->map, &pll->rst, 0); } + + return 0; } static int meson_clk_pll_is_enabled(struct clk_hw *hw) diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c index b3af61cc6fb9..d2760a021301 100644 --- a/drivers/clk/meson/g12a.c +++ b/drivers/clk/meson/g12a.c @@ -4692,6 +4692,7 @@ static struct clk_regmap *const g12a_clk_regmaps[] = { &g12a_bt656, &g12a_usb1_to_ddr, &g12a_mmc_pclk, + &g12a_uart2, &g12a_vpu_intr, &g12a_gic, &g12a_sd_emmc_a_clk0, diff --git a/drivers/clk/meson/meson8-ddr.c b/drivers/clk/meson/meson8-ddr.c new file mode 100644 index 000000000000..4b73ea244b63 --- /dev/null +++ b/drivers/clk/meson/meson8-ddr.c @@ -0,0 +1,149 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Amlogic Meson8 DDR clock controller + * + * Copyright (C) 2019 Martin Blumenstingl <martin.blumenstingl@googlemail.com> + */ + +#include <dt-bindings/clock/meson8-ddr-clkc.h> + +#include <linux/clk-provider.h> +#include <linux/platform_device.h> + +#include "clk-regmap.h" +#include "clk-pll.h" + +#define AM_DDR_PLL_CNTL 0x00 +#define AM_DDR_PLL_CNTL1 0x04 +#define AM_DDR_PLL_CNTL2 0x08 +#define AM_DDR_PLL_CNTL3 0x0c +#define AM_DDR_PLL_CNTL4 0x10 +#define AM_DDR_PLL_STS 0x14 +#define DDR_CLK_CNTL 0x18 +#define DDR_CLK_STS 0x1c + +static struct clk_regmap meson8_ddr_pll_dco = { + .data = &(struct meson_clk_pll_data){ + .en = { + .reg_off = AM_DDR_PLL_CNTL, + .shift = 30, + .width = 1, + }, + .m = { + .reg_off = AM_DDR_PLL_CNTL, + .shift = 0, + .width = 9, + }, + .n = { + .reg_off = AM_DDR_PLL_CNTL, + .shift = 9, + .width = 5, + }, + .l = { + .reg_off = AM_DDR_PLL_CNTL, + .shift = 31, + .width = 1, + }, + .rst = { + .reg_off = AM_DDR_PLL_CNTL, + .shift = 29, + .width = 1, + }, + }, + .hw.init = &(struct clk_init_data){ + .name = "ddr_pll_dco", + .ops = &meson_clk_pll_ro_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap meson8_ddr_pll = { + .data = &(struct clk_regmap_div_data){ + .offset = AM_DDR_PLL_CNTL, + .shift = 16, + .width = 2, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data){ + .name = "ddr_pll", + .ops = &clk_regmap_divider_ro_ops, + .parent_hws = (const struct clk_hw *[]) { + &meson8_ddr_pll_dco.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_hw_onecell_data meson8_ddr_clk_hw_onecell_data = { + .hws = { + [DDR_CLKID_DDR_PLL_DCO] = &meson8_ddr_pll_dco.hw, + [DDR_CLKID_DDR_PLL] = &meson8_ddr_pll.hw, + }, + .num = 2, +}; + +static struct clk_regmap *const meson8_ddr_clk_regmaps[] = { + &meson8_ddr_pll_dco, + &meson8_ddr_pll, +}; + +static const struct regmap_config meson8_ddr_clkc_regmap_config = { + .reg_bits = 8, + .val_bits = 32, + .reg_stride = 4, + .max_register = DDR_CLK_STS, +}; + +static int meson8_ddr_clkc_probe(struct platform_device *pdev) +{ + struct regmap *regmap; + void __iomem *base; + struct clk_hw *hw; + int ret, i; + + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return PTR_ERR(base); + + regmap = devm_regmap_init_mmio(&pdev->dev, base, + &meson8_ddr_clkc_regmap_config); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + /* Populate regmap */ + for (i = 0; i < ARRAY_SIZE(meson8_ddr_clk_regmaps); i++) + meson8_ddr_clk_regmaps[i]->map = regmap; + + /* Register all clks */ + for (i = 0; i < meson8_ddr_clk_hw_onecell_data.num; i++) { + hw = meson8_ddr_clk_hw_onecell_data.hws[i]; + + ret = devm_clk_hw_register(&pdev->dev, hw); + if (ret) { + dev_err(&pdev->dev, "Clock registration failed\n"); + return ret; + } + } + + return devm_of_clk_add_hw_provider(&pdev->dev, of_clk_hw_onecell_get, + &meson8_ddr_clk_hw_onecell_data); +} + +static const struct of_device_id meson8_ddr_clkc_match_table[] = { + { .compatible = "amlogic,meson8-ddr-clkc" }, + { .compatible = "amlogic,meson8b-ddr-clkc" }, + { /* sentinel */ } +}; + +static struct platform_driver meson8_ddr_clkc_driver = { + .probe = meson8_ddr_clkc_probe, + .driver = { + .name = "meson8-ddr-clkc", + .of_match_table = meson8_ddr_clkc_match_table, + }, +}; + +builtin_platform_driver(meson8_ddr_clkc_driver); diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c index 67e6691e080c..9fd31f23b2a9 100644 --- a/drivers/clk/meson/meson8b.c +++ b/drivers/clk/meson/meson8b.c @@ -97,8 +97,10 @@ static struct clk_regmap meson8b_fixed_pll_dco = { .hw.init = &(struct clk_init_data){ .name = "fixed_pll_dco", .ops = &meson_clk_pll_ro_ops, - .parent_hws = (const struct clk_hw *[]) { - &meson8b_xtal.hw + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + .name = "xtal", + .index = -1, }, .num_parents = 1, }, @@ -162,8 +164,10 @@ static struct clk_regmap meson8b_hdmi_pll_dco = { /* sometimes also called "HPLL" or "HPLL PLL" */ .name = "hdmi_pll_dco", .ops = &meson_clk_pll_ro_ops, - .parent_hws = (const struct clk_hw *[]) { - &meson8b_xtal.hw + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + .name = "xtal", + .index = -1, }, .num_parents = 1, }, @@ -237,8 +241,10 @@ static struct clk_regmap meson8b_sys_pll_dco = { .hw.init = &(struct clk_init_data){ .name = "sys_pll_dco", .ops = &meson_clk_pll_ops, - .parent_hws = (const struct clk_hw *[]) { - &meson8b_xtal.hw + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + .name = "xtal", + .index = -1, }, .num_parents = 1, }, @@ -631,9 +637,9 @@ static struct clk_regmap meson8b_cpu_in_sel = { .hw.init = &(struct clk_init_data){ .name = "cpu_in_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = (const struct clk_hw *[]) { - &meson8b_xtal.hw, - &meson8b_sys_pll.hw, + .parent_data = (const struct clk_parent_data[]) { + { .fw_name = "xtal", .name = "xtal", .index = -1, }, + { .hw = &meson8b_sys_pll.hw, }, }, .num_parents = 2, .flags = (CLK_SET_RATE_PARENT | @@ -736,9 +742,9 @@ static struct clk_regmap meson8b_cpu_clk = { .hw.init = &(struct clk_init_data){ .name = "cpu_clk", .ops = &clk_regmap_mux_ops, - .parent_hws = (const struct clk_hw *[]) { - &meson8b_xtal.hw, - &meson8b_cpu_scale_out_sel.hw, + .parent_data = (const struct clk_parent_data[]) { + { .fw_name = "xtal", .name = "xtal", .index = -1, }, + { .hw = &meson8b_cpu_scale_out_sel.hw, }, }, .num_parents = 2, .flags = (CLK_SET_RATE_PARENT | @@ -758,12 +764,12 @@ static struct clk_regmap meson8b_nand_clk_sel = { .name = "nand_clk_sel", .ops = &clk_regmap_mux_ops, /* FIXME all other parents are unknown: */ - .parent_hws = (const struct clk_hw *[]) { - &meson8b_fclk_div4.hw, - &meson8b_fclk_div3.hw, - &meson8b_fclk_div5.hw, - &meson8b_fclk_div7.hw, - &meson8b_xtal.hw, + .parent_data = (const struct clk_parent_data[]) { + { .hw = &meson8b_fclk_div4.hw, }, + { .hw = &meson8b_fclk_div3.hw, }, + { .hw = &meson8b_fclk_div5.hw, }, + { .hw = &meson8b_fclk_div7.hw, }, + { .fw_name = "xtal", .name = "xtal", .index = -1, }, }, .num_parents = 5, .flags = CLK_SET_RATE_PARENT, @@ -1721,8 +1727,10 @@ static struct clk_regmap meson8b_hdmi_sys_sel = { .name = "hdmi_sys_sel", .ops = &clk_regmap_mux_ro_ops, /* FIXME: all other parents are unknown */ - .parent_hws = (const struct clk_hw *[]) { - &meson8b_xtal.hw + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + .name = "xtal", + .index = -1, }, .num_parents = 1, .flags = CLK_SET_RATE_NO_REPARENT, @@ -1764,17 +1772,20 @@ static struct clk_regmap meson8b_hdmi_sys = { /* * The MALI IP is clocked by two identical clocks (mali_0 and mali_1) - * muxed by a glitch-free switch on Meson8b and Meson8m2. Meson8 only - * has mali_0 and no glitch-free mux. + * muxed by a glitch-free switch on Meson8b and Meson8m2. The CCF can + * actually manage this glitch-free mux because it does top-to-bottom + * updates the each clock tree and switches to the "inactive" one when + * CLK_SET_RATE_GATE is set. + * Meson8 only has mali_0 and no glitch-free mux. */ -static const struct clk_hw *meson8b_mali_0_1_parent_hws[] = { - &meson8b_xtal.hw, - &meson8b_mpll2.hw, - &meson8b_mpll1.hw, - &meson8b_fclk_div7.hw, - &meson8b_fclk_div4.hw, - &meson8b_fclk_div3.hw, - &meson8b_fclk_div5.hw, +static const struct clk_parent_data meson8b_mali_0_1_parent_data[] = { + { .fw_name = "xtal", .name = "xtal", .index = -1, }, + { .hw = &meson8b_mpll2.hw, }, + { .hw = &meson8b_mpll1.hw, }, + { .hw = &meson8b_fclk_div7.hw, }, + { .hw = &meson8b_fclk_div4.hw, }, + { .hw = &meson8b_fclk_div3.hw, }, + { .hw = &meson8b_fclk_div5.hw, }, }; static u32 meson8b_mali_0_1_mux_table[] = { 0, 2, 3, 4, 5, 6, 7 }; @@ -1789,8 +1800,8 @@ static struct clk_regmap meson8b_mali_0_sel = { .hw.init = &(struct clk_init_data){ .name = "mali_0_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = meson8b_mali_0_1_parent_hws, - .num_parents = ARRAY_SIZE(meson8b_mali_0_1_parent_hws), + .parent_data = meson8b_mali_0_1_parent_data, + .num_parents = ARRAY_SIZE(meson8b_mali_0_1_parent_data), /* * Don't propagate rate changes up because the only changeable * parents are mpll1 and mpll2 but we need those for audio and @@ -1830,7 +1841,7 @@ static struct clk_regmap meson8b_mali_0 = { &meson8b_mali_0_div.hw }, .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, + .flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT, }, }; @@ -1844,8 +1855,8 @@ static struct clk_regmap meson8b_mali_1_sel = { .hw.init = &(struct clk_init_data){ .name = "mali_1_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = meson8b_mali_0_1_parent_hws, - .num_parents = ARRAY_SIZE(meson8b_mali_0_1_parent_hws), + .parent_data = meson8b_mali_0_1_parent_data, + .num_parents = ARRAY_SIZE(meson8b_mali_0_1_parent_data), /* * Don't propagate rate changes up because the only changeable * parents are mpll1 and mpll2 but we need those for audio and @@ -1885,7 +1896,7 @@ static struct clk_regmap meson8b_mali_1 = { &meson8b_mali_1_div.hw }, .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, + .flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT, }, }; @@ -1944,8 +1955,10 @@ static struct clk_regmap meson8m2_gp_pll_dco = { .hw.init = &(struct clk_init_data){ .name = "gp_pll_dco", .ops = &meson_clk_pll_ops, - .parent_hws = (const struct clk_hw *[]) { - &meson8b_xtal.hw + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + .name = "xtal", + .index = -1, }, .num_parents = 1, }, @@ -3585,7 +3598,7 @@ static const struct reset_control_ops meson8b_clk_reset_ops = { struct meson8b_nb_data { struct notifier_block nb; - struct clk_hw_onecell_data *onecell_data; + struct clk_hw *cpu_clk; }; static int meson8b_cpu_clk_notifier_cb(struct notifier_block *nb, @@ -3593,30 +3606,25 @@ static int meson8b_cpu_clk_notifier_cb(struct notifier_block *nb, { struct meson8b_nb_data *nb_data = container_of(nb, struct meson8b_nb_data, nb); - struct clk_hw **hws = nb_data->onecell_data->hws; - struct clk_hw *cpu_clk_hw, *parent_clk_hw; - struct clk *cpu_clk, *parent_clk; + struct clk_hw *parent_clk; int ret; switch (event) { case PRE_RATE_CHANGE: - parent_clk_hw = hws[CLKID_XTAL]; + /* xtal */ + parent_clk = clk_hw_get_parent_by_index(nb_data->cpu_clk, 0); break; case POST_RATE_CHANGE: - parent_clk_hw = hws[CLKID_CPU_SCALE_OUT_SEL]; + /* cpu_scale_out_sel */ + parent_clk = clk_hw_get_parent_by_index(nb_data->cpu_clk, 1); break; default: return NOTIFY_DONE; } - cpu_clk_hw = hws[CLKID_CPUCLK]; - cpu_clk = __clk_lookup(clk_hw_get_name(cpu_clk_hw)); - - parent_clk = __clk_lookup(clk_hw_get_name(parent_clk_hw)); - - ret = clk_set_parent(cpu_clk, parent_clk); + ret = clk_hw_set_parent(nb_data->cpu_clk, parent_clk); if (ret) return notifier_from_errno(ret); @@ -3682,20 +3690,26 @@ static void __init meson8b_clkc_init_common(struct device_node *np, meson8b_clk_regmaps[i]->map = map; /* - * register all clks - * CLKID_UNUSED = 0, so skip it and start with CLKID_XTAL = 1 + * always skip CLKID_UNUSED and also skip XTAL if the .dtb provides the + * XTAL clock as input. */ - for (i = CLKID_XTAL; i < CLK_NR_CLKS; i++) { + if (!IS_ERR(of_clk_get_by_name(np, "xtal"))) + i = CLKID_PLL_FIXED; + else + i = CLKID_XTAL; + + /* register all clks */ + for (; i < CLK_NR_CLKS; i++) { /* array might be sparse */ if (!clk_hw_onecell_data->hws[i]) continue; - ret = clk_hw_register(NULL, clk_hw_onecell_data->hws[i]); + ret = of_clk_hw_register(np, clk_hw_onecell_data->hws[i]); if (ret) return; } - meson8b_cpu_nb_data.onecell_data = clk_hw_onecell_data; + meson8b_cpu_nb_data.cpu_clk = clk_hw_onecell_data->hws[CLKID_CPUCLK]; /* * FIXME we shouldn't program the muxes in notifier handlers. The diff --git a/drivers/clk/meson/sclk-div.c b/drivers/clk/meson/sclk-div.c index 3acf03780221..76d31c0a3342 100644 --- a/drivers/clk/meson/sclk-div.c +++ b/drivers/clk/meson/sclk-div.c @@ -216,7 +216,7 @@ static int sclk_div_is_enabled(struct clk_hw *hw) return 0; } -static void sclk_div_init(struct clk_hw *hw) +static int sclk_div_init(struct clk_hw *hw) { struct clk_regmap *clk = to_clk_regmap(hw); struct meson_sclk_div_data *sclk = meson_sclk_div_data(clk); @@ -231,6 +231,8 @@ static void sclk_div_init(struct clk_hw *hw) sclk->cached_div = val + 1; sclk_div_get_duty_cycle(hw, &sclk->cached_duty); + + return 0; } const struct clk_ops meson_sclk_div_ops = { diff --git a/drivers/clk/microchip/clk-core.c b/drivers/clk/microchip/clk-core.c index 567755d6f844..1b4f023cdc8b 100644 --- a/drivers/clk/microchip/clk-core.c +++ b/drivers/clk/microchip/clk-core.c @@ -266,10 +266,12 @@ static void roclk_disable(struct clk_hw *hw) writel(REFO_ON | REFO_OE, PIC32_CLR(refo->ctrl_reg)); } -static void roclk_init(struct clk_hw *hw) +static int roclk_init(struct clk_hw *hw) { /* initialize clock in disabled state */ roclk_disable(hw); + + return 0; } static u8 roclk_get_parent(struct clk_hw *hw) @@ -880,7 +882,7 @@ static int sclk_set_parent(struct clk_hw *hw, u8 index) return err; } -static void sclk_init(struct clk_hw *hw) +static int sclk_init(struct clk_hw *hw) { struct pic32_sys_clk *sclk = clkhw_to_sys_clk(hw); unsigned long flags; @@ -899,6 +901,8 @@ static void sclk_init(struct clk_hw *hw) writel(v, sclk->slew_reg); spin_unlock_irqrestore(&sclk->core->reg_lock, flags); } + + return 0; } /* sclk with post-divider */ diff --git a/drivers/clk/mmp/clk-frac.c b/drivers/clk/mmp/clk-frac.c index 90bf181f191a..fabc09aca6c4 100644 --- a/drivers/clk/mmp/clk-frac.c +++ b/drivers/clk/mmp/clk-frac.c @@ -109,7 +109,7 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned long drate, return 0; } -static void clk_factor_init(struct clk_hw *hw) +static int clk_factor_init(struct clk_hw *hw) { struct mmp_clk_factor *factor = to_clk_factor(hw); struct mmp_clk_factor_masks *masks = factor->masks; @@ -146,6 +146,8 @@ static void clk_factor_init(struct clk_hw *hw) if (factor->lock) spin_unlock_irqrestore(factor->lock, flags); + + return 0; } static const struct clk_ops clk_factor_ops = { diff --git a/drivers/clk/mmp/clk-mix.c b/drivers/clk/mmp/clk-mix.c index 90814b2613c0..d2cd36c54474 100644 --- a/drivers/clk/mmp/clk-mix.c +++ b/drivers/clk/mmp/clk-mix.c @@ -419,12 +419,14 @@ static int mmp_clk_set_rate(struct clk_hw *hw, unsigned long rate, } } -static void mmp_clk_mix_init(struct clk_hw *hw) +static int mmp_clk_mix_init(struct clk_hw *hw) { struct mmp_clk_mix *mix = to_clk_mix(hw); if (mix->table) _filter_clk_table(mix, mix->table, mix->table_size); + + return 0; } const struct clk_ops mmp_clk_mix_ops = { diff --git a/drivers/clk/mvebu/Kconfig b/drivers/clk/mvebu/Kconfig index 415e6906a113..ded07b0bd0d5 100644 --- a/drivers/clk/mvebu/Kconfig +++ b/drivers/clk/mvebu/Kconfig @@ -29,7 +29,7 @@ config ARMADA_39X_CLK select MVEBU_CLK_COMMON config ARMADA_37XX_CLK - bool + bool config ARMADA_XP_CLK bool diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 3b33ef129274..15cdcdc9b3b8 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only config KRAIT_CLOCKS - bool - select KRAIT_L2_ACCESSORS + bool + select KRAIT_L2_ACCESSORS config QCOM_GDSC bool @@ -14,6 +14,7 @@ menuconfig COMMON_CLK_QCOM tristate "Support for Qualcomm's clock controllers" depends on OF depends on ARCH_QCOM || COMPILE_TEST + select RATIONAL select REGMAP_MMIO select RESET_CONTROLLER @@ -95,6 +96,14 @@ config IPQ_GCC_4019 Say Y if you want to use peripheral devices such as UART, SPI, i2c, USB, SD/eMMC, etc. +config IPQ_GCC_6018 + tristate "IPQ6018 Global Clock Controller" + help + Support for global clock controller on ipq6018 devices. + Say Y if you want to use peripheral devices such as UART, SPI, + i2c, USB, SD/eMMC, etc. Select this for the root clock + of ipq6018. + config IPQ_GCC_806X tristate "IPQ806x Global Clock Controller" help @@ -229,6 +238,15 @@ config MSM_GPUCC_8998 Say Y if you want to support graphics controller devices and functionality such as 3D graphics. +config MSM_MMCC_8998 + tristate "MSM8998 Multimedia Clock Controller" + select MSM_GCC_8998 + select QCOM_GDSC + help + Support for the multimedia clock controller on msm8998 devices. + Say Y if you want to support multimedia devices such as display, + graphics, video encode/decode, camera, etc. + config QCS_GCC_404 tristate "QCS404 Global Clock Controller" help @@ -236,6 +254,15 @@ config QCS_GCC_404 Say Y if you want to use multimedia devices or peripheral devices such as UART, SPI, I2C, USB, SD/eMMC, PCIe etc. +config SC_DISPCC_7180 + tristate "SC7180 Display Clock Controller" + select SC_GCC_7180 + help + Support for the display clock controller on Qualcomm Technologies, Inc + SC7180 devices. + Say Y if you want to support display devices and functionality such as + splash screen. + config SC_GCC_7180 tristate "SC7180 Global Clock Controller" select QCOM_GDSC @@ -245,6 +272,22 @@ config SC_GCC_7180 Say Y if you want to use peripheral devices such as UART, SPI, I2C, USB, UFS, SDCC, etc. +config SC_GPUCC_7180 + tristate "SC7180 Graphics Clock Controller" + select SC_GCC_7180 + help + Support for the graphics clock controller on SC7180 devices. + Say Y if you want to support graphics controller devices and + functionality such as 3D graphics. + +config SC_VIDEOCC_7180 + tristate "SC7180 Video Clock Controller" + select SC_GCC_7180 + help + Support for the video clock controller on SC7180 devices. + Say Y if you want to support video devices and functionality such as + video encode and decode. + config SDM_CAMCC_845 tristate "SDM845 Camera Clock Controller" select SDM_GCC_845 diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index d899661d0f44..656a87e629d4 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -20,6 +20,7 @@ clk-qcom-$(CONFIG_QCOM_GDSC) += gdsc.o obj-$(CONFIG_APQ_GCC_8084) += gcc-apq8084.o obj-$(CONFIG_APQ_MMCC_8084) += mmcc-apq8084.o obj-$(CONFIG_IPQ_GCC_4019) += gcc-ipq4019.o +obj-$(CONFIG_IPQ_GCC_6018) += gcc-ipq6018.o obj-$(CONFIG_IPQ_GCC_806X) += gcc-ipq806x.o obj-$(CONFIG_IPQ_GCC_8074) += gcc-ipq8074.o obj-$(CONFIG_IPQ_LCC_806X) += lcc-ipq806x.o @@ -37,6 +38,7 @@ obj-$(CONFIG_MSM_GPUCC_8998) += gpucc-msm8998.o obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8960.o obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o obj-$(CONFIG_MSM_MMCC_8996) += mmcc-msm8996.o +obj-$(CONFIG_MSM_MMCC_8998) += mmcc-msm8998.o obj-$(CONFIG_QCOM_A53PLL) += a53-pll.o obj-$(CONFIG_QCOM_CLK_APCS_MSM8916) += apcs-msm8916.o obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o @@ -45,7 +47,10 @@ obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o obj-$(CONFIG_QCS_GCC_404) += gcc-qcs404.o obj-$(CONFIG_QCS_Q6SSTOP_404) += q6sstop-qcs404.o obj-$(CONFIG_QCS_TURING_404) += turingcc-qcs404.o +obj-$(CONFIG_SC_DISPCC_7180) += dispcc-sc7180.o obj-$(CONFIG_SC_GCC_7180) += gcc-sc7180.o +obj-$(CONFIG_SC_GPUCC_7180) += gpucc-sc7180.o +obj-$(CONFIG_SC_VIDEOCC_7180) += videocc-sc7180.o obj-$(CONFIG_SDM_CAMCC_845) += camcc-sdm845.o obj-$(CONFIG_SDM_DISPCC_845) += dispcc-sdm845.o obj-$(CONFIG_SDM_GCC_660) += gcc-sdm660.o diff --git a/drivers/clk/qcom/apcs-msm8916.c b/drivers/clk/qcom/apcs-msm8916.c index a6c89a310b18..cf69a97d0439 100644 --- a/drivers/clk/qcom/apcs-msm8916.c +++ b/drivers/clk/qcom/apcs-msm8916.c @@ -19,9 +19,9 @@ static const u32 gpll0_a53cc_map[] = { 4, 5 }; -static const char * const gpll0_a53cc[] = { - "gpll0_vote", - "a53pll", +static const struct clk_parent_data pdata[] = { + { .fw_name = "aux", .name = "gpll0_vote", }, + { .fw_name = "pll", .name = "a53pll", }, }; /* @@ -62,8 +62,8 @@ static int qcom_apcs_msm8916_clk_probe(struct platform_device *pdev) return -ENOMEM; init.name = "a53mux"; - init.parent_names = gpll0_a53cc; - init.num_parents = ARRAY_SIZE(gpll0_a53cc); + init.parent_data = pdata; + init.num_parents = ARRAY_SIZE(pdata); init.ops = &clk_regmap_mux_div_ops; init.flags = CLK_SET_RATE_PARENT; @@ -79,7 +79,8 @@ static int qcom_apcs_msm8916_clk_probe(struct platform_device *pdev) a53cc->pclk = devm_clk_get(parent, NULL); if (IS_ERR(a53cc->pclk)) { ret = PTR_ERR(a53cc->pclk); - dev_err(dev, "failed to get clk: %d\n", ret); + if (ret != -EPROBE_DEFER) + dev_err(dev, "failed to get clk: %d\n", ret); return ret; } diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c index 055318f97991..7c2936da9b14 100644 --- a/drivers/clk/qcom/clk-alpha-pll.c +++ b/drivers/clk/qcom/clk-alpha-pll.c @@ -878,6 +878,14 @@ static long clk_trion_pll_round_rate(struct clk_hw *hw, unsigned long rate, return clamp(rate, min_freq, max_freq); } +const struct clk_ops clk_alpha_pll_fixed_ops = { + .enable = clk_alpha_pll_enable, + .disable = clk_alpha_pll_disable, + .is_enabled = clk_alpha_pll_is_enabled, + .recalc_rate = clk_alpha_pll_recalc_rate, +}; +EXPORT_SYMBOL_GPL(clk_alpha_pll_fixed_ops); + const struct clk_ops clk_alpha_pll_ops = { .enable = clk_alpha_pll_enable, .disable = clk_alpha_pll_disable, @@ -1024,6 +1032,25 @@ void clk_fabia_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, regmap_write(regmap, PLL_CONFIG_CTL(pll), config->config_ctl_val); + if (config->config_ctl_hi_val) + regmap_write(regmap, PLL_CONFIG_CTL_U(pll), + config->config_ctl_hi_val); + + if (config->user_ctl_val) + regmap_write(regmap, PLL_USER_CTL(pll), config->user_ctl_val); + + if (config->user_ctl_hi_val) + regmap_write(regmap, PLL_USER_CTL_U(pll), + config->user_ctl_hi_val); + + if (config->test_ctl_val) + regmap_write(regmap, PLL_TEST_CTL(pll), + config->test_ctl_val); + + if (config->test_ctl_hi_val) + regmap_write(regmap, PLL_TEST_CTL_U(pll), + config->test_ctl_hi_val); + if (config->post_div_mask) { mask = config->post_div_mask; val = config->post_div_val; @@ -1141,14 +1168,9 @@ static int alpha_pll_fabia_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long prate) { struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); - u32 val, l, alpha_width = pll_alpha_width(pll); + u32 l, alpha_width = pll_alpha_width(pll); u64 a; unsigned long rrate; - int ret = 0; - - ret = regmap_read(pll->clkr.regmap, PLL_MODE(pll), &val); - if (ret) - return ret; rrate = alpha_pll_round_rate(rate, prate, &l, &a, alpha_width); @@ -1167,7 +1189,64 @@ static int alpha_pll_fabia_set_rate(struct clk_hw *hw, unsigned long rate, return __clk_alpha_pll_update_latch(pll); } +static int alpha_pll_fabia_prepare(struct clk_hw *hw) +{ + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); + const struct pll_vco *vco; + struct clk_hw *parent_hw; + unsigned long cal_freq, rrate; + u32 cal_l, val, alpha_width = pll_alpha_width(pll); + u64 a; + int ret; + + /* Check if calibration needs to be done i.e. PLL is in reset */ + ret = regmap_read(pll->clkr.regmap, PLL_MODE(pll), &val); + if (ret) + return ret; + + /* Return early if calibration is not needed. */ + if (val & PLL_RESET_N) + return 0; + + vco = alpha_pll_find_vco(pll, clk_hw_get_rate(hw)); + if (!vco) { + pr_err("alpha pll: not in a valid vco range\n"); + return -EINVAL; + } + + cal_freq = DIV_ROUND_CLOSEST((pll->vco_table[0].min_freq + + pll->vco_table[0].max_freq) * 54, 100); + + parent_hw = clk_hw_get_parent(hw); + if (!parent_hw) + return -EINVAL; + + rrate = alpha_pll_round_rate(cal_freq, clk_hw_get_rate(parent_hw), + &cal_l, &a, alpha_width); + /* + * Due to a limited number of bits for fractional rate programming, the + * rounded up rate could be marginally higher than the requested rate. + */ + if (rrate > (cal_freq + FABIA_PLL_RATE_MARGIN) || rrate < cal_freq) + return -EINVAL; + + /* Setup PLL for calibration frequency */ + regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), cal_l); + + /* Bringup the PLL at calibration frequency */ + ret = clk_alpha_pll_enable(hw); + if (ret) { + pr_err("alpha pll calibration failed\n"); + return ret; + } + + clk_alpha_pll_disable(hw); + + return 0; +} + const struct clk_ops clk_alpha_pll_fabia_ops = { + .prepare = alpha_pll_fabia_prepare, .enable = alpha_pll_fabia_enable, .disable = alpha_pll_fabia_disable, .is_enabled = clk_alpha_pll_is_enabled, diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h index 15f27f4b06df..fbc1f67c7a26 100644 --- a/drivers/clk/qcom/clk-alpha-pll.h +++ b/drivers/clk/qcom/clk-alpha-pll.h @@ -94,6 +94,10 @@ struct alpha_pll_config { u32 alpha_hi; u32 config_ctl_val; u32 config_ctl_hi_val; + u32 user_ctl_val; + u32 user_ctl_hi_val; + u32 test_ctl_val; + u32 test_ctl_hi_val; u32 main_output_mask; u32 aux_output_mask; u32 aux2_output_mask; @@ -109,6 +113,7 @@ struct alpha_pll_config { }; extern const struct clk_ops clk_alpha_pll_ops; +extern const struct clk_ops clk_alpha_pll_fixed_ops; extern const struct clk_ops clk_alpha_pll_hwfsm_ops; extern const struct clk_ops clk_alpha_pll_postdiv_ops; extern const struct clk_ops clk_alpha_pll_huayra_ops; diff --git a/drivers/clk/qcom/clk-hfpll.c b/drivers/clk/qcom/clk-hfpll.c index 3c04805f2a55..e847d586a73a 100644 --- a/drivers/clk/qcom/clk-hfpll.c +++ b/drivers/clk/qcom/clk-hfpll.c @@ -196,7 +196,7 @@ static unsigned long clk_hfpll_recalc_rate(struct clk_hw *hw, return l_val * parent_rate; } -static void clk_hfpll_init(struct clk_hw *hw) +static int clk_hfpll_init(struct clk_hw *hw) { struct clk_hfpll *h = to_clk_hfpll(hw); struct hfpll_data const *hd = h->d; @@ -206,7 +206,7 @@ static void clk_hfpll_init(struct clk_hw *hw) regmap_read(regmap, hd->mode_reg, &mode); if (mode != (PLL_BYPASSNL | PLL_RESET_N | PLL_OUTCTRL)) { __clk_hfpll_init_once(hw); - return; + return 0; } if (hd->status_reg) { @@ -218,6 +218,8 @@ static void clk_hfpll_init(struct clk_hw *hw) __clk_hfpll_init_once(hw); } } + + return 0; } static int hfpll_is_enabled(struct clk_hw *hw) diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h index 78358b81d249..86d2b8b90173 100644 --- a/drivers/clk/qcom/clk-rcg.h +++ b/drivers/clk/qcom/clk-rcg.h @@ -161,6 +161,7 @@ extern const struct clk_ops clk_byte2_ops; extern const struct clk_ops clk_pixel_ops; extern const struct clk_ops clk_gfx3d_ops; extern const struct clk_ops clk_rcg2_shared_ops; +extern const struct clk_ops clk_dp_ops; struct clk_rcg_dfs_data { struct clk_rcg2 *rcg; diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index 8f4b9bec2956..da045b200def 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c @@ -10,6 +10,7 @@ #include <linux/export.h> #include <linux/clk-provider.h> #include <linux/delay.h> +#include <linux/rational.h> #include <linux/regmap.h> #include <linux/math64.h> #include <linux/slab.h> @@ -1124,3 +1125,79 @@ int qcom_cc_register_rcg_dfs(struct regmap *regmap, return 0; } EXPORT_SYMBOL_GPL(qcom_cc_register_rcg_dfs); + +static int clk_rcg2_dp_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct clk_rcg2 *rcg = to_clk_rcg2(hw); + struct freq_tbl f = { 0 }; + u32 mask = BIT(rcg->hid_width) - 1; + u32 hid_div, cfg; + int i, num_parents = clk_hw_get_num_parents(hw); + unsigned long num, den; + + rational_best_approximation(parent_rate, rate, + GENMASK(rcg->mnd_width - 1, 0), + GENMASK(rcg->mnd_width - 1, 0), &den, &num); + + if (!num || !den) + return -EINVAL; + + regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, &cfg); + hid_div = cfg; + cfg &= CFG_SRC_SEL_MASK; + cfg >>= CFG_SRC_SEL_SHIFT; + + for (i = 0; i < num_parents; i++) { + if (cfg == rcg->parent_map[i].cfg) { + f.src = rcg->parent_map[i].src; + break; + } + } + + f.pre_div = hid_div; + f.pre_div >>= CFG_SRC_DIV_SHIFT; + f.pre_div &= mask; + + if (num != den) { + f.m = num; + f.n = den; + } else { + f.m = 0; + f.n = 0; + } + + return clk_rcg2_configure(rcg, &f); +} + +static int clk_rcg2_dp_set_rate_and_parent(struct clk_hw *hw, + unsigned long rate, unsigned long parent_rate, u8 index) +{ + return clk_rcg2_dp_set_rate(hw, rate, parent_rate); +} + +static int clk_rcg2_dp_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + struct clk_rate_request parent_req = *req; + int ret; + + ret = __clk_determine_rate(clk_hw_get_parent(hw), &parent_req); + if (ret) + return ret; + + req->best_parent_rate = parent_req.rate; + + return 0; +} + +const struct clk_ops clk_dp_ops = { + .is_enabled = clk_rcg2_is_enabled, + .get_parent = clk_rcg2_get_parent, + .set_parent = clk_rcg2_set_parent, + .recalc_rate = clk_rcg2_recalc_rate, + .set_rate = clk_rcg2_dp_set_rate, + .set_rate_and_parent = clk_rcg2_dp_set_rate_and_parent, + .determine_rate = clk_rcg2_dp_determine_rate, +}; +EXPORT_SYMBOL_GPL(clk_dp_ops); diff --git a/drivers/clk/qcom/clk-rpmh.c b/drivers/clk/qcom/clk-rpmh.c index 7ed313ad6e43..98a118c1e244 100644 --- a/drivers/clk/qcom/clk-rpmh.c +++ b/drivers/clk/qcom/clk-rpmh.c @@ -396,6 +396,7 @@ static struct clk_hw *sc7180_rpmh_clocks[] = { [RPMH_RF_CLK1_A] = &sdm845_rf_clk1_ao.hw, [RPMH_RF_CLK2] = &sdm845_rf_clk2.hw, [RPMH_RF_CLK2_A] = &sdm845_rf_clk2_ao.hw, + [RPMH_IPA_CLK] = &sdm845_ipa.hw, }; static const struct clk_rpmh_desc clk_rpmh_sc7180 = { @@ -431,11 +432,16 @@ static int clk_rpmh_probe(struct platform_device *pdev) hw_clks = desc->clks; for (i = 0; i < desc->num_clks; i++) { - const char *name = hw_clks[i]->init->name; + const char *name; u32 res_addr; size_t aux_data_len; const struct bcm_db *data; + if (!hw_clks[i]) + continue; + + name = hw_clks[i]->init->name; + rpmh_clk = to_clk_rpmh(hw_clks[i]); res_addr = cmd_db_read_addr(rpmh_clk->res_name); if (!res_addr) { @@ -481,9 +487,9 @@ static int clk_rpmh_probe(struct platform_device *pdev) } static const struct of_device_id clk_rpmh_match_table[] = { + { .compatible = "qcom,sc7180-rpmh-clk", .data = &clk_rpmh_sc7180}, { .compatible = "qcom,sdm845-rpmh-clk", .data = &clk_rpmh_sdm845}, { .compatible = "qcom,sm8150-rpmh-clk", .data = &clk_rpmh_sm8150}, - { .compatible = "qcom,sc7180-rpmh-clk", .data = &clk_rpmh_sc7180}, { } }; MODULE_DEVICE_TABLE(of, clk_rpmh_match_table); diff --git a/drivers/clk/qcom/clk-smd-rpm.c b/drivers/clk/qcom/clk-smd-rpm.c index 930fa4a4c52a..0bbfef9fa6de 100644 --- a/drivers/clk/qcom/clk-smd-rpm.c +++ b/drivers/clk/qcom/clk-smd-rpm.c @@ -485,6 +485,8 @@ static struct clk_smd_rpm *msm8974_clks[] = { [RPM_SMD_MMSSNOC_AHB_CLK] = &msm8974_mmssnoc_ahb_clk, [RPM_SMD_MMSSNOC_AHB_A_CLK] = &msm8974_mmssnoc_ahb_a_clk, [RPM_SMD_BIMC_CLK] = &msm8974_bimc_clk, + [RPM_SMD_GFX3D_CLK_SRC] = &msm8974_gfx3d_clk_src, + [RPM_SMD_GFX3D_A_CLK_SRC] = &msm8974_gfx3d_a_clk_src, [RPM_SMD_BIMC_A_CLK] = &msm8974_bimc_a_clk, [RPM_SMD_OCMEMGX_CLK] = &msm8974_ocmemgx_clk, [RPM_SMD_OCMEMGX_A_CLK] = &msm8974_ocmemgx_a_clk, @@ -648,6 +650,7 @@ static const struct rpm_smd_clk_desc rpm_clk_qcs404 = { }; /* msm8998 */ +DEFINE_CLK_SMD_RPM(msm8998, bimc_clk, bimc_a_clk, QCOM_SMD_RPM_MEM_CLK, 0); DEFINE_CLK_SMD_RPM(msm8998, pcnoc_clk, pcnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 0); DEFINE_CLK_SMD_RPM(msm8998, snoc_clk, snoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 1); DEFINE_CLK_SMD_RPM(msm8998, cnoc_clk, cnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 2); @@ -671,6 +674,8 @@ DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8998, rf_clk2_pin, rf_clk2_a_pin, 5); DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8998, rf_clk3, rf_clk3_a, 6); DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8998, rf_clk3_pin, rf_clk3_a_pin, 6); static struct clk_smd_rpm *msm8998_clks[] = { + [RPM_SMD_BIMC_CLK] = &msm8998_bimc_clk, + [RPM_SMD_BIMC_A_CLK] = &msm8998_bimc_a_clk, [RPM_SMD_PCNOC_CLK] = &msm8998_pcnoc_clk, [RPM_SMD_PCNOC_A_CLK] = &msm8998_pcnoc_a_clk, [RPM_SMD_SNOC_CLK] = &msm8998_snoc_clk, diff --git a/drivers/clk/qcom/dispcc-sc7180.c b/drivers/clk/qcom/dispcc-sc7180.c new file mode 100644 index 000000000000..30c1e25d3edb --- /dev/null +++ b/drivers/clk/qcom/dispcc-sc7180.c @@ -0,0 +1,776 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + */ + +#include <linux/clk-provider.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> + +#include <dt-bindings/clock/qcom,dispcc-sc7180.h> + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap-divider.h" +#include "common.h" +#include "gdsc.h" + +enum { + P_BI_TCXO, + P_CHIP_SLEEP_CLK, + P_CORE_BI_PLL_TEST_SE, + P_DISP_CC_PLL0_OUT_EVEN, + P_DISP_CC_PLL0_OUT_MAIN, + P_DP_PHY_PLL_LINK_CLK, + P_DP_PHY_PLL_VCO_DIV_CLK, + P_DSI0_PHY_PLL_OUT_BYTECLK, + P_DSI0_PHY_PLL_OUT_DSICLK, + P_GPLL0_OUT_MAIN, +}; + +static const struct pll_vco fabia_vco[] = { + { 249600000, 2000000000, 0 }, +}; + +static struct clk_alpha_pll disp_cc_pll0 = { + .offset = 0x0, + .vco_table = fabia_vco, + .num_vco = ARRAY_SIZE(fabia_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_pll0", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fabia_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_disp_cc_pll0_out_even[] = { + { 0x0, 1 }, + { } +}; + +static struct clk_alpha_pll_postdiv disp_cc_pll0_out_even = { + .offset = 0x0, + .post_div_shift = 8, + .post_div_table = post_div_table_disp_cc_pll0_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_disp_cc_pll0_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "disp_cc_pll0_out_even", + .parent_data = &(const struct clk_parent_data){ + .hw = &disp_cc_pll0.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_fabia_ops, + }, +}; + +static const struct parent_map disp_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_0[] = { + { .fw_name = "bi_tcxo" }, + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, +}; + +static const struct parent_map disp_cc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_DP_PHY_PLL_LINK_CLK, 1 }, + { P_DP_PHY_PLL_VCO_DIV_CLK, 2 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_1[] = { + { .fw_name = "bi_tcxo" }, + { .fw_name = "dp_phy_pll_link_clk", .name = "dp_phy_pll_link_clk" }, + { .fw_name = "dp_phy_pll_vco_div_clk", + .name = "dp_phy_pll_vco_div_clk"}, + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, +}; + +static const struct parent_map disp_cc_parent_map_2[] = { + { P_BI_TCXO, 0 }, + { P_DSI0_PHY_PLL_OUT_BYTECLK, 1 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_2[] = { + { .fw_name = "bi_tcxo" }, + { .fw_name = "dsi0_phy_pll_out_byteclk", + .name = "dsi0_phy_pll_out_byteclk" }, + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, +}; + +static const struct parent_map disp_cc_parent_map_3[] = { + { P_BI_TCXO, 0 }, + { P_DISP_CC_PLL0_OUT_MAIN, 1 }, + { P_GPLL0_OUT_MAIN, 4 }, + { P_DISP_CC_PLL0_OUT_EVEN, 5 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_3[] = { + { .fw_name = "bi_tcxo" }, + { .hw = &disp_cc_pll0.clkr.hw }, + { .fw_name = "gcc_disp_gpll0_clk_src" }, + { .hw = &disp_cc_pll0_out_even.clkr.hw }, + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, +}; + +static const struct parent_map disp_cc_parent_map_4[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 4 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_4[] = { + { .fw_name = "bi_tcxo" }, + { .fw_name = "gcc_disp_gpll0_clk_src" }, + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, +}; + +static const struct parent_map disp_cc_parent_map_5[] = { + { P_BI_TCXO, 0 }, + { P_DSI0_PHY_PLL_OUT_DSICLK, 1 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_5[] = { + { .fw_name = "bi_tcxo" }, + { .fw_name = "dsi0_phy_pll_out_dsiclk", + .name = "dsi0_phy_pll_out_dsiclk" }, + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, +}; + +static const struct freq_tbl ftbl_disp_cc_mdss_ahb_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(37500000, P_GPLL0_OUT_MAIN, 16, 0, 0), + F(75000000, P_GPLL0_OUT_MAIN, 8, 0, 0), + { } +}; + +static struct clk_rcg2 disp_cc_mdss_ahb_clk_src = { + .cmd_rcgr = 0x22bc, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_4, + .freq_tbl = ftbl_disp_cc_mdss_ahb_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_ahb_clk_src", + .parent_data = disp_cc_parent_data_4, + .num_parents = 3, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = { + .cmd_rcgr = 0x2110, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_2, + .clkr.hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_byte0_clk_src", + .parent_data = disp_cc_parent_data_2, + .num_parents = 3, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_byte2_ops, + }, +}; + +static const struct freq_tbl ftbl_disp_cc_mdss_dp_aux_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 disp_cc_mdss_dp_aux_clk_src = { + .cmd_rcgr = 0x21dc, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_0, + .freq_tbl = ftbl_disp_cc_mdss_dp_aux_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_dp_aux_clk_src", + .parent_data = disp_cc_parent_data_0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dp_crypto_clk_src = { + .cmd_rcgr = 0x2194, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_1, + .clkr.hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_dp_crypto_clk_src", + .parent_data = disp_cc_parent_data_1, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_byte2_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dp_link_clk_src = { + .cmd_rcgr = 0x2178, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_1, + .clkr.hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_dp_link_clk_src", + .parent_data = disp_cc_parent_data_1, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_byte2_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dp_pixel_clk_src = { + .cmd_rcgr = 0x21ac, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_parent_map_1, + .clkr.hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_dp_pixel_clk_src", + .parent_data = disp_cc_parent_data_1, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = { + .cmd_rcgr = 0x2148, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_2, + .freq_tbl = ftbl_disp_cc_mdss_dp_aux_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_esc0_clk_src", + .parent_data = disp_cc_parent_data_2, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), + F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0), + F(345000000, P_DISP_CC_PLL0_OUT_MAIN, 4, 0, 0), + F(460000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = { + .cmd_rcgr = 0x20c8, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_3, + .freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_mdp_clk_src", + .parent_data = disp_cc_parent_data_3, + .num_parents = 5, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = { + .cmd_rcgr = 0x2098, + .mnd_width = 8, + .hid_width = 5, + .parent_map = disp_cc_parent_map_5, + .clkr.hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_pclk0_clk_src", + .parent_data = disp_cc_parent_data_5, + .num_parents = 3, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_pixel_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_rot_clk_src = { + .cmd_rcgr = 0x20e0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_3, + .freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_rot_clk_src", + .parent_data = disp_cc_parent_data_3, + .num_parents = 5, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = { + .cmd_rcgr = 0x20f8, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_0, + .freq_tbl = ftbl_disp_cc_mdss_dp_aux_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_vsync_clk_src", + .parent_data = disp_cc_parent_data_0, + .num_parents = 2, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_branch disp_cc_mdss_ahb_clk = { + .halt_reg = 0x2080, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2080, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_ahb_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &disp_cc_mdss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_byte0_clk = { + .halt_reg = 0x2028, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2028, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_byte0_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &disp_cc_mdss_byte0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_regmap_div disp_cc_mdss_byte0_div_clk_src = { + .reg = 0x2128, + .shift = 0, + .width = 2, + .clkr.hw.init = &(struct clk_init_data) { + .name = "disp_cc_mdss_byte0_div_clk_src", + .parent_data = &(const struct clk_parent_data){ + .hw = &disp_cc_mdss_byte0_clk_src.clkr.hw + }, + .num_parents = 1, + .ops = &clk_regmap_div_ops, + }, +}; + +static struct clk_regmap_div disp_cc_mdss_dp_link_div_clk_src = { + .reg = 0x2190, + .shift = 0, + .width = 2, + .clkr.hw.init = &(struct clk_init_data) { + .name = "disp_cc_mdss_dp_link_div_clk_src", + .parent_data = &(const struct clk_parent_data){ + .hw = &disp_cc_mdss_dp_link_clk_src.clkr.hw + }, + .num_parents = 1, + .ops = &clk_regmap_div_ops, + }, +}; + +static struct clk_branch disp_cc_mdss_byte0_intf_clk = { + .halt_reg = 0x202c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x202c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_byte0_intf_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &disp_cc_mdss_byte0_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dp_aux_clk = { + .halt_reg = 0x2054, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2054, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_dp_aux_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &disp_cc_mdss_dp_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dp_crypto_clk = { + .halt_reg = 0x2048, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2048, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_dp_crypto_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &disp_cc_mdss_dp_crypto_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dp_link_clk = { + .halt_reg = 0x2040, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2040, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_dp_link_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &disp_cc_mdss_dp_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dp_link_intf_clk = { + .halt_reg = 0x2044, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2044, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_dp_link_intf_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &disp_cc_mdss_dp_link_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dp_pixel_clk = { + .halt_reg = 0x204c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x204c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_dp_pixel_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &disp_cc_mdss_dp_pixel_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_esc0_clk = { + .halt_reg = 0x2038, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2038, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_esc0_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &disp_cc_mdss_esc0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_mdp_clk = { + .halt_reg = 0x200c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x200c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_mdp_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &disp_cc_mdss_mdp_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_mdp_lut_clk = { + .halt_reg = 0x201c, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x201c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_mdp_lut_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &disp_cc_mdss_mdp_clk_src.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_non_gdsc_ahb_clk = { + .halt_reg = 0x4004, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x4004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_non_gdsc_ahb_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &disp_cc_mdss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_pclk0_clk = { + .halt_reg = 0x2004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_pclk0_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &disp_cc_mdss_pclk0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_rot_clk = { + .halt_reg = 0x2014, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_rot_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &disp_cc_mdss_rot_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_rscc_ahb_clk = { + .halt_reg = 0x400c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x400c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_rscc_ahb_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &disp_cc_mdss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_rscc_vsync_clk = { + .halt_reg = 0x4008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_rscc_vsync_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &disp_cc_mdss_vsync_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_vsync_clk = { + .halt_reg = 0x2024, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2024, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_vsync_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &disp_cc_mdss_vsync_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc mdss_gdsc = { + .gdscr = 0x3000, + .pd = { + .name = "mdss_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = HW_CTRL, +}; + +static struct gdsc *disp_cc_sc7180_gdscs[] = { + [MDSS_GDSC] = &mdss_gdsc, +}; + +static struct clk_regmap *disp_cc_sc7180_clocks[] = { + [DISP_CC_MDSS_AHB_CLK] = &disp_cc_mdss_ahb_clk.clkr, + [DISP_CC_MDSS_AHB_CLK_SRC] = &disp_cc_mdss_ahb_clk_src.clkr, + [DISP_CC_MDSS_BYTE0_CLK] = &disp_cc_mdss_byte0_clk.clkr, + [DISP_CC_MDSS_BYTE0_CLK_SRC] = &disp_cc_mdss_byte0_clk_src.clkr, + [DISP_CC_MDSS_BYTE0_DIV_CLK_SRC] = &disp_cc_mdss_byte0_div_clk_src.clkr, + [DISP_CC_MDSS_BYTE0_INTF_CLK] = &disp_cc_mdss_byte0_intf_clk.clkr, + [DISP_CC_MDSS_DP_AUX_CLK] = &disp_cc_mdss_dp_aux_clk.clkr, + [DISP_CC_MDSS_DP_AUX_CLK_SRC] = &disp_cc_mdss_dp_aux_clk_src.clkr, + [DISP_CC_MDSS_DP_CRYPTO_CLK] = &disp_cc_mdss_dp_crypto_clk.clkr, + [DISP_CC_MDSS_DP_CRYPTO_CLK_SRC] = &disp_cc_mdss_dp_crypto_clk_src.clkr, + [DISP_CC_MDSS_DP_LINK_CLK] = &disp_cc_mdss_dp_link_clk.clkr, + [DISP_CC_MDSS_DP_LINK_CLK_SRC] = &disp_cc_mdss_dp_link_clk_src.clkr, + [DISP_CC_MDSS_DP_LINK_DIV_CLK_SRC] = + &disp_cc_mdss_dp_link_div_clk_src.clkr, + [DISP_CC_MDSS_DP_LINK_INTF_CLK] = &disp_cc_mdss_dp_link_intf_clk.clkr, + [DISP_CC_MDSS_DP_PIXEL_CLK] = &disp_cc_mdss_dp_pixel_clk.clkr, + [DISP_CC_MDSS_DP_PIXEL_CLK_SRC] = &disp_cc_mdss_dp_pixel_clk_src.clkr, + [DISP_CC_MDSS_ESC0_CLK] = &disp_cc_mdss_esc0_clk.clkr, + [DISP_CC_MDSS_ESC0_CLK_SRC] = &disp_cc_mdss_esc0_clk_src.clkr, + [DISP_CC_MDSS_MDP_CLK] = &disp_cc_mdss_mdp_clk.clkr, + [DISP_CC_MDSS_MDP_CLK_SRC] = &disp_cc_mdss_mdp_clk_src.clkr, + [DISP_CC_MDSS_MDP_LUT_CLK] = &disp_cc_mdss_mdp_lut_clk.clkr, + [DISP_CC_MDSS_NON_GDSC_AHB_CLK] = &disp_cc_mdss_non_gdsc_ahb_clk.clkr, + [DISP_CC_MDSS_PCLK0_CLK] = &disp_cc_mdss_pclk0_clk.clkr, + [DISP_CC_MDSS_PCLK0_CLK_SRC] = &disp_cc_mdss_pclk0_clk_src.clkr, + [DISP_CC_MDSS_ROT_CLK] = &disp_cc_mdss_rot_clk.clkr, + [DISP_CC_MDSS_ROT_CLK_SRC] = &disp_cc_mdss_rot_clk_src.clkr, + [DISP_CC_MDSS_RSCC_AHB_CLK] = &disp_cc_mdss_rscc_ahb_clk.clkr, + [DISP_CC_MDSS_RSCC_VSYNC_CLK] = &disp_cc_mdss_rscc_vsync_clk.clkr, + [DISP_CC_MDSS_VSYNC_CLK] = &disp_cc_mdss_vsync_clk.clkr, + [DISP_CC_MDSS_VSYNC_CLK_SRC] = &disp_cc_mdss_vsync_clk_src.clkr, + [DISP_CC_PLL0] = &disp_cc_pll0.clkr, + [DISP_CC_PLL0_OUT_EVEN] = &disp_cc_pll0_out_even.clkr, +}; + +static const struct regmap_config disp_cc_sc7180_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x10000, + .fast_io = true, +}; + +static const struct qcom_cc_desc disp_cc_sc7180_desc = { + .config = &disp_cc_sc7180_regmap_config, + .clks = disp_cc_sc7180_clocks, + .num_clks = ARRAY_SIZE(disp_cc_sc7180_clocks), + .gdscs = disp_cc_sc7180_gdscs, + .num_gdscs = ARRAY_SIZE(disp_cc_sc7180_gdscs), +}; + +static const struct of_device_id disp_cc_sc7180_match_table[] = { + { .compatible = "qcom,sc7180-dispcc" }, + { } +}; +MODULE_DEVICE_TABLE(of, disp_cc_sc7180_match_table); + +static int disp_cc_sc7180_probe(struct platform_device *pdev) +{ + struct regmap *regmap; + struct alpha_pll_config disp_cc_pll_config = {}; + + regmap = qcom_cc_map(pdev, &disp_cc_sc7180_desc); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + /* 1380MHz configuration */ + disp_cc_pll_config.l = 0x47; + disp_cc_pll_config.alpha = 0xe000; + disp_cc_pll_config.user_ctl_val = 0x00000001; + disp_cc_pll_config.user_ctl_hi_val = 0x00004805; + + clk_fabia_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll_config); + + return qcom_cc_really_probe(pdev, &disp_cc_sc7180_desc, regmap); +} + +static struct platform_driver disp_cc_sc7180_driver = { + .probe = disp_cc_sc7180_probe, + .driver = { + .name = "sc7180-dispcc", + .of_match_table = disp_cc_sc7180_match_table, + }, +}; + +static int __init disp_cc_sc7180_init(void) +{ + return platform_driver_register(&disp_cc_sc7180_driver); +} +subsys_initcall(disp_cc_sc7180_init); + +static void __exit disp_cc_sc7180_exit(void) +{ + platform_driver_unregister(&disp_cc_sc7180_driver); +} +module_exit(disp_cc_sc7180_exit); + +MODULE_DESCRIPTION("QTI DISP_CC SC7180 Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/qcom/dispcc-sdm845.c b/drivers/clk/qcom/dispcc-sdm845.c index 0cc4909b5dbe..5c932cd17b14 100644 --- a/drivers/clk/qcom/dispcc-sdm845.c +++ b/drivers/clk/qcom/dispcc-sdm845.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #include <linux/clk-provider.h> @@ -29,6 +29,8 @@ enum { P_DSI1_PHY_PLL_OUT_DSICLK, P_GPLL0_OUT_MAIN, P_GPLL0_OUT_MAIN_DIV, + P_DP_PHY_PLL_LINK_CLK, + P_DP_PHY_PLL_VCO_DIV_CLK, }; static const struct parent_map disp_cc_parent_map_0[] = { @@ -45,6 +47,20 @@ static const char * const disp_cc_parent_names_0[] = { "core_bi_pll_test_se", }; +static const struct parent_map disp_cc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_DP_PHY_PLL_LINK_CLK, 1 }, + { P_DP_PHY_PLL_VCO_DIV_CLK, 2 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const disp_cc_parent_names_1[] = { + "bi_tcxo", + "dp_link_clk_divsel_ten", + "dp_vco_divided_clk_src_mux", + "core_bi_pll_test_se", +}; + static const struct parent_map disp_cc_parent_map_2[] = { { P_BI_TCXO, 0 }, { P_CORE_BI_PLL_TEST_SE, 7 }, @@ -128,6 +144,81 @@ static struct clk_rcg2 disp_cc_mdss_byte1_clk_src = { }, }; +static const struct freq_tbl ftbl_disp_cc_mdss_dp_aux_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 disp_cc_mdss_dp_aux_clk_src = { + .cmd_rcgr = 0x219c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_2, + .freq_tbl = ftbl_disp_cc_mdss_dp_aux_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_dp_aux_clk_src", + .parent_names = disp_cc_parent_names_2, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dp_crypto_clk_src = { + .cmd_rcgr = 0x2154, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_1, + .clkr.hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_dp_crypto_clk_src", + .parent_names = disp_cc_parent_names_1, + .num_parents = 4, + .ops = &clk_byte2_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dp_link_clk_src = { + .cmd_rcgr = 0x2138, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_1, + .clkr.hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_dp_link_clk_src", + .parent_names = disp_cc_parent_names_1, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_byte2_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dp_pixel1_clk_src = { + .cmd_rcgr = 0x2184, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_parent_map_1, + .clkr.hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_dp_pixel1_clk_src", + .parent_names = disp_cc_parent_names_1, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dp_pixel_clk_src = { + .cmd_rcgr = 0x216c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_parent_map_1, + .clkr.hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_dp_pixel_clk_src", + .parent_names = disp_cc_parent_names_1, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + static const struct freq_tbl ftbl_disp_cc_mdss_esc0_clk_src[] = { F(19200000, P_BI_TCXO, 1, 0, 0), { } @@ -391,6 +482,114 @@ static struct clk_branch disp_cc_mdss_byte1_intf_clk = { }, }; +static struct clk_branch disp_cc_mdss_dp_aux_clk = { + .halt_reg = 0x2054, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2054, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_dp_aux_clk", + .parent_names = (const char *[]){ + "disp_cc_mdss_dp_aux_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dp_crypto_clk = { + .halt_reg = 0x2048, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2048, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_dp_crypto_clk", + .parent_names = (const char *[]){ + "disp_cc_mdss_dp_crypto_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dp_link_clk = { + .halt_reg = 0x2040, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2040, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_dp_link_clk", + .parent_names = (const char *[]){ + "disp_cc_mdss_dp_link_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +/* reset state of disp_cc_mdss_dp_link_div_clk_src divider is 0x3 (div 4) */ +static struct clk_branch disp_cc_mdss_dp_link_intf_clk = { + .halt_reg = 0x2044, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2044, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_dp_link_intf_clk", + .parent_names = (const char *[]){ + "disp_cc_mdss_dp_link_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dp_pixel1_clk = { + .halt_reg = 0x2050, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2050, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_dp_pixel1_clk", + .parent_names = (const char *[]){ + "disp_cc_mdss_dp_pixel1_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dp_pixel_clk = { + .halt_reg = 0x204c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x204c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_dp_pixel_clk", + .parent_names = (const char *[]){ + "disp_cc_mdss_dp_pixel_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_branch disp_cc_mdss_esc0_clk = { .halt_reg = 0x2038, .halt_check = BRANCH_HALT, @@ -589,6 +788,19 @@ static struct clk_regmap *disp_cc_sdm845_clocks[] = { [DISP_CC_MDSS_BYTE1_INTF_CLK] = &disp_cc_mdss_byte1_intf_clk.clkr, [DISP_CC_MDSS_BYTE1_DIV_CLK_SRC] = &disp_cc_mdss_byte1_div_clk_src.clkr, + [DISP_CC_MDSS_DP_AUX_CLK] = &disp_cc_mdss_dp_aux_clk.clkr, + [DISP_CC_MDSS_DP_AUX_CLK_SRC] = &disp_cc_mdss_dp_aux_clk_src.clkr, + [DISP_CC_MDSS_DP_CRYPTO_CLK] = &disp_cc_mdss_dp_crypto_clk.clkr, + [DISP_CC_MDSS_DP_CRYPTO_CLK_SRC] = + &disp_cc_mdss_dp_crypto_clk_src.clkr, + [DISP_CC_MDSS_DP_LINK_CLK] = &disp_cc_mdss_dp_link_clk.clkr, + [DISP_CC_MDSS_DP_LINK_CLK_SRC] = &disp_cc_mdss_dp_link_clk_src.clkr, + [DISP_CC_MDSS_DP_LINK_INTF_CLK] = &disp_cc_mdss_dp_link_intf_clk.clkr, + [DISP_CC_MDSS_DP_PIXEL1_CLK] = &disp_cc_mdss_dp_pixel1_clk.clkr, + [DISP_CC_MDSS_DP_PIXEL1_CLK_SRC] = + &disp_cc_mdss_dp_pixel1_clk_src.clkr, + [DISP_CC_MDSS_DP_PIXEL_CLK] = &disp_cc_mdss_dp_pixel_clk.clkr, + [DISP_CC_MDSS_DP_PIXEL_CLK_SRC] = &disp_cc_mdss_dp_pixel_clk_src.clkr, [DISP_CC_MDSS_ESC0_CLK] = &disp_cc_mdss_esc0_clk.clkr, [DISP_CC_MDSS_ESC0_CLK_SRC] = &disp_cc_mdss_esc0_clk_src.clkr, [DISP_CC_MDSS_ESC1_CLK] = &disp_cc_mdss_esc1_clk.clkr, diff --git a/drivers/clk/qcom/gcc-ipq6018.c b/drivers/clk/qcom/gcc-ipq6018.c new file mode 100644 index 000000000000..3f9c2f61a5d9 --- /dev/null +++ b/drivers/clk/qcom/gcc-ipq6018.c @@ -0,0 +1,4635 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#include <linux/kernel.h> +#include <linux/err.h> +#include <linux/platform_device.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/clk-provider.h> +#include <linux/regmap.h> + +#include <linux/reset-controller.h> +#include <dt-bindings/clock/qcom,gcc-ipq6018.h> +#include <dt-bindings/reset/qcom,gcc-ipq6018.h> + +#include "common.h" +#include "clk-regmap.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-branch.h" +#include "clk-alpha-pll.h" +#include "clk-regmap-divider.h" +#include "clk-regmap-mux.h" +#include "reset.h" + +#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } + +enum { + P_XO, + P_BIAS_PLL, + P_UNIPHY0_RX, + P_UNIPHY0_TX, + P_UNIPHY1_RX, + P_BIAS_PLL_NSS_NOC, + P_UNIPHY1_TX, + P_PCIE20_PHY0_PIPE, + P_USB3PHY_0_PIPE, + P_GPLL0, + P_GPLL0_DIV2, + P_GPLL2, + P_GPLL4, + P_GPLL6, + P_SLEEP_CLK, + P_UBI32_PLL, + P_NSS_CRYPTO_PLL, + P_PI_SLEEP, +}; + +static struct clk_alpha_pll gpll0_main = { + .offset = 0x21000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr = { + .enable_reg = 0x0b000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpll0_main", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "xo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +static struct clk_fixed_factor gpll0_out_main_div2 = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data){ + .name = "gpll0_out_main_div2", + .parent_hws = (const struct clk_hw *[]){ + &gpll0_main.clkr.hw }, + .num_parents = 1, + .ops = &clk_fixed_factor_ops, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_alpha_pll_postdiv gpll0 = { + .offset = 0x21000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .width = 4, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpll0", + .parent_hws = (const struct clk_hw *[]){ + &gpll0_main.clkr.hw }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_ro_ops, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct clk_parent_data gcc_xo_gpll0_gpll0_out_main_div2[] = { + { .fw_name = "xo" }, + { .hw = &gpll0.clkr.hw}, + { .hw = &gpll0_out_main_div2.hw}, +}; + +static const struct parent_map gcc_xo_gpll0_gpll0_out_main_div2_map[] = { + { P_XO, 0 }, + { P_GPLL0, 1 }, + { P_GPLL0_DIV2, 4 }, +}; + +static struct clk_alpha_pll ubi32_pll_main = { + .offset = 0x25000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_HUAYRA], + .flags = SUPPORTS_DYNAMIC_UPDATE, + .clkr = { + .enable_reg = 0x0b000, + .enable_mask = BIT(6), + .hw.init = &(struct clk_init_data){ + .name = "ubi32_pll_main", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "xo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_huayra_ops, + }, + }, +}; + +static struct clk_alpha_pll_postdiv ubi32_pll = { + .offset = 0x25000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_HUAYRA], + .width = 2, + .clkr.hw.init = &(struct clk_init_data){ + .name = "ubi32_pll", + .parent_hws = (const struct clk_hw *[]){ + &ubi32_pll_main.clkr.hw }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_ro_ops, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_alpha_pll gpll6_main = { + .offset = 0x37000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_BRAMMO], + .clkr = { + .enable_reg = 0x0b000, + .enable_mask = BIT(7), + .hw.init = &(struct clk_init_data){ + .name = "gpll6_main", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "xo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +static struct clk_alpha_pll_postdiv gpll6 = { + .offset = 0x37000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_BRAMMO], + .width = 2, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpll6", + .parent_hws = (const struct clk_hw *[]){ + &gpll6_main.clkr.hw }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_ro_ops, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_alpha_pll gpll4_main = { + .offset = 0x24000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr = { + .enable_reg = 0x0b000, + .enable_mask = BIT(5), + .hw.init = &(struct clk_init_data){ + .name = "gpll4_main", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "xo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +static struct clk_alpha_pll_postdiv gpll4 = { + .offset = 0x24000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .width = 4, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpll4", + .parent_hws = (const struct clk_hw *[]){ + &gpll4_main.clkr.hw }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_ro_ops, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct freq_tbl ftbl_pcnoc_bfdcd_clk_src[] = { + F(24000000, P_XO, 1, 0, 0), + F(50000000, P_GPLL0, 16, 0, 0), + F(100000000, P_GPLL0, 8, 0, 0), + { } +}; + +static struct clk_rcg2 pcnoc_bfdcd_clk_src = { + .cmd_rcgr = 0x27000, + .freq_tbl = ftbl_pcnoc_bfdcd_clk_src, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "pcnoc_bfdcd_clk_src", + .parent_data = gcc_xo_gpll0_gpll0_out_main_div2, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_alpha_pll gpll2_main = { + .offset = 0x4a000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr = { + .enable_reg = 0x0b000, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data){ + .name = "gpll2_main", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "xo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +static struct clk_alpha_pll_postdiv gpll2 = { + .offset = 0x4a000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .width = 4, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpll2", + .parent_hws = (const struct clk_hw *[]){ + &gpll2_main.clkr.hw }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_ro_ops, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_alpha_pll nss_crypto_pll_main = { + .offset = 0x22000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr = { + .enable_reg = 0x0b000, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "nss_crypto_pll_main", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "xo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +static struct clk_alpha_pll_postdiv nss_crypto_pll = { + .offset = 0x22000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .width = 4, + .clkr.hw.init = &(struct clk_init_data){ + .name = "nss_crypto_pll", + .parent_hws = (const struct clk_hw *[]){ + &nss_crypto_pll_main.clkr.hw }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_ro_ops, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct freq_tbl ftbl_qdss_tsctr_clk_src[] = { + F(160000000, P_GPLL0_DIV2, 2.5, 0, 0), + F(320000000, P_GPLL0, 2.5, 0, 0), + F(600000000, P_GPLL4, 2, 0, 0), + { } +}; + +static const struct clk_parent_data gcc_xo_gpll4_gpll0_gpll6_gpll0_div2[] = { + { .fw_name = "xo" }, + { .hw = &gpll4.clkr.hw }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll6.clkr.hw }, + { .hw = &gpll0_out_main_div2.hw }, +}; + +static const struct parent_map gcc_xo_gpll4_gpll0_gpll6_gpll0_div2_map[] = { + { P_XO, 0 }, + { P_GPLL4, 1 }, + { P_GPLL0, 2 }, + { P_GPLL6, 3 }, + { P_GPLL0_DIV2, 4 }, +}; + +static struct clk_rcg2 qdss_tsctr_clk_src = { + .cmd_rcgr = 0x29064, + .freq_tbl = ftbl_qdss_tsctr_clk_src, + .hid_width = 5, + .parent_map = gcc_xo_gpll4_gpll0_gpll6_gpll0_div2_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "qdss_tsctr_clk_src", + .parent_data = gcc_xo_gpll4_gpll0_gpll6_gpll0_div2, + .num_parents = 5, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_fixed_factor qdss_dap_sync_clk_src = { + .mult = 1, + .div = 4, + .hw.init = &(struct clk_init_data){ + .name = "qdss_dap_sync_clk_src", + .parent_hws = (const struct clk_hw *[]){ + &qdss_tsctr_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_fixed_factor_ops, + }, +}; + +static const struct freq_tbl ftbl_qdss_at_clk_src[] = { + F(66670000, P_GPLL0_DIV2, 6, 0, 0), + F(240000000, P_GPLL4, 5, 0, 0), + { } +}; + +static struct clk_rcg2 qdss_at_clk_src = { + .cmd_rcgr = 0x2900c, + .freq_tbl = ftbl_qdss_at_clk_src, + .hid_width = 5, + .parent_map = gcc_xo_gpll4_gpll0_gpll6_gpll0_div2_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "qdss_at_clk_src", + .parent_data = gcc_xo_gpll4_gpll0_gpll6_gpll0_div2, + .num_parents = 5, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_fixed_factor qdss_tsctr_div2_clk_src = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data){ + .name = "qdss_tsctr_div2_clk_src", + .parent_hws = (const struct clk_hw *[]){ + &qdss_tsctr_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_fixed_factor_ops, + }, +}; + +static const struct freq_tbl ftbl_nss_ppe_clk_src[] = { + F(24000000, P_XO, 1, 0, 0), + F(300000000, P_BIAS_PLL, 1, 0, 0), + { } +}; + +static const struct clk_parent_data gcc_xo_bias_gpll0_gpll4_nss_ubi32[] = { + { .fw_name = "xo" }, + { .fw_name = "bias_pll_cc_clk" }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll4.clkr.hw }, + { .hw = &nss_crypto_pll.clkr.hw }, + { .hw = &ubi32_pll.clkr.hw }, +}; + +static const struct parent_map gcc_xo_bias_gpll0_gpll4_nss_ubi32_map[] = { + { P_XO, 0 }, + { P_BIAS_PLL, 1 }, + { P_GPLL0, 2 }, + { P_GPLL4, 3 }, + { P_NSS_CRYPTO_PLL, 4 }, + { P_UBI32_PLL, 5 }, +}; + +static struct clk_rcg2 nss_ppe_clk_src = { + .cmd_rcgr = 0x68080, + .freq_tbl = ftbl_nss_ppe_clk_src, + .hid_width = 5, + .parent_map = gcc_xo_bias_gpll0_gpll4_nss_ubi32_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "nss_ppe_clk_src", + .parent_data = gcc_xo_bias_gpll0_gpll4_nss_ubi32, + .num_parents = 6, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch gcc_xo_clk_src = { + .halt_reg = 0x30018, + .clkr = { + .enable_reg = 0x30018, + .enable_mask = BIT(1), + .hw.init = &(struct clk_init_data){ + .name = "gcc_xo_clk_src", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "xo", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static const struct freq_tbl ftbl_nss_ce_clk_src[] = { + F(24000000, P_XO, 1, 0, 0), + F(200000000, P_GPLL0, 4, 0, 0), + { } +}; + +static const struct clk_parent_data gcc_xo_gpll0[] = { + { .fw_name = "xo" }, + { .hw = &gpll0.clkr.hw }, +}; + +static const struct parent_map gcc_xo_gpll0_map[] = { + { P_XO, 0 }, + { P_GPLL0, 1 }, +}; + +static struct clk_rcg2 nss_ce_clk_src = { + .cmd_rcgr = 0x68098, + .freq_tbl = ftbl_nss_ce_clk_src, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "nss_ce_clk_src", + .parent_data = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch gcc_sleep_clk_src = { + .halt_reg = 0x30000, + .clkr = { + .enable_reg = 0x30000, + .enable_mask = BIT(1), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sleep_clk_src", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "sleep_clk", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static const struct freq_tbl ftbl_snoc_nssnoc_bfdcd_clk_src[] = { + F(24000000, P_XO, 1, 0, 0), + F(50000000, P_GPLL0_DIV2, 8, 0, 0), + F(100000000, P_GPLL0, 8, 0, 0), + F(133333333, P_GPLL0, 6, 0, 0), + F(160000000, P_GPLL0, 5, 0, 0), + F(200000000, P_GPLL0, 4, 0, 0), + F(266666667, P_GPLL0, 3, 0, 0), + { } +}; + +static const struct clk_parent_data + gcc_xo_gpll0_gpll6_gpll0_out_main_div2[] = { + { .fw_name = "xo" }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll6.clkr.hw }, + { .hw = &gpll0_out_main_div2.hw }, +}; + +static const struct parent_map gcc_xo_gpll0_gpll6_gpll0_out_main_div2_map[] = { + { P_XO, 0 }, + { P_GPLL0, 1 }, + { P_GPLL6, 2 }, + { P_GPLL0_DIV2, 3 }, +}; + +static struct clk_rcg2 snoc_nssnoc_bfdcd_clk_src = { + .cmd_rcgr = 0x76054, + .freq_tbl = ftbl_snoc_nssnoc_bfdcd_clk_src, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll6_gpll0_out_main_div2_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "snoc_nssnoc_bfdcd_clk_src", + .parent_data = gcc_xo_gpll0_gpll6_gpll0_out_main_div2, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_apss_ahb_clk_src[] = { + F(24000000, P_XO, 1, 0, 0), + F(25000000, P_GPLL0_DIV2, 16, 0, 0), + F(50000000, P_GPLL0, 16, 0, 0), + F(100000000, P_GPLL0, 8, 0, 0), + { } +}; + +static struct clk_rcg2 apss_ahb_clk_src = { + .cmd_rcgr = 0x46000, + .freq_tbl = ftbl_apss_ahb_clk_src, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "apss_ahb_clk_src", + .parent_data = gcc_xo_gpll0_gpll0_out_main_div2, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_nss_port5_rx_clk_src[] = { + F(24000000, P_XO, 1, 0, 0), + F(25000000, P_UNIPHY1_RX, 12.5, 0, 0), + F(25000000, P_UNIPHY0_RX, 5, 0, 0), + F(78125000, P_UNIPHY1_RX, 4, 0, 0), + F(125000000, P_UNIPHY1_RX, 2.5, 0, 0), + F(125000000, P_UNIPHY0_RX, 1, 0, 0), + F(156250000, P_UNIPHY1_RX, 2, 0, 0), + F(312500000, P_UNIPHY1_RX, 1, 0, 0), + { } +}; + +static const struct clk_parent_data +gcc_xo_uniphy0_rx_tx_uniphy1_rx_tx_ubi32_bias[] = { + { .fw_name = "xo" }, + { .fw_name = "uniphy0_gcc_rx_clk" }, + { .fw_name = "uniphy0_gcc_tx_clk" }, + { .fw_name = "uniphy1_gcc_rx_clk" }, + { .fw_name = "uniphy1_gcc_tx_clk" }, + { .hw = &ubi32_pll.clkr.hw }, + { .fw_name = "bias_pll_cc_clk" }, +}; + +static const struct parent_map +gcc_xo_uniphy0_rx_tx_uniphy1_rx_tx_ubi32_bias_map[] = { + { P_XO, 0 }, + { P_UNIPHY0_RX, 1 }, + { P_UNIPHY0_TX, 2 }, + { P_UNIPHY1_RX, 3 }, + { P_UNIPHY1_TX, 4 }, + { P_UBI32_PLL, 5 }, + { P_BIAS_PLL, 6 }, +}; + +static struct clk_rcg2 nss_port5_rx_clk_src = { + .cmd_rcgr = 0x68060, + .freq_tbl = ftbl_nss_port5_rx_clk_src, + .hid_width = 5, + .parent_map = gcc_xo_uniphy0_rx_tx_uniphy1_rx_tx_ubi32_bias_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "nss_port5_rx_clk_src", + .parent_data = gcc_xo_uniphy0_rx_tx_uniphy1_rx_tx_ubi32_bias, + .num_parents = 7, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_nss_port5_tx_clk_src[] = { + F(24000000, P_XO, 1, 0, 0), + F(25000000, P_UNIPHY1_TX, 12.5, 0, 0), + F(25000000, P_UNIPHY0_TX, 5, 0, 0), + F(78125000, P_UNIPHY1_TX, 4, 0, 0), + F(125000000, P_UNIPHY1_TX, 2.5, 0, 0), + F(125000000, P_UNIPHY0_TX, 1, 0, 0), + F(156250000, P_UNIPHY1_TX, 2, 0, 0), + F(312500000, P_UNIPHY1_TX, 1, 0, 0), + { } +}; + +static const struct clk_parent_data +gcc_xo_uniphy0_tx_rx_uniphy1_tx_rx_ubi32_bias[] = { + { .fw_name = "xo" }, + { .fw_name = "uniphy0_gcc_tx_clk" }, + { .fw_name = "uniphy0_gcc_rx_clk" }, + { .fw_name = "uniphy1_gcc_tx_clk" }, + { .fw_name = "uniphy1_gcc_rx_clk" }, + { .hw = &ubi32_pll.clkr.hw }, + { .fw_name = "bias_pll_cc_clk" }, +}; + +static const struct parent_map +gcc_xo_uniphy0_tx_rx_uniphy1_tx_rx_ubi32_bias_map[] = { + { P_XO, 0 }, + { P_UNIPHY0_TX, 1 }, + { P_UNIPHY0_RX, 2 }, + { P_UNIPHY1_TX, 3 }, + { P_UNIPHY1_RX, 4 }, + { P_UBI32_PLL, 5 }, + { P_BIAS_PLL, 6 }, +}; + +static struct clk_rcg2 nss_port5_tx_clk_src = { + .cmd_rcgr = 0x68068, + .freq_tbl = ftbl_nss_port5_tx_clk_src, + .hid_width = 5, + .parent_map = gcc_xo_uniphy0_tx_rx_uniphy1_tx_rx_ubi32_bias_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "nss_port5_tx_clk_src", + .parent_data = gcc_xo_uniphy0_tx_rx_uniphy1_tx_rx_ubi32_bias, + .num_parents = 7, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_pcie_axi_clk_src[] = { + F(24000000, P_XO, 1, 0, 0), + F(200000000, P_GPLL0, 4, 0, 0), + F(240000000, P_GPLL4, 5, 0, 0), + { } +}; + +static const struct freq_tbl ftbl_pcie_rchng_clk_src[] = { + F(24000000, P_XO, 1, 0, 0), + F(100000000, P_GPLL0, 8, 0, 0), + { } +}; + +static const struct clk_parent_data gcc_xo_gpll0_gpll4[] = { + { .fw_name = "xo" }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll4.clkr.hw }, +}; + +static const struct parent_map gcc_xo_gpll0_gpll4_map[] = { + { P_XO, 0 }, + { P_GPLL0, 1 }, + { P_GPLL4, 2 }, +}; + +static struct clk_rcg2 pcie0_axi_clk_src = { + .cmd_rcgr = 0x75054, + .freq_tbl = ftbl_pcie_axi_clk_src, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll4_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "pcie0_axi_clk_src", + .parent_data = gcc_xo_gpll0_gpll4, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_usb0_master_clk_src[] = { + F(80000000, P_GPLL0_DIV2, 5, 0, 0), + F(100000000, P_GPLL0, 8, 0, 0), + F(133330000, P_GPLL0, 6, 0, 0), + F(200000000, P_GPLL0, 4, 0, 0), + { } +}; + +static const struct clk_parent_data gcc_xo_gpll0_out_main_div2_gpll0[] = { + { .fw_name = "xo" }, + { .hw = &gpll0_out_main_div2.hw }, + { .hw = &gpll0.clkr.hw }, +}; + +static const struct parent_map gcc_xo_gpll0_out_main_div2_gpll0_map[] = { + { P_XO, 0 }, + { P_GPLL0_DIV2, 2 }, + { P_GPLL0, 1 }, +}; + +static struct clk_rcg2 usb0_master_clk_src = { + .cmd_rcgr = 0x3e00c, + .freq_tbl = ftbl_usb0_master_clk_src, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_out_main_div2_gpll0_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "usb0_master_clk_src", + .parent_data = gcc_xo_gpll0_out_main_div2_gpll0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_regmap_div apss_ahb_postdiv_clk_src = { + .reg = 0x46018, + .shift = 4, + .width = 4, + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "apss_ahb_postdiv_clk_src", + .parent_hws = (const struct clk_hw *[]){ + &apss_ahb_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_regmap_div_ops, + }, + }, +}; + +static struct clk_fixed_factor gcc_xo_div4_clk_src = { + .mult = 1, + .div = 4, + .hw.init = &(struct clk_init_data){ + .name = "gcc_xo_div4_clk_src", + .parent_hws = (const struct clk_hw *[]){ + &gcc_xo_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_fixed_factor_ops, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct freq_tbl ftbl_nss_port1_rx_clk_src[] = { + F(24000000, P_XO, 1, 0, 0), + F(25000000, P_UNIPHY0_RX, 5, 0, 0), + F(125000000, P_UNIPHY0_RX, 1, 0, 0), + { } +}; + +static const struct clk_parent_data gcc_xo_uniphy0_rx_tx_ubi32_bias[] = { + { .fw_name = "xo" }, + { .fw_name = "uniphy0_gcc_rx_clk" }, + { .fw_name = "uniphy0_gcc_tx_clk" }, + { .hw = &ubi32_pll.clkr.hw }, + { .fw_name = "bias_pll_cc_clk" }, +}; + +static const struct parent_map gcc_xo_uniphy0_rx_tx_ubi32_bias_map[] = { + { P_XO, 0 }, + { P_UNIPHY0_RX, 1 }, + { P_UNIPHY0_TX, 2 }, + { P_UBI32_PLL, 5 }, + { P_BIAS_PLL, 6 }, +}; + +static struct clk_rcg2 nss_port1_rx_clk_src = { + .cmd_rcgr = 0x68020, + .freq_tbl = ftbl_nss_port1_rx_clk_src, + .hid_width = 5, + .parent_map = gcc_xo_uniphy0_rx_tx_ubi32_bias_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "nss_port1_rx_clk_src", + .parent_data = gcc_xo_uniphy0_rx_tx_ubi32_bias, + .num_parents = 5, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_nss_port1_tx_clk_src[] = { + F(24000000, P_XO, 1, 0, 0), + F(25000000, P_UNIPHY0_TX, 5, 0, 0), + F(125000000, P_UNIPHY0_TX, 1, 0, 0), + { } +}; + +static const struct clk_parent_data gcc_xo_uniphy0_tx_rx_ubi32_bias[] = { + { .fw_name = "xo" }, + { .fw_name = "uniphy0_gcc_tx_clk" }, + { .fw_name = "uniphy0_gcc_rx_clk" }, + { .hw = &ubi32_pll.clkr.hw }, + { .fw_name = "bias_pll_cc_clk" }, +}; + +static const struct parent_map gcc_xo_uniphy0_tx_rx_ubi32_bias_map[] = { + { P_XO, 0 }, + { P_UNIPHY0_TX, 1 }, + { P_UNIPHY0_RX, 2 }, + { P_UBI32_PLL, 5 }, + { P_BIAS_PLL, 6 }, +}; + +static struct clk_rcg2 nss_port1_tx_clk_src = { + .cmd_rcgr = 0x68028, + .freq_tbl = ftbl_nss_port1_tx_clk_src, + .hid_width = 5, + .parent_map = gcc_xo_uniphy0_tx_rx_ubi32_bias_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "nss_port1_tx_clk_src", + .parent_data = gcc_xo_uniphy0_tx_rx_ubi32_bias, + .num_parents = 5, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 nss_port2_rx_clk_src = { + .cmd_rcgr = 0x68030, + .freq_tbl = ftbl_nss_port1_rx_clk_src, + .hid_width = 5, + .parent_map = gcc_xo_uniphy0_rx_tx_ubi32_bias_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "nss_port2_rx_clk_src", + .parent_data = gcc_xo_uniphy0_rx_tx_ubi32_bias, + .num_parents = 5, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 nss_port2_tx_clk_src = { + .cmd_rcgr = 0x68038, + .freq_tbl = ftbl_nss_port1_tx_clk_src, + .hid_width = 5, + .parent_map = gcc_xo_uniphy0_tx_rx_ubi32_bias_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "nss_port2_tx_clk_src", + .parent_data = gcc_xo_uniphy0_tx_rx_ubi32_bias, + .num_parents = 5, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 nss_port3_rx_clk_src = { + .cmd_rcgr = 0x68040, + .freq_tbl = ftbl_nss_port1_rx_clk_src, + .hid_width = 5, + .parent_map = gcc_xo_uniphy0_rx_tx_ubi32_bias_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "nss_port3_rx_clk_src", + .parent_data = gcc_xo_uniphy0_rx_tx_ubi32_bias, + .num_parents = 5, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 nss_port3_tx_clk_src = { + .cmd_rcgr = 0x68048, + .freq_tbl = ftbl_nss_port1_tx_clk_src, + .hid_width = 5, + .parent_map = gcc_xo_uniphy0_tx_rx_ubi32_bias_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "nss_port3_tx_clk_src", + .parent_data = gcc_xo_uniphy0_tx_rx_ubi32_bias, + .num_parents = 5, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 nss_port4_rx_clk_src = { + .cmd_rcgr = 0x68050, + .freq_tbl = ftbl_nss_port1_rx_clk_src, + .hid_width = 5, + .parent_map = gcc_xo_uniphy0_rx_tx_ubi32_bias_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "nss_port4_rx_clk_src", + .parent_data = gcc_xo_uniphy0_rx_tx_ubi32_bias, + .num_parents = 5, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 nss_port4_tx_clk_src = { + .cmd_rcgr = 0x68058, + .freq_tbl = ftbl_nss_port1_tx_clk_src, + .hid_width = 5, + .parent_map = gcc_xo_uniphy0_tx_rx_ubi32_bias_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "nss_port4_tx_clk_src", + .parent_data = gcc_xo_uniphy0_tx_rx_ubi32_bias, + .num_parents = 5, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_regmap_div nss_port5_rx_div_clk_src = { + .reg = 0x68440, + .shift = 0, + .width = 4, + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "nss_port5_rx_div_clk_src", + .parent_hws = (const struct clk_hw *[]){ + &nss_port5_rx_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_regmap_div_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_regmap_div nss_port5_tx_div_clk_src = { + .reg = 0x68444, + .shift = 0, + .width = 4, + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "nss_port5_tx_div_clk_src", + .parent_hws = (const struct clk_hw *[]){ + &nss_port5_tx_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_regmap_div_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static const struct freq_tbl ftbl_apss_axi_clk_src[] = { + F(24000000, P_XO, 1, 0, 0), + F(100000000, P_GPLL0_DIV2, 4, 0, 0), + F(200000000, P_GPLL0, 4, 0, 0), + F(308570000, P_GPLL6, 3.5, 0, 0), + F(400000000, P_GPLL0, 2, 0, 0), + F(533000000, P_GPLL0, 1.5, 0, 0), + { } +}; + +static const struct clk_parent_data gcc_xo_gpll0_gpll6_ubi32_gpll0_div2[] = { + { .fw_name = "xo" }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll6.clkr.hw }, + { .hw = &ubi32_pll.clkr.hw }, + { .hw = &gpll0_out_main_div2.hw }, +}; + +static const struct parent_map +gcc_xo_gpll0_gpll6_ubi32_gpll0_div2_map[] = { + { P_XO, 0 }, + { P_GPLL0, 1 }, + { P_GPLL6, 2 }, + { P_UBI32_PLL, 3 }, + { P_GPLL0_DIV2, 6 }, +}; + +static struct clk_rcg2 apss_axi_clk_src = { + .cmd_rcgr = 0x38048, + .freq_tbl = ftbl_apss_axi_clk_src, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll6_ubi32_gpll0_div2_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "apss_axi_clk_src", + .parent_data = gcc_xo_gpll0_gpll6_ubi32_gpll0_div2, + .num_parents = 5, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_nss_crypto_clk_src[] = { + F(24000000, P_XO, 1, 0, 0), + F(300000000, P_NSS_CRYPTO_PLL, 2, 0, 0), + { } +}; + +static const struct clk_parent_data gcc_xo_nss_crypto_pll_gpll0[] = { + { .fw_name = "xo" }, + { .hw = &nss_crypto_pll.clkr.hw }, + { .hw = &gpll0.clkr.hw }, +}; + +static const struct parent_map gcc_xo_nss_crypto_pll_gpll0_map[] = { + { P_XO, 0 }, + { P_NSS_CRYPTO_PLL, 1 }, + { P_GPLL0, 2 }, +}; + +static struct clk_rcg2 nss_crypto_clk_src = { + .cmd_rcgr = 0x68144, + .freq_tbl = ftbl_nss_crypto_clk_src, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_xo_nss_crypto_pll_gpll0_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "nss_crypto_clk_src", + .parent_data = gcc_xo_nss_crypto_pll_gpll0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_regmap_div nss_port1_rx_div_clk_src = { + .reg = 0x68400, + .shift = 0, + .width = 4, + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "nss_port1_rx_div_clk_src", + .parent_hws = (const struct clk_hw *[]){ + &nss_port1_rx_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_regmap_div_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_regmap_div nss_port1_tx_div_clk_src = { + .reg = 0x68404, + .shift = 0, + .width = 4, + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "nss_port1_tx_div_clk_src", + .parent_hws = (const struct clk_hw *[]){ + &nss_port1_tx_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_regmap_div_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_regmap_div nss_port2_rx_div_clk_src = { + .reg = 0x68410, + .shift = 0, + .width = 4, + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "nss_port2_rx_div_clk_src", + .parent_hws = (const struct clk_hw *[]){ + &nss_port2_rx_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_regmap_div_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_regmap_div nss_port2_tx_div_clk_src = { + .reg = 0x68414, + .shift = 0, + .width = 4, + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "nss_port2_tx_div_clk_src", + .parent_hws = (const struct clk_hw *[]){ + &nss_port2_tx_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_regmap_div_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_regmap_div nss_port3_rx_div_clk_src = { + .reg = 0x68420, + .shift = 0, + .width = 4, + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "nss_port3_rx_div_clk_src", + .parent_hws = (const struct clk_hw *[]){ + &nss_port3_rx_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_regmap_div_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_regmap_div nss_port3_tx_div_clk_src = { + .reg = 0x68424, + .shift = 0, + .width = 4, + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "nss_port3_tx_div_clk_src", + .parent_hws = (const struct clk_hw *[]){ + &nss_port3_tx_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_regmap_div_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_regmap_div nss_port4_rx_div_clk_src = { + .reg = 0x68430, + .shift = 0, + .width = 4, + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "nss_port4_rx_div_clk_src", + .parent_hws = (const struct clk_hw *[]){ + &nss_port4_rx_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_regmap_div_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_regmap_div nss_port4_tx_div_clk_src = { + .reg = 0x68434, + .shift = 0, + .width = 4, + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "nss_port4_tx_div_clk_src", + .parent_hws = (const struct clk_hw *[]){ + &nss_port4_tx_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_regmap_div_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static const struct freq_tbl ftbl_nss_ubi_clk_src[] = { + F(24000000, P_XO, 1, 0, 0), + F(149760000, P_UBI32_PLL, 10, 0, 0), + F(187200000, P_UBI32_PLL, 8, 0, 0), + F(249600000, P_UBI32_PLL, 6, 0, 0), + F(374400000, P_UBI32_PLL, 4, 0, 0), + F(748800000, P_UBI32_PLL, 2, 0, 0), + F(1497600000, P_UBI32_PLL, 1, 0, 0), + { } +}; + +static const struct clk_parent_data + gcc_xo_ubi32_pll_gpll0_gpll2_gpll4_gpll6[] = { + { .fw_name = "xo" }, + { .hw = &ubi32_pll.clkr.hw }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll2.clkr.hw }, + { .hw = &gpll4.clkr.hw }, + { .hw = &gpll6.clkr.hw }, +}; + +static const struct parent_map gcc_xo_ubi32_gpll0_gpll2_gpll4_gpll6_map[] = { + { P_XO, 0 }, + { P_UBI32_PLL, 1 }, + { P_GPLL0, 2 }, + { P_GPLL2, 3 }, + { P_GPLL4, 4 }, + { P_GPLL6, 5 }, +}; + +static struct clk_rcg2 nss_ubi0_clk_src = { + .cmd_rcgr = 0x68104, + .freq_tbl = ftbl_nss_ubi_clk_src, + .hid_width = 5, + .parent_map = gcc_xo_ubi32_gpll0_gpll2_gpll4_gpll6_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "nss_ubi0_clk_src", + .parent_data = gcc_xo_ubi32_pll_gpll0_gpll2_gpll4_gpll6, + .num_parents = 6, + .ops = &clk_rcg2_ops, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct freq_tbl ftbl_adss_pwm_clk_src[] = { + F(24000000, P_XO, 1, 0, 0), + F(100000000, P_GPLL0, 8, 0, 0), + { } +}; + +static struct clk_rcg2 adss_pwm_clk_src = { + .cmd_rcgr = 0x1c008, + .freq_tbl = ftbl_adss_pwm_clk_src, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "adss_pwm_clk_src", + .parent_data = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_blsp1_qup_i2c_apps_clk_src[] = { + F(24000000, P_XO, 1, 0, 0), + F(25000000, P_GPLL0_DIV2, 16, 0, 0), + F(50000000, P_GPLL0, 16, 0, 0), + { } +}; + +static struct clk_rcg2 blsp1_qup1_i2c_apps_clk_src = { + .cmd_rcgr = 0x0200c, + .freq_tbl = ftbl_blsp1_qup_i2c_apps_clk_src, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup1_i2c_apps_clk_src", + .parent_data = gcc_xo_gpll0_gpll0_out_main_div2, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_blsp1_qup_spi_apps_clk_src[] = { + F(960000, P_XO, 10, 2, 5), + F(4800000, P_XO, 5, 0, 0), + F(9600000, P_XO, 2, 4, 5), + F(12500000, P_GPLL0_DIV2, 16, 1, 2), + F(16000000, P_GPLL0, 10, 1, 5), + F(24000000, P_XO, 1, 0, 0), + F(25000000, P_GPLL0, 16, 1, 2), + F(50000000, P_GPLL0, 16, 0, 0), + { } +}; + +static struct clk_rcg2 blsp1_qup1_spi_apps_clk_src = { + .cmd_rcgr = 0x02024, + .freq_tbl = ftbl_blsp1_qup_spi_apps_clk_src, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup1_spi_apps_clk_src", + .parent_data = gcc_xo_gpll0_gpll0_out_main_div2, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup2_i2c_apps_clk_src = { + .cmd_rcgr = 0x03000, + .freq_tbl = ftbl_blsp1_qup_i2c_apps_clk_src, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup2_i2c_apps_clk_src", + .parent_data = gcc_xo_gpll0_gpll0_out_main_div2, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup2_spi_apps_clk_src = { + .cmd_rcgr = 0x03014, + .freq_tbl = ftbl_blsp1_qup_spi_apps_clk_src, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup2_spi_apps_clk_src", + .parent_data = gcc_xo_gpll0_gpll0_out_main_div2, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup3_i2c_apps_clk_src = { + .cmd_rcgr = 0x04000, + .freq_tbl = ftbl_blsp1_qup_i2c_apps_clk_src, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup3_i2c_apps_clk_src", + .parent_data = gcc_xo_gpll0_gpll0_out_main_div2, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup3_spi_apps_clk_src = { + .cmd_rcgr = 0x04014, + .freq_tbl = ftbl_blsp1_qup_spi_apps_clk_src, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup3_spi_apps_clk_src", + .parent_data = gcc_xo_gpll0_gpll0_out_main_div2, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup4_i2c_apps_clk_src = { + .cmd_rcgr = 0x05000, + .freq_tbl = ftbl_blsp1_qup_i2c_apps_clk_src, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup4_i2c_apps_clk_src", + .parent_data = gcc_xo_gpll0_gpll0_out_main_div2, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup4_spi_apps_clk_src = { + .cmd_rcgr = 0x05014, + .freq_tbl = ftbl_blsp1_qup_spi_apps_clk_src, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup4_spi_apps_clk_src", + .parent_data = gcc_xo_gpll0_gpll0_out_main_div2, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup5_i2c_apps_clk_src = { + .cmd_rcgr = 0x06000, + .freq_tbl = ftbl_blsp1_qup_i2c_apps_clk_src, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup5_i2c_apps_clk_src", + .parent_data = gcc_xo_gpll0_gpll0_out_main_div2, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup5_spi_apps_clk_src = { + .cmd_rcgr = 0x06014, + .freq_tbl = ftbl_blsp1_qup_spi_apps_clk_src, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup5_spi_apps_clk_src", + .parent_data = gcc_xo_gpll0_gpll0_out_main_div2, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup6_i2c_apps_clk_src = { + .cmd_rcgr = 0x07000, + .freq_tbl = ftbl_blsp1_qup_i2c_apps_clk_src, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup6_i2c_apps_clk_src", + .parent_data = gcc_xo_gpll0_gpll0_out_main_div2, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup6_spi_apps_clk_src = { + .cmd_rcgr = 0x07014, + .freq_tbl = ftbl_blsp1_qup_spi_apps_clk_src, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup6_spi_apps_clk_src", + .parent_data = gcc_xo_gpll0_gpll0_out_main_div2, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_blsp1_uart_apps_clk_src[] = { + F(3686400, P_GPLL0_DIV2, 1, 144, 15625), + F(7372800, P_GPLL0_DIV2, 1, 288, 15625), + F(14745600, P_GPLL0_DIV2, 1, 576, 15625), + F(16000000, P_GPLL0_DIV2, 5, 1, 5), + F(24000000, P_XO, 1, 0, 0), + F(24000000, P_GPLL0, 1, 3, 100), + F(25000000, P_GPLL0, 16, 1, 2), + F(32000000, P_GPLL0, 1, 1, 25), + F(40000000, P_GPLL0, 1, 1, 20), + F(46400000, P_GPLL0, 1, 29, 500), + F(48000000, P_GPLL0, 1, 3, 50), + F(51200000, P_GPLL0, 1, 8, 125), + F(56000000, P_GPLL0, 1, 7, 100), + F(58982400, P_GPLL0, 1, 1152, 15625), + F(60000000, P_GPLL0, 1, 3, 40), + F(64000000, P_GPLL0, 12.5, 1, 1), + { } +}; + +static struct clk_rcg2 blsp1_uart1_apps_clk_src = { + .cmd_rcgr = 0x02044, + .freq_tbl = ftbl_blsp1_uart_apps_clk_src, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_uart1_apps_clk_src", + .parent_data = gcc_xo_gpll0_gpll0_out_main_div2, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_uart2_apps_clk_src = { + .cmd_rcgr = 0x03034, + .freq_tbl = ftbl_blsp1_uart_apps_clk_src, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_uart2_apps_clk_src", + .parent_data = gcc_xo_gpll0_gpll0_out_main_div2, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_uart3_apps_clk_src = { + .cmd_rcgr = 0x04034, + .freq_tbl = ftbl_blsp1_uart_apps_clk_src, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_uart3_apps_clk_src", + .parent_data = gcc_xo_gpll0_gpll0_out_main_div2, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_uart4_apps_clk_src = { + .cmd_rcgr = 0x05034, + .freq_tbl = ftbl_blsp1_uart_apps_clk_src, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_uart4_apps_clk_src", + .parent_data = gcc_xo_gpll0_gpll0_out_main_div2, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_uart5_apps_clk_src = { + .cmd_rcgr = 0x06034, + .freq_tbl = ftbl_blsp1_uart_apps_clk_src, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_uart5_apps_clk_src", + .parent_data = gcc_xo_gpll0_gpll0_out_main_div2, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_uart6_apps_clk_src = { + .cmd_rcgr = 0x07034, + .freq_tbl = ftbl_blsp1_uart_apps_clk_src, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_uart6_apps_clk_src", + .parent_data = gcc_xo_gpll0_gpll0_out_main_div2, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_crypto_clk_src[] = { + F(40000000, P_GPLL0_DIV2, 10, 0, 0), + F(80000000, P_GPLL0, 10, 0, 0), + F(100000000, P_GPLL0, 8, 0, 0), + F(160000000, P_GPLL0, 5, 0, 0), + { } +}; + +static struct clk_rcg2 crypto_clk_src = { + .cmd_rcgr = 0x16004, + .freq_tbl = ftbl_crypto_clk_src, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "crypto_clk_src", + .parent_data = gcc_xo_gpll0_gpll0_out_main_div2, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gp_clk_src[] = { + F(24000000, P_XO, 1, 0, 0), + F(50000000, P_GPLL0_DIV2, 8, 0, 0), + F(100000000, P_GPLL0, 8, 0, 0), + F(200000000, P_GPLL0, 4, 0, 0), + F(266666666, P_GPLL0, 3, 0, 0), + { } +}; + +static const struct clk_parent_data gcc_xo_gpll0_gpll6_gpll0_sleep_clk[] = { + { .fw_name = "xo" }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll6.clkr.hw }, + { .hw = &gpll0_out_main_div2.hw }, + { .fw_name = "sleep_clk" }, +}; + +static const struct parent_map gcc_xo_gpll0_gpll6_gpll0_sleep_clk_map[] = { + { P_XO, 0 }, + { P_GPLL0, 1 }, + { P_GPLL6, 2 }, + { P_GPLL0_DIV2, 4 }, + { P_SLEEP_CLK, 6 }, +}; + +static struct clk_rcg2 gp1_clk_src = { + .cmd_rcgr = 0x08004, + .freq_tbl = ftbl_gp_clk_src, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll6_gpll0_sleep_clk_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gp1_clk_src", + .parent_data = gcc_xo_gpll0_gpll6_gpll0_sleep_clk, + .num_parents = 5, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gp2_clk_src = { + .cmd_rcgr = 0x09004, + .freq_tbl = ftbl_gp_clk_src, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll6_gpll0_sleep_clk_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gp2_clk_src", + .parent_data = gcc_xo_gpll0_gpll6_gpll0_sleep_clk, + .num_parents = 5, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gp3_clk_src = { + .cmd_rcgr = 0x0a004, + .freq_tbl = ftbl_gp_clk_src, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll6_gpll0_sleep_clk_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gp3_clk_src", + .parent_data = gcc_xo_gpll0_gpll6_gpll0_sleep_clk, + .num_parents = 5, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_fixed_factor nss_ppe_cdiv_clk_src = { + .mult = 1, + .div = 4, + .hw.init = &(struct clk_init_data){ + .name = "nss_ppe_cdiv_clk_src", + .parent_hws = (const struct clk_hw *[]){ + &nss_ppe_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_fixed_factor_ops, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap_div nss_ubi0_div_clk_src = { + .reg = 0x68118, + .shift = 0, + .width = 4, + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "nss_ubi0_div_clk_src", + .parent_hws = (const struct clk_hw *[]){ + &nss_ubi0_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_regmap_div_ro_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static const struct freq_tbl ftbl_pcie_aux_clk_src[] = { + F(24000000, P_XO, 1, 0, 0), +}; + +static const struct clk_parent_data gcc_xo_gpll0_core_pi_sleep_clk[] = { + { .fw_name = "xo" }, + { .hw = &gpll0.clkr.hw }, + { .fw_name = "sleep_clk" }, +}; + +static const struct parent_map gcc_xo_gpll0_core_pi_sleep_clk_map[] = { + { P_XO, 0 }, + { P_GPLL0, 2 }, + { P_PI_SLEEP, 6 }, +}; + +static struct clk_rcg2 pcie0_aux_clk_src = { + .cmd_rcgr = 0x75024, + .freq_tbl = ftbl_pcie_aux_clk_src, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_core_pi_sleep_clk_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "pcie0_aux_clk_src", + .parent_data = gcc_xo_gpll0_core_pi_sleep_clk, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct clk_parent_data gcc_pcie20_phy0_pipe_clk_xo[] = { + { .fw_name = "pcie20_phy0_pipe_clk" }, + { .fw_name = "xo" }, +}; + +static const struct parent_map gcc_pcie20_phy0_pipe_clk_xo_map[] = { + { P_PCIE20_PHY0_PIPE, 0 }, + { P_XO, 2 }, +}; + +static struct clk_regmap_mux pcie0_pipe_clk_src = { + .reg = 0x7501c, + .shift = 8, + .width = 2, + .parent_map = gcc_pcie20_phy0_pipe_clk_xo_map, + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "pcie0_pipe_clk_src", + .parent_data = gcc_pcie20_phy0_pipe_clk_xo, + .num_parents = 2, + .ops = &clk_regmap_mux_closest_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static const struct freq_tbl ftbl_sdcc_apps_clk_src[] = { + F(144000, P_XO, 16, 12, 125), + F(400000, P_XO, 12, 1, 5), + F(24000000, P_GPLL2, 12, 1, 4), + F(48000000, P_GPLL2, 12, 1, 2), + F(96000000, P_GPLL2, 12, 0, 0), + F(177777778, P_GPLL0, 4.5, 0, 0), + F(192000000, P_GPLL2, 6, 0, 0), + F(384000000, P_GPLL2, 3, 0, 0), + { } +}; + +static const struct clk_parent_data + gcc_xo_gpll0_gpll2_gpll0_out_main_div2[] = { + { .fw_name = "xo" }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll2.clkr.hw }, + { .hw = &gpll0_out_main_div2.hw }, +}; + +static const struct parent_map gcc_xo_gpll0_gpll2_gpll0_out_main_div2_map[] = { + { P_XO, 0 }, + { P_GPLL0, 1 }, + { P_GPLL2, 2 }, + { P_GPLL0_DIV2, 4 }, +}; + +static struct clk_rcg2 sdcc1_apps_clk_src = { + .cmd_rcgr = 0x42004, + .freq_tbl = ftbl_sdcc_apps_clk_src, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll2_gpll0_out_main_div2_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "sdcc1_apps_clk_src", + .parent_data = gcc_xo_gpll0_gpll2_gpll0_out_main_div2, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_usb_aux_clk_src[] = { + F(24000000, P_XO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 usb0_aux_clk_src = { + .cmd_rcgr = 0x3e05c, + .freq_tbl = ftbl_usb_aux_clk_src, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_core_pi_sleep_clk_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "usb0_aux_clk_src", + .parent_data = gcc_xo_gpll0_core_pi_sleep_clk, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_usb_mock_utmi_clk_src[] = { + F(24000000, P_XO, 1, 0, 0), + F(60000000, P_GPLL6, 6, 1, 3), + { } +}; + +static const struct clk_parent_data + gcc_xo_gpll6_gpll0_gpll0_out_main_div2[] = { + { .fw_name = "xo" }, + { .hw = &gpll6.clkr.hw }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll0_out_main_div2.hw }, +}; + +static const struct parent_map gcc_xo_gpll6_gpll0_gpll0_out_main_div2_map[] = { + { P_XO, 0 }, + { P_GPLL6, 1 }, + { P_GPLL0, 3 }, + { P_GPLL0_DIV2, 4 }, +}; + +static struct clk_rcg2 usb0_mock_utmi_clk_src = { + .cmd_rcgr = 0x3e020, + .freq_tbl = ftbl_usb_mock_utmi_clk_src, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll6_gpll0_gpll0_out_main_div2_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "usb0_mock_utmi_clk_src", + .parent_data = gcc_xo_gpll6_gpll0_gpll0_out_main_div2, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct clk_parent_data gcc_usb3phy_0_cc_pipe_clk_xo[] = { + { .fw_name = "usb3phy_0_cc_pipe_clk" }, + { .fw_name = "xo" }, +}; + +static const struct parent_map gcc_usb3phy_0_cc_pipe_clk_xo_map[] = { + { P_USB3PHY_0_PIPE, 0 }, + { P_XO, 2 }, +}; + +static struct clk_regmap_mux usb0_pipe_clk_src = { + .reg = 0x3e048, + .shift = 8, + .width = 2, + .parent_map = gcc_usb3phy_0_cc_pipe_clk_xo_map, + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "usb0_pipe_clk_src", + .parent_data = gcc_usb3phy_0_cc_pipe_clk_xo, + .num_parents = 2, + .ops = &clk_regmap_mux_closest_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static const struct freq_tbl ftbl_sdcc_ice_core_clk_src[] = { + F(80000000, P_GPLL0_DIV2, 5, 0, 0), + F(160000000, P_GPLL0, 5, 0, 0), + F(216000000, P_GPLL6, 5, 0, 0), + F(308570000, P_GPLL6, 3.5, 0, 0), +}; + +static const struct clk_parent_data gcc_xo_gpll0_gpll6_gpll0_div2[] = { + { .fw_name = "xo"}, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll6.clkr.hw }, + { .hw = &gpll0_out_main_div2.hw }, +}; + +static const struct parent_map gcc_xo_gpll0_gpll6_gpll0_div2_map[] = { + { P_XO, 0 }, + { P_GPLL0, 1 }, + { P_GPLL6, 2 }, + { P_GPLL0_DIV2, 4 }, +}; + +static struct clk_rcg2 sdcc1_ice_core_clk_src = { + .cmd_rcgr = 0x5d000, + .freq_tbl = ftbl_sdcc_ice_core_clk_src, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll6_gpll0_div2_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "sdcc1_ice_core_clk_src", + .parent_data = gcc_xo_gpll0_gpll6_gpll0_div2, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_qdss_stm_clk_src[] = { + F(24000000, P_XO, 1, 0, 0), + F(50000000, P_GPLL0_DIV2, 8, 0, 0), + F(100000000, P_GPLL0, 8, 0, 0), + F(200000000, P_GPLL0, 4, 0, 0), + { } +}; + +static struct clk_rcg2 qdss_stm_clk_src = { + .cmd_rcgr = 0x2902C, + .freq_tbl = ftbl_qdss_stm_clk_src, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "qdss_stm_clk_src", + .parent_data = gcc_xo_gpll0_gpll0_out_main_div2, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_qdss_traceclkin_clk_src[] = { + F(80000000, P_GPLL0_DIV2, 5, 0, 0), + F(160000000, P_GPLL0, 5, 0, 0), + F(300000000, P_GPLL4, 4, 0, 0), + { } +}; + +static const struct clk_parent_data gcc_xo_gpll4_gpll0_gpll0_div2[] = { + { .fw_name = "xo" }, + { .hw = &gpll4.clkr.hw }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll0_out_main_div2.hw }, +}; + +static const struct parent_map gcc_xo_gpll4_gpll0_gpll0_div2_map[] = { + { P_XO, 0 }, + { P_GPLL4, 1 }, + { P_GPLL0, 2 }, + { P_GPLL0_DIV2, 4 }, +}; + +static struct clk_rcg2 qdss_traceclkin_clk_src = { + .cmd_rcgr = 0x29048, + .freq_tbl = ftbl_qdss_traceclkin_clk_src, + .hid_width = 5, + .parent_map = gcc_xo_gpll4_gpll0_gpll0_div2_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "qdss_traceclkin_clk_src", + .parent_data = gcc_xo_gpll4_gpll0_gpll0_div2, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 usb1_mock_utmi_clk_src = { + .cmd_rcgr = 0x3f020, + .freq_tbl = ftbl_usb_mock_utmi_clk_src, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll6_gpll0_gpll0_out_main_div2_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "usb1_mock_utmi_clk_src", + .parent_data = gcc_xo_gpll6_gpll0_gpll0_out_main_div2, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch gcc_adss_pwm_clk = { + .halt_reg = 0x1c020, + .clkr = { + .enable_reg = 0x1c020, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_adss_pwm_clk", + .parent_hws = (const struct clk_hw *[]){ + &adss_pwm_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_apss_ahb_clk = { + .halt_reg = 0x4601c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x0b004, + .enable_mask = BIT(14), + .hw.init = &(struct clk_init_data){ + .name = "gcc_apss_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ + &apss_ahb_postdiv_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static const struct freq_tbl ftbl_system_noc_bfdcd_clk_src[] = { + F(24000000, P_XO, 1, 0, 0), + F(50000000, P_GPLL0_DIV2, 8, 0, 0), + F(100000000, P_GPLL0, 8, 0, 0), + F(133333333, P_GPLL0, 6, 0, 0), + F(160000000, P_GPLL0, 5, 0, 0), + F(200000000, P_GPLL0, 4, 0, 0), + F(266666667, P_GPLL0, 3, 0, 0), + { } +}; + +static struct clk_rcg2 system_noc_bfdcd_clk_src = { + .cmd_rcgr = 0x26004, + .freq_tbl = ftbl_system_noc_bfdcd_clk_src, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll6_gpll0_out_main_div2_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "system_noc_bfdcd_clk_src", + .parent_data = gcc_xo_gpll0_gpll6_gpll0_out_main_div2, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_ubi32_mem_noc_bfdcd_clk_src[] = { + F(24000000, P_XO, 1, 0, 0), + F(307670000, P_BIAS_PLL_NSS_NOC, 1.5, 0, 0), + F(533333333, P_GPLL0, 1.5, 0, 0), + { } +}; + +static const struct clk_parent_data + gcc_xo_gpll0_gpll2_bias_pll_nss_noc_clk[] = { + { .fw_name = "xo" }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll2.clkr.hw }, + { .fw_name = "bias_pll_nss_noc_clk" }, +}; + +static const struct parent_map gcc_xo_gpll0_gpll2_bias_pll_nss_noc_clk_map[] = { + { P_XO, 0 }, + { P_GPLL0, 1 }, + { P_GPLL2, 3 }, + { P_BIAS_PLL_NSS_NOC, 4 }, +}; + +static struct clk_rcg2 ubi32_mem_noc_bfdcd_clk_src = { + .cmd_rcgr = 0x68088, + .freq_tbl = ftbl_ubi32_mem_noc_bfdcd_clk_src, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll2_bias_pll_nss_noc_clk_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "ubi32_mem_noc_bfdcd_clk_src", + .parent_data = gcc_xo_gpll0_gpll2_bias_pll_nss_noc_clk, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch gcc_apss_axi_clk = { + .halt_reg = 0x46020, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x0b004, + .enable_mask = BIT(13), + .hw.init = &(struct clk_init_data){ + .name = "gcc_apss_axi_clk", + .parent_hws = (const struct clk_hw *[]){ + &apss_axi_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_ahb_clk = { + .halt_reg = 0x01008, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x0b004, + .enable_mask = BIT(10), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ + &pcnoc_bfdcd_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup1_i2c_apps_clk = { + .halt_reg = 0x02008, + .clkr = { + .enable_reg = 0x02008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup1_i2c_apps_clk", + .parent_hws = (const struct clk_hw *[]){ + &blsp1_qup1_i2c_apps_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup1_spi_apps_clk = { + .halt_reg = 0x02004, + .clkr = { + .enable_reg = 0x02004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup1_spi_apps_clk", + .parent_hws = (const struct clk_hw *[]){ + &blsp1_qup1_spi_apps_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup2_i2c_apps_clk = { + .halt_reg = 0x03010, + .clkr = { + .enable_reg = 0x03010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup2_i2c_apps_clk", + .parent_hws = (const struct clk_hw *[]){ + &blsp1_qup2_i2c_apps_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup2_spi_apps_clk = { + .halt_reg = 0x0300c, + .clkr = { + .enable_reg = 0x0300c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup2_spi_apps_clk", + .parent_hws = (const struct clk_hw *[]){ + &blsp1_qup2_spi_apps_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup3_i2c_apps_clk = { + .halt_reg = 0x04010, + .clkr = { + .enable_reg = 0x04010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup3_i2c_apps_clk", + .parent_hws = (const struct clk_hw *[]){ + &blsp1_qup3_i2c_apps_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup3_spi_apps_clk = { + .halt_reg = 0x0400c, + .clkr = { + .enable_reg = 0x0400c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup3_spi_apps_clk", + .parent_hws = (const struct clk_hw *[]){ + &blsp1_qup3_spi_apps_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup4_i2c_apps_clk = { + .halt_reg = 0x05010, + .clkr = { + .enable_reg = 0x05010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup4_i2c_apps_clk", + .parent_hws = (const struct clk_hw *[]){ + &blsp1_qup4_i2c_apps_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup4_spi_apps_clk = { + .halt_reg = 0x0500c, + .clkr = { + .enable_reg = 0x0500c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup4_spi_apps_clk", + .parent_hws = (const struct clk_hw *[]){ + &blsp1_qup4_spi_apps_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup5_i2c_apps_clk = { + .halt_reg = 0x06010, + .clkr = { + .enable_reg = 0x06010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup5_i2c_apps_clk", + .parent_hws = (const struct clk_hw *[]){ + &blsp1_qup5_i2c_apps_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup5_spi_apps_clk = { + .halt_reg = 0x0600c, + .clkr = { + .enable_reg = 0x0600c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup5_spi_apps_clk", + .parent_hws = (const struct clk_hw *[]){ + &blsp1_qup5_spi_apps_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup6_spi_apps_clk = { + .halt_reg = 0x0700c, + .clkr = { + .enable_reg = 0x0700c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup6_spi_apps_clk", + .parent_hws = (const struct clk_hw *[]){ + &blsp1_qup6_spi_apps_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_uart1_apps_clk = { + .halt_reg = 0x0203c, + .clkr = { + .enable_reg = 0x0203c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_uart1_apps_clk", + .parent_hws = (const struct clk_hw *[]){ + &blsp1_uart1_apps_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_uart2_apps_clk = { + .halt_reg = 0x0302c, + .clkr = { + .enable_reg = 0x0302c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_uart2_apps_clk", + .parent_hws = (const struct clk_hw *[]){ + &blsp1_uart2_apps_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_uart3_apps_clk = { + .halt_reg = 0x0402c, + .clkr = { + .enable_reg = 0x0402c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_uart3_apps_clk", + .parent_hws = (const struct clk_hw *[]){ + &blsp1_uart3_apps_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_uart4_apps_clk = { + .halt_reg = 0x0502c, + .clkr = { + .enable_reg = 0x0502c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_uart4_apps_clk", + .parent_hws = (const struct clk_hw *[]){ + &blsp1_uart4_apps_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_uart5_apps_clk = { + .halt_reg = 0x0602c, + .clkr = { + .enable_reg = 0x0602c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_uart5_apps_clk", + .parent_hws = (const struct clk_hw *[]){ + &blsp1_uart5_apps_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_uart6_apps_clk = { + .halt_reg = 0x0702c, + .clkr = { + .enable_reg = 0x0702c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_uart6_apps_clk", + .parent_hws = (const struct clk_hw *[]){ + &blsp1_uart6_apps_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_crypto_ahb_clk = { + .halt_reg = 0x16024, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x0b004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_crypto_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ + &pcnoc_bfdcd_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_crypto_axi_clk = { + .halt_reg = 0x16020, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x0b004, + .enable_mask = BIT(1), + .hw.init = &(struct clk_init_data){ + .name = "gcc_crypto_axi_clk", + .parent_hws = (const struct clk_hw *[]){ + &pcnoc_bfdcd_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_crypto_clk = { + .halt_reg = 0x1601c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x0b004, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data){ + .name = "gcc_crypto_clk", + .parent_hws = (const struct clk_hw *[]){ + &crypto_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_fixed_factor gpll6_out_main_div2 = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data){ + .name = "gpll6_out_main_div2", + .parent_hws = (const struct clk_hw *[]){ + &gpll6_main.clkr.hw }, + .num_parents = 1, + .ops = &clk_fixed_factor_ops, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_branch gcc_xo_clk = { + .halt_reg = 0x30030, + .clkr = { + .enable_reg = 0x30030, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_xo_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_xo_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp1_clk = { + .halt_reg = 0x08000, + .clkr = { + .enable_reg = 0x08000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gp1_clk", + .parent_hws = (const struct clk_hw *[]){ + &gp1_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp2_clk = { + .halt_reg = 0x09000, + .clkr = { + .enable_reg = 0x09000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gp2_clk", + .parent_hws = (const struct clk_hw *[]){ + &gp2_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp3_clk = { + .halt_reg = 0x0a000, + .clkr = { + .enable_reg = 0x0a000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gp3_clk", + .parent_hws = (const struct clk_hw *[]){ + &gp3_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mdio_ahb_clk = { + .halt_reg = 0x58004, + .clkr = { + .enable_reg = 0x58004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mdio_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ + &pcnoc_bfdcd_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_crypto_ppe_clk = { + .halt_reg = 0x68310, + .clkr = { + .enable_reg = 0x68310, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_crypto_ppe_clk", + .parent_hws = (const struct clk_hw *[]){ + &nss_ppe_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_nss_ce_apb_clk = { + .halt_reg = 0x68174, + .clkr = { + .enable_reg = 0x68174, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_nss_ce_apb_clk", + .parent_hws = (const struct clk_hw *[]){ + &nss_ce_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_nss_ce_axi_clk = { + .halt_reg = 0x68170, + .clkr = { + .enable_reg = 0x68170, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_nss_ce_axi_clk", + .parent_hws = (const struct clk_hw *[]){ + &nss_ce_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_nss_cfg_clk = { + .halt_reg = 0x68160, + .clkr = { + .enable_reg = 0x68160, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_nss_cfg_clk", + .parent_hws = (const struct clk_hw *[]){ + &pcnoc_bfdcd_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_nss_crypto_clk = { + .halt_reg = 0x68164, + .clkr = { + .enable_reg = 0x68164, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_nss_crypto_clk", + .parent_hws = (const struct clk_hw *[]){ + &nss_crypto_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_nss_csr_clk = { + .halt_reg = 0x68318, + .clkr = { + .enable_reg = 0x68318, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_nss_csr_clk", + .parent_hws = (const struct clk_hw *[]){ + &nss_ce_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_nss_edma_cfg_clk = { + .halt_reg = 0x6819C, + .clkr = { + .enable_reg = 0x6819C, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_nss_edma_cfg_clk", + .parent_hws = (const struct clk_hw *[]){ + &nss_ppe_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_nss_edma_clk = { + .halt_reg = 0x68198, + .clkr = { + .enable_reg = 0x68198, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_nss_edma_clk", + .parent_hws = (const struct clk_hw *[]){ + &nss_ppe_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_nss_noc_clk = { + .halt_reg = 0x68168, + .clkr = { + .enable_reg = 0x68168, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_nss_noc_clk", + .parent_hws = (const struct clk_hw *[]){ + &snoc_nssnoc_bfdcd_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ubi0_utcm_clk = { + .halt_reg = 0x2606c, + .clkr = { + .enable_reg = 0x2606c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ubi0_utcm_clk", + .parent_hws = (const struct clk_hw *[]){ + &snoc_nssnoc_bfdcd_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_snoc_nssnoc_clk = { + .halt_reg = 0x26070, + .clkr = { + .enable_reg = 0x26070, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_snoc_nssnoc_clk", + .parent_hws = (const struct clk_hw *[]){ + &snoc_nssnoc_bfdcd_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static const struct freq_tbl ftbl_wcss_ahb_clk_src[] = { + F(24000000, P_XO, 1, 0, 0), + F(133333333, P_GPLL0, 6, 0, 0), + { } +}; + +static const struct freq_tbl ftbl_q6_axi_clk_src[] = { + F(24000000, P_XO, 1, 0, 0), + F(400000000, P_GPLL0, 2, 0, 0), + { } +}; + +static struct clk_rcg2 wcss_ahb_clk_src = { + .cmd_rcgr = 0x59020, + .freq_tbl = ftbl_wcss_ahb_clk_src, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "wcss_ahb_clk_src", + .parent_data = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct clk_parent_data gcc_xo_gpll0_gpll2_gpll4_gpll6[] = { + { .fw_name = "xo" }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll2.clkr.hw }, + { .hw = &gpll4.clkr.hw }, + { .hw = &gpll6.clkr.hw }, +}; + +static const struct parent_map gcc_xo_gpll0_gpll2_gpll4_gpll6_map[] = { + { P_XO, 0 }, + { P_GPLL0, 1 }, + { P_GPLL2, 2 }, + { P_GPLL4, 3 }, + { P_GPLL6, 4 }, +}; + +static struct clk_rcg2 q6_axi_clk_src = { + .cmd_rcgr = 0x59120, + .freq_tbl = ftbl_q6_axi_clk_src, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll2_gpll4_gpll6_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "q6_axi_clk_src", + .parent_data = gcc_xo_gpll0_gpll2_gpll4_gpll6, + .num_parents = 5, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_lpass_core_axim_clk_src[] = { + F(24000000, P_XO, 1, 0, 0), + F(100000000, P_GPLL0, 8, 0, 0), + { } +}; + +static struct clk_rcg2 lpass_core_axim_clk_src = { + .cmd_rcgr = 0x1F020, + .freq_tbl = ftbl_lpass_core_axim_clk_src, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "lpass_core_axim_clk_src", + .parent_data = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_lpass_snoc_cfg_clk_src[] = { + F(24000000, P_XO, 1, 0, 0), + F(266666667, P_GPLL0, 3, 0, 0), + { } +}; + +static struct clk_rcg2 lpass_snoc_cfg_clk_src = { + .cmd_rcgr = 0x1F040, + .freq_tbl = ftbl_lpass_snoc_cfg_clk_src, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "lpass_snoc_cfg_clk_src", + .parent_data = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_lpass_q6_axim_clk_src[] = { + F(24000000, P_XO, 1, 0, 0), + F(400000000, P_GPLL0, 2, 0, 0), + { } +}; + +static struct clk_rcg2 lpass_q6_axim_clk_src = { + .cmd_rcgr = 0x1F008, + .freq_tbl = ftbl_lpass_q6_axim_clk_src, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "lpass_q6_axim_clk_src", + .parent_data = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct freq_tbl ftbl_rbcpr_wcss_clk_src[] = { + F(24000000, P_XO, 1, 0, 0), + F(50000000, P_GPLL0, 16, 0, 0), + { } +}; + +static struct clk_rcg2 rbcpr_wcss_clk_src = { + .cmd_rcgr = 0x3a00c, + .freq_tbl = ftbl_rbcpr_wcss_clk_src, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_out_main_div2_gpll0_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "rbcpr_wcss_clk_src", + .parent_data = gcc_xo_gpll0_out_main_div2_gpll0, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch gcc_lpass_core_axim_clk = { + .halt_reg = 0x1F028, + .clkr = { + .enable_reg = 0x1F028, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_lpass_core_axim_clk", + .parent_hws = (const struct clk_hw *[]){ + &lpass_core_axim_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_lpass_snoc_cfg_clk = { + .halt_reg = 0x1F048, + .clkr = { + .enable_reg = 0x1F048, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_lpass_snoc_cfg_clk", + .parent_hws = (const struct clk_hw *[]){ + &lpass_snoc_cfg_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_lpass_q6_axim_clk = { + .halt_reg = 0x1F010, + .clkr = { + .enable_reg = 0x1F010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_lpass_q6_axim_clk", + .parent_hws = (const struct clk_hw *[]){ + &lpass_q6_axim_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_lpass_q6_atbm_at_clk = { + .halt_reg = 0x1F018, + .clkr = { + .enable_reg = 0x1F018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_lpass_q6_atbm_at_clk", + .parent_hws = (const struct clk_hw *[]){ + &qdss_at_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_lpass_q6_pclkdbg_clk = { + .halt_reg = 0x1F01C, + .clkr = { + .enable_reg = 0x1F01C, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_lpass_q6_pclkdbg_clk", + .parent_hws = (const struct clk_hw *[]){ + &qdss_dap_sync_clk_src.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_lpass_q6ss_tsctr_1to2_clk = { + .halt_reg = 0x1F014, + .clkr = { + .enable_reg = 0x1F014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_lpass_q6ss_tsctr_1to2_clk", + .parent_hws = (const struct clk_hw *[]){ + &qdss_tsctr_div2_clk_src.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_lpass_q6ss_trig_clk = { + .halt_reg = 0x1F038, + .clkr = { + .enable_reg = 0x1F038, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_lpass_q6ss_trig_clk", + .parent_hws = (const struct clk_hw *[]){ + &qdss_dap_sync_clk_src.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_lpass_tbu_clk = { + .halt_reg = 0x12094, + .clkr = { + .enable_reg = 0xb00c, + .enable_mask = BIT(10), + .hw.init = &(struct clk_init_data){ + .name = "gcc_lpass_tbu_clk", + .parent_hws = (const struct clk_hw *[]){ + &lpass_q6_axim_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcnoc_lpass_clk = { + .halt_reg = 0x27020, + .clkr = { + .enable_reg = 0x27020, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcnoc_lpass_clk", + .parent_hws = (const struct clk_hw *[]){ + &lpass_core_axim_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mem_noc_lpass_clk = { + .halt_reg = 0x1D044, + .clkr = { + .enable_reg = 0x1D044, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mem_noc_lpass_clk", + .parent_hws = (const struct clk_hw *[]){ + &lpass_q6_axim_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_snoc_lpass_cfg_clk = { + .halt_reg = 0x26074, + .clkr = { + .enable_reg = 0x26074, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_snoc_lpass_cfg_clk", + .parent_hws = (const struct clk_hw *[]){ + &lpass_snoc_cfg_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mem_noc_ubi32_clk = { + .halt_reg = 0x1D03C, + .clkr = { + .enable_reg = 0x1D03C, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mem_noc_ubi32_clk", + .parent_hws = (const struct clk_hw *[]){ + &ubi32_mem_noc_bfdcd_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_nss_port1_rx_clk = { + .halt_reg = 0x68240, + .clkr = { + .enable_reg = 0x68240, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_nss_port1_rx_clk", + .parent_hws = (const struct clk_hw *[]){ + &nss_port1_rx_div_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_nss_port1_tx_clk = { + .halt_reg = 0x68244, + .clkr = { + .enable_reg = 0x68244, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_nss_port1_tx_clk", + .parent_hws = (const struct clk_hw *[]){ + &nss_port1_tx_div_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_nss_port2_rx_clk = { + .halt_reg = 0x68248, + .clkr = { + .enable_reg = 0x68248, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_nss_port2_rx_clk", + .parent_hws = (const struct clk_hw *[]){ + &nss_port2_rx_div_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_nss_port2_tx_clk = { + .halt_reg = 0x6824c, + .clkr = { + .enable_reg = 0x6824c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_nss_port2_tx_clk", + .parent_hws = (const struct clk_hw *[]){ + &nss_port2_tx_div_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_nss_port3_rx_clk = { + .halt_reg = 0x68250, + .clkr = { + .enable_reg = 0x68250, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_nss_port3_rx_clk", + .parent_hws = (const struct clk_hw *[]){ + &nss_port3_rx_div_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_nss_port3_tx_clk = { + .halt_reg = 0x68254, + .clkr = { + .enable_reg = 0x68254, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_nss_port3_tx_clk", + .parent_hws = (const struct clk_hw *[]){ + &nss_port3_tx_div_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_nss_port4_rx_clk = { + .halt_reg = 0x68258, + .clkr = { + .enable_reg = 0x68258, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_nss_port4_rx_clk", + .parent_hws = (const struct clk_hw *[]){ + &nss_port4_rx_div_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_nss_port4_tx_clk = { + .halt_reg = 0x6825c, + .clkr = { + .enable_reg = 0x6825c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_nss_port4_tx_clk", + .parent_hws = (const struct clk_hw *[]){ + &nss_port4_tx_div_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_nss_port5_rx_clk = { + .halt_reg = 0x68260, + .clkr = { + .enable_reg = 0x68260, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_nss_port5_rx_clk", + .parent_hws = (const struct clk_hw *[]){ + &nss_port5_rx_div_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_nss_port5_tx_clk = { + .halt_reg = 0x68264, + .clkr = { + .enable_reg = 0x68264, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_nss_port5_tx_clk", + .parent_hws = (const struct clk_hw *[]){ + &nss_port5_tx_div_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_nss_ppe_cfg_clk = { + .halt_reg = 0x68194, + .clkr = { + .enable_reg = 0x68194, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_nss_ppe_cfg_clk", + .parent_hws = (const struct clk_hw *[]){ + &nss_ppe_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_nss_ppe_clk = { + .halt_reg = 0x68190, + .clkr = { + .enable_reg = 0x68190, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_nss_ppe_clk", + .parent_hws = (const struct clk_hw *[]){ + &nss_ppe_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_nss_ppe_ipe_clk = { + .halt_reg = 0x68338, + .clkr = { + .enable_reg = 0x68338, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_nss_ppe_ipe_clk", + .parent_hws = (const struct clk_hw *[]){ + &nss_ppe_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_nss_ptp_ref_clk = { + .halt_reg = 0x6816C, + .clkr = { + .enable_reg = 0x6816C, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_nss_ptp_ref_clk", + .parent_hws = (const struct clk_hw *[]){ + &nss_ppe_cdiv_clk_src.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_nssnoc_ce_apb_clk = { + .halt_reg = 0x6830C, + .clkr = { + .enable_reg = 0x6830C, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_nssnoc_ce_apb_clk", + .parent_hws = (const struct clk_hw *[]){ + &nss_ce_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_nssnoc_ce_axi_clk = { + .halt_reg = 0x68308, + .clkr = { + .enable_reg = 0x68308, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_nssnoc_ce_axi_clk", + .parent_hws = (const struct clk_hw *[]){ + &nss_ce_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_nssnoc_crypto_clk = { + .halt_reg = 0x68314, + .clkr = { + .enable_reg = 0x68314, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_nssnoc_crypto_clk", + .parent_hws = (const struct clk_hw *[]){ + &nss_crypto_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_nssnoc_ppe_cfg_clk = { + .halt_reg = 0x68304, + .clkr = { + .enable_reg = 0x68304, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_nssnoc_ppe_cfg_clk", + .parent_hws = (const struct clk_hw *[]){ + &nss_ppe_clk_src.clkr.hw }, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_nssnoc_ppe_clk = { + .halt_reg = 0x68300, + .clkr = { + .enable_reg = 0x68300, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_nssnoc_ppe_clk", + .parent_hws = (const struct clk_hw *[]){ + &nss_ppe_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_nssnoc_qosgen_ref_clk = { + .halt_reg = 0x68180, + .clkr = { + .enable_reg = 0x68180, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_nssnoc_qosgen_ref_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_xo_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_nssnoc_snoc_clk = { + .halt_reg = 0x68188, + .clkr = { + .enable_reg = 0x68188, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_nssnoc_snoc_clk", + .parent_hws = (const struct clk_hw *[]){ + &system_noc_bfdcd_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_nssnoc_timeout_ref_clk = { + .halt_reg = 0x68184, + .clkr = { + .enable_reg = 0x68184, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_nssnoc_timeout_ref_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_xo_div4_clk_src.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_nssnoc_ubi0_ahb_clk = { + .halt_reg = 0x68270, + .clkr = { + .enable_reg = 0x68270, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_nssnoc_ubi0_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ + &nss_ce_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_port1_mac_clk = { + .halt_reg = 0x68320, + .clkr = { + .enable_reg = 0x68320, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_port1_mac_clk", + .parent_hws = (const struct clk_hw *[]){ + &nss_ppe_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_port2_mac_clk = { + .halt_reg = 0x68324, + .clkr = { + .enable_reg = 0x68324, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_port2_mac_clk", + .parent_hws = (const struct clk_hw *[]){ + &nss_ppe_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_port3_mac_clk = { + .halt_reg = 0x68328, + .clkr = { + .enable_reg = 0x68328, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_port3_mac_clk", + .parent_hws = (const struct clk_hw *[]){ + &nss_ppe_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_port4_mac_clk = { + .halt_reg = 0x6832c, + .clkr = { + .enable_reg = 0x6832c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_port4_mac_clk", + .parent_hws = (const struct clk_hw *[]){ + &nss_ppe_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_port5_mac_clk = { + .halt_reg = 0x68330, + .clkr = { + .enable_reg = 0x68330, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_port5_mac_clk", + .parent_hws = (const struct clk_hw *[]){ + &nss_ppe_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ubi0_ahb_clk = { + .halt_reg = 0x6820C, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x6820C, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ubi0_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ + &nss_ce_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ubi0_axi_clk = { + .halt_reg = 0x68200, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x68200, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ubi0_axi_clk", + .parent_hws = (const struct clk_hw *[]){ + &ubi32_mem_noc_bfdcd_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ubi0_nc_axi_clk = { + .halt_reg = 0x68204, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x68204, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ubi0_nc_axi_clk", + .parent_hws = (const struct clk_hw *[]){ + &snoc_nssnoc_bfdcd_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ubi0_core_clk = { + .halt_reg = 0x68210, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x68210, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ubi0_core_clk", + .parent_hws = (const struct clk_hw *[]){ + &nss_ubi0_div_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie0_ahb_clk = { + .halt_reg = 0x75010, + .clkr = { + .enable_reg = 0x75010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie0_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ + &pcnoc_bfdcd_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie0_aux_clk = { + .halt_reg = 0x75014, + .clkr = { + .enable_reg = 0x75014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie0_aux_clk", + .parent_hws = (const struct clk_hw *[]){ + &pcie0_aux_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie0_axi_m_clk = { + .halt_reg = 0x75008, + .clkr = { + .enable_reg = 0x75008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie0_axi_m_clk", + .parent_hws = (const struct clk_hw *[]){ + &pcie0_axi_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie0_axi_s_clk = { + .halt_reg = 0x7500c, + .clkr = { + .enable_reg = 0x7500c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie0_axi_s_clk", + .parent_hws = (const struct clk_hw *[]){ + &pcie0_axi_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sys_noc_pcie0_axi_clk = { + .halt_reg = 0x26048, + .clkr = { + .enable_reg = 0x26048, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sys_noc_pcie0_axi_clk", + .parent_hws = (const struct clk_hw *[]){ + &pcie0_axi_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie0_pipe_clk = { + .halt_reg = 0x75018, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x75018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie0_pipe_clk", + .parent_hws = (const struct clk_hw *[]){ + &pcie0_pipe_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_prng_ahb_clk = { + .halt_reg = 0x13004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x0b004, + .enable_mask = BIT(8), + .hw.init = &(struct clk_init_data){ + .name = "gcc_prng_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ + &pcnoc_bfdcd_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qdss_dap_clk = { + .halt_reg = 0x29084, + .clkr = { + .enable_reg = 0x29084, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qdss_dap_clk", + .parent_hws = (const struct clk_hw *[]){ + &qdss_dap_sync_clk_src.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qpic_ahb_clk = { + .halt_reg = 0x57024, + .clkr = { + .enable_reg = 0x57024, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qpic_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ + &pcnoc_bfdcd_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qpic_clk = { + .halt_reg = 0x57020, + .clkr = { + .enable_reg = 0x57020, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qpic_clk", + .parent_hws = (const struct clk_hw *[]){ + &pcnoc_bfdcd_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc1_ahb_clk = { + .halt_reg = 0x4201c, + .clkr = { + .enable_reg = 0x4201c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ + &pcnoc_bfdcd_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc1_apps_clk = { + .halt_reg = 0x42018, + .clkr = { + .enable_reg = 0x42018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_apps_clk", + .parent_hws = (const struct clk_hw *[]){ + &sdcc1_apps_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_uniphy0_ahb_clk = { + .halt_reg = 0x56008, + .clkr = { + .enable_reg = 0x56008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_uniphy0_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ + &pcnoc_bfdcd_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_uniphy0_port1_rx_clk = { + .halt_reg = 0x56010, + .clkr = { + .enable_reg = 0x56010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_uniphy0_port1_rx_clk", + .parent_hws = (const struct clk_hw *[]){ + &nss_port1_rx_div_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_uniphy0_port1_tx_clk = { + .halt_reg = 0x56014, + .clkr = { + .enable_reg = 0x56014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_uniphy0_port1_tx_clk", + .parent_hws = (const struct clk_hw *[]){ + &nss_port1_tx_div_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_uniphy0_port2_rx_clk = { + .halt_reg = 0x56018, + .clkr = { + .enable_reg = 0x56018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_uniphy0_port2_rx_clk", + .parent_hws = (const struct clk_hw *[]){ + &nss_port2_rx_div_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_uniphy0_port2_tx_clk = { + .halt_reg = 0x5601c, + .clkr = { + .enable_reg = 0x5601c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_uniphy0_port2_tx_clk", + .parent_hws = (const struct clk_hw *[]){ + &nss_port2_tx_div_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_uniphy0_port3_rx_clk = { + .halt_reg = 0x56020, + .clkr = { + .enable_reg = 0x56020, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_uniphy0_port3_rx_clk", + .parent_hws = (const struct clk_hw *[]){ + &nss_port3_rx_div_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_uniphy0_port3_tx_clk = { + .halt_reg = 0x56024, + .clkr = { + .enable_reg = 0x56024, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_uniphy0_port3_tx_clk", + .parent_hws = (const struct clk_hw *[]){ + &nss_port3_tx_div_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_uniphy0_port4_rx_clk = { + .halt_reg = 0x56028, + .clkr = { + .enable_reg = 0x56028, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_uniphy0_port4_rx_clk", + .parent_hws = (const struct clk_hw *[]){ + &nss_port4_rx_div_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_uniphy0_port4_tx_clk = { + .halt_reg = 0x5602c, + .clkr = { + .enable_reg = 0x5602c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_uniphy0_port4_tx_clk", + .parent_hws = (const struct clk_hw *[]){ + &nss_port4_tx_div_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_uniphy0_port5_rx_clk = { + .halt_reg = 0x56030, + .clkr = { + .enable_reg = 0x56030, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_uniphy0_port5_rx_clk", + .parent_hws = (const struct clk_hw *[]){ + &nss_port5_rx_div_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_uniphy0_port5_tx_clk = { + .halt_reg = 0x56034, + .clkr = { + .enable_reg = 0x56034, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_uniphy0_port5_tx_clk", + .parent_hws = (const struct clk_hw *[]){ + &nss_port5_tx_div_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_uniphy0_sys_clk = { + .halt_reg = 0x5600C, + .clkr = { + .enable_reg = 0x5600C, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_uniphy0_sys_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_xo_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_uniphy1_ahb_clk = { + .halt_reg = 0x56108, + .clkr = { + .enable_reg = 0x56108, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_uniphy1_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ + &pcnoc_bfdcd_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_uniphy1_port5_rx_clk = { + .halt_reg = 0x56110, + .clkr = { + .enable_reg = 0x56110, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_uniphy1_port5_rx_clk", + .parent_hws = (const struct clk_hw *[]){ + &nss_port5_rx_div_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_uniphy1_port5_tx_clk = { + .halt_reg = 0x56114, + .clkr = { + .enable_reg = 0x56114, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_uniphy1_port5_tx_clk", + .parent_hws = (const struct clk_hw *[]){ + &nss_port5_tx_div_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_uniphy1_sys_clk = { + .halt_reg = 0x5610C, + .clkr = { + .enable_reg = 0x5610C, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_uniphy1_sys_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_xo_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb0_aux_clk = { + .halt_reg = 0x3e044, + .clkr = { + .enable_reg = 0x3e044, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb0_aux_clk", + .parent_hws = (const struct clk_hw *[]){ + &usb0_aux_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb0_master_clk = { + .halt_reg = 0x3e000, + .clkr = { + .enable_reg = 0x3e000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb0_master_clk", + .parent_hws = (const struct clk_hw *[]){ + &usb0_master_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_snoc_bus_timeout2_ahb_clk = { + .halt_reg = 0x47014, + .clkr = { + .enable_reg = 0x47014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_snoc_bus_timeout2_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ + &usb0_master_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_rcg2 pcie0_rchng_clk_src = { + .cmd_rcgr = 0x75070, + .freq_tbl = ftbl_pcie_rchng_clk_src, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "pcie0_rchng_clk_src", + .parent_data = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch gcc_pcie0_rchng_clk = { + .halt_reg = 0x75070, + .clkr = { + .enable_reg = 0x75070, + .enable_mask = BIT(1), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie0_rchng_clk", + .parent_hws = (const struct clk_hw *[]){ + &pcie0_rchng_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie0_axi_s_bridge_clk = { + .halt_reg = 0x75048, + .clkr = { + .enable_reg = 0x75048, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie0_axi_s_bridge_clk", + .parent_hws = (const struct clk_hw *[]){ + &pcie0_axi_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sys_noc_usb0_axi_clk = { + .halt_reg = 0x26040, + .clkr = { + .enable_reg = 0x26040, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sys_noc_usb0_axi_clk", + .parent_hws = (const struct clk_hw *[]){ + &usb0_master_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb0_mock_utmi_clk = { + .halt_reg = 0x3e008, + .clkr = { + .enable_reg = 0x3e008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb0_mock_utmi_clk", + .parent_hws = (const struct clk_hw *[]){ + &usb0_mock_utmi_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb0_phy_cfg_ahb_clk = { + .halt_reg = 0x3e080, + .clkr = { + .enable_reg = 0x3e080, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb0_phy_cfg_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ + &pcnoc_bfdcd_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb0_pipe_clk = { + .halt_reg = 0x3e040, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x3e040, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb0_pipe_clk", + .parent_hws = (const struct clk_hw *[]){ + &usb0_pipe_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb0_sleep_clk = { + .halt_reg = 0x3e004, + .clkr = { + .enable_reg = 0x3e004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb0_sleep_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_sleep_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb1_master_clk = { + .halt_reg = 0x3f000, + .clkr = { + .enable_reg = 0x3f000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb1_master_clk", + .parent_hws = (const struct clk_hw *[]){ + &pcnoc_bfdcd_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb1_mock_utmi_clk = { + .halt_reg = 0x3f008, + .clkr = { + .enable_reg = 0x3f008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb1_mock_utmi_clk", + .parent_hws = (const struct clk_hw *[]){ + &usb1_mock_utmi_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb1_phy_cfg_ahb_clk = { + .halt_reg = 0x3f080, + .clkr = { + .enable_reg = 0x3f080, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb1_phy_cfg_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ + &pcnoc_bfdcd_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb1_sleep_clk = { + .halt_reg = 0x3f004, + .clkr = { + .enable_reg = 0x3f004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb1_sleep_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_sleep_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cmn_12gpll_ahb_clk = { + .halt_reg = 0x56308, + .clkr = { + .enable_reg = 0x56308, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_cmn_12gpll_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ + &pcnoc_bfdcd_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cmn_12gpll_sys_clk = { + .halt_reg = 0x5630c, + .clkr = { + .enable_reg = 0x5630c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_cmn_12gpll_sys_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_xo_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc1_ice_core_clk = { + .halt_reg = 0x5d014, + .clkr = { + .enable_reg = 0x5d014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_ice_core_clk", + .parent_hws = (const struct clk_hw *[]){ + &sdcc1_ice_core_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_dcc_clk = { + .halt_reg = 0x77004, + .clkr = { + .enable_reg = 0x77004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_dcc_clk", + .parent_hws = (const struct clk_hw *[]){ + &pcnoc_bfdcd_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static const struct alpha_pll_config ubi32_pll_config = { + .l = 0x3e, + .alpha = 0x57, + .config_ctl_val = 0x240d6aa8, + .config_ctl_hi_val = 0x3c2, + .main_output_mask = BIT(0), + .aux_output_mask = BIT(1), + .pre_div_val = 0x0, + .pre_div_mask = BIT(12), + .post_div_val = 0x0, + .post_div_mask = GENMASK(9, 8), +}; + +static const struct alpha_pll_config nss_crypto_pll_config = { + .l = 0x32, + .alpha = 0x0, + .alpha_hi = 0x0, + .config_ctl_val = 0x4001055b, + .main_output_mask = BIT(0), + .pre_div_val = 0x0, + .pre_div_mask = GENMASK(14, 12), + .post_div_val = 0x1 << 8, + .post_div_mask = GENMASK(11, 8), + .vco_mask = GENMASK(21, 20), + .vco_val = 0x0, + .alpha_en_mask = BIT(24), +}; + +static struct clk_hw *gcc_ipq6018_hws[] = { + &gpll0_out_main_div2.hw, + &gcc_xo_div4_clk_src.hw, + &nss_ppe_cdiv_clk_src.hw, + &gpll6_out_main_div2.hw, + &qdss_dap_sync_clk_src.hw, + &qdss_tsctr_div2_clk_src.hw, +}; + +static struct clk_regmap *gcc_ipq6018_clks[] = { + [GPLL0_MAIN] = &gpll0_main.clkr, + [GPLL0] = &gpll0.clkr, + [UBI32_PLL_MAIN] = &ubi32_pll_main.clkr, + [UBI32_PLL] = &ubi32_pll.clkr, + [GPLL6_MAIN] = &gpll6_main.clkr, + [GPLL6] = &gpll6.clkr, + [GPLL4_MAIN] = &gpll4_main.clkr, + [GPLL4] = &gpll4.clkr, + [PCNOC_BFDCD_CLK_SRC] = &pcnoc_bfdcd_clk_src.clkr, + [GPLL2_MAIN] = &gpll2_main.clkr, + [GPLL2] = &gpll2.clkr, + [NSS_CRYPTO_PLL_MAIN] = &nss_crypto_pll_main.clkr, + [NSS_CRYPTO_PLL] = &nss_crypto_pll.clkr, + [QDSS_TSCTR_CLK_SRC] = &qdss_tsctr_clk_src.clkr, + [QDSS_AT_CLK_SRC] = &qdss_at_clk_src.clkr, + [NSS_PPE_CLK_SRC] = &nss_ppe_clk_src.clkr, + [GCC_XO_CLK_SRC] = &gcc_xo_clk_src.clkr, + [SYSTEM_NOC_BFDCD_CLK_SRC] = &system_noc_bfdcd_clk_src.clkr, + [SNOC_NSSNOC_BFDCD_CLK_SRC] = &snoc_nssnoc_bfdcd_clk_src.clkr, + [NSS_CE_CLK_SRC] = &nss_ce_clk_src.clkr, + [GCC_SLEEP_CLK_SRC] = &gcc_sleep_clk_src.clkr, + [APSS_AHB_CLK_SRC] = &apss_ahb_clk_src.clkr, + [NSS_PORT5_RX_CLK_SRC] = &nss_port5_rx_clk_src.clkr, + [NSS_PORT5_TX_CLK_SRC] = &nss_port5_tx_clk_src.clkr, + [UBI32_MEM_NOC_BFDCD_CLK_SRC] = &ubi32_mem_noc_bfdcd_clk_src.clkr, + [PCIE0_AXI_CLK_SRC] = &pcie0_axi_clk_src.clkr, + [USB0_MASTER_CLK_SRC] = &usb0_master_clk_src.clkr, + [APSS_AHB_POSTDIV_CLK_SRC] = &apss_ahb_postdiv_clk_src.clkr, + [NSS_PORT1_RX_CLK_SRC] = &nss_port1_rx_clk_src.clkr, + [NSS_PORT1_TX_CLK_SRC] = &nss_port1_tx_clk_src.clkr, + [NSS_PORT2_RX_CLK_SRC] = &nss_port2_rx_clk_src.clkr, + [NSS_PORT2_TX_CLK_SRC] = &nss_port2_tx_clk_src.clkr, + [NSS_PORT3_RX_CLK_SRC] = &nss_port3_rx_clk_src.clkr, + [NSS_PORT3_TX_CLK_SRC] = &nss_port3_tx_clk_src.clkr, + [NSS_PORT4_RX_CLK_SRC] = &nss_port4_rx_clk_src.clkr, + [NSS_PORT4_TX_CLK_SRC] = &nss_port4_tx_clk_src.clkr, + [NSS_PORT5_RX_DIV_CLK_SRC] = &nss_port5_rx_div_clk_src.clkr, + [NSS_PORT5_TX_DIV_CLK_SRC] = &nss_port5_tx_div_clk_src.clkr, + [APSS_AXI_CLK_SRC] = &apss_axi_clk_src.clkr, + [NSS_CRYPTO_CLK_SRC] = &nss_crypto_clk_src.clkr, + [NSS_PORT1_RX_DIV_CLK_SRC] = &nss_port1_rx_div_clk_src.clkr, + [NSS_PORT1_TX_DIV_CLK_SRC] = &nss_port1_tx_div_clk_src.clkr, + [NSS_PORT2_RX_DIV_CLK_SRC] = &nss_port2_rx_div_clk_src.clkr, + [NSS_PORT2_TX_DIV_CLK_SRC] = &nss_port2_tx_div_clk_src.clkr, + [NSS_PORT3_RX_DIV_CLK_SRC] = &nss_port3_rx_div_clk_src.clkr, + [NSS_PORT3_TX_DIV_CLK_SRC] = &nss_port3_tx_div_clk_src.clkr, + [NSS_PORT4_RX_DIV_CLK_SRC] = &nss_port4_rx_div_clk_src.clkr, + [NSS_PORT4_TX_DIV_CLK_SRC] = &nss_port4_tx_div_clk_src.clkr, + [NSS_UBI0_CLK_SRC] = &nss_ubi0_clk_src.clkr, + [ADSS_PWM_CLK_SRC] = &adss_pwm_clk_src.clkr, + [BLSP1_QUP1_I2C_APPS_CLK_SRC] = &blsp1_qup1_i2c_apps_clk_src.clkr, + [BLSP1_QUP1_SPI_APPS_CLK_SRC] = &blsp1_qup1_spi_apps_clk_src.clkr, + [BLSP1_QUP2_I2C_APPS_CLK_SRC] = &blsp1_qup2_i2c_apps_clk_src.clkr, + [BLSP1_QUP2_SPI_APPS_CLK_SRC] = &blsp1_qup2_spi_apps_clk_src.clkr, + [BLSP1_QUP3_I2C_APPS_CLK_SRC] = &blsp1_qup3_i2c_apps_clk_src.clkr, + [BLSP1_QUP3_SPI_APPS_CLK_SRC] = &blsp1_qup3_spi_apps_clk_src.clkr, + [BLSP1_QUP4_I2C_APPS_CLK_SRC] = &blsp1_qup4_i2c_apps_clk_src.clkr, + [BLSP1_QUP4_SPI_APPS_CLK_SRC] = &blsp1_qup4_spi_apps_clk_src.clkr, + [BLSP1_QUP5_I2C_APPS_CLK_SRC] = &blsp1_qup5_i2c_apps_clk_src.clkr, + [BLSP1_QUP5_SPI_APPS_CLK_SRC] = &blsp1_qup5_spi_apps_clk_src.clkr, + [BLSP1_QUP6_I2C_APPS_CLK_SRC] = &blsp1_qup6_i2c_apps_clk_src.clkr, + [BLSP1_QUP6_SPI_APPS_CLK_SRC] = &blsp1_qup6_spi_apps_clk_src.clkr, + [BLSP1_UART1_APPS_CLK_SRC] = &blsp1_uart1_apps_clk_src.clkr, + [BLSP1_UART2_APPS_CLK_SRC] = &blsp1_uart2_apps_clk_src.clkr, + [BLSP1_UART3_APPS_CLK_SRC] = &blsp1_uart3_apps_clk_src.clkr, + [BLSP1_UART4_APPS_CLK_SRC] = &blsp1_uart4_apps_clk_src.clkr, + [BLSP1_UART5_APPS_CLK_SRC] = &blsp1_uart5_apps_clk_src.clkr, + [BLSP1_UART6_APPS_CLK_SRC] = &blsp1_uart6_apps_clk_src.clkr, + [CRYPTO_CLK_SRC] = &crypto_clk_src.clkr, + [GP1_CLK_SRC] = &gp1_clk_src.clkr, + [GP2_CLK_SRC] = &gp2_clk_src.clkr, + [GP3_CLK_SRC] = &gp3_clk_src.clkr, + [NSS_UBI0_DIV_CLK_SRC] = &nss_ubi0_div_clk_src.clkr, + [PCIE0_AUX_CLK_SRC] = &pcie0_aux_clk_src.clkr, + [PCIE0_PIPE_CLK_SRC] = &pcie0_pipe_clk_src.clkr, + [SDCC1_APPS_CLK_SRC] = &sdcc1_apps_clk_src.clkr, + [USB0_AUX_CLK_SRC] = &usb0_aux_clk_src.clkr, + [USB0_MOCK_UTMI_CLK_SRC] = &usb0_mock_utmi_clk_src.clkr, + [USB0_PIPE_CLK_SRC] = &usb0_pipe_clk_src.clkr, + [USB1_MOCK_UTMI_CLK_SRC] = &usb1_mock_utmi_clk_src.clkr, + [GCC_ADSS_PWM_CLK] = &gcc_adss_pwm_clk.clkr, + [GCC_APSS_AHB_CLK] = &gcc_apss_ahb_clk.clkr, + [GCC_APSS_AXI_CLK] = &gcc_apss_axi_clk.clkr, + [GCC_BLSP1_AHB_CLK] = &gcc_blsp1_ahb_clk.clkr, + [GCC_BLSP1_QUP1_I2C_APPS_CLK] = &gcc_blsp1_qup1_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP1_SPI_APPS_CLK] = &gcc_blsp1_qup1_spi_apps_clk.clkr, + [GCC_BLSP1_QUP2_I2C_APPS_CLK] = &gcc_blsp1_qup2_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP2_SPI_APPS_CLK] = &gcc_blsp1_qup2_spi_apps_clk.clkr, + [GCC_BLSP1_QUP3_I2C_APPS_CLK] = &gcc_blsp1_qup3_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP3_SPI_APPS_CLK] = &gcc_blsp1_qup3_spi_apps_clk.clkr, + [GCC_BLSP1_QUP4_I2C_APPS_CLK] = &gcc_blsp1_qup4_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP4_SPI_APPS_CLK] = &gcc_blsp1_qup4_spi_apps_clk.clkr, + [GCC_BLSP1_QUP5_I2C_APPS_CLK] = &gcc_blsp1_qup5_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP5_SPI_APPS_CLK] = &gcc_blsp1_qup5_spi_apps_clk.clkr, + [GCC_BLSP1_QUP6_SPI_APPS_CLK] = &gcc_blsp1_qup6_spi_apps_clk.clkr, + [GCC_BLSP1_UART1_APPS_CLK] = &gcc_blsp1_uart1_apps_clk.clkr, + [GCC_BLSP1_UART2_APPS_CLK] = &gcc_blsp1_uart2_apps_clk.clkr, + [GCC_BLSP1_UART3_APPS_CLK] = &gcc_blsp1_uart3_apps_clk.clkr, + [GCC_BLSP1_UART4_APPS_CLK] = &gcc_blsp1_uart4_apps_clk.clkr, + [GCC_BLSP1_UART5_APPS_CLK] = &gcc_blsp1_uart5_apps_clk.clkr, + [GCC_BLSP1_UART6_APPS_CLK] = &gcc_blsp1_uart6_apps_clk.clkr, + [GCC_CRYPTO_AHB_CLK] = &gcc_crypto_ahb_clk.clkr, + [GCC_CRYPTO_AXI_CLK] = &gcc_crypto_axi_clk.clkr, + [GCC_CRYPTO_CLK] = &gcc_crypto_clk.clkr, + [GCC_XO_CLK] = &gcc_xo_clk.clkr, + [GCC_GP1_CLK] = &gcc_gp1_clk.clkr, + [GCC_GP2_CLK] = &gcc_gp2_clk.clkr, + [GCC_GP3_CLK] = &gcc_gp3_clk.clkr, + [GCC_MDIO_AHB_CLK] = &gcc_mdio_ahb_clk.clkr, + [GCC_CRYPTO_PPE_CLK] = &gcc_crypto_ppe_clk.clkr, + [GCC_NSS_CE_APB_CLK] = &gcc_nss_ce_apb_clk.clkr, + [GCC_NSS_CE_AXI_CLK] = &gcc_nss_ce_axi_clk.clkr, + [GCC_NSS_CFG_CLK] = &gcc_nss_cfg_clk.clkr, + [GCC_NSS_CRYPTO_CLK] = &gcc_nss_crypto_clk.clkr, + [GCC_NSS_CSR_CLK] = &gcc_nss_csr_clk.clkr, + [GCC_NSS_EDMA_CFG_CLK] = &gcc_nss_edma_cfg_clk.clkr, + [GCC_NSS_EDMA_CLK] = &gcc_nss_edma_clk.clkr, + [GCC_NSS_NOC_CLK] = &gcc_nss_noc_clk.clkr, + [GCC_UBI0_UTCM_CLK] = &gcc_ubi0_utcm_clk.clkr, + [GCC_SNOC_NSSNOC_CLK] = &gcc_snoc_nssnoc_clk.clkr, + [GCC_NSS_PORT1_RX_CLK] = &gcc_nss_port1_rx_clk.clkr, + [GCC_NSS_PORT1_TX_CLK] = &gcc_nss_port1_tx_clk.clkr, + [GCC_NSS_PORT2_RX_CLK] = &gcc_nss_port2_rx_clk.clkr, + [GCC_NSS_PORT2_TX_CLK] = &gcc_nss_port2_tx_clk.clkr, + [GCC_NSS_PORT3_RX_CLK] = &gcc_nss_port3_rx_clk.clkr, + [GCC_NSS_PORT3_TX_CLK] = &gcc_nss_port3_tx_clk.clkr, + [GCC_NSS_PORT4_RX_CLK] = &gcc_nss_port4_rx_clk.clkr, + [GCC_NSS_PORT4_TX_CLK] = &gcc_nss_port4_tx_clk.clkr, + [GCC_NSS_PORT5_RX_CLK] = &gcc_nss_port5_rx_clk.clkr, + [GCC_NSS_PORT5_TX_CLK] = &gcc_nss_port5_tx_clk.clkr, + [GCC_NSS_PPE_CFG_CLK] = &gcc_nss_ppe_cfg_clk.clkr, + [GCC_NSS_PPE_CLK] = &gcc_nss_ppe_clk.clkr, + [GCC_NSS_PPE_IPE_CLK] = &gcc_nss_ppe_ipe_clk.clkr, + [GCC_NSS_PTP_REF_CLK] = &gcc_nss_ptp_ref_clk.clkr, + [GCC_NSSNOC_CE_APB_CLK] = &gcc_nssnoc_ce_apb_clk.clkr, + [GCC_NSSNOC_CE_AXI_CLK] = &gcc_nssnoc_ce_axi_clk.clkr, + [GCC_NSSNOC_CRYPTO_CLK] = &gcc_nssnoc_crypto_clk.clkr, + [GCC_NSSNOC_PPE_CFG_CLK] = &gcc_nssnoc_ppe_cfg_clk.clkr, + [GCC_NSSNOC_PPE_CLK] = &gcc_nssnoc_ppe_clk.clkr, + [GCC_NSSNOC_QOSGEN_REF_CLK] = &gcc_nssnoc_qosgen_ref_clk.clkr, + [GCC_NSSNOC_SNOC_CLK] = &gcc_nssnoc_snoc_clk.clkr, + [GCC_NSSNOC_TIMEOUT_REF_CLK] = &gcc_nssnoc_timeout_ref_clk.clkr, + [GCC_NSSNOC_UBI0_AHB_CLK] = &gcc_nssnoc_ubi0_ahb_clk.clkr, + [GCC_PORT1_MAC_CLK] = &gcc_port1_mac_clk.clkr, + [GCC_PORT2_MAC_CLK] = &gcc_port2_mac_clk.clkr, + [GCC_PORT3_MAC_CLK] = &gcc_port3_mac_clk.clkr, + [GCC_PORT4_MAC_CLK] = &gcc_port4_mac_clk.clkr, + [GCC_PORT5_MAC_CLK] = &gcc_port5_mac_clk.clkr, + [GCC_UBI0_AHB_CLK] = &gcc_ubi0_ahb_clk.clkr, + [GCC_UBI0_AXI_CLK] = &gcc_ubi0_axi_clk.clkr, + [GCC_UBI0_NC_AXI_CLK] = &gcc_ubi0_nc_axi_clk.clkr, + [GCC_UBI0_CORE_CLK] = &gcc_ubi0_core_clk.clkr, + [GCC_PCIE0_AHB_CLK] = &gcc_pcie0_ahb_clk.clkr, + [GCC_PCIE0_AUX_CLK] = &gcc_pcie0_aux_clk.clkr, + [GCC_PCIE0_AXI_M_CLK] = &gcc_pcie0_axi_m_clk.clkr, + [GCC_PCIE0_AXI_S_CLK] = &gcc_pcie0_axi_s_clk.clkr, + [GCC_SYS_NOC_PCIE0_AXI_CLK] = &gcc_sys_noc_pcie0_axi_clk.clkr, + [GCC_PCIE0_PIPE_CLK] = &gcc_pcie0_pipe_clk.clkr, + [GCC_PRNG_AHB_CLK] = &gcc_prng_ahb_clk.clkr, + [GCC_QDSS_DAP_CLK] = &gcc_qdss_dap_clk.clkr, + [GCC_QPIC_AHB_CLK] = &gcc_qpic_ahb_clk.clkr, + [GCC_QPIC_CLK] = &gcc_qpic_clk.clkr, + [GCC_SDCC1_AHB_CLK] = &gcc_sdcc1_ahb_clk.clkr, + [GCC_SDCC1_APPS_CLK] = &gcc_sdcc1_apps_clk.clkr, + [GCC_UNIPHY0_AHB_CLK] = &gcc_uniphy0_ahb_clk.clkr, + [GCC_UNIPHY0_PORT1_RX_CLK] = &gcc_uniphy0_port1_rx_clk.clkr, + [GCC_UNIPHY0_PORT1_TX_CLK] = &gcc_uniphy0_port1_tx_clk.clkr, + [GCC_UNIPHY0_PORT2_RX_CLK] = &gcc_uniphy0_port2_rx_clk.clkr, + [GCC_UNIPHY0_PORT2_TX_CLK] = &gcc_uniphy0_port2_tx_clk.clkr, + [GCC_UNIPHY0_PORT3_RX_CLK] = &gcc_uniphy0_port3_rx_clk.clkr, + [GCC_UNIPHY0_PORT3_TX_CLK] = &gcc_uniphy0_port3_tx_clk.clkr, + [GCC_UNIPHY0_PORT4_RX_CLK] = &gcc_uniphy0_port4_rx_clk.clkr, + [GCC_UNIPHY0_PORT4_TX_CLK] = &gcc_uniphy0_port4_tx_clk.clkr, + [GCC_UNIPHY0_PORT5_RX_CLK] = &gcc_uniphy0_port5_rx_clk.clkr, + [GCC_UNIPHY0_PORT5_TX_CLK] = &gcc_uniphy0_port5_tx_clk.clkr, + [GCC_UNIPHY0_SYS_CLK] = &gcc_uniphy0_sys_clk.clkr, + [GCC_UNIPHY1_AHB_CLK] = &gcc_uniphy1_ahb_clk.clkr, + [GCC_UNIPHY1_PORT5_RX_CLK] = &gcc_uniphy1_port5_rx_clk.clkr, + [GCC_UNIPHY1_PORT5_TX_CLK] = &gcc_uniphy1_port5_tx_clk.clkr, + [GCC_UNIPHY1_SYS_CLK] = &gcc_uniphy1_sys_clk.clkr, + [GCC_USB0_AUX_CLK] = &gcc_usb0_aux_clk.clkr, + [GCC_SYS_NOC_USB0_AXI_CLK] = &gcc_sys_noc_usb0_axi_clk.clkr, + [GCC_SNOC_BUS_TIMEOUT2_AHB_CLK] = &gcc_snoc_bus_timeout2_ahb_clk.clkr, + [GCC_USB0_MASTER_CLK] = &gcc_usb0_master_clk.clkr, + [GCC_USB0_MOCK_UTMI_CLK] = &gcc_usb0_mock_utmi_clk.clkr, + [GCC_USB0_PHY_CFG_AHB_CLK] = &gcc_usb0_phy_cfg_ahb_clk.clkr, + [GCC_USB0_PIPE_CLK] = &gcc_usb0_pipe_clk.clkr, + [GCC_USB0_SLEEP_CLK] = &gcc_usb0_sleep_clk.clkr, + [GCC_USB1_MASTER_CLK] = &gcc_usb1_master_clk.clkr, + [GCC_USB1_MOCK_UTMI_CLK] = &gcc_usb1_mock_utmi_clk.clkr, + [GCC_USB1_PHY_CFG_AHB_CLK] = &gcc_usb1_phy_cfg_ahb_clk.clkr, + [GCC_USB1_SLEEP_CLK] = &gcc_usb1_sleep_clk.clkr, + [GCC_CMN_12GPLL_AHB_CLK] = &gcc_cmn_12gpll_ahb_clk.clkr, + [GCC_CMN_12GPLL_SYS_CLK] = &gcc_cmn_12gpll_sys_clk.clkr, + [GCC_SDCC1_ICE_CORE_CLK] = &gcc_sdcc1_ice_core_clk.clkr, + [SDCC1_ICE_CORE_CLK_SRC] = &sdcc1_ice_core_clk_src.clkr, + [GCC_DCC_CLK] = &gcc_dcc_clk.clkr, + [PCIE0_RCHNG_CLK_SRC] = &pcie0_rchng_clk_src.clkr, + [GCC_PCIE0_AXI_S_BRIDGE_CLK] = &gcc_pcie0_axi_s_bridge_clk.clkr, + [PCIE0_RCHNG_CLK] = &gcc_pcie0_rchng_clk.clkr, + [WCSS_AHB_CLK_SRC] = &wcss_ahb_clk_src.clkr, + [Q6_AXI_CLK_SRC] = &q6_axi_clk_src.clkr, + [RBCPR_WCSS_CLK_SRC] = &rbcpr_wcss_clk_src.clkr, + [GCC_LPASS_CORE_AXIM_CLK] = &gcc_lpass_core_axim_clk.clkr, + [LPASS_CORE_AXIM_CLK_SRC] = &lpass_core_axim_clk_src.clkr, + [GCC_LPASS_SNOC_CFG_CLK] = &gcc_lpass_snoc_cfg_clk.clkr, + [LPASS_SNOC_CFG_CLK_SRC] = &lpass_snoc_cfg_clk_src.clkr, + [GCC_LPASS_Q6_AXIM_CLK] = &gcc_lpass_q6_axim_clk.clkr, + [LPASS_Q6_AXIM_CLK_SRC] = &lpass_q6_axim_clk_src.clkr, + [GCC_LPASS_Q6_ATBM_AT_CLK] = &gcc_lpass_q6_atbm_at_clk.clkr, + [GCC_LPASS_Q6_PCLKDBG_CLK] = &gcc_lpass_q6_pclkdbg_clk.clkr, + [GCC_LPASS_Q6SS_TSCTR_1TO2_CLK] = &gcc_lpass_q6ss_tsctr_1to2_clk.clkr, + [GCC_LPASS_Q6SS_TRIG_CLK] = &gcc_lpass_q6ss_trig_clk.clkr, + [GCC_LPASS_TBU_CLK] = &gcc_lpass_tbu_clk.clkr, + [GCC_PCNOC_LPASS_CLK] = &gcc_pcnoc_lpass_clk.clkr, + [GCC_MEM_NOC_UBI32_CLK] = &gcc_mem_noc_ubi32_clk.clkr, + [GCC_MEM_NOC_LPASS_CLK] = &gcc_mem_noc_lpass_clk.clkr, + [GCC_SNOC_LPASS_CFG_CLK] = &gcc_snoc_lpass_cfg_clk.clkr, + [QDSS_STM_CLK_SRC] = &qdss_stm_clk_src.clkr, + [QDSS_TRACECLKIN_CLK_SRC] = &qdss_traceclkin_clk_src.clkr, +}; + +static const struct qcom_reset_map gcc_ipq6018_resets[] = { + [GCC_BLSP1_BCR] = { 0x01000, 0 }, + [GCC_BLSP1_QUP1_BCR] = { 0x02000, 0 }, + [GCC_BLSP1_UART1_BCR] = { 0x02038, 0 }, + [GCC_BLSP1_QUP2_BCR] = { 0x03008, 0 }, + [GCC_BLSP1_UART2_BCR] = { 0x03028, 0 }, + [GCC_BLSP1_QUP3_BCR] = { 0x04008, 0 }, + [GCC_BLSP1_UART3_BCR] = { 0x04028, 0 }, + [GCC_BLSP1_QUP4_BCR] = { 0x05008, 0 }, + [GCC_BLSP1_UART4_BCR] = { 0x05028, 0 }, + [GCC_BLSP1_QUP5_BCR] = { 0x06008, 0 }, + [GCC_BLSP1_UART5_BCR] = { 0x06028, 0 }, + [GCC_BLSP1_QUP6_BCR] = { 0x07008, 0 }, + [GCC_BLSP1_UART6_BCR] = { 0x07028, 0 }, + [GCC_IMEM_BCR] = { 0x0e000, 0 }, + [GCC_SMMU_BCR] = { 0x12000, 0 }, + [GCC_APSS_TCU_BCR] = { 0x12050, 0 }, + [GCC_SMMU_XPU_BCR] = { 0x12054, 0 }, + [GCC_PCNOC_TBU_BCR] = { 0x12058, 0 }, + [GCC_SMMU_CFG_BCR] = { 0x1208c, 0 }, + [GCC_PRNG_BCR] = { 0x13000, 0 }, + [GCC_BOOT_ROM_BCR] = { 0x13008, 0 }, + [GCC_CRYPTO_BCR] = { 0x16000, 0 }, + [GCC_WCSS_BCR] = { 0x18000, 0 }, + [GCC_WCSS_Q6_BCR] = { 0x18100, 0 }, + [GCC_NSS_BCR] = { 0x19000, 0 }, + [GCC_SEC_CTRL_BCR] = { 0x1a000, 0 }, + [GCC_ADSS_BCR] = { 0x1c000, 0 }, + [GCC_DDRSS_BCR] = { 0x1e000, 0 }, + [GCC_SYSTEM_NOC_BCR] = { 0x26000, 0 }, + [GCC_PCNOC_BCR] = { 0x27018, 0 }, + [GCC_TCSR_BCR] = { 0x28000, 0 }, + [GCC_QDSS_BCR] = { 0x29000, 0 }, + [GCC_DCD_BCR] = { 0x2a000, 0 }, + [GCC_MSG_RAM_BCR] = { 0x2b000, 0 }, + [GCC_MPM_BCR] = { 0x2c000, 0 }, + [GCC_SPDM_BCR] = { 0x2f000, 0 }, + [GCC_RBCPR_BCR] = { 0x33000, 0 }, + [GCC_RBCPR_MX_BCR] = { 0x33014, 0 }, + [GCC_TLMM_BCR] = { 0x34000, 0 }, + [GCC_RBCPR_WCSS_BCR] = { 0x3a000, 0 }, + [GCC_USB0_PHY_BCR] = { 0x3e034, 0 }, + [GCC_USB3PHY_0_PHY_BCR] = { 0x3e03c, 0 }, + [GCC_USB0_BCR] = { 0x3e070, 0 }, + [GCC_USB1_BCR] = { 0x3f070, 0 }, + [GCC_QUSB2_0_PHY_BCR] = { 0x4103c, 0 }, + [GCC_QUSB2_1_PHY_BCR] = { 0x41040, 0 }, + [GCC_SDCC1_BCR] = { 0x42000, 0 }, + [GCC_SNOC_BUS_TIMEOUT0_BCR] = { 0x47000, 0 }, + [GCC_SNOC_BUS_TIMEOUT1_BCR] = { 0x47008, 0 }, + [GCC_SNOC_BUS_TIMEOUT2_BCR] = { 0x47010, 0 }, + [GCC_PCNOC_BUS_TIMEOUT0_BCR] = { 0x48000, 0 }, + [GCC_PCNOC_BUS_TIMEOUT1_BCR] = { 0x48008, 0 }, + [GCC_PCNOC_BUS_TIMEOUT2_BCR] = { 0x48010, 0 }, + [GCC_PCNOC_BUS_TIMEOUT3_BCR] = { 0x48018, 0 }, + [GCC_PCNOC_BUS_TIMEOUT4_BCR] = { 0x48020, 0 }, + [GCC_PCNOC_BUS_TIMEOUT5_BCR] = { 0x48028, 0 }, + [GCC_PCNOC_BUS_TIMEOUT6_BCR] = { 0x48030, 0 }, + [GCC_PCNOC_BUS_TIMEOUT7_BCR] = { 0x48038, 0 }, + [GCC_PCNOC_BUS_TIMEOUT8_BCR] = { 0x48040, 0 }, + [GCC_PCNOC_BUS_TIMEOUT9_BCR] = { 0x48048, 0 }, + [GCC_UNIPHY0_BCR] = { 0x56000, 0 }, + [GCC_UNIPHY1_BCR] = { 0x56100, 0 }, + [GCC_CMN_12GPLL_BCR] = { 0x56300, 0 }, + [GCC_QPIC_BCR] = { 0x57018, 0 }, + [GCC_MDIO_BCR] = { 0x58000, 0 }, + [GCC_WCSS_CORE_TBU_BCR] = { 0x66000, 0 }, + [GCC_WCSS_Q6_TBU_BCR] = { 0x67000, 0 }, + [GCC_USB0_TBU_BCR] = { 0x6a000, 0 }, + [GCC_PCIE0_TBU_BCR] = { 0x6b000, 0 }, + [GCC_NSS_NOC_TBU_BCR] = { 0x6e000, 0 }, + [GCC_PCIE0_BCR] = { 0x75004, 0 }, + [GCC_PCIE0_PHY_BCR] = { 0x75038, 0 }, + [GCC_PCIE0PHY_PHY_BCR] = { 0x7503c, 0 }, + [GCC_PCIE0_LINK_DOWN_BCR] = { 0x75044, 0 }, + [GCC_DCC_BCR] = { 0x77000, 0 }, + [GCC_APC0_VOLTAGE_DROOP_DETECTOR_BCR] = { 0x78000, 0 }, + [GCC_SMMU_CATS_BCR] = { 0x7c000, 0 }, + [GCC_UBI0_AXI_ARES] = { 0x68010, 0 }, + [GCC_UBI0_AHB_ARES] = { 0x68010, 1 }, + [GCC_UBI0_NC_AXI_ARES] = { 0x68010, 2 }, + [GCC_UBI0_DBG_ARES] = { 0x68010, 3 }, + [GCC_UBI0_CORE_CLAMP_ENABLE] = { 0x68010, 4 }, + [GCC_UBI0_CLKRST_CLAMP_ENABLE] = { 0x68010, 5 }, + [GCC_UBI0_UTCM_ARES] = { 0x68010, 6 }, + [GCC_UBI0_CORE_ARES] = { 0x68010, 7 }, + [GCC_NSS_CFG_ARES] = { 0x68010, 16 }, + [GCC_NSS_NOC_ARES] = { 0x68010, 18 }, + [GCC_NSS_CRYPTO_ARES] = { 0x68010, 19 }, + [GCC_NSS_CSR_ARES] = { 0x68010, 20 }, + [GCC_NSS_CE_APB_ARES] = { 0x68010, 21 }, + [GCC_NSS_CE_AXI_ARES] = { 0x68010, 22 }, + [GCC_NSSNOC_CE_APB_ARES] = { 0x68010, 23 }, + [GCC_NSSNOC_CE_AXI_ARES] = { 0x68010, 24 }, + [GCC_NSSNOC_UBI0_AHB_ARES] = { 0x68010, 25 }, + [GCC_NSSNOC_SNOC_ARES] = { 0x68010, 27 }, + [GCC_NSSNOC_CRYPTO_ARES] = { 0x68010, 28 }, + [GCC_NSSNOC_ATB_ARES] = { 0x68010, 29 }, + [GCC_NSSNOC_QOSGEN_REF_ARES] = { 0x68010, 30 }, + [GCC_NSSNOC_TIMEOUT_REF_ARES] = { 0x68010, 31 }, + [GCC_PCIE0_PIPE_ARES] = { 0x75040, 0 }, + [GCC_PCIE0_SLEEP_ARES] = { 0x75040, 1 }, + [GCC_PCIE0_CORE_STICKY_ARES] = { 0x75040, 2 }, + [GCC_PCIE0_AXI_MASTER_ARES] = { 0x75040, 3 }, + [GCC_PCIE0_AXI_SLAVE_ARES] = { 0x75040, 4 }, + [GCC_PCIE0_AHB_ARES] = { 0x75040, 5 }, + [GCC_PCIE0_AXI_MASTER_STICKY_ARES] = { 0x75040, 6 }, + [GCC_PCIE0_AXI_SLAVE_STICKY_ARES] = { 0x75040, 7 }, + [GCC_PPE_FULL_RESET] = { 0x68014, 0 }, + [GCC_UNIPHY0_SOFT_RESET] = { 0x56004, 0 }, + [GCC_UNIPHY0_XPCS_RESET] = { 0x56004, 2 }, + [GCC_UNIPHY1_SOFT_RESET] = { 0x56104, 0 }, + [GCC_UNIPHY1_XPCS_RESET] = { 0x56104, 2 }, + [GCC_EDMA_HW_RESET] = { 0x68014, 0 }, + [GCC_NSSPORT1_RESET] = { 0x68014, 0 }, + [GCC_NSSPORT2_RESET] = { 0x68014, 0 }, + [GCC_NSSPORT3_RESET] = { 0x68014, 0 }, + [GCC_NSSPORT4_RESET] = { 0x68014, 0 }, + [GCC_NSSPORT5_RESET] = { 0x68014, 0 }, + [GCC_UNIPHY0_PORT1_ARES] = { 0x56004, 0 }, + [GCC_UNIPHY0_PORT2_ARES] = { 0x56004, 0 }, + [GCC_UNIPHY0_PORT3_ARES] = { 0x56004, 0 }, + [GCC_UNIPHY0_PORT4_ARES] = { 0x56004, 0 }, + [GCC_UNIPHY0_PORT5_ARES] = { 0x56004, 0 }, + [GCC_UNIPHY0_PORT_4_5_RESET] = { 0x56004, 0 }, + [GCC_UNIPHY0_PORT_4_RESET] = { 0x56004, 0 }, + [GCC_LPASS_BCR] = {0x1F000, 0}, + [GCC_UBI32_TBU_BCR] = {0x65000, 0}, + [GCC_LPASS_TBU_BCR] = {0x6C000, 0}, + [GCC_WCSSAON_RESET] = {0x59010, 0}, + [GCC_LPASS_Q6_AXIM_ARES] = {0x1F004, 0}, + [GCC_LPASS_Q6SS_TSCTR_1TO2_ARES] = {0x1F004, 1}, + [GCC_LPASS_Q6SS_TRIG_ARES] = {0x1F004, 2}, + [GCC_LPASS_Q6_ATBM_AT_ARES] = {0x1F004, 3}, + [GCC_LPASS_Q6_PCLKDBG_ARES] = {0x1F004, 4}, + [GCC_LPASS_CORE_AXIM_ARES] = {0x1F004, 5}, + [GCC_LPASS_SNOC_CFG_ARES] = {0x1F004, 6}, + [GCC_WCSS_DBG_ARES] = {0x59008, 0}, + [GCC_WCSS_ECAHB_ARES] = {0x59008, 1}, + [GCC_WCSS_ACMT_ARES] = {0x59008, 2}, + [GCC_WCSS_DBG_BDG_ARES] = {0x59008, 3}, + [GCC_WCSS_AHB_S_ARES] = {0x59008, 4}, + [GCC_WCSS_AXI_M_ARES] = {0x59008, 5}, + [GCC_Q6SS_DBG_ARES] = {0x59110, 0}, + [GCC_Q6_AHB_S_ARES] = {0x59110, 1}, + [GCC_Q6_AHB_ARES] = {0x59110, 2}, + [GCC_Q6_AXIM2_ARES] = {0x59110, 3}, + [GCC_Q6_AXIM_ARES] = {0x59110, 4}, +}; + +static const struct of_device_id gcc_ipq6018_match_table[] = { + { .compatible = "qcom,gcc-ipq6018" }, + { } +}; +MODULE_DEVICE_TABLE(of, gcc_ipq6018_match_table); + +static const struct regmap_config gcc_ipq6018_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x7fffc, + .fast_io = true, +}; + +static const struct qcom_cc_desc gcc_ipq6018_desc = { + .config = &gcc_ipq6018_regmap_config, + .clks = gcc_ipq6018_clks, + .num_clks = ARRAY_SIZE(gcc_ipq6018_clks), + .resets = gcc_ipq6018_resets, + .num_resets = ARRAY_SIZE(gcc_ipq6018_resets), + .clk_hws = gcc_ipq6018_hws, + .num_clk_hws = ARRAY_SIZE(gcc_ipq6018_hws), +}; + +static int gcc_ipq6018_probe(struct platform_device *pdev) +{ + struct regmap *regmap; + + regmap = qcom_cc_map(pdev, &gcc_ipq6018_desc); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + /* Disable SW_COLLAPSE for USB0 GDSCR */ + regmap_update_bits(regmap, 0x3e078, BIT(0), 0x0); + /* Enable SW_OVERRIDE for USB0 GDSCR */ + regmap_update_bits(regmap, 0x3e078, BIT(2), BIT(2)); + /* Disable SW_COLLAPSE for USB1 GDSCR */ + regmap_update_bits(regmap, 0x3f078, BIT(0), 0x0); + /* Enable SW_OVERRIDE for USB1 GDSCR */ + regmap_update_bits(regmap, 0x3f078, BIT(2), BIT(2)); + + /* SW Workaround for UBI Huyara PLL */ + regmap_update_bits(regmap, 0x2501c, BIT(26), BIT(26)); + + clk_alpha_pll_configure(&ubi32_pll_main, regmap, &ubi32_pll_config); + + clk_alpha_pll_configure(&nss_crypto_pll_main, regmap, + &nss_crypto_pll_config); + + return qcom_cc_really_probe(pdev, &gcc_ipq6018_desc, regmap); +} + +static struct platform_driver gcc_ipq6018_driver = { + .probe = gcc_ipq6018_probe, + .driver = { + .name = "qcom,gcc-ipq6018", + .of_match_table = gcc_ipq6018_match_table, + }, +}; + +static int __init gcc_ipq6018_init(void) +{ + return platform_driver_register(&gcc_ipq6018_driver); +} +core_initcall(gcc_ipq6018_init); + +static void __exit gcc_ipq6018_exit(void) +{ + platform_driver_unregister(&gcc_ipq6018_driver); +} +module_exit(gcc_ipq6018_exit); + +MODULE_DESCRIPTION("Qualcomm Technologies, Inc. GCC IPQ6018 Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/qcom/gcc-msm8996.c b/drivers/clk/qcom/gcc-msm8996.c index d004cdaa0e39..3c3a7ff04562 100644 --- a/drivers/clk/qcom/gcc-msm8996.c +++ b/drivers/clk/qcom/gcc-msm8996.c @@ -3046,7 +3046,10 @@ static struct clk_branch gcc_usb3_clkref_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_usb3_clkref_clk", - .parent_names = (const char *[]){ "xo" }, + .parent_data = &(const struct clk_parent_data){ + .fw_name = "cxo2", + .name = "xo", + }, .num_parents = 1, .ops = &clk_branch2_ops, }, @@ -3060,7 +3063,10 @@ static struct clk_branch gcc_hdmi_clkref_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_hdmi_clkref_clk", - .parent_names = (const char *[]){ "xo" }, + .parent_data = &(const struct clk_parent_data){ + .fw_name = "cxo2", + .name = "xo", + }, .num_parents = 1, .ops = &clk_branch2_ops, }, @@ -3074,7 +3080,10 @@ static struct clk_branch gcc_edp_clkref_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_edp_clkref_clk", - .parent_names = (const char *[]){ "xo" }, + .parent_data = &(const struct clk_parent_data){ + .fw_name = "cxo2", + .name = "xo", + }, .num_parents = 1, .ops = &clk_branch2_ops, }, @@ -3088,7 +3097,10 @@ static struct clk_branch gcc_ufs_clkref_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_ufs_clkref_clk", - .parent_names = (const char *[]){ "xo" }, + .parent_data = &(const struct clk_parent_data){ + .fw_name = "cxo2", + .name = "xo", + }, .num_parents = 1, .ops = &clk_branch2_ops, }, @@ -3102,7 +3114,10 @@ static struct clk_branch gcc_pcie_clkref_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_pcie_clkref_clk", - .parent_names = (const char *[]){ "xo" }, + .parent_data = &(const struct clk_parent_data){ + .fw_name = "cxo2", + .name = "xo", + }, .num_parents = 1, .ops = &clk_branch2_ops, }, @@ -3116,7 +3131,10 @@ static struct clk_branch gcc_rx2_usb2_clkref_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_rx2_usb2_clkref_clk", - .parent_names = (const char *[]){ "xo" }, + .parent_data = &(const struct clk_parent_data){ + .fw_name = "cxo2", + .name = "xo", + }, .num_parents = 1, .ops = &clk_branch2_ops, }, @@ -3130,7 +3148,10 @@ static struct clk_branch gcc_rx1_usb2_clkref_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_rx1_usb2_clkref_clk", - .parent_names = (const char *[]){ "xo" }, + .parent_data = &(const struct clk_parent_data){ + .fw_name = "cxo2", + .name = "xo", + }, .num_parents = 1, .ops = &clk_branch2_ops, }, diff --git a/drivers/clk/qcom/gcc-msm8998.c b/drivers/clk/qcom/gcc-msm8998.c index cf31b5d03270..df1d7056436c 100644 --- a/drivers/clk/qcom/gcc-msm8998.c +++ b/drivers/clk/qcom/gcc-msm8998.c @@ -1996,6 +1996,19 @@ static struct clk_branch gcc_gp3_clk = { }, }; +static struct clk_branch gcc_bimc_gfx_clk = { + .halt_reg = 0x46040, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x46040, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_bimc_gfx_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_branch gcc_gpu_bimc_gfx_clk = { .halt_reg = 0x71010, .halt_check = BRANCH_HALT, @@ -2810,6 +2823,7 @@ static struct clk_regmap *gcc_msm8998_clocks[] = { [GCC_GP1_CLK] = &gcc_gp1_clk.clkr, [GCC_GP2_CLK] = &gcc_gp2_clk.clkr, [GCC_GP3_CLK] = &gcc_gp3_clk.clkr, + [GCC_BIMC_GFX_CLK] = &gcc_bimc_gfx_clk.clkr, [GCC_GPU_BIMC_GFX_CLK] = &gcc_gpu_bimc_gfx_clk.clkr, [GCC_GPU_BIMC_GFX_SRC_CLK] = &gcc_gpu_bimc_gfx_src_clk.clkr, [GCC_GPU_CFG_AHB_CLK] = &gcc_gpu_cfg_ahb_clk.clkr, diff --git a/drivers/clk/qcom/gcc-qcs404.c b/drivers/clk/qcom/gcc-qcs404.c index 9b0c4ce2ef4e..46d314d69250 100644 --- a/drivers/clk/qcom/gcc-qcs404.c +++ b/drivers/clk/qcom/gcc-qcs404.c @@ -330,7 +330,7 @@ static struct clk_alpha_pll gpll0_ao_out_main = { .parent_names = (const char *[]){ "cxo" }, .num_parents = 1, .flags = CLK_IS_CRITICAL, - .ops = &clk_alpha_pll_ops, + .ops = &clk_alpha_pll_fixed_ops, }, }, }; diff --git a/drivers/clk/qcom/gcc-sc7180.c b/drivers/clk/qcom/gcc-sc7180.c index 38424e63bcae..7f59fb8da033 100644 --- a/drivers/clk/qcom/gcc-sc7180.c +++ b/drivers/clk/qcom/gcc-sc7180.c @@ -2186,7 +2186,8 @@ static struct gdsc hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc = { .pd = { .name = "hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc", }, - .pwrsts = PWRSTS_OFF_ON | VOTABLE, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, }; static struct gdsc hlos1_vote_mmnoc_mmu_tbu_sf_gdsc = { @@ -2194,7 +2195,8 @@ static struct gdsc hlos1_vote_mmnoc_mmu_tbu_sf_gdsc = { .pd = { .name = "hlos1_vote_mmnoc_mmu_tbu_sf_gdsc", }, - .pwrsts = PWRSTS_OFF_ON | VOTABLE, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, }; static struct gdsc *gcc_sc7180_gdscs[] = { diff --git a/drivers/clk/qcom/gpucc-msm8998.c b/drivers/clk/qcom/gpucc-msm8998.c index e5e2492b20c5..9b3923af02a1 100644 --- a/drivers/clk/qcom/gpucc-msm8998.c +++ b/drivers/clk/qcom/gpucc-msm8998.c @@ -242,10 +242,12 @@ static struct clk_branch gfx3d_isense_clk = { static struct gdsc gpu_cx_gdsc = { .gdscr = 0x1004, + .gds_hw_ctrl = 0x1008, .pd = { .name = "gpu_cx", }, .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, }; static struct gdsc gpu_gx_gdsc = { diff --git a/drivers/clk/qcom/gpucc-sc7180.c b/drivers/clk/qcom/gpucc-sc7180.c new file mode 100644 index 000000000000..ec61194cceaf --- /dev/null +++ b/drivers/clk/qcom/gpucc-sc7180.c @@ -0,0 +1,266 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + */ + +#include <linux/clk-provider.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> + +#include <dt-bindings/clock/qcom,gpucc-sc7180.h> + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "common.h" +#include "gdsc.h" + +#define CX_GMU_CBCR_SLEEP_MASK 0xF +#define CX_GMU_CBCR_SLEEP_SHIFT 4 +#define CX_GMU_CBCR_WAKE_MASK 0xF +#define CX_GMU_CBCR_WAKE_SHIFT 8 +#define CLK_DIS_WAIT_SHIFT 12 +#define CLK_DIS_WAIT_MASK (0xf << CLK_DIS_WAIT_SHIFT) + +enum { + P_BI_TCXO, + P_CORE_BI_PLL_TEST_SE, + P_GPLL0_OUT_MAIN, + P_GPLL0_OUT_MAIN_DIV, + P_GPU_CC_PLL1_OUT_EVEN, + P_GPU_CC_PLL1_OUT_MAIN, + P_GPU_CC_PLL1_OUT_ODD, +}; + +static const struct pll_vco fabia_vco[] = { + { 249600000, 2000000000, 0 }, +}; + +static struct clk_alpha_pll gpu_cc_pll1 = { + .offset = 0x100, + .vco_table = fabia_vco, + .num_vco = ARRAY_SIZE(fabia_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_pll1", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fabia_ops, + }, + }, +}; + +static const struct parent_map gpu_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_GPU_CC_PLL1_OUT_MAIN, 3 }, + { P_GPLL0_OUT_MAIN, 5 }, + { P_GPLL0_OUT_MAIN_DIV, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const struct clk_parent_data gpu_cc_parent_data_0[] = { + { .fw_name = "bi_tcxo" }, + { .hw = &gpu_cc_pll1.clkr.hw }, + { .fw_name = "gcc_gpu_gpll0_clk_src" }, + { .fw_name = "gcc_gpu_gpll0_div_clk_src" }, + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, +}; + +static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(200000000, P_GPLL0_OUT_MAIN_DIV, 1.5, 0, 0), + { } +}; + +static struct clk_rcg2 gpu_cc_gmu_clk_src = { + .cmd_rcgr = 0x1120, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gpu_cc_parent_map_0, + .freq_tbl = ftbl_gpu_cc_gmu_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpu_cc_gmu_clk_src", + .parent_data = gpu_cc_parent_data_0, + .num_parents = 5, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_branch gpu_cc_crc_ahb_clk = { + .halt_reg = 0x107c, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x107c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_crc_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_cx_gmu_clk = { + .halt_reg = 0x1098, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1098, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_cx_gmu_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gpu_cc_gmu_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_cx_snoc_dvm_clk = { + .halt_reg = 0x108c, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x108c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_cx_snoc_dvm_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_cxo_aon_clk = { + .halt_reg = 0x1004, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x1004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_cxo_aon_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_cxo_clk = { + .halt_reg = 0x109c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x109c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_cxo_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc cx_gdsc = { + .gdscr = 0x106c, + .gds_hw_ctrl = 0x1540, + .pd = { + .name = "cx_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, +}; + +static struct gdsc *gpu_cc_sc7180_gdscs[] = { + [CX_GDSC] = &cx_gdsc, +}; + +static struct clk_regmap *gpu_cc_sc7180_clocks[] = { + [GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr, + [GPU_CC_CRC_AHB_CLK] = &gpu_cc_crc_ahb_clk.clkr, + [GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr, + [GPU_CC_CX_SNOC_DVM_CLK] = &gpu_cc_cx_snoc_dvm_clk.clkr, + [GPU_CC_CXO_AON_CLK] = &gpu_cc_cxo_aon_clk.clkr, + [GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr, + [GPU_CC_PLL1] = &gpu_cc_pll1.clkr, +}; + +static const struct regmap_config gpu_cc_sc7180_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x8008, + .fast_io = true, +}; + +static const struct qcom_cc_desc gpu_cc_sc7180_desc = { + .config = &gpu_cc_sc7180_regmap_config, + .clks = gpu_cc_sc7180_clocks, + .num_clks = ARRAY_SIZE(gpu_cc_sc7180_clocks), + .gdscs = gpu_cc_sc7180_gdscs, + .num_gdscs = ARRAY_SIZE(gpu_cc_sc7180_gdscs), +}; + +static const struct of_device_id gpu_cc_sc7180_match_table[] = { + { .compatible = "qcom,sc7180-gpucc" }, + { } +}; +MODULE_DEVICE_TABLE(of, gpu_cc_sc7180_match_table); + +static int gpu_cc_sc7180_probe(struct platform_device *pdev) +{ + struct regmap *regmap; + struct alpha_pll_config gpu_cc_pll_config = {}; + unsigned int value, mask; + + regmap = qcom_cc_map(pdev, &gpu_cc_sc7180_desc); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + /* 360MHz Configuration */ + gpu_cc_pll_config.l = 0x12; + gpu_cc_pll_config.alpha = 0xc000; + gpu_cc_pll_config.config_ctl_val = 0x20485699; + gpu_cc_pll_config.config_ctl_hi_val = 0x00002067; + gpu_cc_pll_config.user_ctl_val = 0x00000001; + gpu_cc_pll_config.user_ctl_hi_val = 0x00004805; + gpu_cc_pll_config.test_ctl_hi_val = 0x40000000; + + clk_fabia_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll_config); + + /* Recommended WAKEUP/SLEEP settings for the gpu_cc_cx_gmu_clk */ + mask = CX_GMU_CBCR_WAKE_MASK << CX_GMU_CBCR_WAKE_SHIFT; + mask |= CX_GMU_CBCR_SLEEP_MASK << CX_GMU_CBCR_SLEEP_SHIFT; + value = 0xF << CX_GMU_CBCR_WAKE_SHIFT | 0xF << CX_GMU_CBCR_SLEEP_SHIFT; + regmap_update_bits(regmap, 0x1098, mask, value); + + /* Configure clk_dis_wait for gpu_cx_gdsc */ + regmap_update_bits(regmap, 0x106c, CLK_DIS_WAIT_MASK, + 8 << CLK_DIS_WAIT_SHIFT); + + return qcom_cc_really_probe(pdev, &gpu_cc_sc7180_desc, regmap); +} + +static struct platform_driver gpu_cc_sc7180_driver = { + .probe = gpu_cc_sc7180_probe, + .driver = { + .name = "sc7180-gpucc", + .of_match_table = gpu_cc_sc7180_match_table, + }, +}; + +static int __init gpu_cc_sc7180_init(void) +{ + return platform_driver_register(&gpu_cc_sc7180_driver); +} +subsys_initcall(gpu_cc_sc7180_init); + +static void __exit gpu_cc_sc7180_exit(void) +{ + platform_driver_unregister(&gpu_cc_sc7180_driver); +} +module_exit(gpu_cc_sc7180_exit); + +MODULE_DESCRIPTION("QTI GPU_CC SC7180 Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/qcom/hfpll.c b/drivers/clk/qcom/hfpll.c index a6de7101430c..5ff7f5a60620 100644 --- a/drivers/clk/qcom/hfpll.c +++ b/drivers/clk/qcom/hfpll.c @@ -53,10 +53,18 @@ static int qcom_hfpll_probe(struct platform_device *pdev) struct regmap *regmap; struct clk_hfpll *h; struct clk_init_data init = { - .parent_names = (const char *[]){ "xo" }, .num_parents = 1, .ops = &clk_ops_hfpll, + /* + * rather than marking the clock critical and forcing the clock + * to be always enabled, we make sure that the clock is not + * disabled: the firmware remains responsible of enabling this + * clock (for more info check the commit log) + */ + .flags = CLK_IGNORE_UNUSED, }; + int ret; + struct clk_parent_data pdata = { .index = 0 }; h = devm_kzalloc(dev, sizeof(*h), GFP_KERNEL); if (!h) @@ -75,11 +83,20 @@ static int qcom_hfpll_probe(struct platform_device *pdev) 0, &init.name)) return -ENODEV; + init.parent_data = &pdata; + h->d = &hdata; h->clkr.hw.init = &init; spin_lock_init(&h->lock); - return devm_clk_register_regmap(&pdev->dev, &h->clkr); + ret = devm_clk_register_regmap(dev, &h->clkr); + if (ret) { + dev_err(dev, "failed to register regmap clock: %d\n", ret); + return ret; + } + + return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, + &h->clkr.hw); } static struct platform_driver qcom_hfpll_driver = { diff --git a/drivers/clk/qcom/mmcc-msm8974.c b/drivers/clk/qcom/mmcc-msm8974.c index bcb0a397ef91..015426262d08 100644 --- a/drivers/clk/qcom/mmcc-msm8974.c +++ b/drivers/clk/qcom/mmcc-msm8974.c @@ -452,18 +452,6 @@ static struct clk_rcg2 mdp_clk_src = { }, }; -static struct clk_rcg2 gfx3d_clk_src = { - .cmd_rcgr = 0x4000, - .hid_width = 5, - .parent_map = mmcc_xo_mmpll0_1_2_gpll0_map, - .clkr.hw.init = &(struct clk_init_data){ - .name = "gfx3d_clk_src", - .parent_names = mmcc_xo_mmpll0_1_2_gpll0, - .num_parents = 5, - .ops = &clk_rcg2_ops, - }, -}; - static struct freq_tbl ftbl_camss_jpeg_jpeg0_2_clk[] = { F(75000000, P_GPLL0, 8, 0, 0), F(133330000, P_GPLL0, 4.5, 0, 0), @@ -2411,7 +2399,6 @@ static struct clk_regmap *mmcc_msm8974_clocks[] = { [VFE0_CLK_SRC] = &vfe0_clk_src.clkr, [VFE1_CLK_SRC] = &vfe1_clk_src.clkr, [MDP_CLK_SRC] = &mdp_clk_src.clkr, - [GFX3D_CLK_SRC] = &gfx3d_clk_src.clkr, [JPEG0_CLK_SRC] = &jpeg0_clk_src.clkr, [JPEG1_CLK_SRC] = &jpeg1_clk_src.clkr, [JPEG2_CLK_SRC] = &jpeg2_clk_src.clkr, diff --git a/drivers/clk/qcom/mmcc-msm8998.c b/drivers/clk/qcom/mmcc-msm8998.c new file mode 100644 index 000000000000..dd68983fe22e --- /dev/null +++ b/drivers/clk/qcom/mmcc-msm8998.c @@ -0,0 +1,2913 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + */ + +#include <linux/kernel.h> +#include <linux/bitops.h> +#include <linux/err.h> +#include <linux/platform_device.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/clk-provider.h> +#include <linux/regmap.h> +#include <linux/reset-controller.h> + +#include <dt-bindings/clock/qcom,mmcc-msm8998.h> + +#include "common.h" +#include "clk-regmap.h" +#include "clk-regmap-divider.h" +#include "clk-alpha-pll.h" +#include "clk-rcg.h" +#include "clk-branch.h" +#include "reset.h" +#include "gdsc.h" + +enum { + P_XO, + P_GPLL0, + P_GPLL0_DIV, + P_MMPLL0_OUT_EVEN, + P_MMPLL1_OUT_EVEN, + P_MMPLL3_OUT_EVEN, + P_MMPLL4_OUT_EVEN, + P_MMPLL5_OUT_EVEN, + P_MMPLL6_OUT_EVEN, + P_MMPLL7_OUT_EVEN, + P_MMPLL10_OUT_EVEN, + P_DSI0PLL, + P_DSI1PLL, + P_DSI0PLL_BYTE, + P_DSI1PLL_BYTE, + P_HDMIPLL, + P_DPVCO, + P_DPLINK, + P_CORE_BI_PLL_TEST_SE, +}; + +static struct clk_fixed_factor gpll0_div = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data){ + .name = "mmss_gpll0_div", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "gpll0", + .name = "gpll0" + }, + .num_parents = 1, + .ops = &clk_fixed_factor_ops, + }, +}; + +static const struct clk_div_table post_div_table_fabia_even[] = { + { 0x0, 1 }, + { 0x1, 2 }, + { 0x3, 4 }, + { 0x7, 8 }, + { } +}; + +static struct clk_alpha_pll mmpll0 = { + .offset = 0xc000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .enable_reg = 0x1e0, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmpll0", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "xo", + .name = "xo" + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_fabia_ops, + }, + }, +}; + +static struct clk_alpha_pll_postdiv mmpll0_out_even = { + .offset = 0xc000, + .post_div_shift = 8, + .post_div_table = post_div_table_fabia_even, + .num_post_div = ARRAY_SIZE(post_div_table_fabia_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "mmpll0_out_even", + .parent_hws = (const struct clk_hw *[]){ &mmpll0.clkr.hw }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_fabia_ops, + }, +}; + +static struct clk_alpha_pll mmpll1 = { + .offset = 0xc050, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .enable_reg = 0x1e0, + .enable_mask = BIT(1), + .hw.init = &(struct clk_init_data){ + .name = "mmpll1", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "xo", + .name = "xo" + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_fabia_ops, + }, + }, +}; + +static struct clk_alpha_pll_postdiv mmpll1_out_even = { + .offset = 0xc050, + .post_div_shift = 8, + .post_div_table = post_div_table_fabia_even, + .num_post_div = ARRAY_SIZE(post_div_table_fabia_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "mmpll1_out_even", + .parent_hws = (const struct clk_hw *[]){ &mmpll1.clkr.hw }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_fabia_ops, + }, +}; + +static struct clk_alpha_pll mmpll3 = { + .offset = 0x0, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "mmpll3", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "xo", + .name = "xo" + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_fabia_ops, + }, +}; + +static struct clk_alpha_pll_postdiv mmpll3_out_even = { + .offset = 0x0, + .post_div_shift = 8, + .post_div_table = post_div_table_fabia_even, + .num_post_div = ARRAY_SIZE(post_div_table_fabia_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "mmpll3_out_even", + .parent_hws = (const struct clk_hw *[]){ &mmpll3.clkr.hw }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_fabia_ops, + }, +}; + +static struct clk_alpha_pll mmpll4 = { + .offset = 0x50, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "mmpll4", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "xo", + .name = "xo" + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_fabia_ops, + }, +}; + +static struct clk_alpha_pll_postdiv mmpll4_out_even = { + .offset = 0x50, + .post_div_shift = 8, + .post_div_table = post_div_table_fabia_even, + .num_post_div = ARRAY_SIZE(post_div_table_fabia_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "mmpll4_out_even", + .parent_hws = (const struct clk_hw *[]){ &mmpll4.clkr.hw }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_fabia_ops, + }, +}; + +static struct clk_alpha_pll mmpll5 = { + .offset = 0xa0, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "mmpll5", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "xo", + .name = "xo" + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_fabia_ops, + }, +}; + +static struct clk_alpha_pll_postdiv mmpll5_out_even = { + .offset = 0xa0, + .post_div_shift = 8, + .post_div_table = post_div_table_fabia_even, + .num_post_div = ARRAY_SIZE(post_div_table_fabia_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "mmpll5_out_even", + .parent_hws = (const struct clk_hw *[]){ &mmpll5.clkr.hw }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_fabia_ops, + }, +}; + +static struct clk_alpha_pll mmpll6 = { + .offset = 0xf0, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "mmpll6", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "xo", + .name = "xo" + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_fabia_ops, + }, +}; + +static struct clk_alpha_pll_postdiv mmpll6_out_even = { + .offset = 0xf0, + .post_div_shift = 8, + .post_div_table = post_div_table_fabia_even, + .num_post_div = ARRAY_SIZE(post_div_table_fabia_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "mmpll6_out_even", + .parent_hws = (const struct clk_hw *[]){ &mmpll6.clkr.hw }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_fabia_ops, + }, +}; + +static struct clk_alpha_pll mmpll7 = { + .offset = 0x140, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "mmpll7", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "xo", + .name = "xo" + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_fabia_ops, + }, +}; + +static struct clk_alpha_pll_postdiv mmpll7_out_even = { + .offset = 0x140, + .post_div_shift = 8, + .post_div_table = post_div_table_fabia_even, + .num_post_div = ARRAY_SIZE(post_div_table_fabia_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "mmpll7_out_even", + .parent_hws = (const struct clk_hw *[]){ &mmpll7.clkr.hw }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_fabia_ops, + }, +}; + +static struct clk_alpha_pll mmpll10 = { + .offset = 0x190, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "mmpll10", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "xo", + .name = "xo" + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_fabia_ops, + }, +}; + +static struct clk_alpha_pll_postdiv mmpll10_out_even = { + .offset = 0x190, + .post_div_shift = 8, + .post_div_table = post_div_table_fabia_even, + .num_post_div = ARRAY_SIZE(post_div_table_fabia_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "mmpll10_out_even", + .parent_hws = (const struct clk_hw *[]){ &mmpll10.clkr.hw }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_fabia_ops, + }, +}; + +static const struct parent_map mmss_xo_hdmi_map[] = { + { P_XO, 0 }, + { P_HDMIPLL, 1 }, + { P_CORE_BI_PLL_TEST_SE, 7 } +}; + +static const struct clk_parent_data mmss_xo_hdmi[] = { + { .fw_name = "xo", .name = "xo" }, + { .fw_name = "hdmipll", .name = "hdmipll" }, + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, +}; + +static const struct parent_map mmss_xo_dsi0pll_dsi1pll_map[] = { + { P_XO, 0 }, + { P_DSI0PLL, 1 }, + { P_DSI1PLL, 2 }, + { P_CORE_BI_PLL_TEST_SE, 7 } +}; + +static const struct clk_parent_data mmss_xo_dsi0pll_dsi1pll[] = { + { .fw_name = "xo", .name = "xo" }, + { .fw_name = "dsi0dsi", .name = "dsi0dsi" }, + { .fw_name = "dsi1dsi", .name = "dsi1dsi" }, + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, +}; + +static const struct parent_map mmss_xo_dsibyte_map[] = { + { P_XO, 0 }, + { P_DSI0PLL_BYTE, 1 }, + { P_DSI1PLL_BYTE, 2 }, + { P_CORE_BI_PLL_TEST_SE, 7 } +}; + +static const struct clk_parent_data mmss_xo_dsibyte[] = { + { .fw_name = "xo", .name = "xo" }, + { .fw_name = "dsi0byte", .name = "dsi0byte" }, + { .fw_name = "dsi1byte", .name = "dsi1byte" }, + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, +}; + +static const struct parent_map mmss_xo_dp_map[] = { + { P_XO, 0 }, + { P_DPLINK, 1 }, + { P_DPVCO, 2 }, + { P_CORE_BI_PLL_TEST_SE, 7 } +}; + +static const struct clk_parent_data mmss_xo_dp[] = { + { .fw_name = "xo", .name = "xo" }, + { .fw_name = "dplink", .name = "dplink" }, + { .fw_name = "dpvco", .name = "dpvco" }, + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, +}; + +static const struct parent_map mmss_xo_gpll0_gpll0_div_map[] = { + { P_XO, 0 }, + { P_GPLL0, 5 }, + { P_GPLL0_DIV, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 } +}; + +static const struct clk_parent_data mmss_xo_gpll0_gpll0_div[] = { + { .fw_name = "xo", .name = "xo" }, + { .fw_name = "gpll0", .name = "gpll0" }, + { .hw = &gpll0_div.hw }, + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, +}; + +static const struct parent_map mmss_xo_mmpll0_gpll0_gpll0_div_map[] = { + { P_XO, 0 }, + { P_MMPLL0_OUT_EVEN, 1 }, + { P_GPLL0, 5 }, + { P_GPLL0_DIV, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 } +}; + +static const struct clk_parent_data mmss_xo_mmpll0_gpll0_gpll0_div[] = { + { .fw_name = "xo", .name = "xo" }, + { .hw = &mmpll0_out_even.clkr.hw }, + { .fw_name = "gpll0", .name = "gpll0" }, + { .hw = &gpll0_div.hw }, + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, +}; + +static const struct parent_map mmss_xo_mmpll0_mmpll1_gpll0_gpll0_div_map[] = { + { P_XO, 0 }, + { P_MMPLL0_OUT_EVEN, 1 }, + { P_MMPLL1_OUT_EVEN, 2 }, + { P_GPLL0, 5 }, + { P_GPLL0_DIV, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 } +}; + +static const struct clk_parent_data mmss_xo_mmpll0_mmpll1_gpll0_gpll0_div[] = { + { .fw_name = "xo", .name = "xo" }, + { .hw = &mmpll0_out_even.clkr.hw }, + { .hw = &mmpll1_out_even.clkr.hw }, + { .fw_name = "gpll0", .name = "gpll0" }, + { .hw = &gpll0_div.hw }, + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, +}; + +static const struct parent_map mmss_xo_mmpll0_mmpll5_gpll0_gpll0_div_map[] = { + { P_XO, 0 }, + { P_MMPLL0_OUT_EVEN, 1 }, + { P_MMPLL5_OUT_EVEN, 2 }, + { P_GPLL0, 5 }, + { P_GPLL0_DIV, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 } +}; + +static const struct clk_parent_data mmss_xo_mmpll0_mmpll5_gpll0_gpll0_div[] = { + { .fw_name = "xo", .name = "xo" }, + { .hw = &mmpll0_out_even.clkr.hw }, + { .hw = &mmpll5_out_even.clkr.hw }, + { .fw_name = "gpll0", .name = "gpll0" }, + { .hw = &gpll0_div.hw }, + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, +}; + +static const struct parent_map mmss_xo_mmpll0_mmpll3_mmpll6_gpll0_gpll0_div_map[] = { + { P_XO, 0 }, + { P_MMPLL0_OUT_EVEN, 1 }, + { P_MMPLL3_OUT_EVEN, 3 }, + { P_MMPLL6_OUT_EVEN, 4 }, + { P_GPLL0, 5 }, + { P_GPLL0_DIV, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 } +}; + +static const struct clk_parent_data mmss_xo_mmpll0_mmpll3_mmpll6_gpll0_gpll0_div[] = { + { .fw_name = "xo", .name = "xo" }, + { .hw = &mmpll0_out_even.clkr.hw }, + { .hw = &mmpll3_out_even.clkr.hw }, + { .hw = &mmpll6_out_even.clkr.hw }, + { .fw_name = "gpll0", .name = "gpll0" }, + { .hw = &gpll0_div.hw }, + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, +}; + +static const struct parent_map mmss_xo_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div_map[] = { + { P_XO, 0 }, + { P_MMPLL4_OUT_EVEN, 1 }, + { P_MMPLL7_OUT_EVEN, 2 }, + { P_MMPLL10_OUT_EVEN, 3 }, + { P_GPLL0, 5 }, + { P_GPLL0_DIV, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 } +}; + +static const struct clk_parent_data mmss_xo_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div[] = { + { .fw_name = "xo", .name = "xo" }, + { .hw = &mmpll4_out_even.clkr.hw }, + { .hw = &mmpll7_out_even.clkr.hw }, + { .hw = &mmpll10_out_even.clkr.hw }, + { .fw_name = "gpll0", .name = "gpll0" }, + { .hw = &gpll0_div.hw }, + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, +}; + +static const struct parent_map mmss_xo_mmpll0_mmpll7_mmpll10_gpll0_gpll0_div_map[] = { + { P_XO, 0 }, + { P_MMPLL0_OUT_EVEN, 1 }, + { P_MMPLL7_OUT_EVEN, 2 }, + { P_MMPLL10_OUT_EVEN, 3 }, + { P_GPLL0, 5 }, + { P_GPLL0_DIV, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 } +}; + +static const struct clk_parent_data mmss_xo_mmpll0_mmpll7_mmpll10_gpll0_gpll0_div[] = { + { .fw_name = "xo", .name = "xo" }, + { .hw = &mmpll0_out_even.clkr.hw }, + { .hw = &mmpll7_out_even.clkr.hw }, + { .hw = &mmpll10_out_even.clkr.hw }, + { .fw_name = "gpll0", .name = "gpll0" }, + { .hw = &gpll0_div.hw }, + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, +}; + +static const struct parent_map mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div_map[] = { + { P_XO, 0 }, + { P_MMPLL0_OUT_EVEN, 1 }, + { P_MMPLL4_OUT_EVEN, 2 }, + { P_MMPLL7_OUT_EVEN, 3 }, + { P_MMPLL10_OUT_EVEN, 4 }, + { P_GPLL0, 5 }, + { P_GPLL0_DIV, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 } +}; + +static const struct clk_parent_data mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div[] = { + { .fw_name = "xo", .name = "xo" }, + { .hw = &mmpll0_out_even.clkr.hw }, + { .hw = &mmpll4_out_even.clkr.hw }, + { .hw = &mmpll7_out_even.clkr.hw }, + { .hw = &mmpll10_out_even.clkr.hw }, + { .fw_name = "gpll0", .name = "gpll0" }, + { .hw = &gpll0_div.hw }, + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, +}; + +static struct clk_rcg2 byte0_clk_src = { + .cmd_rcgr = 0x2120, + .hid_width = 5, + .parent_map = mmss_xo_dsibyte_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "byte0_clk_src", + .parent_data = mmss_xo_dsibyte, + .num_parents = 4, + .ops = &clk_byte2_ops, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_rcg2 byte1_clk_src = { + .cmd_rcgr = 0x2140, + .hid_width = 5, + .parent_map = mmss_xo_dsibyte_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "byte1_clk_src", + .parent_data = mmss_xo_dsibyte, + .num_parents = 4, + .ops = &clk_byte2_ops, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct freq_tbl ftbl_cci_clk_src[] = { + F(37500000, P_GPLL0, 16, 0, 0), + F(50000000, P_GPLL0, 12, 0, 0), + F(100000000, P_GPLL0, 6, 0, 0), + { } +}; + +static struct clk_rcg2 cci_clk_src = { + .cmd_rcgr = 0x3300, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll7_mmpll10_gpll0_gpll0_div_map, + .freq_tbl = ftbl_cci_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cci_clk_src", + .parent_data = mmss_xo_mmpll0_mmpll7_mmpll10_gpll0_gpll0_div, + .num_parents = 7, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_cpp_clk_src[] = { + F(100000000, P_GPLL0, 6, 0, 0), + F(200000000, P_GPLL0, 3, 0, 0), + F(384000000, P_MMPLL4_OUT_EVEN, 2, 0, 0), + F(404000000, P_MMPLL0_OUT_EVEN, 2, 0, 0), + F(480000000, P_MMPLL7_OUT_EVEN, 2, 0, 0), + F(576000000, P_MMPLL10_OUT_EVEN, 1, 0, 0), + F(600000000, P_GPLL0, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cpp_clk_src = { + .cmd_rcgr = 0x3640, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div_map, + .freq_tbl = ftbl_cpp_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cpp_clk_src", + .parent_data = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div, + .num_parents = 8, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_csi_clk_src[] = { + F(164571429, P_MMPLL10_OUT_EVEN, 3.5, 0, 0), + F(256000000, P_MMPLL4_OUT_EVEN, 3, 0, 0), + F(274290000, P_MMPLL7_OUT_EVEN, 3.5, 0, 0), + F(300000000, P_GPLL0, 2, 0, 0), + F(384000000, P_MMPLL4_OUT_EVEN, 2, 0, 0), + F(576000000, P_MMPLL10_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 csi0_clk_src = { + .cmd_rcgr = 0x3090, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div_map, + .freq_tbl = ftbl_csi_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "csi0_clk_src", + .parent_data = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div, + .num_parents = 8, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 csi1_clk_src = { + .cmd_rcgr = 0x3100, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div_map, + .freq_tbl = ftbl_csi_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "csi1_clk_src", + .parent_data = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div, + .num_parents = 8, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 csi2_clk_src = { + .cmd_rcgr = 0x3160, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div_map, + .freq_tbl = ftbl_csi_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "csi2_clk_src", + .parent_data = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div, + .num_parents = 8, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 csi3_clk_src = { + .cmd_rcgr = 0x31c0, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div_map, + .freq_tbl = ftbl_csi_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "csi3_clk_src", + .parent_data = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div, + .num_parents = 8, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_csiphy_clk_src[] = { + F(164571429, P_MMPLL10_OUT_EVEN, 3.5, 0, 0), + F(256000000, P_MMPLL4_OUT_EVEN, 3, 0, 0), + F(274290000, P_MMPLL7_OUT_EVEN, 3.5, 0, 0), + F(300000000, P_GPLL0, 2, 0, 0), + F(384000000, P_MMPLL4_OUT_EVEN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 csiphy_clk_src = { + .cmd_rcgr = 0x3800, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div_map, + .freq_tbl = ftbl_csiphy_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "csiphy_clk_src", + .parent_data = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div, + .num_parents = 8, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_csiphytimer_clk_src[] = { + F(200000000, P_GPLL0, 3, 0, 0), + F(269333333, P_MMPLL0_OUT_EVEN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 csi0phytimer_clk_src = { + .cmd_rcgr = 0x3000, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div_map, + .freq_tbl = ftbl_csiphytimer_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "csi0phytimer_clk_src", + .parent_data = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div, + .num_parents = 8, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 csi1phytimer_clk_src = { + .cmd_rcgr = 0x3030, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div_map, + .freq_tbl = ftbl_csiphytimer_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "csi1phytimer_clk_src", + .parent_data = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div, + .num_parents = 8, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 csi2phytimer_clk_src = { + .cmd_rcgr = 0x3060, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div_map, + .freq_tbl = ftbl_csiphytimer_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "csi2phytimer_clk_src", + .parent_data = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div, + .num_parents = 8, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_dp_aux_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 dp_aux_clk_src = { + .cmd_rcgr = 0x2260, + .hid_width = 5, + .parent_map = mmss_xo_gpll0_gpll0_div_map, + .freq_tbl = ftbl_dp_aux_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "dp_aux_clk_src", + .parent_data = mmss_xo_gpll0_gpll0_div, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_dp_crypto_clk_src[] = { + F(101250, P_DPLINK, 1, 5, 16), + F(168750, P_DPLINK, 1, 5, 16), + F(337500, P_DPLINK, 1, 5, 16), + { } +}; + +static struct clk_rcg2 dp_crypto_clk_src = { + .cmd_rcgr = 0x2220, + .hid_width = 5, + .parent_map = mmss_xo_dp_map, + .freq_tbl = ftbl_dp_crypto_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "dp_crypto_clk_src", + .parent_data = mmss_xo_dp, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_dp_link_clk_src[] = { + F(162000, P_DPLINK, 2, 0, 0), + F(270000, P_DPLINK, 2, 0, 0), + F(540000, P_DPLINK, 2, 0, 0), + { } +}; + +static struct clk_rcg2 dp_link_clk_src = { + .cmd_rcgr = 0x2200, + .hid_width = 5, + .parent_map = mmss_xo_dp_map, + .freq_tbl = ftbl_dp_link_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "dp_link_clk_src", + .parent_data = mmss_xo_dp, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_dp_pixel_clk_src[] = { + F(154000000, P_DPVCO, 1, 0, 0), + F(337500000, P_DPVCO, 2, 0, 0), + F(675000000, P_DPVCO, 2, 0, 0), + { } +}; + +static struct clk_rcg2 dp_pixel_clk_src = { + .cmd_rcgr = 0x2240, + .hid_width = 5, + .parent_map = mmss_xo_dp_map, + .freq_tbl = ftbl_dp_pixel_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "dp_pixel_clk_src", + .parent_data = mmss_xo_dp, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_esc_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 esc0_clk_src = { + .cmd_rcgr = 0x2160, + .hid_width = 5, + .parent_map = mmss_xo_dsibyte_map, + .freq_tbl = ftbl_esc_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "esc0_clk_src", + .parent_data = mmss_xo_dsibyte, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 esc1_clk_src = { + .cmd_rcgr = 0x2180, + .hid_width = 5, + .parent_map = mmss_xo_dsibyte_map, + .freq_tbl = ftbl_esc_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "esc1_clk_src", + .parent_data = mmss_xo_dsibyte, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_extpclk_clk_src[] = { + { .src = P_HDMIPLL }, + { } +}; + +static struct clk_rcg2 extpclk_clk_src = { + .cmd_rcgr = 0x2060, + .hid_width = 5, + .parent_map = mmss_xo_hdmi_map, + .freq_tbl = ftbl_extpclk_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "extpclk_clk_src", + .parent_data = mmss_xo_hdmi, + .num_parents = 3, + .ops = &clk_byte_ops, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct freq_tbl ftbl_fd_core_clk_src[] = { + F(100000000, P_GPLL0, 6, 0, 0), + F(200000000, P_GPLL0, 3, 0, 0), + F(404000000, P_MMPLL0_OUT_EVEN, 2, 0, 0), + F(480000000, P_MMPLL7_OUT_EVEN, 2, 0, 0), + F(576000000, P_MMPLL10_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 fd_core_clk_src = { + .cmd_rcgr = 0x3b00, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div_map, + .freq_tbl = ftbl_fd_core_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "fd_core_clk_src", + .parent_data = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div, + .num_parents = 8, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_hdmi_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 hdmi_clk_src = { + .cmd_rcgr = 0x2100, + .hid_width = 5, + .parent_map = mmss_xo_gpll0_gpll0_div_map, + .freq_tbl = ftbl_hdmi_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "hdmi_clk_src", + .parent_data = mmss_xo_gpll0_gpll0_div, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_jpeg0_clk_src[] = { + F(75000000, P_GPLL0, 8, 0, 0), + F(150000000, P_GPLL0, 4, 0, 0), + F(320000000, P_MMPLL7_OUT_EVEN, 3, 0, 0), + F(480000000, P_MMPLL7_OUT_EVEN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 jpeg0_clk_src = { + .cmd_rcgr = 0x3500, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div_map, + .freq_tbl = ftbl_jpeg0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "jpeg0_clk_src", + .parent_data = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div, + .num_parents = 8, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_maxi_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(75000000, P_GPLL0_DIV, 4, 0, 0), + F(171428571, P_GPLL0, 3.5, 0, 0), + F(323200000, P_MMPLL0_OUT_EVEN, 2.5, 0, 0), + F(406000000, P_MMPLL1_OUT_EVEN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 maxi_clk_src = { + .cmd_rcgr = 0xf020, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll1_gpll0_gpll0_div_map, + .freq_tbl = ftbl_maxi_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "maxi_clk_src", + .parent_data = mmss_xo_mmpll0_mmpll1_gpll0_gpll0_div, + .num_parents = 6, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_mclk_clk_src[] = { + F(4800000, P_XO, 4, 0, 0), + F(6000000, P_GPLL0_DIV, 10, 1, 5), + F(8000000, P_GPLL0_DIV, 1, 2, 75), + F(9600000, P_XO, 2, 0, 0), + F(16666667, P_GPLL0_DIV, 2, 1, 9), + F(19200000, P_XO, 1, 0, 0), + F(24000000, P_GPLL0_DIV, 1, 2, 25), + F(33333333, P_GPLL0_DIV, 1, 2, 9), + F(48000000, P_GPLL0, 1, 2, 25), + F(66666667, P_GPLL0, 1, 2, 9), + { } +}; + +static struct clk_rcg2 mclk0_clk_src = { + .cmd_rcgr = 0x3360, + .hid_width = 5, + .parent_map = mmss_xo_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div_map, + .freq_tbl = ftbl_mclk_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "mclk0_clk_src", + .parent_data = mmss_xo_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div, + .num_parents = 7, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 mclk1_clk_src = { + .cmd_rcgr = 0x3390, + .hid_width = 5, + .parent_map = mmss_xo_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div_map, + .freq_tbl = ftbl_mclk_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "mclk1_clk_src", + .parent_data = mmss_xo_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div, + .num_parents = 7, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 mclk2_clk_src = { + .cmd_rcgr = 0x33c0, + .hid_width = 5, + .parent_map = mmss_xo_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div_map, + .freq_tbl = ftbl_mclk_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "mclk2_clk_src", + .parent_data = mmss_xo_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div, + .num_parents = 7, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 mclk3_clk_src = { + .cmd_rcgr = 0x33f0, + .hid_width = 5, + .parent_map = mmss_xo_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div_map, + .freq_tbl = ftbl_mclk_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "mclk3_clk_src", + .parent_data = mmss_xo_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div, + .num_parents = 7, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_mdp_clk_src[] = { + F(85714286, P_GPLL0, 7, 0, 0), + F(100000000, P_GPLL0, 6, 0, 0), + F(150000000, P_GPLL0, 4, 0, 0), + F(171428571, P_GPLL0, 3.5, 0, 0), + F(200000000, P_GPLL0, 3, 0, 0), + F(275000000, P_MMPLL5_OUT_EVEN, 3, 0, 0), + F(300000000, P_GPLL0, 2, 0, 0), + F(330000000, P_MMPLL5_OUT_EVEN, 2.5, 0, 0), + F(412500000, P_MMPLL5_OUT_EVEN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 mdp_clk_src = { + .cmd_rcgr = 0x2040, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll5_gpll0_gpll0_div_map, + .freq_tbl = ftbl_mdp_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "mdp_clk_src", + .parent_data = mmss_xo_mmpll0_mmpll5_gpll0_gpll0_div, + .num_parents = 6, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_vsync_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 vsync_clk_src = { + .cmd_rcgr = 0x2080, + .hid_width = 5, + .parent_map = mmss_xo_gpll0_gpll0_div_map, + .freq_tbl = ftbl_vsync_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "vsync_clk_src", + .parent_data = mmss_xo_gpll0_gpll0_div, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_ahb_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(40000000, P_GPLL0, 15, 0, 0), + F(80800000, P_MMPLL0_OUT_EVEN, 10, 0, 0), + { } +}; + +static struct clk_rcg2 ahb_clk_src = { + .cmd_rcgr = 0x5000, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_gpll0_gpll0_div_map, + .freq_tbl = ftbl_ahb_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "ahb_clk_src", + .parent_data = mmss_xo_mmpll0_gpll0_gpll0_div, + .num_parents = 5, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_axi_clk_src[] = { + F(75000000, P_GPLL0, 8, 0, 0), + F(171428571, P_GPLL0, 3.5, 0, 0), + F(240000000, P_GPLL0, 2.5, 0, 0), + F(323200000, P_MMPLL0_OUT_EVEN, 2.5, 0, 0), + F(406000000, P_MMPLL0_OUT_EVEN, 2, 0, 0), + { } +}; + +/* RO to linux */ +static struct clk_rcg2 axi_clk_src = { + .cmd_rcgr = 0xd000, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll1_gpll0_gpll0_div_map, + .freq_tbl = ftbl_axi_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "axi_clk_src", + .parent_data = mmss_xo_mmpll0_mmpll1_gpll0_gpll0_div, + .num_parents = 6, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 pclk0_clk_src = { + .cmd_rcgr = 0x2000, + .mnd_width = 8, + .hid_width = 5, + .parent_map = mmss_xo_dsi0pll_dsi1pll_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "pclk0_clk_src", + .parent_data = mmss_xo_dsi0pll_dsi1pll, + .num_parents = 4, + .ops = &clk_pixel_ops, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_rcg2 pclk1_clk_src = { + .cmd_rcgr = 0x2020, + .mnd_width = 8, + .hid_width = 5, + .parent_map = mmss_xo_dsi0pll_dsi1pll_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "pclk1_clk_src", + .parent_data = mmss_xo_dsi0pll_dsi1pll, + .num_parents = 4, + .ops = &clk_pixel_ops, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct freq_tbl ftbl_rot_clk_src[] = { + F(171428571, P_GPLL0, 3.5, 0, 0), + F(275000000, P_MMPLL5_OUT_EVEN, 3, 0, 0), + F(330000000, P_MMPLL5_OUT_EVEN, 2.5, 0, 0), + F(412500000, P_MMPLL5_OUT_EVEN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 rot_clk_src = { + .cmd_rcgr = 0x21a0, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll5_gpll0_gpll0_div_map, + .freq_tbl = ftbl_rot_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "rot_clk_src", + .parent_data = mmss_xo_mmpll0_mmpll5_gpll0_gpll0_div, + .num_parents = 6, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_video_core_clk_src[] = { + F(200000000, P_GPLL0, 3, 0, 0), + F(269330000, P_MMPLL0_OUT_EVEN, 3, 0, 0), + F(355200000, P_MMPLL6_OUT_EVEN, 2.5, 0, 0), + F(444000000, P_MMPLL6_OUT_EVEN, 2, 0, 0), + F(533000000, P_MMPLL3_OUT_EVEN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 video_core_clk_src = { + .cmd_rcgr = 0x1000, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll3_mmpll6_gpll0_gpll0_div_map, + .freq_tbl = ftbl_video_core_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "video_core_clk_src", + .parent_data = mmss_xo_mmpll0_mmpll3_mmpll6_gpll0_gpll0_div, + .num_parents = 7, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 video_subcore0_clk_src = { + .cmd_rcgr = 0x1060, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll3_mmpll6_gpll0_gpll0_div_map, + .freq_tbl = ftbl_video_core_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "video_subcore0_clk_src", + .parent_data = mmss_xo_mmpll0_mmpll3_mmpll6_gpll0_gpll0_div, + .num_parents = 7, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 video_subcore1_clk_src = { + .cmd_rcgr = 0x1080, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll3_mmpll6_gpll0_gpll0_div_map, + .freq_tbl = ftbl_video_core_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "video_subcore1_clk_src", + .parent_data = mmss_xo_mmpll0_mmpll3_mmpll6_gpll0_gpll0_div, + .num_parents = 7, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_vfe_clk_src[] = { + F(200000000, P_GPLL0, 3, 0, 0), + F(300000000, P_GPLL0, 2, 0, 0), + F(320000000, P_MMPLL7_OUT_EVEN, 3, 0, 0), + F(384000000, P_MMPLL4_OUT_EVEN, 2, 0, 0), + F(404000000, P_MMPLL0_OUT_EVEN, 2, 0, 0), + F(480000000, P_MMPLL7_OUT_EVEN, 2, 0, 0), + F(576000000, P_MMPLL10_OUT_EVEN, 1, 0, 0), + F(600000000, P_GPLL0, 1, 0, 0), + { } +}; + +static struct clk_rcg2 vfe0_clk_src = { + .cmd_rcgr = 0x3600, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div_map, + .freq_tbl = ftbl_vfe_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "vfe0_clk_src", + .parent_data = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div, + .num_parents = 8, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 vfe1_clk_src = { + .cmd_rcgr = 0x3620, + .hid_width = 5, + .parent_map = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div_map, + .freq_tbl = ftbl_vfe_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "vfe1_clk_src", + .parent_data = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div, + .num_parents = 8, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch misc_ahb_clk = { + .halt_reg = 0x328, + .clkr = { + .enable_reg = 0x328, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "misc_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch video_core_clk = { + .halt_reg = 0x1028, + .clkr = { + .enable_reg = 0x1028, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "video_core_clk", + .parent_hws = (const struct clk_hw *[]){ &video_core_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch video_ahb_clk = { + .halt_reg = 0x1030, + .clkr = { + .enable_reg = 0x1030, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "video_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch video_axi_clk = { + .halt_reg = 0x1034, + .clkr = { + .enable_reg = 0x1034, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "video_axi_clk", + .parent_hws = (const struct clk_hw *[]){ &axi_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_maxi_clk = { + .halt_reg = 0x1038, + .clkr = { + .enable_reg = 0x1038, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "video_maxi_clk", + .parent_hws = (const struct clk_hw *[]){ &maxi_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch video_subcore0_clk = { + .halt_reg = 0x1048, + .clkr = { + .enable_reg = 0x1048, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "video_subcore0_clk", + .parent_hws = (const struct clk_hw *[]){ &video_subcore0_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch video_subcore1_clk = { + .halt_reg = 0x104c, + .clkr = { + .enable_reg = 0x104c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "video_subcore1_clk", + .parent_hws = (const struct clk_hw *[]){ &video_subcore1_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch mdss_ahb_clk = { + .halt_reg = 0x2308, + .clkr = { + .enable_reg = 0x2308, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mdss_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch mdss_hdmi_dp_ahb_clk = { + .halt_reg = 0x230c, + .clkr = { + .enable_reg = 0x230c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mdss_hdmi_dp_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch mdss_axi_clk = { + .halt_reg = 0x2310, + .clkr = { + .enable_reg = 0x2310, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mdss_axi_clk", + .parent_hws = (const struct clk_hw *[]){ &axi_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mdss_pclk0_clk = { + .halt_reg = 0x2314, + .clkr = { + .enable_reg = 0x2314, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mdss_pclk0_clk", + .parent_hws = (const struct clk_hw *[]){ &pclk0_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch mdss_pclk1_clk = { + .halt_reg = 0x2318, + .clkr = { + .enable_reg = 0x2318, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mdss_pclk1_clk", + .parent_hws = (const struct clk_hw *[]){ &pclk1_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch mdss_mdp_clk = { + .halt_reg = 0x231c, + .clkr = { + .enable_reg = 0x231c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mdss_mdp_clk", + .parent_hws = (const struct clk_hw *[]){ &mdp_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch mdss_mdp_lut_clk = { + .halt_reg = 0x2320, + .clkr = { + .enable_reg = 0x2320, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mdss_mdp_lut_clk", + .parent_hws = (const struct clk_hw *[]){ &mdp_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch mdss_extpclk_clk = { + .halt_reg = 0x2324, + .clkr = { + .enable_reg = 0x2324, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mdss_extpclk_clk", + .parent_hws = (const struct clk_hw *[]){ &extpclk_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch mdss_vsync_clk = { + .halt_reg = 0x2328, + .clkr = { + .enable_reg = 0x2328, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mdss_vsync_clk", + .parent_hws = (const struct clk_hw *[]){ &vsync_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch mdss_hdmi_clk = { + .halt_reg = 0x2338, + .clkr = { + .enable_reg = 0x2338, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mdss_hdmi_clk", + .parent_hws = (const struct clk_hw *[]){ &hdmi_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch mdss_byte0_clk = { + .halt_reg = 0x233c, + .clkr = { + .enable_reg = 0x233c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mdss_byte0_clk", + .parent_hws = (const struct clk_hw *[]){ &byte0_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch mdss_byte1_clk = { + .halt_reg = 0x2340, + .clkr = { + .enable_reg = 0x2340, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mdss_byte1_clk", + .parent_hws = (const struct clk_hw *[]){ &byte1_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch mdss_esc0_clk = { + .halt_reg = 0x2344, + .clkr = { + .enable_reg = 0x2344, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mdss_esc0_clk", + .parent_hws = (const struct clk_hw *[]){ &esc0_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch mdss_esc1_clk = { + .halt_reg = 0x2348, + .clkr = { + .enable_reg = 0x2348, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mdss_esc1_clk", + .parent_hws = (const struct clk_hw *[]){ &esc1_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch mdss_rot_clk = { + .halt_reg = 0x2350, + .clkr = { + .enable_reg = 0x2350, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mdss_rot_clk", + .parent_hws = (const struct clk_hw *[]){ &rot_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch mdss_dp_link_clk = { + .halt_reg = 0x2354, + .clkr = { + .enable_reg = 0x2354, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mdss_dp_link_clk", + .parent_hws = (const struct clk_hw *[]){ &dp_link_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch mdss_dp_link_intf_clk = { + .halt_reg = 0x2358, + .clkr = { + .enable_reg = 0x2358, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mdss_dp_link_intf_clk", + .parent_hws = (const struct clk_hw *[]){ &dp_link_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch mdss_dp_crypto_clk = { + .halt_reg = 0x235c, + .clkr = { + .enable_reg = 0x235c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mdss_dp_crypto_clk", + .parent_hws = (const struct clk_hw *[]){ &dp_crypto_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch mdss_dp_pixel_clk = { + .halt_reg = 0x2360, + .clkr = { + .enable_reg = 0x2360, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mdss_dp_pixel_clk", + .parent_hws = (const struct clk_hw *[]){ &dp_pixel_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch mdss_dp_aux_clk = { + .halt_reg = 0x2364, + .clkr = { + .enable_reg = 0x2364, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mdss_dp_aux_clk", + .parent_hws = (const struct clk_hw *[]){ &dp_aux_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch mdss_byte0_intf_clk = { + .halt_reg = 0x2374, + .clkr = { + .enable_reg = 0x2374, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mdss_byte0_intf_clk", + .parent_hws = (const struct clk_hw *[]){ &byte0_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch mdss_byte1_intf_clk = { + .halt_reg = 0x2378, + .clkr = { + .enable_reg = 0x2378, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mdss_byte1_intf_clk", + .parent_hws = (const struct clk_hw *[]){ &byte1_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_csi0phytimer_clk = { + .halt_reg = 0x3024, + .clkr = { + .enable_reg = 0x3024, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csi0phytimer_clk", + .parent_hws = (const struct clk_hw *[]){ &csi0phytimer_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_csi1phytimer_clk = { + .halt_reg = 0x3054, + .clkr = { + .enable_reg = 0x3054, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csi1phytimer_clk", + .parent_hws = (const struct clk_hw *[]){ &csi1phytimer_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_csi2phytimer_clk = { + .halt_reg = 0x3084, + .clkr = { + .enable_reg = 0x3084, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csi2phytimer_clk", + .parent_hws = (const struct clk_hw *[]){ &csi2phytimer_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_csi0_clk = { + .halt_reg = 0x30b4, + .clkr = { + .enable_reg = 0x30b4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csi0_clk", + .parent_hws = (const struct clk_hw *[]){ &csi0_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_csi0_ahb_clk = { + .halt_reg = 0x30bc, + .clkr = { + .enable_reg = 0x30bc, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csi0_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_csi0rdi_clk = { + .halt_reg = 0x30d4, + .clkr = { + .enable_reg = 0x30d4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csi0rdi_clk", + .parent_hws = (const struct clk_hw *[]){ &csi0_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_csi0pix_clk = { + .halt_reg = 0x30e4, + .clkr = { + .enable_reg = 0x30e4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csi0pix_clk", + .parent_hws = (const struct clk_hw *[]){ &csi0_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_csi1_clk = { + .halt_reg = 0x3124, + .clkr = { + .enable_reg = 0x3124, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csi1_clk", + .parent_hws = (const struct clk_hw *[]){ &csi1_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_csi1_ahb_clk = { + .halt_reg = 0x3128, + .clkr = { + .enable_reg = 0x3128, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csi1_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_csi1rdi_clk = { + .halt_reg = 0x3144, + .clkr = { + .enable_reg = 0x3144, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csi1rdi_clk", + .parent_hws = (const struct clk_hw *[]){ &csi1_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_csi1pix_clk = { + .halt_reg = 0x3154, + .clkr = { + .enable_reg = 0x3154, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csi1pix_clk", + .parent_hws = (const struct clk_hw *[]){ &csi1_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_csi2_clk = { + .halt_reg = 0x3184, + .clkr = { + .enable_reg = 0x3184, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csi2_clk", + .parent_hws = (const struct clk_hw *[]){ &csi2_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_csi2_ahb_clk = { + .halt_reg = 0x3188, + .clkr = { + .enable_reg = 0x3188, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csi2_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_csi2rdi_clk = { + .halt_reg = 0x31a4, + .clkr = { + .enable_reg = 0x31a4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csi2rdi_clk", + .parent_hws = (const struct clk_hw *[]){ &csi2_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_csi2pix_clk = { + .halt_reg = 0x31b4, + .clkr = { + .enable_reg = 0x31b4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csi2pix_clk", + .parent_hws = (const struct clk_hw *[]){ &csi2_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_csi3_clk = { + .halt_reg = 0x31e4, + .clkr = { + .enable_reg = 0x31e4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csi3_clk", + .parent_hws = (const struct clk_hw *[]){ &csi3_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_csi3_ahb_clk = { + .halt_reg = 0x31e8, + .clkr = { + .enable_reg = 0x31e8, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csi3_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_csi3rdi_clk = { + .halt_reg = 0x3204, + .clkr = { + .enable_reg = 0x3204, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csi3rdi_clk", + .parent_hws = (const struct clk_hw *[]){ &csi3_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_csi3pix_clk = { + .halt_reg = 0x3214, + .clkr = { + .enable_reg = 0x3214, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csi3pix_clk", + .parent_hws = (const struct clk_hw *[]){ &csi3_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_ispif_ahb_clk = { + .halt_reg = 0x3224, + .clkr = { + .enable_reg = 0x3224, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_ispif_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_cci_clk = { + .halt_reg = 0x3344, + .clkr = { + .enable_reg = 0x3344, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_cci_clk", + .parent_hws = (const struct clk_hw *[]){ &cci_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_cci_ahb_clk = { + .halt_reg = 0x3348, + .clkr = { + .enable_reg = 0x3348, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_cci_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_mclk0_clk = { + .halt_reg = 0x3384, + .clkr = { + .enable_reg = 0x3384, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_mclk0_clk", + .parent_hws = (const struct clk_hw *[]){ &mclk0_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_mclk1_clk = { + .halt_reg = 0x33b4, + .clkr = { + .enable_reg = 0x33b4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_mclk1_clk", + .parent_hws = (const struct clk_hw *[]){ &mclk1_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_mclk2_clk = { + .halt_reg = 0x33e4, + .clkr = { + .enable_reg = 0x33e4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_mclk2_clk", + .parent_hws = (const struct clk_hw *[]){ &mclk2_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_mclk3_clk = { + .halt_reg = 0x3414, + .clkr = { + .enable_reg = 0x3414, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_mclk3_clk", + .parent_hws = (const struct clk_hw *[]){ &mclk3_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_top_ahb_clk = { + .halt_reg = 0x3484, + .clkr = { + .enable_reg = 0x3484, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_top_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_ahb_clk = { + .halt_reg = 0x348c, + .clkr = { + .enable_reg = 0x348c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_micro_ahb_clk = { + .halt_reg = 0x3494, + .clkr = { + .enable_reg = 0x3494, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_micro_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_jpeg0_clk = { + .halt_reg = 0x35a8, + .clkr = { + .enable_reg = 0x35a8, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_jpeg0_clk", + .parent_hws = (const struct clk_hw *[]){ &jpeg0_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_jpeg_ahb_clk = { + .halt_reg = 0x35b4, + .clkr = { + .enable_reg = 0x35b4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_jpeg_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_jpeg_axi_clk = { + .halt_reg = 0x35b8, + .clkr = { + .enable_reg = 0x35b8, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_jpeg_axi_clk", + .parent_hws = (const struct clk_hw *[]){ &axi_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_vfe0_ahb_clk = { + .halt_reg = 0x3668, + .clkr = { + .enable_reg = 0x3668, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_vfe0_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_vfe1_ahb_clk = { + .halt_reg = 0x3678, + .clkr = { + .enable_reg = 0x3678, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_vfe1_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_vfe0_clk = { + .halt_reg = 0x36a8, + .clkr = { + .enable_reg = 0x36a8, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_vfe0_clk", + .parent_hws = (const struct clk_hw *[]){ &vfe0_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_vfe1_clk = { + .halt_reg = 0x36ac, + .clkr = { + .enable_reg = 0x36ac, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_vfe1_clk", + .parent_hws = (const struct clk_hw *[]){ &vfe1_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_cpp_clk = { + .halt_reg = 0x36b0, + .clkr = { + .enable_reg = 0x36b0, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_cpp_clk", + .parent_hws = (const struct clk_hw *[]){ &cpp_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_cpp_ahb_clk = { + .halt_reg = 0x36b4, + .clkr = { + .enable_reg = 0x36b4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_cpp_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_vfe_vbif_ahb_clk = { + .halt_reg = 0x36b8, + .clkr = { + .enable_reg = 0x36b8, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_vfe_vbif_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_vfe_vbif_axi_clk = { + .halt_reg = 0x36bc, + .clkr = { + .enable_reg = 0x36bc, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_vfe_vbif_axi_clk", + .parent_hws = (const struct clk_hw *[]){ &axi_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_cpp_axi_clk = { + .halt_reg = 0x36c4, + .clkr = { + .enable_reg = 0x36c4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_cpp_axi_clk", + .parent_hws = (const struct clk_hw *[]){ &axi_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch camss_cpp_vbif_ahb_clk = { + .halt_reg = 0x36c8, + .clkr = { + .enable_reg = 0x36c8, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_cpp_vbif_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_csi_vfe0_clk = { + .halt_reg = 0x3704, + .clkr = { + .enable_reg = 0x3704, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csi_vfe0_clk", + .parent_hws = (const struct clk_hw *[]){ &vfe0_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_csi_vfe1_clk = { + .halt_reg = 0x3714, + .clkr = { + .enable_reg = 0x3714, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csi_vfe1_clk", + .parent_hws = (const struct clk_hw *[]){ &vfe1_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_vfe0_stream_clk = { + .halt_reg = 0x3720, + .clkr = { + .enable_reg = 0x3720, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_vfe0_stream_clk", + .parent_hws = (const struct clk_hw *[]){ &vfe0_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_vfe1_stream_clk = { + .halt_reg = 0x3724, + .clkr = { + .enable_reg = 0x3724, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_vfe1_stream_clk", + .parent_hws = (const struct clk_hw *[]){ &vfe1_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_cphy_csid0_clk = { + .halt_reg = 0x3730, + .clkr = { + .enable_reg = 0x3730, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_cphy_csid0_clk", + .parent_hws = (const struct clk_hw *[]){ &csiphy_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_cphy_csid1_clk = { + .halt_reg = 0x3734, + .clkr = { + .enable_reg = 0x3734, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_cphy_csid1_clk", + .parent_hws = (const struct clk_hw *[]){ &csiphy_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_cphy_csid2_clk = { + .halt_reg = 0x3738, + .clkr = { + .enable_reg = 0x3738, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_cphy_csid2_clk", + .parent_hws = (const struct clk_hw *[]){ &csiphy_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_cphy_csid3_clk = { + .halt_reg = 0x373c, + .clkr = { + .enable_reg = 0x373c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_cphy_csid3_clk", + .parent_hws = (const struct clk_hw *[]){ &csiphy_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_csiphy0_clk = { + .halt_reg = 0x3740, + .clkr = { + .enable_reg = 0x3740, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csiphy0_clk", + .parent_hws = (const struct clk_hw *[]){ &csiphy_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_csiphy1_clk = { + .halt_reg = 0x3744, + .clkr = { + .enable_reg = 0x3744, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csiphy1_clk", + .parent_hws = (const struct clk_hw *[]){ &csiphy_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch camss_csiphy2_clk = { + .halt_reg = 0x3748, + .clkr = { + .enable_reg = 0x3748, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "camss_csiphy2_clk", + .parent_hws = (const struct clk_hw *[]){ &csiphy_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch fd_core_clk = { + .halt_reg = 0x3b68, + .clkr = { + .enable_reg = 0x3b68, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "fd_core_clk", + .parent_hws = (const struct clk_hw *[]){ &fd_core_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch fd_core_uar_clk = { + .halt_reg = 0x3b6c, + .clkr = { + .enable_reg = 0x3b6c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "fd_core_uar_clk", + .parent_hws = (const struct clk_hw *[]){ &fd_core_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch fd_ahb_clk = { + .halt_reg = 0x3b74, + .clkr = { + .enable_reg = 0x3b74, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "fd_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch mnoc_ahb_clk = { + .halt_reg = 0x5024, + .clkr = { + .enable_reg = 0x5024, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mnoc_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch bimc_smmu_ahb_clk = { + .halt_reg = 0xe004, + .clkr = { + .enable_reg = 0xe004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "bimc_smmu_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch bimc_smmu_axi_clk = { + .halt_reg = 0xe008, + .clkr = { + .enable_reg = 0xe008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "bimc_smmu_axi_clk", + .parent_hws = (const struct clk_hw *[]){ &axi_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mnoc_maxi_clk = { + .halt_reg = 0xf004, + .clkr = { + .enable_reg = 0xf004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mnoc_maxi_clk", + .parent_hws = (const struct clk_hw *[]){ &maxi_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch vmem_maxi_clk = { + .halt_reg = 0xf064, + .clkr = { + .enable_reg = 0xf064, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "vmem_maxi_clk", + .parent_hws = (const struct clk_hw *[]){ &maxi_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch vmem_ahb_clk = { + .halt_reg = 0xf068, + .clkr = { + .enable_reg = 0xf068, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "vmem_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_hw *mmcc_msm8998_hws[] = { + &gpll0_div.hw, +}; + +static struct gdsc video_top_gdsc = { + .gdscr = 0x1024, + .pd = { + .name = "video_top", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc video_subcore0_gdsc = { + .gdscr = 0x1040, + .pd = { + .name = "video_subcore0", + }, + .parent = &video_top_gdsc.pd, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc video_subcore1_gdsc = { + .gdscr = 0x1044, + .pd = { + .name = "video_subcore1", + }, + .parent = &video_top_gdsc.pd, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc mdss_gdsc = { + .gdscr = 0x2304, + .cxcs = (unsigned int []){ 0x2310, 0x2350, 0x231c, 0x2320 }, + .cxc_count = 4, + .pd = { + .name = "mdss", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc camss_top_gdsc = { + .gdscr = 0x34a0, + .cxcs = (unsigned int []){ 0x35b8, 0x36c4, 0x3704, 0x3714, 0x3494, + 0x35a8, 0x3868 }, + .cxc_count = 7, + .pd = { + .name = "camss_top", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc camss_vfe0_gdsc = { + .gdscr = 0x3664, + .pd = { + .name = "camss_vfe0", + }, + .parent = &camss_top_gdsc.pd, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc camss_vfe1_gdsc = { + .gdscr = 0x3674, + .pd = { + .name = "camss_vfe1_gdsc", + }, + .parent = &camss_top_gdsc.pd, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc camss_cpp_gdsc = { + .gdscr = 0x36d4, + .pd = { + .name = "camss_cpp", + }, + .parent = &camss_top_gdsc.pd, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc bimc_smmu_gdsc = { + .gdscr = 0xe020, + .gds_hw_ctrl = 0xe024, + .pd = { + .name = "bimc_smmu", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = HW_CTRL, +}; + +static struct clk_regmap *mmcc_msm8998_clocks[] = { + [MMPLL0] = &mmpll0.clkr, + [MMPLL0_OUT_EVEN] = &mmpll0_out_even.clkr, + [MMPLL1] = &mmpll1.clkr, + [MMPLL1_OUT_EVEN] = &mmpll1_out_even.clkr, + [MMPLL3] = &mmpll3.clkr, + [MMPLL3_OUT_EVEN] = &mmpll3_out_even.clkr, + [MMPLL4] = &mmpll4.clkr, + [MMPLL4_OUT_EVEN] = &mmpll4_out_even.clkr, + [MMPLL5] = &mmpll5.clkr, + [MMPLL5_OUT_EVEN] = &mmpll5_out_even.clkr, + [MMPLL6] = &mmpll6.clkr, + [MMPLL6_OUT_EVEN] = &mmpll6_out_even.clkr, + [MMPLL7] = &mmpll7.clkr, + [MMPLL7_OUT_EVEN] = &mmpll7_out_even.clkr, + [MMPLL10] = &mmpll10.clkr, + [MMPLL10_OUT_EVEN] = &mmpll10_out_even.clkr, + [BYTE0_CLK_SRC] = &byte0_clk_src.clkr, + [BYTE1_CLK_SRC] = &byte1_clk_src.clkr, + [CCI_CLK_SRC] = &cci_clk_src.clkr, + [CPP_CLK_SRC] = &cpp_clk_src.clkr, + [CSI0_CLK_SRC] = &csi0_clk_src.clkr, + [CSI1_CLK_SRC] = &csi1_clk_src.clkr, + [CSI2_CLK_SRC] = &csi2_clk_src.clkr, + [CSI3_CLK_SRC] = &csi3_clk_src.clkr, + [CSIPHY_CLK_SRC] = &csiphy_clk_src.clkr, + [CSI0PHYTIMER_CLK_SRC] = &csi0phytimer_clk_src.clkr, + [CSI1PHYTIMER_CLK_SRC] = &csi1phytimer_clk_src.clkr, + [CSI2PHYTIMER_CLK_SRC] = &csi2phytimer_clk_src.clkr, + [DP_AUX_CLK_SRC] = &dp_aux_clk_src.clkr, + [DP_CRYPTO_CLK_SRC] = &dp_crypto_clk_src.clkr, + [DP_LINK_CLK_SRC] = &dp_link_clk_src.clkr, + [DP_PIXEL_CLK_SRC] = &dp_pixel_clk_src.clkr, + [ESC0_CLK_SRC] = &esc0_clk_src.clkr, + [ESC1_CLK_SRC] = &esc1_clk_src.clkr, + [EXTPCLK_CLK_SRC] = &extpclk_clk_src.clkr, + [FD_CORE_CLK_SRC] = &fd_core_clk_src.clkr, + [HDMI_CLK_SRC] = &hdmi_clk_src.clkr, + [JPEG0_CLK_SRC] = &jpeg0_clk_src.clkr, + [MAXI_CLK_SRC] = &maxi_clk_src.clkr, + [MCLK0_CLK_SRC] = &mclk0_clk_src.clkr, + [MCLK1_CLK_SRC] = &mclk1_clk_src.clkr, + [MCLK2_CLK_SRC] = &mclk2_clk_src.clkr, + [MCLK3_CLK_SRC] = &mclk3_clk_src.clkr, + [MDP_CLK_SRC] = &mdp_clk_src.clkr, + [VSYNC_CLK_SRC] = &vsync_clk_src.clkr, + [AHB_CLK_SRC] = &ahb_clk_src.clkr, + [AXI_CLK_SRC] = &axi_clk_src.clkr, + [PCLK0_CLK_SRC] = &pclk0_clk_src.clkr, + [PCLK1_CLK_SRC] = &pclk1_clk_src.clkr, + [ROT_CLK_SRC] = &rot_clk_src.clkr, + [VIDEO_CORE_CLK_SRC] = &video_core_clk_src.clkr, + [VIDEO_SUBCORE0_CLK_SRC] = &video_subcore0_clk_src.clkr, + [VIDEO_SUBCORE1_CLK_SRC] = &video_subcore1_clk_src.clkr, + [VFE0_CLK_SRC] = &vfe0_clk_src.clkr, + [VFE1_CLK_SRC] = &vfe1_clk_src.clkr, + [MISC_AHB_CLK] = &misc_ahb_clk.clkr, + [VIDEO_CORE_CLK] = &video_core_clk.clkr, + [VIDEO_AHB_CLK] = &video_ahb_clk.clkr, + [VIDEO_AXI_CLK] = &video_axi_clk.clkr, + [VIDEO_MAXI_CLK] = &video_maxi_clk.clkr, + [VIDEO_SUBCORE0_CLK] = &video_subcore0_clk.clkr, + [VIDEO_SUBCORE1_CLK] = &video_subcore1_clk.clkr, + [MDSS_AHB_CLK] = &mdss_ahb_clk.clkr, + [MDSS_HDMI_DP_AHB_CLK] = &mdss_hdmi_dp_ahb_clk.clkr, + [MDSS_AXI_CLK] = &mdss_axi_clk.clkr, + [MDSS_PCLK0_CLK] = &mdss_pclk0_clk.clkr, + [MDSS_PCLK1_CLK] = &mdss_pclk1_clk.clkr, + [MDSS_MDP_CLK] = &mdss_mdp_clk.clkr, + [MDSS_MDP_LUT_CLK] = &mdss_mdp_lut_clk.clkr, + [MDSS_EXTPCLK_CLK] = &mdss_extpclk_clk.clkr, + [MDSS_VSYNC_CLK] = &mdss_vsync_clk.clkr, + [MDSS_HDMI_CLK] = &mdss_hdmi_clk.clkr, + [MDSS_BYTE0_CLK] = &mdss_byte0_clk.clkr, + [MDSS_BYTE1_CLK] = &mdss_byte1_clk.clkr, + [MDSS_ESC0_CLK] = &mdss_esc0_clk.clkr, + [MDSS_ESC1_CLK] = &mdss_esc1_clk.clkr, + [MDSS_ROT_CLK] = &mdss_rot_clk.clkr, + [MDSS_DP_LINK_CLK] = &mdss_dp_link_clk.clkr, + [MDSS_DP_LINK_INTF_CLK] = &mdss_dp_link_intf_clk.clkr, + [MDSS_DP_CRYPTO_CLK] = &mdss_dp_crypto_clk.clkr, + [MDSS_DP_PIXEL_CLK] = &mdss_dp_pixel_clk.clkr, + [MDSS_DP_AUX_CLK] = &mdss_dp_aux_clk.clkr, + [MDSS_BYTE0_INTF_CLK] = &mdss_byte0_intf_clk.clkr, + [MDSS_BYTE1_INTF_CLK] = &mdss_byte1_intf_clk.clkr, + [CAMSS_CSI0PHYTIMER_CLK] = &camss_csi0phytimer_clk.clkr, + [CAMSS_CSI1PHYTIMER_CLK] = &camss_csi1phytimer_clk.clkr, + [CAMSS_CSI2PHYTIMER_CLK] = &camss_csi2phytimer_clk.clkr, + [CAMSS_CSI0_CLK] = &camss_csi0_clk.clkr, + [CAMSS_CSI0_AHB_CLK] = &camss_csi0_ahb_clk.clkr, + [CAMSS_CSI0RDI_CLK] = &camss_csi0rdi_clk.clkr, + [CAMSS_CSI0PIX_CLK] = &camss_csi0pix_clk.clkr, + [CAMSS_CSI1_CLK] = &camss_csi1_clk.clkr, + [CAMSS_CSI1_AHB_CLK] = &camss_csi1_ahb_clk.clkr, + [CAMSS_CSI1RDI_CLK] = &camss_csi1rdi_clk.clkr, + [CAMSS_CSI1PIX_CLK] = &camss_csi1pix_clk.clkr, + [CAMSS_CSI2_CLK] = &camss_csi2_clk.clkr, + [CAMSS_CSI2_AHB_CLK] = &camss_csi2_ahb_clk.clkr, + [CAMSS_CSI2RDI_CLK] = &camss_csi2rdi_clk.clkr, + [CAMSS_CSI2PIX_CLK] = &camss_csi2pix_clk.clkr, + [CAMSS_CSI3_CLK] = &camss_csi3_clk.clkr, + [CAMSS_CSI3_AHB_CLK] = &camss_csi3_ahb_clk.clkr, + [CAMSS_CSI3RDI_CLK] = &camss_csi3rdi_clk.clkr, + [CAMSS_CSI3PIX_CLK] = &camss_csi3pix_clk.clkr, + [CAMSS_ISPIF_AHB_CLK] = &camss_ispif_ahb_clk.clkr, + [CAMSS_CCI_CLK] = &camss_cci_clk.clkr, + [CAMSS_CCI_AHB_CLK] = &camss_cci_ahb_clk.clkr, + [CAMSS_MCLK0_CLK] = &camss_mclk0_clk.clkr, + [CAMSS_MCLK1_CLK] = &camss_mclk1_clk.clkr, + [CAMSS_MCLK2_CLK] = &camss_mclk2_clk.clkr, + [CAMSS_MCLK3_CLK] = &camss_mclk3_clk.clkr, + [CAMSS_TOP_AHB_CLK] = &camss_top_ahb_clk.clkr, + [CAMSS_AHB_CLK] = &camss_ahb_clk.clkr, + [CAMSS_MICRO_AHB_CLK] = &camss_micro_ahb_clk.clkr, + [CAMSS_JPEG0_CLK] = &camss_jpeg0_clk.clkr, + [CAMSS_JPEG_AHB_CLK] = &camss_jpeg_ahb_clk.clkr, + [CAMSS_JPEG_AXI_CLK] = &camss_jpeg_axi_clk.clkr, + [CAMSS_VFE0_AHB_CLK] = &camss_vfe0_ahb_clk.clkr, + [CAMSS_VFE1_AHB_CLK] = &camss_vfe1_ahb_clk.clkr, + [CAMSS_VFE0_CLK] = &camss_vfe0_clk.clkr, + [CAMSS_VFE1_CLK] = &camss_vfe1_clk.clkr, + [CAMSS_CPP_CLK] = &camss_cpp_clk.clkr, + [CAMSS_CPP_AHB_CLK] = &camss_cpp_ahb_clk.clkr, + [CAMSS_VFE_VBIF_AHB_CLK] = &camss_vfe_vbif_ahb_clk.clkr, + [CAMSS_VFE_VBIF_AXI_CLK] = &camss_vfe_vbif_axi_clk.clkr, + [CAMSS_CPP_AXI_CLK] = &camss_cpp_axi_clk.clkr, + [CAMSS_CPP_VBIF_AHB_CLK] = &camss_cpp_vbif_ahb_clk.clkr, + [CAMSS_CSI_VFE0_CLK] = &camss_csi_vfe0_clk.clkr, + [CAMSS_CSI_VFE1_CLK] = &camss_csi_vfe1_clk.clkr, + [CAMSS_VFE0_STREAM_CLK] = &camss_vfe0_stream_clk.clkr, + [CAMSS_VFE1_STREAM_CLK] = &camss_vfe1_stream_clk.clkr, + [CAMSS_CPHY_CSID0_CLK] = &camss_cphy_csid0_clk.clkr, + [CAMSS_CPHY_CSID1_CLK] = &camss_cphy_csid1_clk.clkr, + [CAMSS_CPHY_CSID2_CLK] = &camss_cphy_csid2_clk.clkr, + [CAMSS_CPHY_CSID3_CLK] = &camss_cphy_csid3_clk.clkr, + [CAMSS_CSIPHY0_CLK] = &camss_csiphy0_clk.clkr, + [CAMSS_CSIPHY1_CLK] = &camss_csiphy1_clk.clkr, + [CAMSS_CSIPHY2_CLK] = &camss_csiphy2_clk.clkr, + [FD_CORE_CLK] = &fd_core_clk.clkr, + [FD_CORE_UAR_CLK] = &fd_core_uar_clk.clkr, + [FD_AHB_CLK] = &fd_ahb_clk.clkr, + [MNOC_AHB_CLK] = &mnoc_ahb_clk.clkr, + [BIMC_SMMU_AHB_CLK] = &bimc_smmu_ahb_clk.clkr, + [BIMC_SMMU_AXI_CLK] = &bimc_smmu_axi_clk.clkr, + [MNOC_MAXI_CLK] = &mnoc_maxi_clk.clkr, + [VMEM_MAXI_CLK] = &vmem_maxi_clk.clkr, + [VMEM_AHB_CLK] = &vmem_ahb_clk.clkr, +}; + +static struct gdsc *mmcc_msm8998_gdscs[] = { + [VIDEO_TOP_GDSC] = &video_top_gdsc, + [VIDEO_SUBCORE0_GDSC] = &video_subcore0_gdsc, + [VIDEO_SUBCORE1_GDSC] = &video_subcore1_gdsc, + [MDSS_GDSC] = &mdss_gdsc, + [CAMSS_TOP_GDSC] = &camss_top_gdsc, + [CAMSS_VFE0_GDSC] = &camss_vfe0_gdsc, + [CAMSS_VFE1_GDSC] = &camss_vfe1_gdsc, + [CAMSS_CPP_GDSC] = &camss_cpp_gdsc, + [BIMC_SMMU_GDSC] = &bimc_smmu_gdsc, +}; + +static const struct qcom_reset_map mmcc_msm8998_resets[] = { + [SPDM_BCR] = { 0x200 }, + [SPDM_RM_BCR] = { 0x300 }, + [MISC_BCR] = { 0x320 }, + [VIDEO_TOP_BCR] = { 0x1020 }, + [THROTTLE_VIDEO_BCR] = { 0x1180 }, + [MDSS_BCR] = { 0x2300 }, + [THROTTLE_MDSS_BCR] = { 0x2460 }, + [CAMSS_PHY0_BCR] = { 0x3020 }, + [CAMSS_PHY1_BCR] = { 0x3050 }, + [CAMSS_PHY2_BCR] = { 0x3080 }, + [CAMSS_CSI0_BCR] = { 0x30b0 }, + [CAMSS_CSI0RDI_BCR] = { 0x30d0 }, + [CAMSS_CSI0PIX_BCR] = { 0x30e0 }, + [CAMSS_CSI1_BCR] = { 0x3120 }, + [CAMSS_CSI1RDI_BCR] = { 0x3140 }, + [CAMSS_CSI1PIX_BCR] = { 0x3150 }, + [CAMSS_CSI2_BCR] = { 0x3180 }, + [CAMSS_CSI2RDI_BCR] = { 0x31a0 }, + [CAMSS_CSI2PIX_BCR] = { 0x31b0 }, + [CAMSS_CSI3_BCR] = { 0x31e0 }, + [CAMSS_CSI3RDI_BCR] = { 0x3200 }, + [CAMSS_CSI3PIX_BCR] = { 0x3210 }, + [CAMSS_ISPIF_BCR] = { 0x3220 }, + [CAMSS_CCI_BCR] = { 0x3340 }, + [CAMSS_TOP_BCR] = { 0x3480 }, + [CAMSS_AHB_BCR] = { 0x3488 }, + [CAMSS_MICRO_BCR] = { 0x3490 }, + [CAMSS_JPEG_BCR] = { 0x35a0 }, + [CAMSS_VFE0_BCR] = { 0x3660 }, + [CAMSS_VFE1_BCR] = { 0x3670 }, + [CAMSS_VFE_VBIF_BCR] = { 0x36a0 }, + [CAMSS_CPP_TOP_BCR] = { 0x36c0 }, + [CAMSS_CPP_BCR] = { 0x36d0 }, + [CAMSS_CSI_VFE0_BCR] = { 0x3700 }, + [CAMSS_CSI_VFE1_BCR] = { 0x3710 }, + [CAMSS_FD_BCR] = { 0x3b60 }, + [THROTTLE_CAMSS_BCR] = { 0x3c30 }, + [MNOCAHB_BCR] = { 0x5020 }, + [MNOCAXI_BCR] = { 0xd020 }, + [BMIC_SMMU_BCR] = { 0xe000 }, + [MNOC_MAXI_BCR] = { 0xf000 }, + [VMEM_BCR] = { 0xf060 }, + [BTO_BCR] = { 0x10004 }, +}; + +static const struct regmap_config mmcc_msm8998_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x10004, + .fast_io = true, +}; + +static const struct qcom_cc_desc mmcc_msm8998_desc = { + .config = &mmcc_msm8998_regmap_config, + .clks = mmcc_msm8998_clocks, + .num_clks = ARRAY_SIZE(mmcc_msm8998_clocks), + .resets = mmcc_msm8998_resets, + .num_resets = ARRAY_SIZE(mmcc_msm8998_resets), + .gdscs = mmcc_msm8998_gdscs, + .num_gdscs = ARRAY_SIZE(mmcc_msm8998_gdscs), + .clk_hws = mmcc_msm8998_hws, + .num_clk_hws = ARRAY_SIZE(mmcc_msm8998_hws), +}; + +static const struct of_device_id mmcc_msm8998_match_table[] = { + { .compatible = "qcom,mmcc-msm8998" }, + { } +}; +MODULE_DEVICE_TABLE(of, mmcc_msm8998_match_table); + +static int mmcc_msm8998_probe(struct platform_device *pdev) +{ + struct regmap *regmap; + + regmap = qcom_cc_map(pdev, &mmcc_msm8998_desc); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + return qcom_cc_really_probe(pdev, &mmcc_msm8998_desc, regmap); +} + +static struct platform_driver mmcc_msm8998_driver = { + .probe = mmcc_msm8998_probe, + .driver = { + .name = "mmcc-msm8998", + .of_match_table = mmcc_msm8998_match_table, + }, +}; +module_platform_driver(mmcc_msm8998_driver); + +MODULE_DESCRIPTION("QCOM MMCC MSM8998 Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/qcom/videocc-sc7180.c b/drivers/clk/qcom/videocc-sc7180.c new file mode 100644 index 000000000000..76add30024aa --- /dev/null +++ b/drivers/clk/qcom/videocc-sc7180.c @@ -0,0 +1,259 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + */ + +#include <linux/clk-provider.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> + +#include <dt-bindings/clock/qcom,videocc-sc7180.h> + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "common.h" +#include "gdsc.h" + +enum { + P_BI_TCXO, + P_CHIP_SLEEP_CLK, + P_CORE_BI_PLL_TEST_SE, + P_VIDEO_PLL0_OUT_EVEN, + P_VIDEO_PLL0_OUT_MAIN, + P_VIDEO_PLL0_OUT_ODD, +}; + +static const struct pll_vco fabia_vco[] = { + { 249600000, 2000000000, 0 }, +}; + +static struct clk_alpha_pll video_pll0 = { + .offset = 0x42c, + .vco_table = fabia_vco, + .num_vco = ARRAY_SIZE(fabia_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "video_pll0", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fabia_ops, + }, + }, +}; + +static const struct parent_map video_cc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_VIDEO_PLL0_OUT_MAIN, 1 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const struct clk_parent_data video_cc_parent_data_1[] = { + { .fw_name = "bi_tcxo" }, + { .hw = &video_pll0.clkr.hw }, + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, +}; + +static const struct freq_tbl ftbl_video_cc_venus_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(150000000, P_VIDEO_PLL0_OUT_MAIN, 4, 0, 0), + F(270000000, P_VIDEO_PLL0_OUT_MAIN, 2.5, 0, 0), + F(340000000, P_VIDEO_PLL0_OUT_MAIN, 2, 0, 0), + F(434000000, P_VIDEO_PLL0_OUT_MAIN, 2, 0, 0), + F(500000000, P_VIDEO_PLL0_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 video_cc_venus_clk_src = { + .cmd_rcgr = 0x7f0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_1, + .freq_tbl = ftbl_video_cc_venus_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "video_cc_venus_clk_src", + .parent_data = video_cc_parent_data_1, + .num_parents = 3, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_branch video_cc_vcodec0_axi_clk = { + .halt_reg = 0x9ec, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9ec, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "video_cc_vcodec0_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_vcodec0_core_clk = { + .halt_reg = 0x890, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x890, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "video_cc_vcodec0_core_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &video_cc_venus_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_venus_ahb_clk = { + .halt_reg = 0xa4c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xa4c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "video_cc_venus_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_venus_ctl_axi_clk = { + .halt_reg = 0x9cc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9cc, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "video_cc_venus_ctl_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_venus_ctl_core_clk = { + .halt_reg = 0x850, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x850, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "video_cc_venus_ctl_core_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &video_cc_venus_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc venus_gdsc = { + .gdscr = 0x814, + .pd = { + .name = "venus_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc vcodec0_gdsc = { + .gdscr = 0x874, + .pd = { + .name = "vcodec0_gdsc", + }, + .flags = HW_CTRL, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct clk_regmap *video_cc_sc7180_clocks[] = { + [VIDEO_CC_VCODEC0_AXI_CLK] = &video_cc_vcodec0_axi_clk.clkr, + [VIDEO_CC_VCODEC0_CORE_CLK] = &video_cc_vcodec0_core_clk.clkr, + [VIDEO_CC_VENUS_AHB_CLK] = &video_cc_venus_ahb_clk.clkr, + [VIDEO_CC_VENUS_CLK_SRC] = &video_cc_venus_clk_src.clkr, + [VIDEO_CC_VENUS_CTL_AXI_CLK] = &video_cc_venus_ctl_axi_clk.clkr, + [VIDEO_CC_VENUS_CTL_CORE_CLK] = &video_cc_venus_ctl_core_clk.clkr, + [VIDEO_PLL0] = &video_pll0.clkr, +}; + +static struct gdsc *video_cc_sc7180_gdscs[] = { + [VENUS_GDSC] = &venus_gdsc, + [VCODEC0_GDSC] = &vcodec0_gdsc, +}; + +static const struct regmap_config video_cc_sc7180_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0xb94, + .fast_io = true, +}; + +static const struct qcom_cc_desc video_cc_sc7180_desc = { + .config = &video_cc_sc7180_regmap_config, + .clks = video_cc_sc7180_clocks, + .num_clks = ARRAY_SIZE(video_cc_sc7180_clocks), + .gdscs = video_cc_sc7180_gdscs, + .num_gdscs = ARRAY_SIZE(video_cc_sc7180_gdscs), +}; + +static const struct of_device_id video_cc_sc7180_match_table[] = { + { .compatible = "qcom,sc7180-videocc" }, + { } +}; +MODULE_DEVICE_TABLE(of, video_cc_sc7180_match_table); + +static int video_cc_sc7180_probe(struct platform_device *pdev) +{ + struct regmap *regmap; + struct alpha_pll_config video_pll0_config = {}; + + regmap = qcom_cc_map(pdev, &video_cc_sc7180_desc); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + video_pll0_config.l = 0x1f; + video_pll0_config.alpha = 0x4000; + video_pll0_config.user_ctl_val = 0x00000001; + video_pll0_config.user_ctl_hi_val = 0x00004805; + + clk_fabia_pll_configure(&video_pll0, regmap, &video_pll0_config); + + /* Keep VIDEO_CC_XO_CLK ALWAYS-ON */ + regmap_update_bits(regmap, 0x984, 0x1, 0x1); + + return qcom_cc_really_probe(pdev, &video_cc_sc7180_desc, regmap); +} + +static struct platform_driver video_cc_sc7180_driver = { + .probe = video_cc_sc7180_probe, + .driver = { + .name = "sc7180-videocc", + .of_match_table = video_cc_sc7180_match_table, + }, +}; + +static int __init video_cc_sc7180_init(void) +{ + return platform_driver_register(&video_cc_sc7180_driver); +} +subsys_initcall(video_cc_sc7180_init); + +static void __exit video_cc_sc7180_exit(void) +{ + platform_driver_unregister(&video_cc_sc7180_driver); +} +module_exit(video_cc_sc7180_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("QTI VIDEOCC SC7180 Driver"); diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig index 4cd846bc98cc..250d8165167a 100644 --- a/drivers/clk/renesas/Kconfig +++ b/drivers/clk/renesas/Kconfig @@ -20,8 +20,8 @@ config CLK_RENESAS select CLK_R8A7791 if ARCH_R8A7791 || ARCH_R8A7793 select CLK_R8A7792 if ARCH_R8A7792 select CLK_R8A7794 if ARCH_R8A7794 - select CLK_R8A7795 if ARCH_R8A7795 - select CLK_R8A77960 if ARCH_R8A77960 || ARCH_R8A7796 + select CLK_R8A7795 if ARCH_R8A77950 || ARCH_R8A77951 || ARCH_R8A7795 + select CLK_R8A77960 if ARCH_R8A77960 select CLK_R8A77961 if ARCH_R8A77961 select CLK_R8A77965 if ARCH_R8A77965 select CLK_R8A77970 if ARCH_R8A77970 diff --git a/drivers/clk/renesas/r7s9210-cpg-mssr.c b/drivers/clk/renesas/r7s9210-cpg-mssr.c index cf65d4e0e116..443bff08df4c 100644 --- a/drivers/clk/renesas/r7s9210-cpg-mssr.c +++ b/drivers/clk/renesas/r7s9210-cpg-mssr.c @@ -93,6 +93,7 @@ static const struct mssr_mod_clk r7s9210_mod_clks[] __initconst = { DEF_MOD_STB("ether1", 64, R7S9210_CLK_B), DEF_MOD_STB("ether0", 65, R7S9210_CLK_B), + DEF_MOD_STB("spibsc", 83, R7S9210_CLK_P1), DEF_MOD_STB("i2c3", 84, R7S9210_CLK_P1), DEF_MOD_STB("i2c2", 85, R7S9210_CLK_P1), DEF_MOD_STB("i2c1", 86, R7S9210_CLK_P1), diff --git a/drivers/clk/renesas/rcar-gen2-cpg.h b/drivers/clk/renesas/rcar-gen2-cpg.h index db2f57ef2f99..bdcd4a38d48d 100644 --- a/drivers/clk/renesas/rcar-gen2-cpg.h +++ b/drivers/clk/renesas/rcar-gen2-cpg.h @@ -24,10 +24,10 @@ enum rcar_gen2_clk_types { }; struct rcar_gen2_cpg_pll_config { - unsigned int extal_div; - unsigned int pll1_mult; - unsigned int pll3_mult; - unsigned int pll0_mult; /* leave as zero if PLL0CR exists */ + u8 extal_div; + u8 pll1_mult; + u8 pll3_mult; + u8 pll0_mult; /* leave as zero if PLL0CR exists */ }; struct clk *rcar_gen2_cpg_clk_register(struct device *dev, diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c index c97b647db9b6..488f8b3980c5 100644 --- a/drivers/clk/renesas/rcar-gen3-cpg.c +++ b/drivers/clk/renesas/rcar-gen3-cpg.c @@ -470,7 +470,8 @@ static struct clk * __init cpg_rpc_clk_register(const char *name, clk = clk_register_composite(NULL, name, &parent_name, 1, NULL, NULL, &rpc->div.hw, &clk_divider_ops, - &rpc->gate.hw, &clk_gate_ops, 0); + &rpc->gate.hw, &clk_gate_ops, + CLK_SET_RATE_PARENT); if (IS_ERR(clk)) { kfree(rpc); return clk; @@ -506,7 +507,8 @@ static struct clk * __init cpg_rpcd2_clk_register(const char *name, clk = clk_register_composite(NULL, name, &parent_name, 1, NULL, NULL, &rpcd2->fixed.hw, &clk_fixed_factor_ops, - &rpcd2->gate.hw, &clk_gate_ops, 0); + &rpcd2->gate.hw, &clk_gate_ops, + CLK_SET_RATE_PARENT); if (IS_ERR(clk)) kfree(rpcd2); diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c index 198417d56300..10560d963baf 100644 --- a/drivers/clk/rockchip/clk-pll.c +++ b/drivers/clk/rockchip/clk-pll.c @@ -282,7 +282,7 @@ static int rockchip_rk3036_pll_is_enabled(struct clk_hw *hw) return !(pllcon & RK3036_PLLCON1_PWRDOWN); } -static void rockchip_rk3036_pll_init(struct clk_hw *hw) +static int rockchip_rk3036_pll_init(struct clk_hw *hw) { struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); const struct rockchip_pll_rate_table *rate; @@ -290,14 +290,14 @@ static void rockchip_rk3036_pll_init(struct clk_hw *hw) unsigned long drate; if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE)) - return; + return 0; drate = clk_hw_get_rate(hw); rate = rockchip_get_pll_settings(pll, drate); /* when no rate setting for the current rate, rely on clk_set_rate */ if (!rate) - return; + return 0; rockchip_rk3036_pll_get_params(pll, &cur); @@ -319,13 +319,15 @@ static void rockchip_rk3036_pll_init(struct clk_hw *hw) if (!parent) { pr_warn("%s: parent of %s not available\n", __func__, __clk_get_name(hw->clk)); - return; + return 0; } pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n", __func__, __clk_get_name(hw->clk)); rockchip_rk3036_pll_set_params(pll, rate); } + + return 0; } static const struct clk_ops rockchip_rk3036_pll_clk_norate_ops = { @@ -515,7 +517,7 @@ static int rockchip_rk3066_pll_is_enabled(struct clk_hw *hw) return !(pllcon & RK3066_PLLCON3_PWRDOWN); } -static void rockchip_rk3066_pll_init(struct clk_hw *hw) +static int rockchip_rk3066_pll_init(struct clk_hw *hw) { struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); const struct rockchip_pll_rate_table *rate; @@ -523,14 +525,14 @@ static void rockchip_rk3066_pll_init(struct clk_hw *hw) unsigned long drate; if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE)) - return; + return 0; drate = clk_hw_get_rate(hw); rate = rockchip_get_pll_settings(pll, drate); /* when no rate setting for the current rate, rely on clk_set_rate */ if (!rate) - return; + return 0; rockchip_rk3066_pll_get_params(pll, &cur); @@ -543,6 +545,8 @@ static void rockchip_rk3066_pll_init(struct clk_hw *hw) __func__, clk_hw_get_name(hw)); rockchip_rk3066_pll_set_params(pll, rate); } + + return 0; } static const struct clk_ops rockchip_rk3066_pll_clk_norate_ops = { @@ -761,7 +765,7 @@ static int rockchip_rk3399_pll_is_enabled(struct clk_hw *hw) return !(pllcon & RK3399_PLLCON3_PWRDOWN); } -static void rockchip_rk3399_pll_init(struct clk_hw *hw) +static int rockchip_rk3399_pll_init(struct clk_hw *hw) { struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); const struct rockchip_pll_rate_table *rate; @@ -769,14 +773,14 @@ static void rockchip_rk3399_pll_init(struct clk_hw *hw) unsigned long drate; if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE)) - return; + return 0; drate = clk_hw_get_rate(hw); rate = rockchip_get_pll_settings(pll, drate); /* when no rate setting for the current rate, rely on clk_set_rate */ if (!rate) - return; + return 0; rockchip_rk3399_pll_get_params(pll, &cur); @@ -798,13 +802,15 @@ static void rockchip_rk3399_pll_init(struct clk_hw *hw) if (!parent) { pr_warn("%s: parent of %s not available\n", __func__, __clk_get_name(hw->clk)); - return; + return 0; } pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n", __func__, __clk_get_name(hw->clk)); rockchip_rk3399_pll_set_params(pll, rate); } + + return 0; } static const struct clk_ops rockchip_rk3399_pll_clk_norate_ops = { diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index 3a991ca1ee36..c9e5a1fb6653 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -12,6 +12,7 @@ #include <linux/clk-provider.h> #include <linux/of.h> #include <linux/of_address.h> +#include <linux/clk.h> #include "clk.h" #include "clk-cpu.h" @@ -1646,6 +1647,13 @@ static void __init exynos5x_clk_init(struct device_node *np, exynos5x_subcmus); } + /* + * Keep top part of G3D clock path enabled permanently to ensure + * that the internal busses get their clock regardless of the + * main G3D clock enablement status. + */ + clk_prepare_enable(__clk_lookup("mout_sw_aclk_g3d")); + samsung_clk_of_add_provider(np, ctx); } diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c index 49bd7a4c015c..5f66bf879772 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c +++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c @@ -921,11 +921,26 @@ static const struct sunxi_ccu_desc sun50i_a64_ccu_desc = { .num_resets = ARRAY_SIZE(sun50i_a64_ccu_resets), }; +static struct ccu_pll_nb sun50i_a64_pll_cpu_nb = { + .common = &pll_cpux_clk.common, + /* copy from pll_cpux_clk */ + .enable = BIT(31), + .lock = BIT(28), +}; + +static struct ccu_mux_nb sun50i_a64_cpu_nb = { + .common = &cpux_clk.common, + .cm = &cpux_clk.mux, + .delay_us = 1, /* > 8 clock cycles at 24 MHz */ + .bypass_index = 1, /* index of 24 MHz oscillator */ +}; + static int sun50i_a64_ccu_probe(struct platform_device *pdev) { struct resource *res; void __iomem *reg; u32 val; + int ret; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); reg = devm_ioremap_resource(&pdev->dev, res); @@ -939,7 +954,18 @@ static int sun50i_a64_ccu_probe(struct platform_device *pdev) writel(0x515, reg + SUN50I_A64_PLL_MIPI_REG); - return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_a64_ccu_desc); + ret = sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_a64_ccu_desc); + if (ret) + return ret; + + /* Gate then ungate PLL CPU after any rate changes */ + ccu_pll_notifier_register(&sun50i_a64_pll_cpu_nb); + + /* Reparent CPU during PLL CPU rate changes */ + ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk, + &sun50i_a64_cpu_nb); + + return 0; } static const struct of_device_id sun50i_a64_ccu_ids[] = { diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.h b/drivers/clk/sunxi-ng/ccu-sun50i-a64.h index 979929276709..116e6f826d04 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.h +++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.h @@ -36,7 +36,6 @@ #define CLK_PLL_HSIC 18 #define CLK_PLL_DE 19 #define CLK_PLL_DDR1 20 -#define CLK_CPUX 21 #define CLK_AXI 22 #define CLK_APB 23 #define CLK_AHB1 24 diff --git a/drivers/clk/sunxi-ng/ccu-sun6i-a31.h b/drivers/clk/sunxi-ng/ccu-sun6i-a31.h index a361388b4670..3ed2a59b0dc6 100644 --- a/drivers/clk/sunxi-ng/ccu-sun6i-a31.h +++ b/drivers/clk/sunxi-ng/ccu-sun6i-a31.h @@ -32,7 +32,9 @@ /* The PLL_VIDEO1_2X clock is exported */ #define CLK_PLL_GPU 14 -#define CLK_PLL_MIPI 15 + +/* The PLL_VIDEO1_2X clock is exported */ + #define CLK_PLL9 16 #define CLK_PLL10 17 diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a23-a33.h b/drivers/clk/sunxi-ng/ccu-sun8i-a23-a33.h index 72df69291cc6..5bf5c4d13b4c 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-a23-a33.h +++ b/drivers/clk/sunxi-ng/ccu-sun8i-a23-a33.h @@ -24,7 +24,9 @@ #define CLK_PLL_PERIPH 10 #define CLK_PLL_PERIPH_2X 11 #define CLK_PLL_GPU 12 -#define CLK_PLL_MIPI 13 + +/* The PLL MIPI clock is exported */ + #define CLK_PLL_HSIC 14 #define CLK_PLL_DE 15 #define CLK_PLL_DDR1 16 diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r40.h b/drivers/clk/sunxi-ng/ccu-sun8i-r40.h index a69637b6b0c1..6f7071df8e1c 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-r40.h +++ b/drivers/clk/sunxi-ng/ccu-sun8i-r40.h @@ -55,10 +55,6 @@ /* Some more module clocks are exported */ -#define CLK_MBUS 155 - -/* Another bunch of module clocks are exported */ - #define CLK_NUMBER (CLK_OUTB + 1) #endif /* _CCU_SUN8I_R40_H_ */ diff --git a/drivers/clk/sunxi/clk-sun6i-apb0-gates.c b/drivers/clk/sunxi/clk-sun6i-apb0-gates.c index a165e7172346..4c75b0770c74 100644 --- a/drivers/clk/sunxi/clk-sun6i-apb0-gates.c +++ b/drivers/clk/sunxi/clk-sun6i-apb0-gates.c @@ -37,7 +37,6 @@ static int sun6i_a31_apb0_gates_clk_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct clk_onecell_data *clk_data; - const struct of_device_id *device; const struct gates_data *data; const char *clk_parent; const char *clk_name; @@ -50,10 +49,9 @@ static int sun6i_a31_apb0_gates_clk_probe(struct platform_device *pdev) if (!np) return -ENODEV; - device = of_match_device(sun6i_a31_apb0_gates_clk_dt_ids, &pdev->dev); - if (!device) + data = of_device_get_match_data(&pdev->dev); + if (!data) return -ENODEV; - data = device->data; r = platform_get_resource(pdev, IORESOURCE_MEM, 0); reg = devm_ioremap_resource(&pdev->dev, r); diff --git a/drivers/clk/tegra/clk.c b/drivers/clk/tegra/clk.c index e6bd6d1ea012..f6cdce441cf7 100644 --- a/drivers/clk/tegra/clk.c +++ b/drivers/clk/tegra/clk.c @@ -231,8 +231,10 @@ struct clk ** __init tegra_clk_init(void __iomem *regs, int num, int banks) periph_banks = banks; clks = kcalloc(num, sizeof(struct clk *), GFP_KERNEL); - if (!clks) + if (!clks) { kfree(periph_clk_enb_refcnt); + return NULL; + } clk_num = num; diff --git a/drivers/clk/ti/clk-54xx.c b/drivers/clk/ti/clk-54xx.c index c9608e5d993a..14d98a890c02 100644 --- a/drivers/clk/ti/clk-54xx.c +++ b/drivers/clk/ti/clk-54xx.c @@ -35,6 +35,20 @@ static const struct omap_clkctrl_reg_data omap5_dsp_clkctrl_regs[] __initconst = { 0 }, }; +static const char * const omap5_aess_fclk_parents[] __initconst = { + "abe_clk", + NULL, +}; + +static const struct omap_clkctrl_div_data omap5_aess_fclk_data __initconst = { + .max_div = 2, +}; + +static const struct omap_clkctrl_bit_data omap5_aess_bit_data[] __initconst = { + { 24, TI_CLK_DIVIDER, omap5_aess_fclk_parents, &omap5_aess_fclk_data }, + { 0 }, +}; + static const char * const omap5_dmic_gfclk_parents[] __initconst = { "abe_cm:clk:0018:26", "pad_clks_ck", @@ -122,6 +136,7 @@ static const struct omap_clkctrl_bit_data omap5_timer8_bit_data[] __initconst = static const struct omap_clkctrl_reg_data omap5_abe_clkctrl_regs[] __initconst = { { OMAP5_L4_ABE_CLKCTRL, NULL, 0, "abe_iclk" }, + { OMAP5_AESS_CLKCTRL, omap5_aess_bit_data, CLKF_SW_SUP, "abe_cm:clk:0008:24" }, { OMAP5_MCPDM_CLKCTRL, NULL, CLKF_SW_SUP, "pad_clks_ck" }, { OMAP5_DMIC_CLKCTRL, omap5_dmic_bit_data, CLKF_SW_SUP, "abe_cm:clk:0018:24" }, { OMAP5_MCBSP1_CLKCTRL, omap5_mcbsp1_bit_data, CLKF_SW_SUP, "abe_cm:clk:0028:24" }, diff --git a/drivers/clk/ti/clk-7xx.c b/drivers/clk/ti/clk-7xx.c index 5f46782cebeb..14b645093107 100644 --- a/drivers/clk/ti/clk-7xx.c +++ b/drivers/clk/ti/clk-7xx.c @@ -146,6 +146,29 @@ static const struct omap_clkctrl_reg_data dra7_rtc_clkctrl_regs[] __initconst = { 0 }, }; +static const char * const dra7_cam_gfclk_mux_parents[] __initconst = { + "l3_iclk_div", + "core_iss_main_clk", + NULL, +}; + +static const struct omap_clkctrl_bit_data dra7_cam_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_cam_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data dra7_cam_clkctrl_regs[] __initconst = { + { DRA7_CAM_VIP1_CLKCTRL, dra7_cam_bit_data, CLKF_HW_SUP, "l3_iclk_div" }, + { DRA7_CAM_VIP2_CLKCTRL, dra7_cam_bit_data, CLKF_HW_SUP, "l3_iclk_div" }, + { DRA7_CAM_VIP3_CLKCTRL, dra7_cam_bit_data, CLKF_HW_SUP, "l3_iclk_div" }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data dra7_vpe_clkctrl_regs[] __initconst = { + { DRA7_VPE_VPE_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_core_h23x2_ck" }, + { 0 }, +}; + static const struct omap_clkctrl_reg_data dra7_coreaon_clkctrl_regs[] __initconst = { { DRA7_COREAON_SMARTREFLEX_MPU_CLKCTRL, NULL, CLKF_SW_SUP, "wkupaon_iclk_mux" }, { DRA7_COREAON_SMARTREFLEX_CORE_CLKCTRL, NULL, CLKF_SW_SUP, "wkupaon_iclk_mux" }, @@ -275,6 +298,40 @@ static const struct omap_clkctrl_reg_data dra7_dss_clkctrl_regs[] __initconst = { 0 }, }; +static const char * const dra7_gpu_core_mux_parents[] __initconst = { + "dpll_core_h14x2_ck", + "dpll_per_h14x2_ck", + "dpll_gpu_m2_ck", + NULL, +}; + +static const char * const dra7_gpu_hyd_mux_parents[] __initconst = { + "dpll_core_h14x2_ck", + "dpll_per_h14x2_ck", + "dpll_gpu_m2_ck", + NULL, +}; + +static const char * const dra7_gpu_sys_clk_parents[] __initconst = { + "sys_clkin", + NULL, +}; + +static const struct omap_clkctrl_div_data dra7_gpu_sys_clk_data __initconst = { + .max_div = 2, +}; + +static const struct omap_clkctrl_bit_data dra7_gpu_core_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_gpu_core_mux_parents, NULL, }, + { 26, TI_CLK_MUX, dra7_gpu_hyd_mux_parents, NULL, }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data dra7_gpu_clkctrl_regs[] __initconst = { + { DRA7_GPU_CLKCTRL, dra7_gpu_core_bit_data, CLKF_SW_SUP, "gpu_cm:clk:0000:24", }, + { 0 }, +}; + static const char * const dra7_mmc1_fclk_mux_parents[] __initconst = { "func_128m_clk", "dpll_per_m2x2_ck", @@ -405,7 +462,7 @@ static const struct omap_clkctrl_bit_data dra7_gmac_bit_data[] __initconst = { }; static const struct omap_clkctrl_reg_data dra7_gmac_clkctrl_regs[] __initconst = { - { DRA7_GMAC_GMAC_CLKCTRL, dra7_gmac_bit_data, CLKF_SW_SUP, "dpll_gmac_ck" }, + { DRA7_GMAC_GMAC_CLKCTRL, dra7_gmac_bit_data, CLKF_SW_SUP, "gmac_main_clk" }, { 0 }, }; @@ -769,6 +826,7 @@ const struct omap_clkctrl_data dra7_clkctrl_data[] __initconst = { { 0x4a005550, dra7_ipu_clkctrl_regs }, { 0x4a005620, dra7_dsp2_clkctrl_regs }, { 0x4a005720, dra7_rtc_clkctrl_regs }, + { 0x4a005760, dra7_vpe_clkctrl_regs }, { 0x4a008620, dra7_coreaon_clkctrl_regs }, { 0x4a008720, dra7_l3main1_clkctrl_regs }, { 0x4a008920, dra7_ipu2_clkctrl_regs }, @@ -777,7 +835,9 @@ const struct omap_clkctrl_data dra7_clkctrl_data[] __initconst = { { 0x4a008c00, dra7_atl_clkctrl_regs }, { 0x4a008d20, dra7_l4cfg_clkctrl_regs }, { 0x4a008e20, dra7_l3instr_clkctrl_regs }, + { 0x4a009020, dra7_cam_clkctrl_regs }, { 0x4a009120, dra7_dss_clkctrl_regs }, + { 0x4a009220, dra7_gpu_clkctrl_regs }, { 0x4a009320, dra7_l3init_clkctrl_regs }, { 0x4a0093b0, dra7_pcie_clkctrl_regs }, { 0x4a0093d0, dra7_gmac_clkctrl_regs }, diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c index e0b8ed3a1e80..3da33c786d77 100644 --- a/drivers/clk/ti/clk.c +++ b/drivers/clk/ti/clk.c @@ -171,7 +171,9 @@ void __init ti_dt_clocks_register(struct ti_dt_clk oclks[]) node = of_find_node_by_name(NULL, buf); if (num_args && compat_mode) { parent = node; - node = of_get_child_by_name(parent, "clk"); + node = of_get_child_by_name(parent, "clock"); + if (!node) + node = of_get_child_by_name(parent, "clk"); of_node_put(parent); } diff --git a/drivers/clk/ti/clkctrl.c b/drivers/clk/ti/clkctrl.c index 17b9a761242f..062266034d84 100644 --- a/drivers/clk/ti/clkctrl.c +++ b/drivers/clk/ti/clkctrl.c @@ -440,6 +440,63 @@ static void __init _clkctrl_add_provider(void *data, of_clk_add_hw_provider(np, _ti_omap4_clkctrl_xlate, data); } +/* Get clock name based on compatible string for clkctrl */ +static char * __init clkctrl_get_name(struct device_node *np) +{ + struct property *prop; + const int prefix_len = 11; + const char *compat; + char *name; + + of_property_for_each_string(np, "compatible", prop, compat) { + if (!strncmp("ti,clkctrl-", compat, prefix_len)) { + /* Two letter minimum name length for l3, l4 etc */ + if (strnlen(compat + prefix_len, 16) < 2) + continue; + name = kasprintf(GFP_KERNEL, "%s", compat + prefix_len); + if (!name) + continue; + strreplace(name, '-', '_'); + + return name; + } + } + of_node_put(np); + + return NULL; +} + +/* Get clkctrl clock base name based on clkctrl_name or dts node */ +static const char * __init clkctrl_get_clock_name(struct device_node *np, + const char *clkctrl_name, + int offset, int index, + bool legacy_naming) +{ + char *clock_name; + + /* l4per-clkctrl:1234:0 style naming based on clkctrl_name */ + if (clkctrl_name && !legacy_naming) { + clock_name = kasprintf(GFP_KERNEL, "%s-clkctrl:%04x:%d", + clkctrl_name, offset, index); + strreplace(clock_name, '_', '-'); + + return clock_name; + } + + /* l4per:1234:0 old style naming based on clkctrl_name */ + if (clkctrl_name) + return kasprintf(GFP_KERNEL, "%s_cm:clk:%04x:%d", + clkctrl_name, offset, index); + + /* l4per_cm:1234:0 old style naming based on parent node name */ + if (legacy_naming) + return kasprintf(GFP_KERNEL, "%pOFn:clk:%04x:%d", + np->parent, offset, index); + + /* l4per-clkctrl:1234:0 style naming based on node name */ + return kasprintf(GFP_KERNEL, "%pOFn:%04x:%d", np, offset, index); +} + static void __init _ti_omap4_clkctrl_setup(struct device_node *node) { struct omap_clkctrl_provider *provider; @@ -448,8 +505,10 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node) struct clk_init_data init = { NULL }; struct clk_hw_omap *hw; struct clk *clk; - struct omap_clkctrl_clk *clkctrl_clk; + struct omap_clkctrl_clk *clkctrl_clk = NULL; const __be32 *addrp; + bool legacy_naming; + char *clkctrl_name; u32 addr; int ret; char *c; @@ -537,7 +596,19 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node) provider->base = of_iomap(node, 0); - if (ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT) { + legacy_naming = ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT; + clkctrl_name = clkctrl_get_name(node); + if (clkctrl_name) { + provider->clkdm_name = kasprintf(GFP_KERNEL, + "%s_clkdm", clkctrl_name); + goto clkdm_found; + } + + /* + * The code below can be removed when all clkctrl nodes use domain + * specific compatible proprerty and standard clock node naming + */ + if (legacy_naming) { provider->clkdm_name = kasprintf(GFP_KERNEL, "%pOFnxxx", node->parent); if (!provider->clkdm_name) { kfree(provider); @@ -573,7 +644,7 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node) *c = '_'; c++; } - +clkdm_found: INIT_LIST_HEAD(&provider->clocks); /* Generate clocks */ @@ -612,15 +683,15 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node) init.flags = 0; if (reg_data->flags & CLKF_SET_RATE_PARENT) init.flags |= CLK_SET_RATE_PARENT; - if (ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT) - init.name = kasprintf(GFP_KERNEL, "%pOFn:%pOFn:%04x:%d", - node->parent, node, - reg_data->offset, 0); - else - init.name = kasprintf(GFP_KERNEL, "%pOFn:%04x:%d", - node, reg_data->offset, 0); + + init.name = clkctrl_get_clock_name(node, clkctrl_name, + reg_data->offset, 0, + legacy_naming); + if (!init.name) + goto cleanup; + clkctrl_clk = kzalloc(sizeof(*clkctrl_clk), GFP_KERNEL); - if (!init.name || !clkctrl_clk) + if (!clkctrl_clk) goto cleanup; init.ops = &omap4_clkctrl_clk_ops; @@ -642,11 +713,14 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node) if (ret == -EPROBE_DEFER) ti_clk_retry_init(node, provider, _clkctrl_add_provider); + kfree(clkctrl_name); + return; cleanup: kfree(hw); kfree(init.name); + kfree(clkctrl_name); kfree(clkctrl_clk); } CLK_OF_DECLARE(ti_omap4_clkctrl_clock, "ti,clkctrl", diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h index e6995c04001e..f1dd62de2bfc 100644 --- a/drivers/clk/ti/clock.h +++ b/drivers/clk/ti/clock.h @@ -253,7 +253,7 @@ extern const struct clk_ops omap_gate_clk_ops; extern struct ti_clk_features ti_clk_features; -void omap2_init_clk_clkdm(struct clk_hw *hw); +int omap2_init_clk_clkdm(struct clk_hw *hw); int omap2_clkops_enable_clkdm(struct clk_hw *hw); void omap2_clkops_disable_clkdm(struct clk_hw *hw); diff --git a/drivers/clk/ti/clockdomain.c b/drivers/clk/ti/clockdomain.c index 423a99b9f10c..ee56306f79d5 100644 --- a/drivers/clk/ti/clockdomain.c +++ b/drivers/clk/ti/clockdomain.c @@ -101,16 +101,16 @@ void omap2_clkops_disable_clkdm(struct clk_hw *hw) * * Convert a clockdomain name stored in a struct clk 'clk' into a * clockdomain pointer, and save it into the struct clk. Intended to be - * called during clk_register(). No return value. + * called during clk_register(). Returns 0 on success, -EERROR otherwise. */ -void omap2_init_clk_clkdm(struct clk_hw *hw) +int omap2_init_clk_clkdm(struct clk_hw *hw) { struct clk_hw_omap *clk = to_clk_hw_omap(hw); struct clockdomain *clkdm; const char *clk_name; if (!clk->clkdm_name) - return; + return 0; clk_name = __clk_get_name(hw->clk); @@ -123,6 +123,8 @@ void omap2_init_clk_clkdm(struct clk_hw *hw) pr_debug("clock: could not associate clk %s to clkdm %s\n", clk_name, clk->clkdm_name); } + + return 0; } static void __init of_ti_clockdomain_setup(struct device_node *node) diff --git a/drivers/clk/uniphier/clk-uniphier-peri.c b/drivers/clk/uniphier/clk-uniphier-peri.c index 9caa52944b1c..3e32db9dad81 100644 --- a/drivers/clk/uniphier/clk-uniphier-peri.c +++ b/drivers/clk/uniphier/clk-uniphier-peri.c @@ -18,8 +18,8 @@ #define UNIPHIER_PERI_CLK_FI2C(idx, ch) \ UNIPHIER_CLK_GATE("i2c" #ch, (idx), "i2c", 0x24, 24 + (ch)) -#define UNIPHIER_PERI_CLK_SCSSI(idx) \ - UNIPHIER_CLK_GATE("scssi", (idx), "spi", 0x20, 17) +#define UNIPHIER_PERI_CLK_SCSSI(idx, ch) \ + UNIPHIER_CLK_GATE("scssi" #ch, (idx), "spi", 0x20, 17 + (ch)) #define UNIPHIER_PERI_CLK_MCSSI(idx) \ UNIPHIER_CLK_GATE("mcssi", (idx), "spi", 0x24, 14) @@ -35,7 +35,7 @@ const struct uniphier_clk_data uniphier_ld4_peri_clk_data[] = { UNIPHIER_PERI_CLK_I2C(6, 2), UNIPHIER_PERI_CLK_I2C(7, 3), UNIPHIER_PERI_CLK_I2C(8, 4), - UNIPHIER_PERI_CLK_SCSSI(11), + UNIPHIER_PERI_CLK_SCSSI(11, 0), { /* sentinel */ } }; @@ -51,7 +51,10 @@ const struct uniphier_clk_data uniphier_pro4_peri_clk_data[] = { UNIPHIER_PERI_CLK_FI2C(8, 4), UNIPHIER_PERI_CLK_FI2C(9, 5), UNIPHIER_PERI_CLK_FI2C(10, 6), - UNIPHIER_PERI_CLK_SCSSI(11), - UNIPHIER_PERI_CLK_MCSSI(12), + UNIPHIER_PERI_CLK_SCSSI(11, 0), + UNIPHIER_PERI_CLK_SCSSI(12, 1), + UNIPHIER_PERI_CLK_SCSSI(13, 2), + UNIPHIER_PERI_CLK_SCSSI(14, 3), + UNIPHIER_PERI_CLK_MCSSI(15), { /* sentinel */ } }; diff --git a/drivers/clk/ux500/u8500_of_clk.c b/drivers/clk/ux500/u8500_of_clk.c index 72ed97c6662a..0aedd42fad52 100644 --- a/drivers/clk/ux500/u8500_of_clk.c +++ b/drivers/clk/ux500/u8500_of_clk.c @@ -99,8 +99,10 @@ static void u8500_clk_init(struct device_node *np) if (fw_version != NULL) { switch (fw_version->project) { case PRCMU_FW_PROJECT_U8500_C2: + case PRCMU_FW_PROJECT_U8500_MBL: case PRCMU_FW_PROJECT_U8520: case PRCMU_FW_PROJECT_U8420: + case PRCMU_FW_PROJECT_U8420_SYSCLK: sgaclk_parent = "soc0_pll"; break; default: diff --git a/drivers/clk/versatile/Kconfig b/drivers/clk/versatile/Kconfig index ac766855ba16..c2618f1477a2 100644 --- a/drivers/clk/versatile/Kconfig +++ b/drivers/clk/versatile/Kconfig @@ -9,7 +9,7 @@ config COMMON_CLK_VERSATILE COMPILE_TEST select REGMAP_MMIO ---help--- - Supports clocking on ARM Reference designs: + Supports clocking on ARM Reference designs: - Integrator/AP and Integrator/CP - RealView PB1176, EB, PB11MP and PBX - Versatile Express diff --git a/drivers/clk/zynqmp/clkc.c b/drivers/clk/zynqmp/clkc.c index a11f93ecbf34..10e89f23880b 100644 --- a/drivers/clk/zynqmp/clkc.c +++ b/drivers/clk/zynqmp/clkc.c @@ -2,7 +2,7 @@ /* * Zynq UltraScale+ MPSoC clock controller * - * Copyright (C) 2016-2018 Xilinx + * Copyright (C) 2016-2019 Xilinx * * Based on drivers/clk/zynq/clkc.c */ @@ -749,6 +749,7 @@ static int zynqmp_clock_probe(struct platform_device *pdev) static const struct of_device_id zynqmp_clock_of_match[] = { {.compatible = "xlnx,zynqmp-clk"}, + {.compatible = "xlnx,versal-clk"}, {}, }; MODULE_DEVICE_TABLE(of, zynqmp_clock_of_match); diff --git a/drivers/clk/zynqmp/divider.c b/drivers/clk/zynqmp/divider.c index d8f5b70d2709..4be2cc76aa2e 100644 --- a/drivers/clk/zynqmp/divider.c +++ b/drivers/clk/zynqmp/divider.c @@ -2,7 +2,7 @@ /* * Zynq UltraScale+ MPSoC Divider support * - * Copyright (C) 2016-2018 Xilinx + * Copyright (C) 2016-2019 Xilinx * * Adjustable divider clock implementation */ @@ -41,12 +41,30 @@ struct zynqmp_clk_divider { bool is_frac; u32 clk_id; u32 div_type; + u16 max_div; }; static inline int zynqmp_divider_get_val(unsigned long parent_rate, - unsigned long rate) + unsigned long rate, u16 flags) { - return DIV_ROUND_CLOSEST(parent_rate, rate); + int up, down; + unsigned long up_rate, down_rate; + + if (flags & CLK_DIVIDER_POWER_OF_TWO) { + up = DIV_ROUND_UP_ULL((u64)parent_rate, rate); + down = DIV_ROUND_DOWN_ULL((u64)parent_rate, rate); + + up = __roundup_pow_of_two(up); + down = __rounddown_pow_of_two(down); + + up_rate = DIV_ROUND_UP_ULL((u64)parent_rate, up); + down_rate = DIV_ROUND_UP_ULL((u64)parent_rate, down); + + return (rate - up_rate) <= (down_rate - rate) ? up : down; + + } else { + return DIV_ROUND_CLOSEST(parent_rate, rate); + } } /** @@ -78,6 +96,9 @@ static unsigned long zynqmp_clk_divider_recalc_rate(struct clk_hw *hw, else value = div >> 16; + if (divider->flags & CLK_DIVIDER_POWER_OF_TWO) + value = 1 << value; + if (!value) { WARN(!(divider->flags & CLK_DIVIDER_ALLOW_ZERO), "%s: Zero divisor and CLK_DIVIDER_ALLOW_ZERO not set\n", @@ -88,6 +109,42 @@ static unsigned long zynqmp_clk_divider_recalc_rate(struct clk_hw *hw, return DIV_ROUND_UP_ULL(parent_rate, value); } +static void zynqmp_get_divider2_val(struct clk_hw *hw, + unsigned long rate, + unsigned long parent_rate, + struct zynqmp_clk_divider *divider, + int *bestdiv) +{ + int div1; + int div2; + long error = LONG_MAX; + struct clk_hw *parent_hw = clk_hw_get_parent(hw); + struct zynqmp_clk_divider *pdivider = to_zynqmp_clk_divider(parent_hw); + + if (!pdivider) + return; + + *bestdiv = 1; + for (div1 = 1; div1 <= pdivider->max_div;) { + for (div2 = 1; div2 <= divider->max_div;) { + long new_error = ((parent_rate / div1) / div2) - rate; + + if (abs(new_error) < abs(error)) { + *bestdiv = div2; + error = new_error; + } + if (divider->flags & CLK_DIVIDER_POWER_OF_TWO) + div2 = div2 << 1; + else + div2++; + } + if (pdivider->flags & CLK_DIVIDER_POWER_OF_TWO) + div1 = div1 << 1; + else + div1++; + } +} + /** * zynqmp_clk_divider_round_rate() - Round rate of divider clock * @hw: handle between common and hardware-specific interfaces @@ -120,10 +177,23 @@ static long zynqmp_clk_divider_round_rate(struct clk_hw *hw, else bestdiv = bestdiv >> 16; + if (divider->flags & CLK_DIVIDER_POWER_OF_TWO) + bestdiv = 1 << bestdiv; + return DIV_ROUND_UP_ULL((u64)*prate, bestdiv); } - bestdiv = zynqmp_divider_get_val(*prate, rate); + bestdiv = zynqmp_divider_get_val(*prate, rate, divider->flags); + + /* + * In case of two divisors, compute best divider values and return + * divider2 value based on compute value. div1 will be automatically + * set to optimum based on required total divider value. + */ + if (div_type == TYPE_DIV2 && + (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) { + zynqmp_get_divider2_val(hw, rate, *prate, divider, &bestdiv); + } if ((clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) && divider->is_frac) bestdiv = rate % *prate ? 1 : bestdiv; @@ -151,7 +221,7 @@ static int zynqmp_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate, int ret; const struct zynqmp_eemi_ops *eemi_ops = zynqmp_pm_get_eemi_ops(); - value = zynqmp_divider_get_val(parent_rate, rate); + value = zynqmp_divider_get_val(parent_rate, rate, divider->flags); if (div_type == TYPE_DIV1) { div = value & 0xFFFF; div |= 0xffff << 16; @@ -160,6 +230,9 @@ static int zynqmp_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate, div |= value << 16; } + if (divider->flags & CLK_DIVIDER_POWER_OF_TWO) + div = __ffs(div); + ret = eemi_ops->clock_setdivider(clk_id, div); if (ret) @@ -176,6 +249,35 @@ static const struct clk_ops zynqmp_clk_divider_ops = { }; /** + * zynqmp_clk_get_max_divisor() - Get maximum supported divisor from firmware. + * @clk_id: Id of clock + * @type: Divider type + * + * Return: Maximum divisor of a clock if query data is successful + * U16_MAX in case of query data is not success + */ +u32 zynqmp_clk_get_max_divisor(u32 clk_id, u32 type) +{ + const struct zynqmp_eemi_ops *eemi_ops = zynqmp_pm_get_eemi_ops(); + struct zynqmp_pm_query_data qdata = {0}; + u32 ret_payload[PAYLOAD_ARG_CNT]; + int ret; + + qdata.qid = PM_QID_CLOCK_GET_MAX_DIVISOR; + qdata.arg1 = clk_id; + qdata.arg2 = type; + ret = eemi_ops->query_data(qdata, ret_payload); + /* + * To maintain backward compatibility return maximum possible value + * (0xFFFF) if query for max divisor is not successful. + */ + if (ret) + return U16_MAX; + + return ret_payload[1]; +} + +/** * zynqmp_clk_register_divider() - Register a divider clock * @name: Name of this clock * @clk_id: Id of clock @@ -215,6 +317,12 @@ struct clk_hw *zynqmp_clk_register_divider(const char *name, div->clk_id = clk_id; div->div_type = nodes->type; + /* + * To achieve best possible rate, maximum limit of divider is required + * while computation. + */ + div->max_div = zynqmp_clk_get_max_divisor(clk_id, nodes->type); + hw = &div->hw; ret = clk_hw_register(NULL, hw); if (ret) { diff --git a/drivers/clk/zynqmp/pll.c b/drivers/clk/zynqmp/pll.c index a541397a172c..89b599530105 100644 --- a/drivers/clk/zynqmp/pll.c +++ b/drivers/clk/zynqmp/pll.c @@ -188,10 +188,12 @@ static int zynqmp_pll_set_rate(struct clk_hw *hw, unsigned long rate, frac = (parent_rate * f) / FRAC_DIV; ret = eemi_ops->clock_setdivider(clk_id, m); - if (ret) + if (ret == -EUSERS) + WARN(1, "More than allowed devices are using the %s, which is forbidden\n", + clk_name); + else if (ret) pr_warn_once("%s() set divider failed for %s, ret = %d\n", __func__, clk_name, ret); - eemi_ops->ioctl(0, IOCTL_SET_PLL_FRAC_DATA, clk_id, f, NULL); return rate + frac; diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/xilinx/zynqmp.c index 75bdfaa08380..74d9f13d72c4 100644 --- a/drivers/firmware/xilinx/zynqmp.c +++ b/drivers/firmware/xilinx/zynqmp.c @@ -48,6 +48,8 @@ static int zynqmp_pm_ret_code(u32 ret_status) return -EACCES; case XST_PM_ABORT_SUSPEND: return -ECANCELED; + case XST_PM_MULT_USER: + return -EUSERS; case XST_PM_INTERNAL: case XST_PM_CONFLICT: case XST_PM_INVALID_NODE: diff --git a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c index 8f6100db90ed..1c894548dd72 100644 --- a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c +++ b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c @@ -751,9 +751,9 @@ static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm) snprintf(parent4, 32, "dsi%d_pll_post_out_div_clk", pll_10nm->id); hw = clk_hw_register_mux(dev, clk_name, - (const char *[]){ + ((const char *[]){ parent, parent2, parent3, parent4 - }, 4, 0, pll_10nm->phy_cmn_mmio + + }), 4, 0, pll_10nm->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_CLK_CFG1, 0, 2, 0, NULL); if (IS_ERR(hw)) { diff --git a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_28nm.c b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_28nm.c index 8c99e01ae332..6dffd7f4a99b 100644 --- a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_28nm.c +++ b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_28nm.c @@ -554,9 +554,9 @@ static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm) snprintf(parent1, 32, "dsi%dvco_clk", pll_28nm->id); snprintf(parent2, 32, "dsi%dindirect_path_div2_clk", pll_28nm->id); clks[num++] = clk_register_mux(dev, clk_name, - (const char *[]){ + ((const char *[]){ parent1, parent2 - }, 2, CLK_SET_RATE_PARENT, pll_28nm->mmio + + }), 2, CLK_SET_RATE_PARENT, pll_28nm->mmio + REG_DSI_28nm_PHY_PLL_VREG_CFG, 1, 1, 0, NULL); snprintf(clk_name, 32, "dsi%dpllbyte", pll_28nm->id); diff --git a/drivers/net/phy/mdio-mux-meson-g12a.c b/drivers/net/phy/mdio-mux-meson-g12a.c index 7a9ad54582e1..bf86c9c7a288 100644 --- a/drivers/net/phy/mdio-mux-meson-g12a.c +++ b/drivers/net/phy/mdio-mux-meson-g12a.c @@ -123,7 +123,7 @@ static int g12a_ephy_pll_is_enabled(struct clk_hw *hw) return (val & PLL_CTL0_LOCK_DIG) ? 1 : 0; } -static void g12a_ephy_pll_init(struct clk_hw *hw) +static int g12a_ephy_pll_init(struct clk_hw *hw) { struct g12a_ephy_pll *pll = g12a_ephy_pll_to_dev(hw); @@ -136,6 +136,8 @@ static void g12a_ephy_pll_init(struct clk_hw *hw) writel(0x20200000, pll->base + ETH_PLL_CTL5); writel(0x0000c002, pll->base + ETH_PLL_CTL6); writel(0x00000023, pll->base + ETH_PLL_CTL7); + + return 0; } static const struct clk_ops g12a_ephy_pll_ops = { |