diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-12-01 16:06:02 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-12-01 16:06:02 -0800 |
commit | ddebe839c6013ab42f376bdeaaaf66bd0c0d68d6 (patch) | |
tree | a70880a70a6b2b96b71de7d64c0b7b94239ff3e7 /drivers/clk | |
parent | ceb307474506f888e8f16dab183405ff01dffa08 (diff) | |
parent | ec16ffe36d80b18a1f98d126a865d5557ab27c30 (diff) |
Merge tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux
Pull clk updates from Stephen Boyd:
"This merge window we have one small clk provider API in the core
framework and then a bunch of driver updates and a handful of new
drivers. In terms of diffstat the Qualcomm and Amlogic drivers are
high up there because of all the clk data introcued by new drivers.
The Nvidia Tegra driver had a lot of work done this cycle too to
support suspend/resume and memory controllers. And the OMAP clk driver
got proper clk and reset handling in place.
Rounding out the patches are various updates to remove unused data,
mark things static, correct incorrect data in drivers, etc. All the
little things that improve drivers and maintain code health. I will
point out that there's a patch in here for the GPIO clk driver, that
almost nobody uses, which changes behavior and causes clk_set_rate()
to try to change the GPIO gate clk's parent. Other than that things
are fairly well SoC specific here.
Core:
- Add a clk provider API to get current parent index
- Plug a memory leak in clk_unregister() path
New Drivers:
- CGU in Ingenix X1000
- Bitmain BM1880 clks
- Qualcomm MSM8998 GPU clk controllers
- Qualcomm SC7180 GCC and RPMH clk controllers
- Qualcomm QCS404 Q6SSTOP clk controllers
- Add support for the Renesas R-Car M3-W+ (r8a77961) SoC
- Add support for the Renesas RZ/G2N (r8a774b1) SoC
- Add Tegra20/30 External Memory Clock (EMC) support
Updates:
- Make gpio gate clks propagate rate setting up to parent
- Prepare Armada 3700 for suspend to RAM by moving PCIe
suspend/resume priority
- Drop unused variables, enums, etc. in various clk drivers
- Convert various drivers to use devm_platform_ioremap_resource()
- Use struct_size() some more in various clk drivers
- Improve Rockchip px30 clk tree
- Add suspend/resume support to Tegra210 clk driver
- Reimplement SOR clks on earlier Tegra SoCs, helping HDMI and DP
- Allwinner DT exports and H6 clk tree fixes
- Proper clk and reset handling for OMAP SoCs
- Revamped TI divider clk to clamp max divider
- Make 1443X/1416X PLL clock structure common for reusing among i.MX8
SoCs
- Drop IMX7ULP_CLK_MIPI_PLL clock, it shouldn't be used
- Add VIDEO2_PLL clock for imx8mq
- Add missing gate clock for pll1/2 fixed dividers on i.MX8 SoCs
- Add sm1 support in the Amlogic audio clock controller
- Switch some clocks on R-Car Gen2/3 to .determine_rate()
- Remove Renesas R-Car Gen2 legacy DT clock support
- Improve arithmetic divisions on Renesas R-Car Gen2 and Gen3
- Improve Renesas R-Car Gen3 SD clock handling
- Add rate table for Samsung exynos542x GPU and VPLL clks
- Fix potential CPU performance degradation after system
suspend/resume cycle on exynos542x SoCs"
* tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: (160 commits)
clk: aspeed: Add RMII RCLK gates for both AST2500 MACs
MAINTAINERS: Add entry for BM1880 SoC clock driver
clk: Add common clock driver for BM1880 SoC
dt-bindings: clock: Add devicetree binding for BM1880 SoC
clk: Add clk_hw_unregister_composite helper function definition
clk: Zero init clk_init_data in helpers
clk: ingenic: Allow drivers to be built with COMPILE_TEST
MAINTAINERS: Update section for Ux500 clock drivers
clk: mark clk_disable_unused() as __init
clk: Fix memory leak in clk_unregister()
clk: Ingenic: Add CGU driver for X1000.
dt-bindings: clock: Add X1000 bindings.
clk: tegra: Use match_string() helper to simplify the code
clk: pxa: fix one of the pxa RTC clocks
clk: sprd: Use IS_ERR() to validate the return value of syscon_regmap_lookup_by_phandle()
clk: armada-xp: remove unused code
clk: tegra: Fix build error without CONFIG_PM_SLEEP
clk: tegra: Add missing stubs for the case of !CONFIG_PM_SLEEP
clk: tegra: Optimize PLLX restore on Tegra20/30
clk: tegra: Add suspend and resume support on Tegra210
...
Diffstat (limited to 'drivers/clk')
115 files changed, 7936 insertions, 2241 deletions
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index c44247d0b83e..dc920daa6dbb 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -136,6 +136,13 @@ config COMMON_CLK_SI570 This driver supports Silicon Labs 570/571/598/599 programmable clock generators. +config COMMON_CLK_BM1880 + bool "Clock driver for Bitmain BM1880 SoC" + depends on ARCH_BITMAIN || COMPILE_TEST + default ARCH_BITMAIN + help + This driver supports the clocks on Bitmain BM1880 SoC. + config COMMON_CLK_CDCE706 tristate "Clock driver for TI CDCE706 clock synthesizer" depends on I2C diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 0138fb14e6f8..0696a0c1ab58 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -22,6 +22,7 @@ obj-$(CONFIG_MACH_ASM9260) += clk-asm9260.o obj-$(CONFIG_COMMON_CLK_AXI_CLKGEN) += clk-axi-clkgen.o obj-$(CONFIG_ARCH_AXXIA) += clk-axm5516.o obj-$(CONFIG_COMMON_CLK_BD718XX) += clk-bd718x7.o +obj-$(CONFIG_COMMON_CLK_BM1880) += clk-bm1880.o obj-$(CONFIG_COMMON_CLK_CDCE706) += clk-cdce706.o obj-$(CONFIG_COMMON_CLK_CDCE925) += clk-cdce925.o obj-$(CONFIG_ARCH_CLPS711X) += clk-clps711x.o diff --git a/drivers/clk/at91/sckc.c b/drivers/clk/at91/sckc.c index fac0ca56d42d..15dc4cd86d76 100644 --- a/drivers/clk/at91/sckc.c +++ b/drivers/clk/at91/sckc.c @@ -487,8 +487,7 @@ static void __init of_sam9x60_sckc_setup(struct device_node *np) if (IS_ERR(slow_osc)) goto unregister_slow_rc; - clk_data = kzalloc(sizeof(*clk_data) + (2 * sizeof(struct clk_hw *)), - GFP_KERNEL); + clk_data = kzalloc(struct_size(clk_data, hws, 2), GFP_KERNEL); if (!clk_data) goto unregister_slow_osc; diff --git a/drivers/clk/axs10x/i2s_pll_clock.c b/drivers/clk/axs10x/i2s_pll_clock.c index 71c2e9519ca8..e9da0e69bf6c 100644 --- a/drivers/clk/axs10x/i2s_pll_clock.c +++ b/drivers/clk/axs10x/i2s_pll_clock.c @@ -172,14 +172,12 @@ static int i2s_pll_clk_probe(struct platform_device *pdev) struct clk *clk; struct i2s_pll_clk *pll_clk; struct clk_init_data init; - struct resource *mem; pll_clk = devm_kzalloc(dev, sizeof(*pll_clk), GFP_KERNEL); if (!pll_clk) return -ENOMEM; - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - pll_clk->base = devm_ioremap_resource(dev, mem); + pll_clk->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(pll_clk->base)) return PTR_ERR(pll_clk->base); diff --git a/drivers/clk/axs10x/pll_clock.c b/drivers/clk/axs10x/pll_clock.c index aba787b2e771..500345d99adb 100644 --- a/drivers/clk/axs10x/pll_clock.c +++ b/drivers/clk/axs10x/pll_clock.c @@ -221,7 +221,6 @@ static int axs10x_pll_clk_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; const char *parent_name; struct axs10x_pll_clk *pll_clk; - struct resource *mem; struct clk_init_data init = { }; int ret; @@ -229,13 +228,11 @@ static int axs10x_pll_clk_probe(struct platform_device *pdev) if (!pll_clk) return -ENOMEM; - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - pll_clk->base = devm_ioremap_resource(dev, mem); + pll_clk->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(pll_clk->base)) return PTR_ERR(pll_clk->base); - mem = platform_get_resource(pdev, IORESOURCE_MEM, 1); - pll_clk->lock = devm_ioremap_resource(dev, mem); + pll_clk->lock = devm_platform_ioremap_resource(pdev, 1); if (IS_ERR(pll_clk->lock)) return PTR_ERR(pll_clk->lock); diff --git a/drivers/clk/bcm/clk-bcm2835-aux.c b/drivers/clk/bcm/clk-bcm2835-aux.c index b6d07ca0164f..290a2846a86b 100644 --- a/drivers/clk/bcm/clk-bcm2835-aux.c +++ b/drivers/clk/bcm/clk-bcm2835-aux.c @@ -19,7 +19,6 @@ static int bcm2835_aux_clk_probe(struct platform_device *pdev) struct clk_hw_onecell_data *onecell; const char *parent; struct clk *parent_clk; - struct resource *res; void __iomem *reg, *gate; parent_clk = devm_clk_get(dev, NULL); @@ -27,8 +26,7 @@ static int bcm2835_aux_clk_probe(struct platform_device *pdev) return PTR_ERR(parent_clk); parent = __clk_get_name(parent_clk); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - reg = devm_ioremap_resource(dev, res); + reg = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(reg)) return PTR_ERR(reg); diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index 802e488fd3c3..ded13ccf768e 100644 --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c @@ -2192,7 +2192,6 @@ static int bcm2835_clk_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct clk_hw **hws; struct bcm2835_cprman *cprman; - struct resource *res; const struct bcm2835_clk_desc *desc; const size_t asize = ARRAY_SIZE(clk_desc_array); const struct cprman_plat_data *pdata; @@ -2211,8 +2210,7 @@ static int bcm2835_clk_probe(struct platform_device *pdev) spin_lock_init(&cprman->regs_lock); cprman->dev = dev; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - cprman->regs = devm_ioremap_resource(dev, res); + cprman->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(cprman->regs)) return PTR_ERR(cprman->regs); diff --git a/drivers/clk/clk-aspeed.c b/drivers/clk/clk-aspeed.c index abf06fb6453e..411ff5fb2c07 100644 --- a/drivers/clk/clk-aspeed.c +++ b/drivers/clk/clk-aspeed.c @@ -14,7 +14,7 @@ #include "clk-aspeed.h" -#define ASPEED_NUM_CLKS 36 +#define ASPEED_NUM_CLKS 38 #define ASPEED_RESET2_OFFSET 32 @@ -28,6 +28,7 @@ #define AST2400_HPLL_BYPASS_EN BIT(17) #define ASPEED_MISC_CTRL 0x2c #define UART_DIV13_EN BIT(12) +#define ASPEED_MAC_CLK_DLY 0x48 #define ASPEED_STRAP 0x70 #define CLKIN_25MHZ_EN BIT(23) #define AST2400_CLK_SOURCE_SEL BIT(18) @@ -462,6 +463,30 @@ static int aspeed_clk_probe(struct platform_device *pdev) return PTR_ERR(hw); aspeed_clk_data->hws[ASPEED_CLK_MAC] = hw; + if (of_device_is_compatible(pdev->dev.of_node, "aspeed,ast2500-scu")) { + /* RMII 50MHz RCLK */ + hw = clk_hw_register_fixed_rate(dev, "mac12rclk", "hpll", 0, + 50000000); + if (IS_ERR(hw)) + return PTR_ERR(hw); + + /* RMII1 50MHz (RCLK) output enable */ + hw = clk_hw_register_gate(dev, "mac1rclk", "mac12rclk", 0, + scu_base + ASPEED_MAC_CLK_DLY, 29, 0, + &aspeed_clk_lock); + if (IS_ERR(hw)) + return PTR_ERR(hw); + aspeed_clk_data->hws[ASPEED_CLK_MAC1RCLK] = hw; + + /* RMII2 50MHz (RCLK) output enable */ + hw = clk_hw_register_gate(dev, "mac2rclk", "mac12rclk", 0, + scu_base + ASPEED_MAC_CLK_DLY, 30, 0, + &aspeed_clk_lock); + if (IS_ERR(hw)) + return PTR_ERR(hw); + aspeed_clk_data->hws[ASPEED_CLK_MAC2RCLK] = hw; + } + /* LPC Host (LHCLK) clock divider */ hw = clk_hw_register_divider_table(dev, "lhclk", "hpll", 0, scu_base + ASPEED_CLK_SELECTION, 20, 3, 0, diff --git a/drivers/clk/clk-ast2600.c b/drivers/clk/clk-ast2600.c index b1318e6b655b..392d01705b97 100644 --- a/drivers/clk/clk-ast2600.c +++ b/drivers/clk/clk-ast2600.c @@ -15,7 +15,7 @@ #include "clk-aspeed.h" -#define ASPEED_G6_NUM_CLKS 67 +#define ASPEED_G6_NUM_CLKS 71 #define ASPEED_G6_SILICON_REV 0x004 @@ -40,6 +40,9 @@ #define ASPEED_G6_STRAP1 0x500 +#define ASPEED_MAC12_CLK_DLY 0x340 +#define ASPEED_MAC34_CLK_DLY 0x350 + /* Globally visible clocks */ static DEFINE_SPINLOCK(aspeed_g6_clk_lock); @@ -116,8 +119,6 @@ static const struct aspeed_gate_data aspeed_g6_gates[] = { [ASPEED_CLK_GATE_FSICLK] = { 62, 59, "fsiclk-gate", NULL, 0 }, /* FSI */ }; -static const char * const eclk_parent_names[] = { "mpll", "hpll", "dpll" }; - static const struct clk_div_table ast2600_eclk_div_table[] = { { 0x0, 2 }, { 0x1, 2 }, @@ -486,6 +487,11 @@ static int aspeed_g6_clk_probe(struct platform_device *pdev) return PTR_ERR(hw); aspeed_g6_clk_data->hws[ASPEED_CLK_SDIO] = hw; + /* MAC1/2 RMII 50MHz RCLK */ + hw = clk_hw_register_fixed_rate(dev, "mac12rclk", "hpll", 0, 50000000); + if (IS_ERR(hw)) + return PTR_ERR(hw); + /* MAC1/2 AHB bus clock divider */ hw = clk_hw_register_divider_table(dev, "mac12", "hpll", 0, scu_g6_base + ASPEED_G6_CLK_SELECTION1, 16, 3, 0, @@ -495,6 +501,27 @@ static int aspeed_g6_clk_probe(struct platform_device *pdev) return PTR_ERR(hw); aspeed_g6_clk_data->hws[ASPEED_CLK_MAC12] = hw; + /* RMII1 50MHz (RCLK) output enable */ + hw = clk_hw_register_gate(dev, "mac1rclk", "mac12rclk", 0, + scu_g6_base + ASPEED_MAC12_CLK_DLY, 29, 0, + &aspeed_g6_clk_lock); + if (IS_ERR(hw)) + return PTR_ERR(hw); + aspeed_g6_clk_data->hws[ASPEED_CLK_MAC1RCLK] = hw; + + /* RMII2 50MHz (RCLK) output enable */ + hw = clk_hw_register_gate(dev, "mac2rclk", "mac12rclk", 0, + scu_g6_base + ASPEED_MAC12_CLK_DLY, 30, 0, + &aspeed_g6_clk_lock); + if (IS_ERR(hw)) + return PTR_ERR(hw); + aspeed_g6_clk_data->hws[ASPEED_CLK_MAC2RCLK] = hw; + + /* MAC1/2 RMII 50MHz RCLK */ + hw = clk_hw_register_fixed_rate(dev, "mac34rclk", "hclk", 0, 50000000); + if (IS_ERR(hw)) + return PTR_ERR(hw); + /* MAC3/4 AHB bus clock divider */ hw = clk_hw_register_divider_table(dev, "mac34", "hpll", 0, scu_g6_base + 0x310, 24, 3, 0, @@ -504,6 +531,22 @@ static int aspeed_g6_clk_probe(struct platform_device *pdev) return PTR_ERR(hw); aspeed_g6_clk_data->hws[ASPEED_CLK_MAC34] = hw; + /* RMII3 50MHz (RCLK) output enable */ + hw = clk_hw_register_gate(dev, "mac3rclk", "mac34rclk", 0, + scu_g6_base + ASPEED_MAC34_CLK_DLY, 29, 0, + &aspeed_g6_clk_lock); + if (IS_ERR(hw)) + return PTR_ERR(hw); + aspeed_g6_clk_data->hws[ASPEED_CLK_MAC3RCLK] = hw; + + /* RMII4 50MHz (RCLK) output enable */ + hw = clk_hw_register_gate(dev, "mac4rclk", "mac34rclk", 0, + scu_g6_base + ASPEED_MAC34_CLK_DLY, 30, 0, + &aspeed_g6_clk_lock); + if (IS_ERR(hw)) + return PTR_ERR(hw); + aspeed_g6_clk_data->hws[ASPEED_CLK_MAC4RCLK] = hw; + /* LPC Host (LHCLK) clock divider */ hw = clk_hw_register_divider_table(dev, "lhclk", "hpll", 0, scu_g6_base + ASPEED_G6_CLK_SELECTION1, 20, 3, 0, diff --git a/drivers/clk/clk-bd718x7.c b/drivers/clk/clk-bd718x7.c index ae6e5baee330..00926c587390 100644 --- a/drivers/clk/clk-bd718x7.c +++ b/drivers/clk/clk-bd718x7.c @@ -133,3 +133,4 @@ module_platform_driver(bd71837_clk); MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>"); MODULE_DESCRIPTION("BD71837/BD71847/BD70528 chip clk driver"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:bd718xx-clk"); diff --git a/drivers/clk/clk-bm1880.c b/drivers/clk/clk-bm1880.c new file mode 100644 index 000000000000..4cd175afce9b --- /dev/null +++ b/drivers/clk/clk-bm1880.c @@ -0,0 +1,969 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Bitmain BM1880 SoC clock driver + * + * Copyright (c) 2019 Linaro Ltd. + * Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> + */ + +#include <linux/clk-provider.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/of_address.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> +#include <linux/slab.h> + +#include <dt-bindings/clock/bm1880-clock.h> + +#define BM1880_CLK_MPLL_CTL 0x00 +#define BM1880_CLK_SPLL_CTL 0x04 +#define BM1880_CLK_FPLL_CTL 0x08 +#define BM1880_CLK_DDRPLL_CTL 0x0c + +#define BM1880_CLK_ENABLE0 0x00 +#define BM1880_CLK_ENABLE1 0x04 +#define BM1880_CLK_SELECT 0x20 +#define BM1880_CLK_DIV0 0x40 +#define BM1880_CLK_DIV1 0x44 +#define BM1880_CLK_DIV2 0x48 +#define BM1880_CLK_DIV3 0x4c +#define BM1880_CLK_DIV4 0x50 +#define BM1880_CLK_DIV5 0x54 +#define BM1880_CLK_DIV6 0x58 +#define BM1880_CLK_DIV7 0x5c +#define BM1880_CLK_DIV8 0x60 +#define BM1880_CLK_DIV9 0x64 +#define BM1880_CLK_DIV10 0x68 +#define BM1880_CLK_DIV11 0x6c +#define BM1880_CLK_DIV12 0x70 +#define BM1880_CLK_DIV13 0x74 +#define BM1880_CLK_DIV14 0x78 +#define BM1880_CLK_DIV15 0x7c +#define BM1880_CLK_DIV16 0x80 +#define BM1880_CLK_DIV17 0x84 +#define BM1880_CLK_DIV18 0x88 +#define BM1880_CLK_DIV19 0x8c +#define BM1880_CLK_DIV20 0x90 +#define BM1880_CLK_DIV21 0x94 +#define BM1880_CLK_DIV22 0x98 +#define BM1880_CLK_DIV23 0x9c +#define BM1880_CLK_DIV24 0xa0 +#define BM1880_CLK_DIV25 0xa4 +#define BM1880_CLK_DIV26 0xa8 +#define BM1880_CLK_DIV27 0xac +#define BM1880_CLK_DIV28 0xb0 + +#define to_bm1880_pll_clk(_hw) container_of(_hw, struct bm1880_pll_hw_clock, hw) +#define to_bm1880_div_clk(_hw) container_of(_hw, struct bm1880_div_hw_clock, hw) + +static DEFINE_SPINLOCK(bm1880_clk_lock); + +struct bm1880_clock_data { + void __iomem *pll_base; + void __iomem *sys_base; + struct clk_hw_onecell_data hw_data; +}; + +struct bm1880_gate_clock { + unsigned int id; + const char *name; + const char *parent; + u32 gate_reg; + s8 gate_shift; + unsigned long flags; +}; + +struct bm1880_mux_clock { + unsigned int id; + const char *name; + const char * const *parents; + s8 num_parents; + u32 reg; + s8 shift; + unsigned long flags; +}; + +struct bm1880_div_clock { + unsigned int id; + const char *name; + u32 reg; + u8 shift; + u8 width; + u32 initval; + const struct clk_div_table *table; + unsigned long flags; +}; + +struct bm1880_div_hw_clock { + struct bm1880_div_clock div; + void __iomem *base; + spinlock_t *lock; + struct clk_hw hw; + struct clk_init_data init; +}; + +struct bm1880_composite_clock { + unsigned int id; + const char *name; + const char *parent; + const char * const *parents; + unsigned int num_parents; + unsigned long flags; + + u32 gate_reg; + u32 mux_reg; + u32 div_reg; + + s8 gate_shift; + s8 mux_shift; + s8 div_shift; + s8 div_width; + s16 div_initval; + const struct clk_div_table *table; +}; + +struct bm1880_pll_clock { + unsigned int id; + const char *name; + u32 reg; + unsigned long flags; +}; + +struct bm1880_pll_hw_clock { + struct bm1880_pll_clock pll; + void __iomem *base; + struct clk_hw hw; + struct clk_init_data init; +}; + +static const struct clk_ops bm1880_pll_ops; +static const struct clk_ops bm1880_clk_div_ops; + +#define GATE_DIV(_id, _name, _parent, _gate_reg, _gate_shift, _div_reg, \ + _div_shift, _div_width, _div_initval, _table, \ + _flags) { \ + .id = _id, \ + .parent = _parent, \ + .name = _name, \ + .gate_reg = _gate_reg, \ + .gate_shift = _gate_shift, \ + .div_reg = _div_reg, \ + .div_shift = _div_shift, \ + .div_width = _div_width, \ + .div_initval = _div_initval, \ + .table = _table, \ + .mux_shift = -1, \ + .flags = _flags, \ + } + +#define GATE_MUX(_id, _name, _parents, _gate_reg, _gate_shift, \ + _mux_reg, _mux_shift, _flags) { \ + .id = _id, \ + .parents = _parents, \ + .num_parents = ARRAY_SIZE(_parents), \ + .name = _name, \ + .gate_reg = _gate_reg, \ + .gate_shift = _gate_shift, \ + .div_shift = -1, \ + .mux_reg = _mux_reg, \ + .mux_shift = _mux_shift, \ + .flags = _flags, \ + } + +#define CLK_PLL(_id, _name, _parent, _reg, _flags) { \ + .pll.id = _id, \ + .pll.name = _name, \ + .pll.reg = _reg, \ + .hw.init = CLK_HW_INIT_PARENTS_DATA(_name, _parent, \ + &bm1880_pll_ops, \ + _flags), \ + } + +#define CLK_DIV(_id, _name, _parent, _reg, _shift, _width, _initval, \ + _table, _flags) { \ + .div.id = _id, \ + .div.name = _name, \ + .div.reg = _reg, \ + .div.shift = _shift, \ + .div.width = _width, \ + .div.initval = _initval, \ + .div.table = _table, \ + .hw.init = CLK_HW_INIT_HW(_name, _parent, \ + &bm1880_clk_div_ops, \ + _flags), \ + } + +static struct clk_parent_data bm1880_pll_parent[] = { + { .fw_name = "osc", .name = "osc" }, +}; + +/* + * All PLL clocks are marked as CRITICAL, hence they are very crucial + * for the functioning of the SoC + */ +static struct bm1880_pll_hw_clock bm1880_pll_clks[] = { + CLK_PLL(BM1880_CLK_MPLL, "clk_mpll", bm1880_pll_parent, + BM1880_CLK_MPLL_CTL, 0), + CLK_PLL(BM1880_CLK_SPLL, "clk_spll", bm1880_pll_parent, + BM1880_CLK_SPLL_CTL, 0), + CLK_PLL(BM1880_CLK_FPLL, "clk_fpll", bm1880_pll_parent, + BM1880_CLK_FPLL_CTL, 0), + CLK_PLL(BM1880_CLK_DDRPLL, "clk_ddrpll", bm1880_pll_parent, + BM1880_CLK_DDRPLL_CTL, 0), +}; + +/* + * Clocks marked as CRITICAL are needed for the proper functioning + * of the SoC. + */ +static const struct bm1880_gate_clock bm1880_gate_clks[] = { + { BM1880_CLK_AHB_ROM, "clk_ahb_rom", "clk_mux_axi6", + BM1880_CLK_ENABLE0, 2, 0 }, + { BM1880_CLK_AXI_SRAM, "clk_axi_sram", "clk_axi1", + BM1880_CLK_ENABLE0, 3, 0 }, + /* + * Since this clock is sourcing the DDR memory, let's mark it as + * critical to avoid gating. + */ + { BM1880_CLK_DDR_AXI, "clk_ddr_axi", "clk_mux_axi6", + BM1880_CLK_ENABLE0, 4, CLK_IS_CRITICAL }, + { BM1880_CLK_APB_EFUSE, "clk_apb_efuse", "clk_mux_axi6", + BM1880_CLK_ENABLE0, 6, 0 }, + { BM1880_CLK_AXI5_EMMC, "clk_axi5_emmc", "clk_axi5", + BM1880_CLK_ENABLE0, 7, 0 }, + { BM1880_CLK_AXI5_SD, "clk_axi5_sd", "clk_axi5", + BM1880_CLK_ENABLE0, 10, 0 }, + { BM1880_CLK_AXI4_ETH0, "clk_axi4_eth0", "clk_axi4", + BM1880_CLK_ENABLE0, 14, 0 }, + { BM1880_CLK_AXI4_ETH1, "clk_axi4_eth1", "clk_axi4", + BM1880_CLK_ENABLE0, 16, 0 }, + { BM1880_CLK_AXI1_GDMA, "clk_axi1_gdma", "clk_axi1", + BM1880_CLK_ENABLE0, 17, 0 }, + /* Don't gate GPIO clocks as it is not owned by the GPIO driver */ + { BM1880_CLK_APB_GPIO, "clk_apb_gpio", "clk_mux_axi6", + BM1880_CLK_ENABLE0, 18, CLK_IGNORE_UNUSED }, + { BM1880_CLK_APB_GPIO_INTR, "clk_apb_gpio_intr", "clk_mux_axi6", + BM1880_CLK_ENABLE0, 19, CLK_IGNORE_UNUSED }, + { BM1880_CLK_AXI1_MINER, "clk_axi1_miner", "clk_axi1", + BM1880_CLK_ENABLE0, 21, 0 }, + { BM1880_CLK_AHB_SF, "clk_ahb_sf", "clk_mux_axi6", + BM1880_CLK_ENABLE0, 22, 0 }, + /* + * Not sure which module this clock is sourcing but gating this clock + * prevents the system from booting. So, let's mark it as critical. + */ + { BM1880_CLK_SDMA_AXI, "clk_sdma_axi", "clk_axi5", + BM1880_CLK_ENABLE0, 23, CLK_IS_CRITICAL }, + { BM1880_CLK_APB_I2C, "clk_apb_i2c", "clk_mux_axi6", + BM1880_CLK_ENABLE0, 25, 0 }, + { BM1880_CLK_APB_WDT, "clk_apb_wdt", "clk_mux_axi6", + BM1880_CLK_ENABLE0, 26, 0 }, + { BM1880_CLK_APB_JPEG, "clk_apb_jpeg", "clk_axi6", + BM1880_CLK_ENABLE0, 27, 0 }, + { BM1880_CLK_AXI5_NF, "clk_axi5_nf", "clk_axi5", + BM1880_CLK_ENABLE0, 29, 0 }, + { BM1880_CLK_APB_NF, "clk_apb_nf", "clk_axi6", + BM1880_CLK_ENABLE0, 30, 0 }, + { BM1880_CLK_APB_PWM, "clk_apb_pwm", "clk_mux_axi6", + BM1880_CLK_ENABLE1, 0, 0 }, + { BM1880_CLK_RV, "clk_rv", "clk_mux_rv", + BM1880_CLK_ENABLE1, 1, 0 }, + { BM1880_CLK_APB_SPI, "clk_apb_spi", "clk_mux_axi6", + BM1880_CLK_ENABLE1, 2, 0 }, + { BM1880_CLK_UART_500M, "clk_uart_500m", "clk_div_uart_500m", + BM1880_CLK_ENABLE1, 4, 0 }, + { BM1880_CLK_APB_UART, "clk_apb_uart", "clk_axi6", + BM1880_CLK_ENABLE1, 5, 0 }, + { BM1880_CLK_APB_I2S, "clk_apb_i2s", "clk_axi6", + BM1880_CLK_ENABLE1, 6, 0 }, + { BM1880_CLK_AXI4_USB, "clk_axi4_usb", "clk_axi4", + BM1880_CLK_ENABLE1, 7, 0 }, + { BM1880_CLK_APB_USB, "clk_apb_usb", "clk_axi6", + BM1880_CLK_ENABLE1, 8, 0 }, + { BM1880_CLK_12M_USB, "clk_12m_usb", "clk_div_12m_usb", + BM1880_CLK_ENABLE1, 11, 0 }, + { BM1880_CLK_APB_VIDEO, "clk_apb_video", "clk_axi6", + BM1880_CLK_ENABLE1, 12, 0 }, + { BM1880_CLK_APB_VPP, "clk_apb_vpp", "clk_axi6", + BM1880_CLK_ENABLE1, 15, 0 }, + { BM1880_CLK_AXI6, "clk_axi6", "clk_mux_axi6", + BM1880_CLK_ENABLE1, 21, 0 }, +}; + +static const char * const clk_a53_parents[] = { "clk_spll", "clk_mpll" }; +static const char * const clk_rv_parents[] = { "clk_div_1_rv", "clk_div_0_rv" }; +static const char * const clk_axi1_parents[] = { "clk_div_1_axi1", "clk_div_0_axi1" }; +static const char * const clk_axi6_parents[] = { "clk_div_1_axi6", "clk_div_0_axi6" }; + +static const struct bm1880_mux_clock bm1880_mux_clks[] = { + { BM1880_CLK_MUX_RV, "clk_mux_rv", clk_rv_parents, 2, + BM1880_CLK_SELECT, 1, 0 }, + { BM1880_CLK_MUX_AXI6, "clk_mux_axi6", clk_axi6_parents, 2, + BM1880_CLK_SELECT, 3, 0 }, +}; + +static const struct clk_div_table bm1880_div_table_0[] = { + { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 }, + { 4, 5 }, { 5, 6 }, { 6, 7 }, { 7, 8 }, + { 8, 9 }, { 9, 10 }, { 10, 11 }, { 11, 12 }, + { 12, 13 }, { 13, 14 }, { 14, 15 }, { 15, 16 }, + { 16, 17 }, { 17, 18 }, { 18, 19 }, { 19, 20 }, + { 20, 21 }, { 21, 22 }, { 22, 23 }, { 23, 24 }, + { 24, 25 }, { 25, 26 }, { 26, 27 }, { 27, 28 }, + { 28, 29 }, { 29, 30 }, { 30, 31 }, { 31, 32 }, + { 0, 0 } +}; + +static const struct clk_div_table bm1880_div_table_1[] = { + { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 }, + { 4, 5 }, { 5, 6 }, { 6, 7 }, { 7, 8 }, + { 8, 9 }, { 9, 10 }, { 10, 11 }, { 11, 12 }, + { 12, 13 }, { 13, 14 }, { 14, 15 }, { 15, 16 }, + { 16, 17 }, { 17, 18 }, { 18, 19 }, { 19, 20 }, + { 20, 21 }, { 21, 22 }, { 22, 23 }, { 23, 24 }, + { 24, 25 }, { 25, 26 }, { 26, 27 }, { 27, 28 }, + { 28, 29 }, { 29, 30 }, { 30, 31 }, { 31, 32 }, + { 127, 128 }, { 0, 0 } +}; + +static const struct clk_div_table bm1880_div_table_2[] = { + { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 }, + { 4, 5 }, { 5, 6 }, { 6, 7 }, { 7, 8 }, + { 8, 9 }, { 9, 10 }, { 10, 11 }, { 11, 12 }, + { 12, 13 }, { 13, 14 }, { 14, 15 }, { 15, 16 }, + { 16, 17 }, { 17, 18 }, { 18, 19 }, { 19, 20 }, + { 20, 21 }, { 21, 22 }, { 22, 23 }, { 23, 24 }, + { 24, 25 }, { 25, 26 }, { 26, 27 }, { 27, 28 }, + { 28, 29 }, { 29, 30 }, { 30, 31 }, { 31, 32 }, + { 127, 128 }, { 255, 256 }, { 0, 0 } +}; + +static const struct clk_div_table bm1880_div_table_3[] = { + { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 }, + { 4, 5 }, { 5, 6 }, { 6, 7 }, { 7, 8 }, + { 8, 9 }, { 9, 10 }, { 10, 11 }, { 11, 12 }, + { 12, 13 }, { 13, 14 }, { 14, 15 }, { 15, 16 }, + { 16, 17 }, { 17, 18 }, { 18, 19 }, { 19, 20 }, + { 20, 21 }, { 21, 22 }, { 22, 23 }, { 23, 24 }, + { 24, 25 }, { 25, 26 }, { 26, 27 }, { 27, 28 }, + { 28, 29 }, { 29, 30 }, { 30, 31 }, { 31, 32 }, + { 127, 128 }, { 255, 256 }, { 511, 512 }, { 0, 0 } +}; + +static const struct clk_div_table bm1880_div_table_4[] = { + { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 }, + { 4, 5 }, { 5, 6 }, { 6, 7 }, { 7, 8 }, + { 8, 9 }, { 9, 10 }, { 10, 11 }, { 11, 12 }, + { 12, 13 }, { 13, 14 }, { 14, 15 }, { 15, 16 }, + { 16, 17 }, { 17, 18 }, { 18, 19 }, { 19, 20 }, + { 20, 21 }, { 21, 22 }, { 22, 23 }, { 23, 24 }, + { 24, 25 }, { 25, 26 }, { 26, 27 }, { 27, 28 }, + { 28, 29 }, { 29, 30 }, { 30, 31 }, { 31, 32 }, + { 127, 128 }, { 255, 256 }, { 511, 512 }, { 65535, 65536 }, + { 0, 0 } +}; + +/* + * Clocks marked as CRITICAL are needed for the proper functioning + * of the SoC. + */ +static struct bm1880_div_hw_clock bm1880_div_clks[] = { + CLK_DIV(BM1880_CLK_DIV_0_RV, "clk_div_0_rv", &bm1880_pll_clks[1].hw, + BM1880_CLK_DIV12, 16, 5, 1, bm1880_div_table_0, 0), + CLK_DIV(BM1880_CLK_DIV_1_RV, "clk_div_1_rv", &bm1880_pll_clks[2].hw, + BM1880_CLK_DIV13, 16, 5, 1, bm1880_div_table_0, 0), + CLK_DIV(BM1880_CLK_DIV_UART_500M, "clk_div_uart_500m", &bm1880_pll_clks[2].hw, + BM1880_CLK_DIV15, 16, 7, 3, bm1880_div_table_1, 0), + CLK_DIV(BM1880_CLK_DIV_0_AXI1, "clk_div_0_axi1", &bm1880_pll_clks[0].hw, + BM1880_CLK_DIV21, 16, 5, 2, bm1880_div_table_0, + 0), + CLK_DIV(BM1880_CLK_DIV_1_AXI1, "clk_div_1_axi1", &bm1880_pll_clks[2].hw, + BM1880_CLK_DIV22, 16, 5, 3, bm1880_div_table_0, + 0), + CLK_DIV(BM1880_CLK_DIV_0_AXI6, "clk_div_0_axi6", &bm1880_pll_clks[2].hw, + BM1880_CLK_DIV27, 16, 5, 15, bm1880_div_table_0, + 0), + CLK_DIV(BM1880_CLK_DIV_1_AXI6, "clk_div_1_axi6", &bm1880_pll_clks[0].hw, + BM1880_CLK_DIV28, 16, 5, 11, bm1880_div_table_0, + 0), + CLK_DIV(BM1880_CLK_DIV_12M_USB, "clk_div_12m_usb", &bm1880_pll_clks[2].hw, + BM1880_CLK_DIV18, 16, 7, 125, bm1880_div_table_1, 0), +}; + +/* + * Clocks marked as CRITICAL are all needed for the proper functioning + * of the SoC. + */ +static struct bm1880_composite_clock bm1880_composite_clks[] = { + /* + * Since clk_a53 and clk_50m_a53 clocks are sourcing the CPU core, + * let's mark them as critical to avoid gating. + */ + GATE_MUX(BM1880_CLK_A53, "clk_a53", clk_a53_parents, + BM1880_CLK_ENABLE0, 0, BM1880_CLK_SELECT, 0, + CLK_IS_CRITICAL), + GATE_DIV(BM1880_CLK_50M_A53, "clk_50m_a53", "clk_fpll", + BM1880_CLK_ENABLE0, 1, BM1880_CLK_DIV0, 16, 5, 30, + bm1880_div_table_0, CLK_IS_CRITICAL), + GATE_DIV(BM1880_CLK_EFUSE, "clk_efuse", "clk_fpll", + BM1880_CLK_ENABLE0, 5, BM1880_CLK_DIV1, 16, 7, 60, + bm1880_div_table_1, 0), + GATE_DIV(BM1880_CLK_EMMC, "clk_emmc", "clk_fpll", + BM1880_CLK_ENABLE0, 8, BM1880_CLK_DIV2, 16, 5, 15, + bm1880_div_table_0, 0), + GATE_DIV(BM1880_CLK_100K_EMMC, "clk_100k_emmc", "clk_div_12m_usb", + BM1880_CLK_ENABLE0, 9, BM1880_CLK_DIV3, 16, 8, 120, + bm1880_div_table_2, 0), + GATE_DIV(BM1880_CLK_SD, "clk_sd", "clk_fpll", + BM1880_CLK_ENABLE0, 11, BM1880_CLK_DIV4, 16, 5, 15, + bm1880_div_table_0, 0), + GATE_DIV(BM1880_CLK_100K_SD, "clk_100k_sd", "clk_div_12m_usb", + BM1880_CLK_ENABLE0, 12, BM1880_CLK_DIV5, 16, 8, 120, + bm1880_div_table_2, 0), + GATE_DIV(BM1880_CLK_500M_ETH0, "clk_500m_eth0", "clk_fpll", + BM1880_CLK_ENABLE0, 13, BM1880_CLK_DIV6, 16, 5, 3, + bm1880_div_table_0, 0), + GATE_DIV(BM1880_CLK_500M_ETH1, "clk_500m_eth1", "clk_fpll", + BM1880_CLK_ENABLE0, 15, BM1880_CLK_DIV7, 16, 5, 3, + bm1880_div_table_0, 0), + /* Don't gate GPIO clocks as it is not owned by the GPIO driver */ + GATE_DIV(BM1880_CLK_GPIO_DB, "clk_gpio_db", "clk_div_12m_usb", + BM1880_CLK_ENABLE0, 20, BM1880_CLK_DIV8, 16, 16, 120, + bm1880_div_table_4, CLK_IGNORE_UNUSED), + GATE_DIV(BM1880_CLK_SDMA_AUD, "clk_sdma_aud", "clk_fpll", + BM1880_CLK_ENABLE0, 24, BM1880_CLK_DIV9, 16, 7, 61, + bm1880_div_table_1, 0), + GATE_DIV(BM1880_CLK_JPEG_AXI, "clk_jpeg_axi", "clk_fpll", + BM1880_CLK_ENABLE0, 28, BM1880_CLK_DIV10, 16, 5, 4, + bm1880_div_table_0, 0), + GATE_DIV(BM1880_CLK_NF, "clk_nf", "clk_fpll", + BM1880_CLK_ENABLE0, 31, BM1880_CLK_DIV11, 16, 5, 30, + bm1880_div_table_0, 0), + GATE_DIV(BM1880_CLK_TPU_AXI, "clk_tpu_axi", "clk_spll", + BM1880_CLK_ENABLE1, 3, BM1880_CLK_DIV14, 16, 5, 1, + bm1880_div_table_0, 0), + GATE_DIV(BM1880_CLK_125M_USB, "clk_125m_usb", "clk_fpll", + BM1880_CLK_ENABLE1, 9, BM1880_CLK_DIV16, 16, 5, 12, + bm1880_div_table_0, 0), + GATE_DIV(BM1880_CLK_33K_USB, "clk_33k_usb", "clk_div_12m_usb", + BM1880_CLK_ENABLE1, 10, BM1880_CLK_DIV17, 16, 9, 363, + bm1880_div_table_3, 0), + GATE_DIV(BM1880_CLK_VIDEO_AXI, "clk_video_axi", "clk_fpll", + BM1880_CLK_ENABLE1, 13, BM1880_CLK_DIV19, 16, 5, 4, + bm1880_div_table_0, 0), + GATE_DIV(BM1880_CLK_VPP_AXI, "clk_vpp_axi", "clk_fpll", + BM1880_CLK_ENABLE1, 14, BM1880_CLK_DIV20, 16, 5, 4, + bm1880_div_table_0, 0), + GATE_MUX(BM1880_CLK_AXI1, "clk_axi1", clk_axi1_parents, + BM1880_CLK_ENABLE1, 15, BM1880_CLK_SELECT, 2, 0), + GATE_DIV(BM1880_CLK_AXI2, "clk_axi2", "clk_fpll", + BM1880_CLK_ENABLE1, 17, BM1880_CLK_DIV23, 16, 5, 3, + bm1880_div_table_0, 0), + GATE_DIV(BM1880_CLK_AXI3, "clk_axi3", "clk_mux_rv", + BM1880_CLK_ENABLE1, 18, BM1880_CLK_DIV24, 16, 5, 2, + bm1880_div_table_0, 0), + GATE_DIV(BM1880_CLK_AXI4, "clk_axi4", "clk_fpll", + BM1880_CLK_ENABLE1, 19, BM1880_CLK_DIV25, 16, 5, 6, + bm1880_div_table_0, 0), + GATE_DIV(BM1880_CLK_AXI5, "clk_axi5", "clk_fpll", + BM1880_CLK_ENABLE1, 20, BM1880_CLK_DIV26, 16, 5, 15, + bm1880_div_table_0, 0), +}; + +static unsigned long bm1880_pll_rate_calc(u32 regval, unsigned long parent_rate) +{ + u64 numerator; + u32 fbdiv, fref, refdiv; + u32 postdiv1, postdiv2, denominator; + + fbdiv = (regval >> 16) & 0xfff; + fref = parent_rate; + refdiv = regval & 0x1f; + postdiv1 = (regval >> 8) & 0x7; + postdiv2 = (regval >> 12) & 0x7; + + numerator = parent_rate * fbdiv; + denominator = refdiv * postdiv1 * postdiv2; + do_div(numerator, denominator); + + return (unsigned long)numerator; +} + +static unsigned long bm1880_pll_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct bm1880_pll_hw_clock *pll_hw = to_bm1880_pll_clk(hw); + unsigned long rate; + u32 regval; + + regval = readl(pll_hw->base + pll_hw->pll.reg); + rate = bm1880_pll_rate_calc(regval, parent_rate); + + return rate; +} + +static const struct clk_ops bm1880_pll_ops = { + .recalc_rate = bm1880_pll_recalc_rate, +}; + +static struct clk_hw *bm1880_clk_register_pll(struct bm1880_pll_hw_clock *pll_clk, + void __iomem *sys_base) +{ + struct clk_hw *hw; + int err; + + pll_clk->base = sys_base; + hw = &pll_clk->hw; + + err = clk_hw_register(NULL, hw); + if (err) + return ERR_PTR(err); + + return hw; +} + +static void bm1880_clk_unregister_pll(struct clk_hw *hw) +{ + struct bm1880_pll_hw_clock *pll_hw = to_bm1880_pll_clk(hw); + + clk_hw_unregister(hw); + kfree(pll_hw); +} + +static int bm1880_clk_register_plls(struct bm1880_pll_hw_clock *clks, + int num_clks, + struct bm1880_clock_data *data) +{ + struct clk_hw *hw; + void __iomem *pll_base = data->pll_base; + int i; + + for (i = 0; i < num_clks; i++) { + struct bm1880_pll_hw_clock *bm1880_clk = &clks[i]; + + hw = bm1880_clk_register_pll(bm1880_clk, pll_base); + if (IS_ERR(hw)) { + pr_err("%s: failed to register clock %s\n", + __func__, bm1880_clk->pll.name); + goto err_clk; + } + + data->hw_data.hws[clks[i].pll.id] = hw; + } + + return 0; + +err_clk: + while (i--) + bm1880_clk_unregister_pll(data->hw_data.hws[clks[i].pll.id]); + + return PTR_ERR(hw); +} + +static int bm1880_clk_register_mux(const struct bm1880_mux_clock *clks, + int num_clks, + struct bm1880_clock_data *data) +{ + struct clk_hw *hw; + void __iomem *sys_base = data->sys_base; + int i; + + for (i = 0; i < num_clks; i++) { + hw = clk_hw_register_mux(NULL, clks[i].name, + clks[i].parents, + clks[i].num_parents, + clks[i].flags, + sys_base + clks[i].reg, + clks[i].shift, 1, 0, + &bm1880_clk_lock); + if (IS_ERR(hw)) { + pr_err("%s: failed to register clock %s\n", + __func__, clks[i].name); + goto err_clk; + } + + data->hw_data.hws[clks[i].id] = hw; + } + + return 0; + +err_clk: + while (i--) + clk_hw_unregister_mux(data->hw_data.hws[clks[i].id]); + + return PTR_ERR(hw); +} + +static unsigned long bm1880_clk_div_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct bm1880_div_hw_clock *div_hw = to_bm1880_div_clk(hw); + struct bm1880_div_clock *div = &div_hw->div; + void __iomem *reg_addr = div_hw->base + div->reg; + unsigned int val; + unsigned long rate; + + if (!(readl(reg_addr) & BIT(3))) { + val = div->initval; + } else { + val = readl(reg_addr) >> div->shift; + val &= clk_div_mask(div->width); + } + + rate = divider_recalc_rate(hw, parent_rate, val, div->table, + div->flags, div->width); + + return rate; +} + +static long bm1880_clk_div_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) +{ + struct bm1880_div_hw_clock *div_hw = to_bm1880_div_clk(hw); + struct bm1880_div_clock *div = &div_hw->div; + void __iomem *reg_addr = div_hw->base + div->reg; + + if (div->flags & CLK_DIVIDER_READ_ONLY) { + u32 val; + + val = readl(reg_addr) >> div->shift; + val &= clk_div_mask(div->width); + + return divider_ro_round_rate(hw, rate, prate, div->table, + div->width, div->flags, + val); + } + + return divider_round_rate(hw, rate, prate, div->table, + div->width, div->flags); +} + +static int bm1880_clk_div_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct bm1880_div_hw_clock *div_hw = to_bm1880_div_clk(hw); + struct bm1880_div_clock *div = &div_hw->div; + void __iomem *reg_addr = div_hw->base + div->reg; + unsigned long flags = 0; + int value; + u32 val; + + value = divider_get_val(rate, parent_rate, div->table, + div->width, div_hw->div.flags); + if (value < 0) + return value; + + if (div_hw->lock) + spin_lock_irqsave(div_hw->lock, flags); + else + __acquire(div_hw->lock); + + val = readl(reg_addr); + val &= ~(clk_div_mask(div->width) << div_hw->div.shift); + val |= (u32)value << div->shift; + writel(val, reg_addr); + + if (div_hw->lock) + spin_unlock_irqrestore(div_hw->lock, flags); + else + __release(div_hw->lock); + + return 0; +} + +static const struct clk_ops bm1880_clk_div_ops = { + .recalc_rate = bm1880_clk_div_recalc_rate, + .round_rate = bm1880_clk_div_round_rate, + .set_rate = bm1880_clk_div_set_rate, +}; + +static struct clk_hw *bm1880_clk_register_div(struct bm1880_div_hw_clock *div_clk, + void __iomem *sys_base) +{ + struct clk_hw *hw; + int err; + + div_clk->div.flags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO; + div_clk->base = sys_base; + div_clk->lock = &bm1880_clk_lock; + + hw = &div_clk->hw; + err = clk_hw_register(NULL, hw); + if (err) + return ERR_PTR(err); + + return hw; +} + +static void bm1880_clk_unregister_div(struct clk_hw *hw) +{ + struct bm1880_div_hw_clock *div_hw = to_bm1880_div_clk(hw); + + clk_hw_unregister(hw); + kfree(div_hw); +} + +static int bm1880_clk_register_divs(struct bm1880_div_hw_clock *clks, + int num_clks, + struct bm1880_clock_data *data) +{ + struct clk_hw *hw; + void __iomem *sys_base = data->sys_base; + unsigned int i, id; + + for (i = 0; i < num_clks; i++) { + struct bm1880_div_hw_clock *bm1880_clk = &clks[i]; + + hw = bm1880_clk_register_div(bm1880_clk, sys_base); + if (IS_ERR(hw)) { + pr_err("%s: failed to register clock %s\n", + __func__, bm1880_clk->div.name); + goto err_clk; + } + + id = clks[i].div.id; + data->hw_data.hws[id] = hw; + } + + return 0; + +err_clk: + while (i--) + bm1880_clk_unregister_div(data->hw_data.hws[clks[i].div.id]); + + return PTR_ERR(hw); +} + +static int bm1880_clk_register_gate(const struct bm1880_gate_clock *clks, + int num_clks, + struct bm1880_clock_data *data) +{ + struct clk_hw *hw; + void __iomem *sys_base = data->sys_base; + int i; + + for (i = 0; i < num_clks; i++) { + hw = clk_hw_register_gate(NULL, clks[i].name, + clks[i].parent, + clks[i].flags, + sys_base + clks[i].gate_reg, + clks[i].gate_shift, 0, + &bm1880_clk_lock); + if (IS_ERR(hw)) { + pr_err("%s: failed to register clock %s\n", + __func__, clks[i].name); + goto err_clk; + } + + data->hw_data.hws[clks[i].id] = hw; + } + + return 0; + +err_clk: + while (i--) + clk_hw_unregister_gate(data->hw_data.hws[clks[i].id]); + + return PTR_ERR(hw); +} + +static struct clk_hw *bm1880_clk_register_composite(struct bm1880_composite_clock *clks, + void __iomem *sys_base) +{ + struct clk_hw *hw; + struct clk_mux *mux = NULL; + struct clk_gate *gate = NULL; + struct bm1880_div_hw_clock *div_hws = NULL; + struct clk_hw *mux_hw = NULL, *gate_hw = NULL, *div_hw = NULL; + const struct clk_ops *mux_ops = NULL, *gate_ops = NULL, *div_ops = NULL; + const char * const *parent_names; + const char *parent; + int num_parents; + int ret; + + if (clks->mux_shift >= 0) { + mux = kzalloc(sizeof(*mux), GFP_KERNEL); + if (!mux) + return ERR_PTR(-ENOMEM); + + mux->reg = sys_base + clks->mux_reg; + mux->mask = 1; + mux->shift = clks->mux_shift; + mux_hw = &mux->hw; + mux_ops = &clk_mux_ops; + mux->lock = &bm1880_clk_lock; + + parent_names = clks->parents; + num_parents = clks->num_parents; + } else { + parent = clks->parent; + parent_names = &parent; + num_parents = 1; + } + + if (clks->gate_shift >= 0) { + gate = kzalloc(sizeof(*gate), GFP_KERNEL); + if (!gate) { + ret = -ENOMEM; + goto err_out; + } + + gate->reg = sys_base + clks->gate_reg; + gate->bit_idx = clks->gate_shift; + gate->lock = &bm1880_clk_lock; + + gate_hw = &gate->hw; + gate_ops = &clk_gate_ops; + } + + if (clks->div_shift >= 0) { + div_hws = kzalloc(sizeof(*div_hws), GFP_KERNEL); + if (!div_hws) { + ret = -ENOMEM; + goto err_out; + } + + div_hws->base = sys_base; + div_hws->div.reg = clks->div_reg; + div_hws->div.shift = clks->div_shift; + div_hws->div.width = clks->div_width; + div_hws->div.table = clks->table; + div_hws->div.initval = clks->div_initval; + div_hws->lock = &bm1880_clk_lock; + div_hws->div.flags = CLK_DIVIDER_ONE_BASED | + CLK_DIVIDER_ALLOW_ZERO; + + div_hw = &div_hws->hw; + div_ops = &bm1880_clk_div_ops; + } + + hw = clk_hw_register_composite(NULL, clks->name, parent_names, + num_parents, mux_hw, mux_ops, div_hw, + div_ops, gate_hw, gate_ops, + clks->flags); + + if (IS_ERR(hw)) { + ret = PTR_ERR(hw); + goto err_out; + } + + return hw; + +err_out: + kfree(div_hws); + kfree(gate); + kfree(mux); + + return ERR_PTR(ret); +} + +static int bm1880_clk_register_composites(struct bm1880_composite_clock *clks, + int num_clks, + struct bm1880_clock_data *data) +{ + struct clk_hw *hw; + void __iomem *sys_base = data->sys_base; + int i; + + for (i = 0; i < num_clks; i++) { + struct bm1880_composite_clock *bm1880_clk = &clks[i]; + + hw = bm1880_clk_register_composite(bm1880_clk, sys_base); + if (IS_ERR(hw)) { + pr_err("%s: failed to register clock %s\n", + __func__, bm1880_clk->name); + goto err_clk; + } + + data->hw_data.hws[clks[i].id] = hw; + } + + return 0; + +err_clk: + while (i--) + clk_hw_unregister_composite(data->hw_data.hws[clks[i].id]); + + return PTR_ERR(hw); +} + +static int bm1880_clk_probe(struct platform_device *pdev) +{ + struct bm1880_clock_data *clk_data; + void __iomem *pll_base, *sys_base; + struct device *dev = &pdev->dev; + struct resource *res; + int num_clks, i; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + pll_base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(pll_base)) + return PTR_ERR(pll_base); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + sys_base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(sys_base)) + return PTR_ERR(sys_base); + + num_clks = ARRAY_SIZE(bm1880_pll_clks) + + ARRAY_SIZE(bm1880_div_clks) + + ARRAY_SIZE(bm1880_mux_clks) + + ARRAY_SIZE(bm1880_composite_clks) + + ARRAY_SIZE(bm1880_gate_clks); + + clk_data = devm_kzalloc(dev, struct_size(clk_data, hw_data.hws, + num_clks), GFP_KERNEL); + if (!clk_data) + return -ENOMEM; + + clk_data->pll_base = pll_base; + clk_data->sys_base = sys_base; + + for (i = 0; i < num_clks; i++) + clk_data->hw_data.hws[i] = ERR_PTR(-ENOENT); + + clk_data->hw_data.num = num_clks; + + bm1880_clk_register_plls(bm1880_pll_clks, + ARRAY_SIZE(bm1880_pll_clks), + clk_data); + + bm1880_clk_register_divs(bm1880_div_clks, + ARRAY_SIZE(bm1880_div_clks), + clk_data); + + bm1880_clk_register_mux(bm1880_mux_clks, + ARRAY_SIZE(bm1880_mux_clks), + clk_data); + + bm1880_clk_register_composites(bm1880_composite_clks, + ARRAY_SIZE(bm1880_composite_clks), + clk_data); + + bm1880_clk_register_gate(bm1880_gate_clks, + ARRAY_SIZE(bm1880_gate_clks), + clk_data); + + return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, + &clk_data->hw_data); +} + +static const struct of_device_id bm1880_of_match[] = { + { .compatible = "bitmain,bm1880-clk", }, + {} +}; +MODULE_DEVICE_TABLE(of, bm1880_of_match); + +static struct platform_driver bm1880_clk_driver = { + .driver = { + .name = "bm1880-clk", + .of_match_table = bm1880_of_match, + }, + .probe = bm1880_clk_probe, +}; +module_platform_driver(bm1880_clk_driver); + +MODULE_AUTHOR("Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>"); +MODULE_DESCRIPTION("Clock driver for Bitmain BM1880 SoC"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c index 4f13a681ddfc..3e9c3e608769 100644 --- a/drivers/clk/clk-composite.c +++ b/drivers/clk/clk-composite.c @@ -207,7 +207,7 @@ struct clk_hw *clk_hw_register_composite(struct device *dev, const char *name, unsigned long flags) { struct clk_hw *hw; - struct clk_init_data init; + struct clk_init_data init = {}; struct clk_composite *composite; struct clk_ops *clk_composite_ops; int ret; @@ -343,3 +343,14 @@ void clk_unregister_composite(struct clk *clk) clk_unregister(clk); kfree(composite); } + +void clk_hw_unregister_composite(struct clk_hw *hw) +{ + struct clk_composite *composite; + + composite = to_clk_composite(hw); + + clk_hw_unregister(hw); + kfree(composite); +} +EXPORT_SYMBOL_GPL(clk_hw_unregister_composite); diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c index 3f9ff78c4a2a..098b2b01f0af 100644 --- a/drivers/clk/clk-divider.c +++ b/drivers/clk/clk-divider.c @@ -471,7 +471,7 @@ static struct clk_hw *_register_divider(struct device *dev, const char *name, { struct clk_divider *div; struct clk_hw *hw; - struct clk_init_data init; + struct clk_init_data init = {}; int ret; if (clk_divider_flags & CLK_DIVIDER_HIWORD_MASK) { diff --git a/drivers/clk/clk-fixed-rate.c b/drivers/clk/clk-fixed-rate.c index a7e4aef7a376..2c4486c09040 100644 --- a/drivers/clk/clk-fixed-rate.c +++ b/drivers/clk/clk-fixed-rate.c @@ -58,7 +58,7 @@ struct clk_hw *clk_hw_register_fixed_rate_with_accuracy(struct device *dev, { struct clk_fixed_rate *fixed; struct clk_hw *hw; - struct clk_init_data init; + struct clk_init_data init = {}; int ret; /* allocate fixed-rate clock */ diff --git a/drivers/clk/clk-gate.c b/drivers/clk/clk-gate.c index 1b99fc962745..670053c58c1a 100644 --- a/drivers/clk/clk-gate.c +++ b/drivers/clk/clk-gate.c @@ -141,7 +141,7 @@ struct clk_hw *clk_hw_register_gate(struct device *dev, const char *name, { struct clk_gate *gate; struct clk_hw *hw; - struct clk_init_data init; + struct clk_init_data init = {}; int ret; if (clk_gate_flags & CLK_GATE_HIWORD_MASK) { diff --git a/drivers/clk/clk-gpio.c b/drivers/clk/clk-gpio.c index 9d930edd6516..13304cf5f2a8 100644 --- a/drivers/clk/clk-gpio.c +++ b/drivers/clk/clk-gpio.c @@ -280,7 +280,7 @@ static int gpio_clk_driver_probe(struct platform_device *pdev) else clk = clk_register_gpio_gate(&pdev->dev, node->name, parent_names ? parent_names[0] : NULL, gpiod, - 0); + CLK_SET_RATE_PARENT); if (IS_ERR(clk)) return PTR_ERR(clk); diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c index 66e91f740508..570b6e5b603b 100644 --- a/drivers/clk/clk-mux.c +++ b/drivers/clk/clk-mux.c @@ -153,7 +153,7 @@ struct clk_hw *clk_hw_register_mux_table(struct device *dev, const char *name, { struct clk_mux *mux; struct clk_hw *hw; - struct clk_init_data init; + struct clk_init_data init = {}; u8 width = 0; int ret; diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 1c677d7f7f53..b68e200829f2 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -1187,7 +1187,7 @@ static void clk_core_disable_unprepare(struct clk_core *core) clk_core_unprepare_lock(core); } -static void clk_unprepare_unused_subtree(struct clk_core *core) +static void __init clk_unprepare_unused_subtree(struct clk_core *core) { struct clk_core *child; @@ -1217,7 +1217,7 @@ static void clk_unprepare_unused_subtree(struct clk_core *core) clk_pm_runtime_put(core); } -static void clk_disable_unused_subtree(struct clk_core *core) +static void __init clk_disable_unused_subtree(struct clk_core *core) { struct clk_core *child; unsigned long flags; @@ -1263,7 +1263,7 @@ unprepare_out: clk_core_disable_unprepare(core->parent); } -static bool clk_ignore_unused; +static bool clk_ignore_unused __initdata; static int __init clk_ignore_unused_setup(char *__unused) { clk_ignore_unused = true; @@ -1271,7 +1271,7 @@ static int __init clk_ignore_unused_setup(char *__unused) } __setup("clk_ignore_unused", clk_ignore_unused_setup); -static int clk_disable_unused(void) +static int __init clk_disable_unused(void) { struct clk_core *core; @@ -1674,6 +1674,24 @@ static int clk_fetch_parent_index(struct clk_core *core, return i; } +/** + * clk_hw_get_parent_index - return the index of the parent clock + * @hw: clk_hw associated with the clk being consumed + * + * Fetches and returns the index of parent clock. Returns -EINVAL if the given + * clock does not have a current parent. + */ +int clk_hw_get_parent_index(struct clk_hw *hw) +{ + struct clk_hw *parent = clk_hw_get_parent(hw); + + if (WARN_ON(parent == NULL)) + return -EINVAL; + + return clk_fetch_parent_index(hw->core, parent->core); +} +EXPORT_SYMBOL_GPL(clk_hw_get_parent_index); + /* * Update the orphan status of @core and all its children. */ @@ -3879,6 +3897,7 @@ void clk_unregister(struct clk *clk) __func__, clk->core->name); kref_put(&clk->core->ref, __clk_release); + free_clk(clk); unlock: clk_prepare_unlock(); } diff --git a/drivers/clk/davinci/pll.c b/drivers/clk/davinci/pll.c index 1ac11b6a47a3..8a23d5dfd1f8 100644 --- a/drivers/clk/davinci/pll.c +++ b/drivers/clk/davinci/pll.c @@ -910,7 +910,6 @@ static int davinci_pll_probe(struct platform_device *pdev) struct davinci_pll_platform_data *pdata; const struct of_device_id *of_id; davinci_pll_init pll_init = NULL; - struct resource *res; void __iomem *base; of_id = of_match_device(davinci_pll_of_match, dev); @@ -930,8 +929,7 @@ static int davinci_pll_probe(struct platform_device *pdev) return -EINVAL; } - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(dev, res); + base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) return PTR_ERR(base); diff --git a/drivers/clk/davinci/psc.c b/drivers/clk/davinci/psc.c index 5b69e24a224f..7387e7f6276e 100644 --- a/drivers/clk/davinci/psc.c +++ b/drivers/clk/davinci/psc.c @@ -531,7 +531,6 @@ static int davinci_psc_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; const struct of_device_id *of_id; const struct davinci_psc_init_data *init_data = NULL; - struct resource *res; void __iomem *base; int ret; @@ -546,8 +545,7 @@ static int davinci_psc_probe(struct platform_device *pdev) return -EINVAL; } - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(dev, res); + base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) return PTR_ERR(base); diff --git a/drivers/clk/hisilicon/clk-hi3660.c b/drivers/clk/hisilicon/clk-hi3660.c index 5b3ad26dcc77..41f61726ab19 100644 --- a/drivers/clk/hisilicon/clk-hi3660.c +++ b/drivers/clk/hisilicon/clk-hi3660.c @@ -333,49 +333,49 @@ static const struct hisi_mux_clock hi3660_crgctrl_mux_clks[] = { static const struct hisi_divider_clock hi3660_crgctrl_divider_clks[] = { { HI3660_CLK_DIV_UART0, "clk_div_uart0", "clk_andgt_uart0", - CLK_SET_RATE_PARENT, 0xb0, 4, 4, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xb0, 4, 4, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_DIV_UART1, "clk_div_uart1", "clk_andgt_uart1", - CLK_SET_RATE_PARENT, 0xb0, 8, 4, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xb0, 8, 4, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_DIV_UARTH, "clk_div_uarth", "clk_andgt_uarth", - CLK_SET_RATE_PARENT, 0xb0, 12, 4, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xb0, 12, 4, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_DIV_MMC, "clk_div_mmc", "clk_andgt_mmc", - CLK_SET_RATE_PARENT, 0xb4, 3, 4, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xb4, 3, 4, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_DIV_SD, "clk_div_sd", "clk_andgt_sd", - CLK_SET_RATE_PARENT, 0xb8, 0, 4, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xb8, 0, 4, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_DIV_EDC0, "clk_div_edc0", "clk_andgt_edc0", - CLK_SET_RATE_PARENT, 0xbc, 0, 6, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xbc, 0, 6, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_DIV_LDI0, "clk_div_ldi0", "clk_andgt_ldi0", - CLK_SET_RATE_PARENT, 0xbc, 10, 6, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xbc, 10, 6, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_DIV_SDIO, "clk_div_sdio", "clk_andgt_sdio", - CLK_SET_RATE_PARENT, 0xc0, 0, 4, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xc0, 0, 4, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_DIV_LDI1, "clk_div_ldi1", "clk_andgt_ldi1", - CLK_SET_RATE_PARENT, 0xc0, 8, 6, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xc0, 8, 6, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_DIV_SPI, "clk_div_spi", "clk_andgt_spi", - CLK_SET_RATE_PARENT, 0xc4, 12, 4, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xc4, 12, 4, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_DIV_VENC, "clk_div_venc", "clk_andgt_venc", - CLK_SET_RATE_PARENT, 0xc8, 6, 5, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xc8, 6, 5, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_DIV_VDEC, "clk_div_vdec", "clk_andgt_vdec", - CLK_SET_RATE_PARENT, 0xcc, 0, 5, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xcc, 0, 5, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_DIV_VIVOBUS, "clk_div_vivobus", "clk_vivobus_andgt", - CLK_SET_RATE_PARENT, 0xd0, 7, 5, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xd0, 7, 5, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_DIV_I2C, "clk_div_i2c", "clk_div_320m", - CLK_SET_RATE_PARENT, 0xe8, 4, 4, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xe8, 4, 4, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_DIV_UFSPHY, "clk_div_ufsphy_cfg", "clk_gate_ufsphy_gt", - CLK_SET_RATE_PARENT, 0xe8, 9, 2, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xe8, 9, 2, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_DIV_CFGBUS, "clk_div_cfgbus", "clk_div_sysbus", - CLK_SET_RATE_PARENT, 0xec, 0, 2, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xec, 0, 2, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_DIV_MMC0BUS, "clk_div_mmc0bus", "autodiv_emmc0bus", - CLK_SET_RATE_PARENT, 0xec, 2, 1, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xec, 2, 1, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_DIV_MMC1BUS, "clk_div_mmc1bus", "clk_div_sysbus", - CLK_SET_RATE_PARENT, 0xec, 3, 1, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xec, 3, 1, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_DIV_UFSPERI, "clk_div_ufsperi", "clk_gate_ufs_subsys", - CLK_SET_RATE_PARENT, 0xec, 14, 1, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xec, 14, 1, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_DIV_AOMM, "clk_div_aomm", "clk_aomm_andgt", - CLK_SET_RATE_PARENT, 0x100, 7, 4, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x100, 7, 4, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_DIV_ISP_SNCLK, "clk_isp_snclk_div", "clk_isp_snclk_fac", - CLK_SET_RATE_PARENT, 0x108, 0, 2, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x108, 0, 2, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_DIV_IOPERI, "clk_div_ioperi", "clk_mux_ioperi", - CLK_SET_RATE_PARENT, 0x108, 11, 4, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x108, 11, 4, CLK_DIVIDER_HIWORD_MASK, }, }; /* clk_pmuctrl */ @@ -420,13 +420,13 @@ static const struct hisi_gate_clock hi3660_sctrl_gate_clks[] = { { HI3660_PCLK_MMBUF_ANDGT, "pclk_mmbuf_andgt", "clk_sw_mmbuf", CLK_SET_RATE_PARENT, 0x258, 7, CLK_GATE_HIWORD_MASK, }, { HI3660_CLK_MMBUF_PLL_ANDGT, "clk_mmbuf_pll_andgt", "clk_ppll0", - CLK_SET_RATE_PARENT, 0x260, 11, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x260, 11, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_FLL_MMBUF_ANDGT, "clk_fll_mmbuf_andgt", "clk_fll_src", - CLK_SET_RATE_PARENT, 0x260, 12, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x260, 12, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_SYS_MMBUF_ANDGT, "clk_sys_mmbuf_andgt", "clkin_sys", - CLK_SET_RATE_PARENT, 0x260, 13, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x260, 13, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_GATE_PCIEPHY_GT, "clk_gate_pciephy_gt", "clk_ppll0", - CLK_SET_RATE_PARENT, 0x268, 11, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x268, 11, CLK_DIVIDER_HIWORD_MASK, }, }; static const char *const @@ -446,13 +446,13 @@ static const struct hisi_mux_clock hi3660_sctrl_mux_clks[] = { static const struct hisi_divider_clock hi3660_sctrl_divider_clks[] = { { HI3660_CLK_DIV_AOBUS, "clk_div_aobus", "clk_ppll0", - CLK_SET_RATE_PARENT, 0x254, 0, 6, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x254, 0, 6, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_PCLK_DIV_MMBUF, "pclk_div_mmbuf", "pclk_mmbuf_andgt", - CLK_SET_RATE_PARENT, 0x258, 10, 2, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x258, 10, 2, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_ACLK_DIV_MMBUF, "aclk_div_mmbuf", "clk_mmbuf_pll_andgt", - CLK_SET_RATE_PARENT, 0x258, 12, 4, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x258, 12, 4, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_DIV_PCIEPHY, "clk_div_pciephy", "clk_gate_pciephy_gt", - CLK_SET_RATE_PARENT, 0x268, 12, 4, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x268, 12, 4, CLK_DIVIDER_HIWORD_MASK, }, }; /* clk_iomcu */ diff --git a/drivers/clk/hisilicon/clk-hi3670.c b/drivers/clk/hisilicon/clk-hi3670.c index fd8c837a6ea3..4d05a71683a5 100644 --- a/drivers/clk/hisilicon/clk-hi3670.c +++ b/drivers/clk/hisilicon/clk-hi3670.c @@ -295,61 +295,61 @@ static const struct hisi_gate_clock hi3670_crgctrl_gate_sep_clks[] = { static const struct hisi_gate_clock hi3670_crgctrl_gate_clks[] = { { HI3670_AUTODIV_SYSBUS, "autodiv_sysbus", "clk_div_sysbus", - CLK_SET_RATE_PARENT, 0x404, 5, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x404, 5, CLK_GATE_HIWORD_MASK, }, { HI3670_AUTODIV_EMMC0BUS, "autodiv_emmc0bus", "autodiv_sysbus", - CLK_SET_RATE_PARENT, 0x404, 1, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x404, 1, CLK_GATE_HIWORD_MASK, }, { HI3670_PCLK_ANDGT_MMC1_PCIE, "pclk_andgt_mmc1_pcie", "clk_div_320m", - CLK_SET_RATE_PARENT, 0xf8, 13, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xf8, 13, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_GATE_VCODECBUS_GT, "clk_gate_vcodecbus_gt", "clk_mux_vcodecbus", - CLK_SET_RATE_PARENT, 0x0F0, 8, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x0F0, 8, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_ANDGT_SD, "clk_andgt_sd", "clk_mux_sd_pll", - CLK_SET_RATE_PARENT, 0xF4, 3, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xF4, 3, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_SD_SYS_GT, "clk_sd_sys_gt", "clkin_sys", - CLK_SET_RATE_PARENT, 0xF4, 5, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xF4, 5, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_ANDGT_SDIO, "clk_andgt_sdio", "clk_mux_sdio_pll", - CLK_SET_RATE_PARENT, 0xF4, 8, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xF4, 8, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_SDIO_SYS_GT, "clk_sdio_sys_gt", "clkin_sys", - CLK_SET_RATE_PARENT, 0xF4, 6, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xF4, 6, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_A53HPM_ANDGT, "clk_a53hpm_andgt", "clk_mux_a53hpm", - CLK_SET_RATE_PARENT, 0x0F4, 7, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x0F4, 7, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_320M_PLL_GT, "clk_320m_pll_gt", "clk_mux_320m", - CLK_SET_RATE_PARENT, 0xF8, 10, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xF8, 10, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_ANDGT_UARTH, "clk_andgt_uarth", "clk_div_320m", - CLK_SET_RATE_PARENT, 0xF4, 11, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xF4, 11, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_ANDGT_UARTL, "clk_andgt_uartl", "clk_div_320m", - CLK_SET_RATE_PARENT, 0xF4, 10, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xF4, 10, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_ANDGT_UART0, "clk_andgt_uart0", "clk_div_320m", - CLK_SET_RATE_PARENT, 0xF4, 9, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xF4, 9, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_ANDGT_SPI, "clk_andgt_spi", "clk_div_320m", - CLK_SET_RATE_PARENT, 0xF4, 13, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xF4, 13, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_ANDGT_PCIEAXI, "clk_andgt_pcieaxi", "clk_mux_pcieaxi", - CLK_SET_RATE_PARENT, 0xfc, 15, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xfc, 15, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_DIV_AO_ASP_GT, "clk_div_ao_asp_gt", "clk_mux_ao_asp", - CLK_SET_RATE_PARENT, 0xF4, 4, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xF4, 4, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_GATE_CSI_TRANS, "clk_gate_csi_trans", "clk_ppll2", - CLK_SET_RATE_PARENT, 0xF4, 14, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xF4, 14, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_GATE_DSI_TRANS, "clk_gate_dsi_trans", "clk_ppll2", - CLK_SET_RATE_PARENT, 0xF4, 1, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xF4, 1, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_ANDGT_PTP, "clk_andgt_ptp", "clk_div_320m", - CLK_SET_RATE_PARENT, 0xF8, 5, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xF8, 5, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_ANDGT_OUT0, "clk_andgt_out0", "clk_ppll0", - CLK_SET_RATE_PARENT, 0xF0, 10, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xF0, 10, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_ANDGT_OUT1, "clk_andgt_out1", "clk_ppll0", - CLK_SET_RATE_PARENT, 0xF0, 11, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xF0, 11, CLK_GATE_HIWORD_MASK, }, { HI3670_CLKGT_DP_AUDIO_PLL_AO, "clkgt_dp_audio_pll_ao", "clk_ppll6", - CLK_SET_RATE_PARENT, 0xF8, 15, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xF8, 15, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_ANDGT_VDEC, "clk_andgt_vdec", "clk_mux_vdec", - CLK_SET_RATE_PARENT, 0xF0, 13, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xF0, 13, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_ANDGT_VENC, "clk_andgt_venc", "clk_mux_venc", - CLK_SET_RATE_PARENT, 0xF0, 9, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xF0, 9, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_ISP_SNCLK_ANGT, "clk_isp_snclk_angt", "clk_div_a53hpm", - CLK_SET_RATE_PARENT, 0x108, 2, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x108, 2, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_ANDGT_RXDPHY, "clk_andgt_rxdphy", "clk_div_a53hpm", - CLK_SET_RATE_PARENT, 0x0F0, 12, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x0F0, 12, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_ANDGT_ICS, "clk_andgt_ics", "clk_mux_ics", - CLK_SET_RATE_PARENT, 0xf0, 14, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xf0, 14, CLK_GATE_HIWORD_MASK, }, { HI3670_AUTODIV_DMABUS, "autodiv_dmabus", "autodiv_sysbus", - CLK_SET_RATE_PARENT, 0x404, 3, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x404, 3, CLK_GATE_HIWORD_MASK, }, }; static const char *const @@ -485,57 +485,57 @@ static const struct hisi_mux_clock hi3670_crgctrl_mux_clks[] = { static const struct hisi_divider_clock hi3670_crgctrl_divider_clks[] = { { HI3670_CLK_DIV_CFGBUS, "clk_div_cfgbus", "clk_div_sysbus", - CLK_SET_RATE_PARENT, 0xEC, 0, 2, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xEC, 0, 2, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_MMC0BUS, "clk_div_mmc0bus", "autodiv_emmc0bus", - CLK_SET_RATE_PARENT, 0x0EC, 2, 1, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x0EC, 2, 1, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_MMC1BUS, "clk_div_mmc1bus", "clk_div_sysbus", - CLK_SET_RATE_PARENT, 0x0EC, 3, 1, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x0EC, 3, 1, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_PCLK_DIV_MMC1_PCIE, "pclk_div_mmc1_pcie", "pclk_andgt_mmc1_pcie", - CLK_SET_RATE_PARENT, 0xb4, 6, 4, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xb4, 6, 4, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_VCODECBUS, "clk_div_vcodecbus", "clk_gate_vcodecbus_gt", - CLK_SET_RATE_PARENT, 0x0BC, 0, 6, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x0BC, 0, 6, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_SD, "clk_div_sd", "clk_andgt_sd", - CLK_SET_RATE_PARENT, 0xB8, 0, 4, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xB8, 0, 4, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_SDIO, "clk_div_sdio", "clk_andgt_sdio", - CLK_SET_RATE_PARENT, 0xC0, 0, 4, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xC0, 0, 4, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_UARTH, "clk_div_uarth", "clk_andgt_uarth", - CLK_SET_RATE_PARENT, 0xB0, 12, 4, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xB0, 12, 4, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_UARTL, "clk_div_uartl", "clk_andgt_uartl", - CLK_SET_RATE_PARENT, 0xB0, 8, 4, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xB0, 8, 4, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_UART0, "clk_div_uart0", "clk_andgt_uart0", - CLK_SET_RATE_PARENT, 0xB0, 4, 4, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xB0, 4, 4, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_I2C, "clk_div_i2c", "clk_div_320m", - CLK_SET_RATE_PARENT, 0xE8, 4, 4, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xE8, 4, 4, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_SPI, "clk_div_spi", "clk_andgt_spi", - CLK_SET_RATE_PARENT, 0xC4, 12, 4, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xC4, 12, 4, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_PCIEAXI, "clk_div_pcieaxi", "clk_andgt_pcieaxi", - CLK_SET_RATE_PARENT, 0xb4, 0, 5, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xb4, 0, 5, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_AO_ASP, "clk_div_ao_asp", "clk_div_ao_asp_gt", - CLK_SET_RATE_PARENT, 0x108, 6, 4, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x108, 6, 4, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_CSI_TRANS, "clk_div_csi_trans", "clk_gate_csi_trans", - CLK_SET_RATE_PARENT, 0xD4, 0, 5, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xD4, 0, 5, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_DSI_TRANS, "clk_div_dsi_trans", "clk_gate_dsi_trans", - CLK_SET_RATE_PARENT, 0xD4, 10, 5, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xD4, 10, 5, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_PTP, "clk_div_ptp", "clk_andgt_ptp", - CLK_SET_RATE_PARENT, 0xD8, 0, 4, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xD8, 0, 4, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_CLKOUT0_PLL, "clk_div_clkout0_pll", "clk_andgt_out0", - CLK_SET_RATE_PARENT, 0xe0, 4, 6, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xe0, 4, 6, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_CLKOUT1_PLL, "clk_div_clkout1_pll", "clk_andgt_out1", - CLK_SET_RATE_PARENT, 0xe0, 10, 6, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xe0, 10, 6, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLKDIV_DP_AUDIO_PLL_AO, "clkdiv_dp_audio_pll_ao", "clkgt_dp_audio_pll_ao", - CLK_SET_RATE_PARENT, 0xBC, 11, 4, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xBC, 11, 4, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_VDEC, "clk_div_vdec", "clk_andgt_vdec", - CLK_SET_RATE_PARENT, 0xC4, 0, 6, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xC4, 0, 6, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_VENC, "clk_div_venc", "clk_andgt_venc", - CLK_SET_RATE_PARENT, 0xC0, 8, 6, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xC0, 8, 6, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_ISP_SNCLK_DIV0, "clk_isp_snclk_div0", "clk_isp_snclk_fac", - CLK_SET_RATE_PARENT, 0x108, 0, 2, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x108, 0, 2, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_ISP_SNCLK_DIV1, "clk_isp_snclk_div1", "clk_isp_snclk_fac", - CLK_SET_RATE_PARENT, 0x10C, 14, 2, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x10C, 14, 2, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_ISP_SNCLK_DIV2, "clk_isp_snclk_div2", "clk_isp_snclk_fac", - CLK_SET_RATE_PARENT, 0x10C, 11, 2, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x10C, 11, 2, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_ICS, "clk_div_ics", "clk_andgt_ics", - CLK_SET_RATE_PARENT, 0xE4, 9, 6, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xE4, 9, 6, CLK_DIVIDER_HIWORD_MASK, }, }; /* clk_pmuctrl */ @@ -608,12 +608,12 @@ static const struct hisi_gate_clock hi3670_sctrl_gate_sep_clks[] = { static const struct hisi_gate_clock hi3670_sctrl_gate_clks[] = { { HI3670_CLK_ANDGT_IOPERI, "clk_andgt_ioperi", "clk_ppll0", - CLK_SET_RATE_PARENT, 0x270, 6, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x270, 6, CLK_GATE_HIWORD_MASK, }, { HI3670_CLKANDGT_ASP_SUBSYS_PERI, "clkandgt_asp_subsys_peri", "clk_ppll0", - CLK_SET_RATE_PARENT, 0x268, 3, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x268, 3, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_ANGT_ASP_SUBSYS, "clk_angt_asp_subsys", "clk_ppll0", - CLK_SET_RATE_PARENT, 0x258, 0, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x258, 0, CLK_GATE_HIWORD_MASK, }, }; static const char *const @@ -650,19 +650,19 @@ static const struct hisi_mux_clock hi3670_sctrl_mux_clks[] = { static const struct hisi_divider_clock hi3670_sctrl_divider_clks[] = { { HI3670_CLK_DIV_AOBUS, "clk_div_aobus", "clk_ppll0", - CLK_SET_RATE_PARENT, 0x254, 0, 6, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x254, 0, 6, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_UFS_SUBSYS, "clk_div_ufs_subsys", "clk_mux_ufs_subsys", - CLK_SET_RATE_PARENT, 0x274, 0, 6, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x274, 0, 6, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_IOPERI, "clk_div_ioperi", "clk_andgt_ioperi", - CLK_SET_RATE_PARENT, 0x270, 0, 6, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x270, 0, 6, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_CLKOUT0_TCXO, "clk_div_clkout0_tcxo", "clkin_sys", - CLK_SET_RATE_PARENT, 0x254, 6, 3, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x254, 6, 3, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_CLKOUT1_TCXO, "clk_div_clkout1_tcxo", "clkin_sys", - CLK_SET_RATE_PARENT, 0x254, 9, 3, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x254, 9, 3, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_ASP_SUBSYS_PERI_DIV, "clk_asp_subsys_peri_div", "clkandgt_asp_subsys_peri", - CLK_SET_RATE_PARENT, 0x268, 0, 3, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x268, 0, 3, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_ASP_SUBSYS, "clk_div_asp_subsys", "clk_angt_asp_subsys", - CLK_SET_RATE_PARENT, 0x250, 0, 3, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x250, 0, 3, CLK_DIVIDER_HIWORD_MASK, }, }; /* clk_iomcu */ @@ -732,17 +732,17 @@ static const struct hisi_gate_clock hi3670_media1_gate_sep_clks[] = { static const struct hisi_gate_clock hi3670_media1_gate_clks[] = { { HI3670_CLK_GATE_VIVOBUS_ANDGT, "clk_gate_vivobus_andgt", "clk_mux_vivobus", - CLK_SET_RATE_PARENT, 0x84, 3, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x84, 3, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_ANDGT_EDC0, "clk_andgt_edc0", "clk_mux_edc0", - CLK_SET_RATE_PARENT, 0x84, 7, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x84, 7, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_ANDGT_LDI0, "clk_andgt_ldi0", "clk_mux_ldi0", - CLK_SET_RATE_PARENT, 0x84, 9, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x84, 9, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_ANDGT_LDI1, "clk_andgt_ldi1", "clk_mux_ldi1", - CLK_SET_RATE_PARENT, 0x84, 8, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x84, 8, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_MMBUF_PLL_ANDGT, "clk_mmbuf_pll_andgt", "clk_sw_mmbuf", - CLK_SET_RATE_PARENT, 0x84, 14, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x84, 14, CLK_GATE_HIWORD_MASK, }, { HI3670_PCLK_MMBUF_ANDGT, "pclk_mmbuf_andgt", "aclk_div_mmbuf", - CLK_SET_RATE_PARENT, 0x84, 15, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x84, 15, CLK_GATE_HIWORD_MASK, }, }; static const char *const @@ -799,17 +799,17 @@ static const struct hisi_mux_clock hi3670_media1_mux_clks[] = { static const struct hisi_divider_clock hi3670_media1_divider_clks[] = { { HI3670_CLK_DIV_VIVOBUS, "clk_div_vivobus", "clk_gate_vivobus_andgt", - CLK_SET_RATE_PARENT, 0x74, 0, 6, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x74, 0, 6, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_EDC0, "clk_div_edc0", "clk_andgt_edc0", - CLK_SET_RATE_PARENT, 0x68, 0, 6, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x68, 0, 6, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_LDI0, "clk_div_ldi0", "clk_andgt_ldi0", - CLK_SET_RATE_PARENT, 0x60, 0, 6, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x60, 0, 6, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_LDI1, "clk_div_ldi1", "clk_andgt_ldi1", - CLK_SET_RATE_PARENT, 0x64, 0, 6, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x64, 0, 6, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_ACLK_DIV_MMBUF, "aclk_div_mmbuf", "clk_mmbuf_pll_andgt", - CLK_SET_RATE_PARENT, 0x7C, 10, 6, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x7C, 10, 6, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_PCLK_DIV_MMBUF, "pclk_div_mmbuf", "pclk_mmbuf_andgt", - CLK_SET_RATE_PARENT, 0x78, 0, 2, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x78, 0, 2, CLK_DIVIDER_HIWORD_MASK, }, }; /* clk_media2 */ diff --git a/drivers/clk/hisilicon/clk-hi6220.c b/drivers/clk/hisilicon/clk-hi6220.c index b2c5b6bbb1c1..e7cdf72d4b06 100644 --- a/drivers/clk/hisilicon/clk-hi6220.c +++ b/drivers/clk/hisilicon/clk-hi6220.c @@ -86,7 +86,8 @@ static void __init hi6220_clk_ao_init(struct device_node *np) hisi_clk_register_gate_sep(hi6220_separated_gate_clks_ao, ARRAY_SIZE(hi6220_separated_gate_clks_ao), clk_data_ao); } -CLK_OF_DECLARE(hi6220_clk_ao, "hisilicon,hi6220-aoctrl", hi6220_clk_ao_init); +/* Allow reset driver to probe as well */ +CLK_OF_DECLARE_DRIVER(hi6220_clk_ao, "hisilicon,hi6220-aoctrl", hi6220_clk_ao_init); /* clocks in sysctrl */ diff --git a/drivers/clk/hisilicon/reset.c b/drivers/clk/hisilicon/reset.c index 2e22fea2a2e7..93cee17db8b1 100644 --- a/drivers/clk/hisilicon/reset.c +++ b/drivers/clk/hisilicon/reset.c @@ -90,14 +90,12 @@ static const struct reset_control_ops hisi_reset_ops = { struct hisi_reset_controller *hisi_reset_init(struct platform_device *pdev) { struct hisi_reset_controller *rstc; - struct resource *res; rstc = devm_kmalloc(&pdev->dev, sizeof(*rstc), GFP_KERNEL); if (!rstc) return NULL; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - rstc->membase = devm_ioremap_resource(&pdev->dev, res); + rstc->membase = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(rstc->membase)) return NULL; diff --git a/drivers/clk/imgtec/clk-boston.c b/drivers/clk/imgtec/clk-boston.c index 33ab4ff61165..b00cbd045af5 100644 --- a/drivers/clk/imgtec/clk-boston.c +++ b/drivers/clk/imgtec/clk-boston.c @@ -58,8 +58,7 @@ static void __init clk_boston_setup(struct device_node *np) cpu_div = ext_field(mmcmdiv, BOSTON_PLAT_MMCMDIV_CLK1DIV); cpu_freq = mult_frac(in_freq, mul, cpu_div); - onecell = kzalloc(sizeof(*onecell) + - (BOSTON_CLK_COUNT * sizeof(struct clk_hw *)), + onecell = kzalloc(struct_size(onecell, hws, BOSTON_CLK_COUNT), GFP_KERNEL); if (!onecell) return; diff --git a/drivers/clk/imx/clk-imx6sll.c b/drivers/clk/imx/clk-imx6sll.c index 5f3e92c09a5e..8e8288bda4d0 100644 --- a/drivers/clk/imx/clk-imx6sll.c +++ b/drivers/clk/imx/clk-imx6sll.c @@ -107,12 +107,12 @@ static void __init imx6sll_clocks_init(struct device_node *ccm_node) hws[IMX6SLL_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0); - hws[IMX6SLL_CLK_CKIL] = __clk_get_hw(of_clk_get_by_name(ccm_node, "ckil")); - hws[IMX6SLL_CLK_OSC] = __clk_get_hw(of_clk_get_by_name(ccm_node, "osc")); + hws[IMX6SLL_CLK_CKIL] = imx_obtain_fixed_clk_hw(ccm_node, "ckil"); + hws[IMX6SLL_CLK_OSC] = imx_obtain_fixed_clk_hw(ccm_node, "osc"); /* ipp_di clock is external input */ - hws[IMX6SLL_CLK_IPP_DI0] = __clk_get_hw(of_clk_get_by_name(ccm_node, "ipp_di0")); - hws[IMX6SLL_CLK_IPP_DI1] = __clk_get_hw(of_clk_get_by_name(ccm_node, "ipp_di1")); + hws[IMX6SLL_CLK_IPP_DI0] = imx_obtain_fixed_clk_hw(ccm_node, "ipp_di0"); + hws[IMX6SLL_CLK_IPP_DI1] = imx_obtain_fixed_clk_hw(ccm_node, "ipp_di1"); np = of_find_compatible_node(NULL, NULL, "fsl,imx6sll-anatop"); base = of_iomap(np, 0); diff --git a/drivers/clk/imx/clk-imx6sx.c b/drivers/clk/imx/clk-imx6sx.c index c4685c01929a..89ba71271e5c 100644 --- a/drivers/clk/imx/clk-imx6sx.c +++ b/drivers/clk/imx/clk-imx6sx.c @@ -139,16 +139,16 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node) hws[IMX6SX_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0); - hws[IMX6SX_CLK_CKIL] = __clk_get_hw(of_clk_get_by_name(ccm_node, "ckil")); - hws[IMX6SX_CLK_OSC] = __clk_get_hw(of_clk_get_by_name(ccm_node, "osc")); + hws[IMX6SX_CLK_CKIL] = imx_obtain_fixed_clk_hw(ccm_node, "ckil"); + hws[IMX6SX_CLK_OSC] = imx_obtain_fixed_clk_hw(ccm_node, "osc"); /* ipp_di clock is external input */ - hws[IMX6SX_CLK_IPP_DI0] = __clk_get_hw(of_clk_get_by_name(ccm_node, "ipp_di0")); - hws[IMX6SX_CLK_IPP_DI1] = __clk_get_hw(of_clk_get_by_name(ccm_node, "ipp_di1")); + hws[IMX6SX_CLK_IPP_DI0] = imx_obtain_fixed_clk_hw(ccm_node, "ipp_di0"); + hws[IMX6SX_CLK_IPP_DI1] = imx_obtain_fixed_clk_hw(ccm_node, "ipp_di1"); /* Clock source from external clock via CLK1/2 PAD */ - hws[IMX6SX_CLK_ANACLK1] = __clk_get_hw(of_clk_get_by_name(ccm_node, "anaclk1")); - hws[IMX6SX_CLK_ANACLK2] = __clk_get_hw(of_clk_get_by_name(ccm_node, "anaclk2")); + hws[IMX6SX_CLK_ANACLK1] = imx_obtain_fixed_clk_hw(ccm_node, "anaclk1"); + hws[IMX6SX_CLK_ANACLK2] = imx_obtain_fixed_clk_hw(ccm_node, "anaclk2"); np = of_find_compatible_node(NULL, NULL, "fsl,imx6sx-anatop"); base = of_iomap(np, 0); diff --git a/drivers/clk/imx/clk-imx6ul.c b/drivers/clk/imx/clk-imx6ul.c index bc931988fe7b..dafc8806b03e 100644 --- a/drivers/clk/imx/clk-imx6ul.c +++ b/drivers/clk/imx/clk-imx6ul.c @@ -126,12 +126,12 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) hws[IMX6UL_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0); - hws[IMX6UL_CLK_CKIL] = __clk_get_hw(of_clk_get_by_name(ccm_node, "ckil")); - hws[IMX6UL_CLK_OSC] = __clk_get_hw(of_clk_get_by_name(ccm_node, "osc")); + hws[IMX6UL_CLK_CKIL] = imx_obtain_fixed_clk_hw(ccm_node, "ckil"); + hws[IMX6UL_CLK_OSC] = imx_obtain_fixed_clk_hw(ccm_node, "osc"); /* ipp_di clock is external input */ - hws[IMX6UL_CLK_IPP_DI0] = __clk_get_hw(of_clk_get_by_name(ccm_node, "ipp_di0")); - hws[IMX6UL_CLK_IPP_DI1] = __clk_get_hw(of_clk_get_by_name(ccm_node, "ipp_di1")); + hws[IMX6UL_CLK_IPP_DI0] = imx_obtain_fixed_clk_hw(ccm_node, "ipp_di0"); + hws[IMX6UL_CLK_IPP_DI1] = imx_obtain_fixed_clk_hw(ccm_node, "ipp_di1"); np = of_find_compatible_node(NULL, NULL, "fsl,imx6ul-anatop"); base = of_iomap(np, 0); diff --git a/drivers/clk/imx/clk-imx7d.c b/drivers/clk/imx/clk-imx7d.c index fbea774ef687..0c9f7adb41ae 100644 --- a/drivers/clk/imx/clk-imx7d.c +++ b/drivers/clk/imx/clk-imx7d.c @@ -403,8 +403,8 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node) hws = clk_hw_data->hws; hws[IMX7D_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0); - hws[IMX7D_OSC_24M_CLK] = __clk_get_hw(of_clk_get_by_name(ccm_node, "osc")); - hws[IMX7D_CKIL] = __clk_get_hw(of_clk_get_by_name(ccm_node, "ckil")); + hws[IMX7D_OSC_24M_CLK] = imx_obtain_fixed_clk_hw(ccm_node, "osc"); + hws[IMX7D_CKIL] = imx_obtain_fixed_clk_hw(ccm_node, "ckil"); np = of_find_compatible_node(NULL, NULL, "fsl,imx7d-anatop"); base = of_iomap(np, 0); diff --git a/drivers/clk/imx/clk-imx7ulp.c b/drivers/clk/imx/clk-imx7ulp.c index 2022d9bead91..3fdf3d494f0a 100644 --- a/drivers/clk/imx/clk-imx7ulp.c +++ b/drivers/clk/imx/clk-imx7ulp.c @@ -24,11 +24,11 @@ static const char * const spll_pfd_sels[] = { "spll_pfd0", "spll_pfd1", "spll_pf static const char * const spll_sels[] = { "spll", "spll_pfd_sel", }; static const char * const apll_pfd_sels[] = { "apll_pfd0", "apll_pfd1", "apll_pfd2", "apll_pfd3", }; static const char * const apll_sels[] = { "apll", "apll_pfd_sel", }; -static const char * const scs_sels[] = { "dummy", "sosc", "sirc", "firc", "dummy", "apll_sel", "spll_sel", "upll", }; -static const char * const ddr_sels[] = { "apll_pfd_sel", "upll", }; +static const char * const scs_sels[] = { "dummy", "sosc", "sirc", "firc", "dummy", "apll_sel", "spll_sel", "dummy", }; +static const char * const ddr_sels[] = { "apll_pfd_sel", "dummy", "dummy", "dummy", }; static const char * const nic_sels[] = { "firc", "ddr_clk", }; static const char * const periph_plat_sels[] = { "dummy", "nic1_bus_clk", "nic1_clk", "ddr_clk", "apll_pfd2", "apll_pfd1", "apll_pfd0", "upll", }; -static const char * const periph_bus_sels[] = { "dummy", "sosc_bus_clk", "mpll", "firc_bus_clk", "rosc", "nic1_bus_clk", "nic1_clk", "spll_bus_clk", }; +static const char * const periph_bus_sels[] = { "dummy", "sosc_bus_clk", "dummy", "firc_bus_clk", "rosc", "nic1_bus_clk", "nic1_clk", "spll_bus_clk", }; static const char * const arm_sels[] = { "divcore", "dummy", "dummy", "hsrun_divcore", }; /* used by sosc/sirc/firc/ddr/spll/apll dividers */ @@ -75,7 +75,6 @@ static void __init imx7ulp_clk_scg1_init(struct device_node *np) 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_MIPI_PLL] = imx_obtain_fixed_clk_hw(np, "mpll"); clks[IMX7ULP_CLK_UPLL] = imx_obtain_fixed_clk_hw(np, "upll"); /* SCG1 */ @@ -118,7 +117,7 @@ static void __init imx7ulp_clk_scg1_init(struct device_node *np) 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, 1, ddr_sels, ARRAY_SIZE(ddr_sels), CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE); + 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); 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); diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c index 172589e94f60..030b15d7c0ce 100644 --- a/drivers/clk/imx/clk-imx8mm.c +++ b/drivers/clk/imx/clk-imx8mm.c @@ -26,73 +26,6 @@ static u32 share_count_disp; static u32 share_count_pdm; static u32 share_count_nand; -static const struct imx_pll14xx_rate_table imx8mm_pll1416x_tbl[] = { - PLL_1416X_RATE(1800000000U, 225, 3, 0), - PLL_1416X_RATE(1600000000U, 200, 3, 0), - PLL_1416X_RATE(1200000000U, 300, 3, 1), - PLL_1416X_RATE(1000000000U, 250, 3, 1), - PLL_1416X_RATE(800000000U, 200, 3, 1), - PLL_1416X_RATE(750000000U, 250, 2, 2), - PLL_1416X_RATE(700000000U, 350, 3, 2), - PLL_1416X_RATE(600000000U, 300, 3, 2), -}; - -static const struct imx_pll14xx_rate_table imx8mm_audiopll_tbl[] = { - PLL_1443X_RATE(393216000U, 262, 2, 3, 9437), - PLL_1443X_RATE(361267200U, 361, 3, 3, 17511), -}; - -static const struct imx_pll14xx_rate_table imx8mm_videopll_tbl[] = { - PLL_1443X_RATE(650000000U, 325, 3, 2, 0), - PLL_1443X_RATE(594000000U, 198, 2, 2, 0), -}; - -static const struct imx_pll14xx_rate_table imx8mm_drampll_tbl[] = { - PLL_1443X_RATE(650000000U, 325, 3, 2, 0), -}; - -static struct imx_pll14xx_clk imx8mm_audio_pll = { - .type = PLL_1443X, - .rate_table = imx8mm_audiopll_tbl, - .rate_count = ARRAY_SIZE(imx8mm_audiopll_tbl), -}; - -static struct imx_pll14xx_clk imx8mm_video_pll = { - .type = PLL_1443X, - .rate_table = imx8mm_videopll_tbl, - .rate_count = ARRAY_SIZE(imx8mm_videopll_tbl), -}; - -static struct imx_pll14xx_clk imx8mm_dram_pll = { - .type = PLL_1443X, - .rate_table = imx8mm_drampll_tbl, - .rate_count = ARRAY_SIZE(imx8mm_drampll_tbl), -}; - -static struct imx_pll14xx_clk imx8mm_arm_pll = { - .type = PLL_1416X, - .rate_table = imx8mm_pll1416x_tbl, - .rate_count = ARRAY_SIZE(imx8mm_pll1416x_tbl), -}; - -static struct imx_pll14xx_clk imx8mm_gpu_pll = { - .type = PLL_1416X, - .rate_table = imx8mm_pll1416x_tbl, - .rate_count = ARRAY_SIZE(imx8mm_pll1416x_tbl), -}; - -static struct imx_pll14xx_clk imx8mm_vpu_pll = { - .type = PLL_1416X, - .rate_table = imx8mm_pll1416x_tbl, - .rate_count = ARRAY_SIZE(imx8mm_pll1416x_tbl), -}; - -static struct imx_pll14xx_clk imx8mm_sys_pll = { - .type = PLL_1416X, - .rate_table = imx8mm_pll1416x_tbl, - .rate_count = ARRAY_SIZE(imx8mm_pll1416x_tbl), -}; - static const char *pll_ref_sels[] = { "osc_24m", "dummy", "dummy", "dummy", }; static const char *audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ref_sel", }; static const char *audio_pll2_bypass_sels[] = {"audio_pll2", "audio_pll2_ref_sel", }; @@ -101,8 +34,6 @@ static const char *dram_pll_bypass_sels[] = {"dram_pll", "dram_pll_ref_sel", }; static const char *gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", }; static const char *vpu_pll_bypass_sels[] = {"vpu_pll", "vpu_pll_ref_sel", }; static const char *arm_pll_bypass_sels[] = {"arm_pll", "arm_pll_ref_sel", }; -static const char *sys_pll1_bypass_sels[] = {"sys_pll1", "sys_pll1_ref_sel", }; -static const char *sys_pll2_bypass_sels[] = {"sys_pll2", "sys_pll2_ref_sel", }; static const char *sys_pll3_bypass_sels[] = {"sys_pll3", "sys_pll3_ref_sel", }; /* CCM ROOT */ @@ -392,20 +323,18 @@ static int imx8mm_clocks_probe(struct platform_device *pdev) 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_PLL1_REF_SEL] = imx_clk_mux("sys_pll1_ref_sel", base + 0x94, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); - clks[IMX8MM_SYS_PLL2_REF_SEL] = imx_clk_mux("sys_pll2_ref_sel", base + 0x104, 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, &imx8mm_audio_pll); - clks[IMX8MM_AUDIO_PLL2] = imx_clk_pll14xx("audio_pll2", "audio_pll2_ref_sel", base + 0x14, &imx8mm_audio_pll); - clks[IMX8MM_VIDEO_PLL1] = imx_clk_pll14xx("video_pll1", "video_pll1_ref_sel", base + 0x28, &imx8mm_video_pll); - clks[IMX8MM_DRAM_PLL] = imx_clk_pll14xx("dram_pll", "dram_pll_ref_sel", base + 0x50, &imx8mm_dram_pll); - clks[IMX8MM_GPU_PLL] = imx_clk_pll14xx("gpu_pll", "gpu_pll_ref_sel", base + 0x64, &imx8mm_gpu_pll); - clks[IMX8MM_VPU_PLL] = imx_clk_pll14xx("vpu_pll", "vpu_pll_ref_sel", base + 0x74, &imx8mm_vpu_pll); - clks[IMX8MM_ARM_PLL] = imx_clk_pll14xx("arm_pll", "arm_pll_ref_sel", base + 0x84, &imx8mm_arm_pll); - clks[IMX8MM_SYS_PLL1] = imx_clk_pll14xx("sys_pll1", "sys_pll1_ref_sel", base + 0x94, &imx8mm_sys_pll); - clks[IMX8MM_SYS_PLL2] = imx_clk_pll14xx("sys_pll2", "sys_pll2_ref_sel", base + 0x104, &imx8mm_sys_pll); - clks[IMX8MM_SYS_PLL3] = imx_clk_pll14xx("sys_pll3", "sys_pll3_ref_sel", base + 0x114, &imx8mm_sys_pll); + 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); /* 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); @@ -415,8 +344,6 @@ static int imx8mm_clocks_probe(struct platform_device *pdev) 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_PLL1_BYPASS] = imx_clk_mux_flags("sys_pll1_bypass", base + 0x94, 28, 1, sys_pll1_bypass_sels, ARRAY_SIZE(sys_pll1_bypass_sels), CLK_SET_RATE_PARENT); - clks[IMX8MM_SYS_PLL2_BYPASS] = imx_clk_mux_flags("sys_pll2_bypass", base + 0x104, 28, 1, sys_pll2_bypass_sels, ARRAY_SIZE(sys_pll2_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); /* PLL out gate */ @@ -427,29 +354,48 @@ static int imx8mm_clocks_probe(struct platform_device *pdev) 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_PLL1_OUT] = imx_clk_gate("sys_pll1_out", "sys_pll1_bypass", base + 0x94, 11); - clks[IMX8MM_SYS_PLL2_OUT] = imx_clk_gate("sys_pll2_out", "sys_pll2_bypass", base + 0x104, 11); clks[IMX8MM_SYS_PLL3_OUT] = imx_clk_gate("sys_pll3_out", "sys_pll3_bypass", base + 0x114, 11); - /* SYS PLL fixed output */ - clks[IMX8MM_SYS_PLL1_40M] = imx_clk_fixed_factor("sys_pll1_40m", "sys_pll1_out", 1, 20); - clks[IMX8MM_SYS_PLL1_80M] = imx_clk_fixed_factor("sys_pll1_80m", "sys_pll1_out", 1, 10); - clks[IMX8MM_SYS_PLL1_100M] = imx_clk_fixed_factor("sys_pll1_100m", "sys_pll1_out", 1, 8); - clks[IMX8MM_SYS_PLL1_133M] = imx_clk_fixed_factor("sys_pll1_133m", "sys_pll1_out", 1, 6); - clks[IMX8MM_SYS_PLL1_160M] = imx_clk_fixed_factor("sys_pll1_160m", "sys_pll1_out", 1, 5); - clks[IMX8MM_SYS_PLL1_200M] = imx_clk_fixed_factor("sys_pll1_200m", "sys_pll1_out", 1, 4); - clks[IMX8MM_SYS_PLL1_266M] = imx_clk_fixed_factor("sys_pll1_266m", "sys_pll1_out", 1, 3); - clks[IMX8MM_SYS_PLL1_400M] = imx_clk_fixed_factor("sys_pll1_400m", "sys_pll1_out", 1, 2); + /* 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); - clks[IMX8MM_SYS_PLL2_50M] = imx_clk_fixed_factor("sys_pll2_50m", "sys_pll2_out", 1, 20); - clks[IMX8MM_SYS_PLL2_100M] = imx_clk_fixed_factor("sys_pll2_100m", "sys_pll2_out", 1, 10); - clks[IMX8MM_SYS_PLL2_125M] = imx_clk_fixed_factor("sys_pll2_125m", "sys_pll2_out", 1, 8); - clks[IMX8MM_SYS_PLL2_166M] = imx_clk_fixed_factor("sys_pll2_166m", "sys_pll2_out", 1, 6); - clks[IMX8MM_SYS_PLL2_200M] = imx_clk_fixed_factor("sys_pll2_200m", "sys_pll2_out", 1, 5); - clks[IMX8MM_SYS_PLL2_250M] = imx_clk_fixed_factor("sys_pll2_250m", "sys_pll2_out", 1, 4); - clks[IMX8MM_SYS_PLL2_333M] = imx_clk_fixed_factor("sys_pll2_333m", "sys_pll2_out", 1, 3); - clks[IMX8MM_SYS_PLL2_500M] = imx_clk_fixed_factor("sys_pll2_500m", "sys_pll2_out", 1, 2); + /* 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); np = dev->of_node; diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c index 58b5acee3830..9f5a5a56b45e 100644 --- a/drivers/clk/imx/clk-imx8mn.c +++ b/drivers/clk/imx/clk-imx8mn.c @@ -25,89 +25,6 @@ static u32 share_count_disp; static u32 share_count_pdm; static u32 share_count_nand; -enum { - ARM_PLL, - GPU_PLL, - VPU_PLL, - SYS_PLL1, - SYS_PLL2, - SYS_PLL3, - DRAM_PLL, - AUDIO_PLL1, - AUDIO_PLL2, - VIDEO_PLL2, - NR_PLLS, -}; - -static const struct imx_pll14xx_rate_table imx8mn_pll1416x_tbl[] = { - PLL_1416X_RATE(1800000000U, 225, 3, 0), - PLL_1416X_RATE(1600000000U, 200, 3, 0), - PLL_1416X_RATE(1500000000U, 375, 3, 1), - PLL_1416X_RATE(1400000000U, 350, 3, 1), - PLL_1416X_RATE(1200000000U, 300, 3, 1), - PLL_1416X_RATE(1000000000U, 250, 3, 1), - PLL_1416X_RATE(800000000U, 200, 3, 1), - PLL_1416X_RATE(750000000U, 250, 2, 2), - PLL_1416X_RATE(700000000U, 350, 3, 2), - PLL_1416X_RATE(600000000U, 300, 3, 2), -}; - -static const struct imx_pll14xx_rate_table imx8mn_audiopll_tbl[] = { - PLL_1443X_RATE(393216000U, 262, 2, 3, 9437), - PLL_1443X_RATE(361267200U, 361, 3, 3, 17511), -}; - -static const struct imx_pll14xx_rate_table imx8mn_videopll_tbl[] = { - PLL_1443X_RATE(650000000U, 325, 3, 2, 0), - PLL_1443X_RATE(594000000U, 198, 2, 2, 0), -}; - -static const struct imx_pll14xx_rate_table imx8mn_drampll_tbl[] = { - PLL_1443X_RATE(650000000U, 325, 3, 2, 0), -}; - -static struct imx_pll14xx_clk imx8mn_audio_pll = { - .type = PLL_1443X, - .rate_table = imx8mn_audiopll_tbl, - .rate_count = ARRAY_SIZE(imx8mn_audiopll_tbl), -}; - -static struct imx_pll14xx_clk imx8mn_video_pll = { - .type = PLL_1443X, - .rate_table = imx8mn_videopll_tbl, - .rate_count = ARRAY_SIZE(imx8mn_videopll_tbl), -}; - -static struct imx_pll14xx_clk imx8mn_dram_pll = { - .type = PLL_1443X, - .rate_table = imx8mn_drampll_tbl, - .rate_count = ARRAY_SIZE(imx8mn_drampll_tbl), -}; - -static struct imx_pll14xx_clk imx8mn_arm_pll = { - .type = PLL_1416X, - .rate_table = imx8mn_pll1416x_tbl, - .rate_count = ARRAY_SIZE(imx8mn_pll1416x_tbl), -}; - -static struct imx_pll14xx_clk imx8mn_gpu_pll = { - .type = PLL_1416X, - .rate_table = imx8mn_pll1416x_tbl, - .rate_count = ARRAY_SIZE(imx8mn_pll1416x_tbl), -}; - -static struct imx_pll14xx_clk imx8mn_vpu_pll = { - .type = PLL_1416X, - .rate_table = imx8mn_pll1416x_tbl, - .rate_count = ARRAY_SIZE(imx8mn_pll1416x_tbl), -}; - -static struct imx_pll14xx_clk imx8mn_sys_pll = { - .type = PLL_1416X, - .rate_table = imx8mn_pll1416x_tbl, - .rate_count = ARRAY_SIZE(imx8mn_pll1416x_tbl), -}; - 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", }; @@ -116,8 +33,6 @@ static const char * const dram_pll_bypass_sels[] = {"dram_pll", "dram_pll_ref_se 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 imx8mn_a53_sels[] = {"osc_24m", "arm_pll_out", "sys_pll2_500m", @@ -405,20 +320,18 @@ static int imx8mn_clocks_probe(struct platform_device *pdev) 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_PLL1_REF_SEL] = imx_clk_mux("sys_pll1_ref_sel", base + 0x94, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); - clks[IMX8MN_SYS_PLL2_REF_SEL] = imx_clk_mux("sys_pll2_ref_sel", base + 0x104, 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, &imx8mn_audio_pll); - clks[IMX8MN_AUDIO_PLL2] = imx_clk_pll14xx("audio_pll2", "audio_pll2_ref_sel", base + 0x14, &imx8mn_audio_pll); - clks[IMX8MN_VIDEO_PLL1] = imx_clk_pll14xx("video_pll1", "video_pll1_ref_sel", base + 0x28, &imx8mn_video_pll); - clks[IMX8MN_DRAM_PLL] = imx_clk_pll14xx("dram_pll", "dram_pll_ref_sel", base + 0x50, &imx8mn_dram_pll); - clks[IMX8MN_GPU_PLL] = imx_clk_pll14xx("gpu_pll", "gpu_pll_ref_sel", base + 0x64, &imx8mn_gpu_pll); - clks[IMX8MN_VPU_PLL] = imx_clk_pll14xx("vpu_pll", "vpu_pll_ref_sel", base + 0x74, &imx8mn_vpu_pll); - clks[IMX8MN_ARM_PLL] = imx_clk_pll14xx("arm_pll", "arm_pll_ref_sel", base + 0x84, &imx8mn_arm_pll); - clks[IMX8MN_SYS_PLL1] = imx_clk_pll14xx("sys_pll1", "sys_pll1_ref_sel", base + 0x94, &imx8mn_sys_pll); - clks[IMX8MN_SYS_PLL2] = imx_clk_pll14xx("sys_pll2", "sys_pll2_ref_sel", base + 0x104, &imx8mn_sys_pll); - clks[IMX8MN_SYS_PLL3] = imx_clk_pll14xx("sys_pll3", "sys_pll3_ref_sel", base + 0x114, &imx8mn_sys_pll); + 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); /* 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); @@ -428,8 +341,6 @@ static int imx8mn_clocks_probe(struct platform_device *pdev) 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_PLL1_BYPASS] = imx_clk_mux_flags("sys_pll1_bypass", base + 0x94, 28, 1, sys_pll1_bypass_sels, ARRAY_SIZE(sys_pll1_bypass_sels), CLK_SET_RATE_PARENT); - clks[IMX8MN_SYS_PLL2_BYPASS] = imx_clk_mux_flags("sys_pll2_bypass", base + 0x104, 28, 1, sys_pll2_bypass_sels, ARRAY_SIZE(sys_pll2_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); /* PLL out gate */ @@ -440,29 +351,48 @@ static int imx8mn_clocks_probe(struct platform_device *pdev) 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_PLL1_OUT] = imx_clk_gate("sys_pll1_out", "sys_pll1_bypass", base + 0x94, 11); - clks[IMX8MN_SYS_PLL2_OUT] = imx_clk_gate("sys_pll2_out", "sys_pll2_bypass", base + 0x104, 11); clks[IMX8MN_SYS_PLL3_OUT] = imx_clk_gate("sys_pll3_out", "sys_pll3_bypass", base + 0x114, 11); - /* SYS PLL fixed output */ - clks[IMX8MN_SYS_PLL1_40M] = imx_clk_fixed_factor("sys_pll1_40m", "sys_pll1_out", 1, 20); - clks[IMX8MN_SYS_PLL1_80M] = imx_clk_fixed_factor("sys_pll1_80m", "sys_pll1_out", 1, 10); - clks[IMX8MN_SYS_PLL1_100M] = imx_clk_fixed_factor("sys_pll1_100m", "sys_pll1_out", 1, 8); - clks[IMX8MN_SYS_PLL1_133M] = imx_clk_fixed_factor("sys_pll1_133m", "sys_pll1_out", 1, 6); - clks[IMX8MN_SYS_PLL1_160M] = imx_clk_fixed_factor("sys_pll1_160m", "sys_pll1_out", 1, 5); - clks[IMX8MN_SYS_PLL1_200M] = imx_clk_fixed_factor("sys_pll1_200m", "sys_pll1_out", 1, 4); - clks[IMX8MN_SYS_PLL1_266M] = imx_clk_fixed_factor("sys_pll1_266m", "sys_pll1_out", 1, 3); - clks[IMX8MN_SYS_PLL1_400M] = imx_clk_fixed_factor("sys_pll1_400m", "sys_pll1_out", 1, 2); + /* 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); - clks[IMX8MN_SYS_PLL2_50M] = imx_clk_fixed_factor("sys_pll2_50m", "sys_pll2_out", 1, 20); - clks[IMX8MN_SYS_PLL2_100M] = imx_clk_fixed_factor("sys_pll2_100m", "sys_pll2_out", 1, 10); - clks[IMX8MN_SYS_PLL2_125M] = imx_clk_fixed_factor("sys_pll2_125m", "sys_pll2_out", 1, 8); - clks[IMX8MN_SYS_PLL2_166M] = imx_clk_fixed_factor("sys_pll2_166m", "sys_pll2_out", 1, 6); - clks[IMX8MN_SYS_PLL2_200M] = imx_clk_fixed_factor("sys_pll2_200m", "sys_pll2_out", 1, 5); - clks[IMX8MN_SYS_PLL2_250M] = imx_clk_fixed_factor("sys_pll2_250m", "sys_pll2_out", 1, 4); - clks[IMX8MN_SYS_PLL2_333M] = imx_clk_fixed_factor("sys_pll2_333m", "sys_pll2_out", 1, 3); - clks[IMX8MN_SYS_PLL2_500M] = imx_clk_fixed_factor("sys_pll2_500m", "sys_pll2_out", 1, 2); + /* 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); np = dev->of_node; diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c index 41fc9c63356e..5f10a606d836 100644 --- a/drivers/clk/imx/clk-imx8mq.c +++ b/drivers/clk/imx/clk-imx8mq.c @@ -34,10 +34,9 @@ static const char * const audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ 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 sys1_pll_out_sels[] = {"sys1_pll1_ref_sel", }; -static const char * const sys2_pll_out_sels[] = {"sys1_pll1_ref_sel", "sys2_pll1_ref_sel", }; -static const char * const sys3_pll_out_sels[] = {"sys3_pll1_ref_sel", "sys2_pll1_ref_sel", }; +static const char * const sys3_pll_out_sels[] = {"sys3_pll1_ref_sel", }; static const char * const dram_pll_out_sels[] = {"dram_pll1_ref_sel", }; +static const char * const video2_pll_out_sels[] = {"video2_pll1_ref_sel", }; /* CCM ROOT */ static const char * const imx8mq_a53_sels[] = {"osc_25m", "arm_pll_out", "sys2_pll_500m", "sys2_pll_1000m", @@ -307,10 +306,9 @@ static int imx8mq_clocks_probe(struct platform_device *pdev) 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_SYS1_PLL1_REF_SEL] = imx_clk_mux("sys1_pll1_ref_sel", base + 0x30, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); - clks[IMX8MQ_SYS2_PLL1_REF_SEL] = imx_clk_mux("sys2_pll1_ref_sel", base + 0x3c, 0, 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); @@ -342,30 +340,53 @@ static int imx8mq_clocks_probe(struct platform_device *pdev) 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_sccg_pll("sys1_pll_out", sys1_pll_out_sels, ARRAY_SIZE(sys1_pll_out_sels), 0, 0, 0, base + 0x30, CLK_IS_CRITICAL); - clks[IMX8MQ_SYS2_PLL_OUT] = imx_clk_sccg_pll("sys2_pll_out", sys2_pll_out_sels, ARRAY_SIZE(sys2_pll_out_sels), 0, 0, 1, base + 0x3c, CLK_IS_CRITICAL); - clks[IMX8MQ_SYS3_PLL_OUT] = imx_clk_sccg_pll("sys3_pll_out", sys3_pll_out_sels, ARRAY_SIZE(sys3_pll_out_sels), 0, 0, 1, base + 0x48, CLK_IS_CRITICAL); + 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); - /* SYS PLL fixed output */ - clks[IMX8MQ_SYS1_PLL_40M] = imx_clk_fixed_factor("sys1_pll_40m", "sys1_pll_out", 1, 20); - clks[IMX8MQ_SYS1_PLL_80M] = imx_clk_fixed_factor("sys1_pll_80m", "sys1_pll_out", 1, 10); - clks[IMX8MQ_SYS1_PLL_100M] = imx_clk_fixed_factor("sys1_pll_100m", "sys1_pll_out", 1, 8); - clks[IMX8MQ_SYS1_PLL_133M] = imx_clk_fixed_factor("sys1_pll_133m", "sys1_pll_out", 1, 6); - clks[IMX8MQ_SYS1_PLL_160M] = imx_clk_fixed_factor("sys1_pll_160m", "sys1_pll_out", 1, 5); - clks[IMX8MQ_SYS1_PLL_200M] = imx_clk_fixed_factor("sys1_pll_200m", "sys1_pll_out", 1, 4); - clks[IMX8MQ_SYS1_PLL_266M] = imx_clk_fixed_factor("sys1_pll_266m", "sys1_pll_out", 1, 3); - clks[IMX8MQ_SYS1_PLL_400M] = imx_clk_fixed_factor("sys1_pll_400m", "sys1_pll_out", 1, 2); - clks[IMX8MQ_SYS1_PLL_800M] = imx_clk_fixed_factor("sys1_pll_800m", "sys1_pll_out", 1, 1); - - clks[IMX8MQ_SYS2_PLL_50M] = imx_clk_fixed_factor("sys2_pll_50m", "sys2_pll_out", 1, 20); - clks[IMX8MQ_SYS2_PLL_100M] = imx_clk_fixed_factor("sys2_pll_100m", "sys2_pll_out", 1, 10); - clks[IMX8MQ_SYS2_PLL_125M] = imx_clk_fixed_factor("sys2_pll_125m", "sys2_pll_out", 1, 8); - clks[IMX8MQ_SYS2_PLL_166M] = imx_clk_fixed_factor("sys2_pll_166m", "sys2_pll_out", 1, 6); - clks[IMX8MQ_SYS2_PLL_200M] = imx_clk_fixed_factor("sys2_pll_200m", "sys2_pll_out", 1, 5); - clks[IMX8MQ_SYS2_PLL_250M] = imx_clk_fixed_factor("sys2_pll_250m", "sys2_pll_out", 1, 4); - clks[IMX8MQ_SYS2_PLL_333M] = imx_clk_fixed_factor("sys2_pll_333m", "sys2_pll_out", 1, 3); - clks[IMX8MQ_SYS2_PLL_500M] = imx_clk_fixed_factor("sys2_pll_500m", "sys2_pll_out", 1, 2); - clks[IMX8MQ_SYS2_PLL_1000M] = imx_clk_fixed_factor("sys2_pll_1000m", "sys2_pll_out", 1, 1); + 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); + + /* 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); + + /* 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); np = dev->of_node; base = devm_platform_ioremap_resource(pdev, 0); diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c index 7a815ec76aa5..5c458199060a 100644 --- a/drivers/clk/imx/clk-pll14xx.c +++ b/drivers/clk/imx/clk-pll14xx.c @@ -41,6 +41,38 @@ struct clk_pll14xx { #define to_clk_pll14xx(_hw) container_of(_hw, struct clk_pll14xx, hw) +static const struct imx_pll14xx_rate_table imx_pll1416x_tbl[] = { + PLL_1416X_RATE(1800000000U, 225, 3, 0), + PLL_1416X_RATE(1600000000U, 200, 3, 0), + PLL_1416X_RATE(1500000000U, 375, 3, 1), + PLL_1416X_RATE(1400000000U, 350, 3, 1), + PLL_1416X_RATE(1200000000U, 300, 3, 1), + PLL_1416X_RATE(1000000000U, 250, 3, 1), + PLL_1416X_RATE(800000000U, 200, 3, 1), + PLL_1416X_RATE(750000000U, 250, 2, 2), + PLL_1416X_RATE(700000000U, 350, 3, 2), + PLL_1416X_RATE(600000000U, 300, 3, 2), +}; + +static const struct imx_pll14xx_rate_table imx_pll1443x_tbl[] = { + PLL_1443X_RATE(650000000U, 325, 3, 2, 0), + PLL_1443X_RATE(594000000U, 198, 2, 2, 0), + PLL_1443X_RATE(393216000U, 262, 2, 3, 9437), + PLL_1443X_RATE(361267200U, 361, 3, 3, 17511), +}; + +struct imx_pll14xx_clk imx_1443x_pll = { + .type = PLL_1443X, + .rate_table = imx_pll1443x_tbl, + .rate_count = ARRAY_SIZE(imx_pll1443x_tbl), +}; + +struct imx_pll14xx_clk imx_1416x_pll = { + .type = PLL_1416X, + .rate_table = imx_pll1416x_tbl, + .rate_count = ARRAY_SIZE(imx_pll1416x_tbl), +}; + static const struct imx_pll14xx_rate_table *imx_get_pll_settings( struct clk_pll14xx *pll, unsigned long rate) { @@ -112,43 +144,17 @@ static unsigned long clk_pll1443x_recalc_rate(struct clk_hw *hw, return fvco; } -static inline bool clk_pll1416x_mp_change(const struct imx_pll14xx_rate_table *rate, +static inline bool clk_pll14xx_mp_change(const struct imx_pll14xx_rate_table *rate, u32 pll_div) { u32 old_mdiv, old_pdiv; - old_mdiv = (pll_div >> MDIV_SHIFT) & MDIV_MASK; - old_pdiv = (pll_div >> PDIV_SHIFT) & PDIV_MASK; + old_mdiv = (pll_div & MDIV_MASK) >> MDIV_SHIFT; + old_pdiv = (pll_div & PDIV_MASK) >> PDIV_SHIFT; return rate->mdiv != old_mdiv || rate->pdiv != old_pdiv; } -static inline bool clk_pll1443x_mpk_change(const struct imx_pll14xx_rate_table *rate, - u32 pll_div_ctl0, u32 pll_div_ctl1) -{ - u32 old_mdiv, old_pdiv, old_kdiv; - - old_mdiv = (pll_div_ctl0 >> MDIV_SHIFT) & MDIV_MASK; - old_pdiv = (pll_div_ctl0 >> PDIV_SHIFT) & PDIV_MASK; - old_kdiv = (pll_div_ctl1 >> KDIV_SHIFT) & KDIV_MASK; - - return rate->mdiv != old_mdiv || rate->pdiv != old_pdiv || - rate->kdiv != old_kdiv; -} - -static inline bool clk_pll1443x_mp_change(const struct imx_pll14xx_rate_table *rate, - u32 pll_div_ctl0, u32 pll_div_ctl1) -{ - u32 old_mdiv, old_pdiv, old_kdiv; - - old_mdiv = (pll_div_ctl0 >> MDIV_SHIFT) & MDIV_MASK; - old_pdiv = (pll_div_ctl0 >> PDIV_SHIFT) & PDIV_MASK; - old_kdiv = (pll_div_ctl1 >> KDIV_SHIFT) & KDIV_MASK; - - return rate->mdiv != old_mdiv || rate->pdiv != old_pdiv || - rate->kdiv != old_kdiv; -} - static int clk_pll14xx_wait_lock(struct clk_pll14xx *pll) { u32 val; @@ -174,7 +180,7 @@ static int clk_pll1416x_set_rate(struct clk_hw *hw, unsigned long drate, tmp = readl_relaxed(pll->base + 4); - if (!clk_pll1416x_mp_change(rate, tmp)) { + if (!clk_pll14xx_mp_change(rate, tmp)) { tmp &= ~(SDIV_MASK) << SDIV_SHIFT; tmp |= rate->sdiv << SDIV_SHIFT; writel_relaxed(tmp, pll->base + 4); @@ -239,13 +245,15 @@ static int clk_pll1443x_set_rate(struct clk_hw *hw, unsigned long drate, } tmp = readl_relaxed(pll->base + 4); - div_val = readl_relaxed(pll->base + 8); - if (!clk_pll1443x_mpk_change(rate, tmp, div_val)) { + if (!clk_pll14xx_mp_change(rate, tmp)) { tmp &= ~(SDIV_MASK) << SDIV_SHIFT; tmp |= rate->sdiv << SDIV_SHIFT; writel_relaxed(tmp, pll->base + 4); + tmp = rate->kdiv << KDIV_SHIFT; + writel_relaxed(tmp, pll->base + 8); + return 0; } diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h index f7a389a50401..bc5bb6ac8636 100644 --- a/drivers/clk/imx/clk.h +++ b/drivers/clk/imx/clk.h @@ -50,6 +50,9 @@ struct imx_pll14xx_clk { int flags; }; +extern struct imx_pll14xx_clk imx_1416x_pll; +extern struct imx_pll14xx_clk imx_1443x_pll; + #define imx_clk_cpu(name, parent_name, div, mux, pll, step) \ imx_clk_hw_cpu(name, parent_name, div, mux, pll, step)->clk diff --git a/drivers/clk/ingenic/Kconfig b/drivers/clk/ingenic/Kconfig index 1cb489959a99..b4555b465ea6 100644 --- a/drivers/clk/ingenic/Kconfig +++ b/drivers/clk/ingenic/Kconfig @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only menu "Ingenic SoCs drivers" - depends on MIPS + depends on MIPS || COMPILE_TEST config INGENIC_CGU_COMMON bool @@ -45,6 +45,16 @@ config INGENIC_CGU_JZ4780 If building for a JZ4780 SoC, you want to say Y here. +config INGENIC_CGU_X1000 + bool "Ingenic X1000 CGU driver" + default MACH_X1000 + select INGENIC_CGU_COMMON + help + Support the clocks provided by the CGU hardware on Ingenic X1000 + and compatible SoCs. + + If building for a X1000 SoC, you want to say Y here. + config INGENIC_TCU_CLK bool "Ingenic JZ47xx TCU clocks driver" default MACH_INGENIC diff --git a/drivers/clk/ingenic/Makefile b/drivers/clk/ingenic/Makefile index 097220b05131..8b1dad9b74a7 100644 --- a/drivers/clk/ingenic/Makefile +++ b/drivers/clk/ingenic/Makefile @@ -4,4 +4,5 @@ obj-$(CONFIG_INGENIC_CGU_JZ4740) += jz4740-cgu.o obj-$(CONFIG_INGENIC_CGU_JZ4725B) += jz4725b-cgu.o obj-$(CONFIG_INGENIC_CGU_JZ4770) += jz4770-cgu.o obj-$(CONFIG_INGENIC_CGU_JZ4780) += jz4780-cgu.o +obj-$(CONFIG_INGENIC_CGU_X1000) += x1000-cgu.o obj-$(CONFIG_INGENIC_TCU_CLK) += tcu.o diff --git a/drivers/clk/ingenic/tcu.c b/drivers/clk/ingenic/tcu.c index a1a5f9cb439e..ad7daa494fd4 100644 --- a/drivers/clk/ingenic/tcu.c +++ b/drivers/clk/ingenic/tcu.c @@ -358,8 +358,7 @@ static int __init ingenic_tcu_probe(struct device_node *np) } } - tcu->clocks = kzalloc(sizeof(*tcu->clocks) + - sizeof(*tcu->clocks->hws) * TCU_CLK_COUNT, + tcu->clocks = kzalloc(struct_size(tcu->clocks, hws, TCU_CLK_COUNT), GFP_KERNEL); if (!tcu->clocks) { ret = -ENOMEM; diff --git a/drivers/clk/ingenic/x1000-cgu.c b/drivers/clk/ingenic/x1000-cgu.c new file mode 100644 index 000000000000..b22d87b3f555 --- /dev/null +++ b/drivers/clk/ingenic/x1000-cgu.c @@ -0,0 +1,274 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * X1000 SoC CGU driver + * Copyright (c) 2019 Zhou Yanjie <zhouyanjie@zoho.com> + */ + +#include <linux/clk-provider.h> +#include <linux/delay.h> +#include <linux/of.h> +#include <dt-bindings/clock/x1000-cgu.h> +#include "cgu.h" +#include "pm.h" + +/* CGU register offsets */ +#define CGU_REG_CPCCR 0x00 +#define CGU_REG_APLL 0x10 +#define CGU_REG_MPLL 0x14 +#define CGU_REG_CLKGR 0x20 +#define CGU_REG_OPCR 0x24 +#define CGU_REG_DDRCDR 0x2c +#define CGU_REG_MACCDR 0x54 +#define CGU_REG_I2SCDR 0x60 +#define CGU_REG_LPCDR 0x64 +#define CGU_REG_MSC0CDR 0x68 +#define CGU_REG_I2SCDR1 0x70 +#define CGU_REG_SSICDR 0x74 +#define CGU_REG_CIMCDR 0x7c +#define CGU_REG_PCMCDR 0x84 +#define CGU_REG_MSC1CDR 0xa4 +#define CGU_REG_CMP_INTR 0xb0 +#define CGU_REG_CMP_INTRE 0xb4 +#define CGU_REG_DRCG 0xd0 +#define CGU_REG_CPCSR 0xd4 +#define CGU_REG_PCMCDR1 0xe0 +#define CGU_REG_MACPHYC 0xe8 + +/* bits within the OPCR register */ +#define OPCR_SPENDN0 BIT(7) +#define OPCR_SPENDN1 BIT(6) + +static struct ingenic_cgu *cgu; + +static const s8 pll_od_encoding[8] = { + 0x0, 0x1, -1, 0x2, -1, -1, -1, 0x3, +}; + +static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = { + + /* External clocks */ + + [X1000_CLK_EXCLK] = { "ext", CGU_CLK_EXT }, + [X1000_CLK_RTCLK] = { "rtc", CGU_CLK_EXT }, + + /* PLLs */ + + [X1000_CLK_APLL] = { + "apll", CGU_CLK_PLL, + .parents = { X1000_CLK_EXCLK, -1, -1, -1 }, + .pll = { + .reg = CGU_REG_APLL, + .m_shift = 24, + .m_bits = 7, + .m_offset = 1, + .n_shift = 18, + .n_bits = 5, + .n_offset = 1, + .od_shift = 16, + .od_bits = 2, + .od_max = 8, + .od_encoding = pll_od_encoding, + .bypass_bit = 9, + .enable_bit = 8, + .stable_bit = 10, + }, + }, + + [X1000_CLK_MPLL] = { + "mpll", CGU_CLK_PLL, + .parents = { X1000_CLK_EXCLK, -1, -1, -1 }, + .pll = { + .reg = CGU_REG_MPLL, + .m_shift = 24, + .m_bits = 7, + .m_offset = 1, + .n_shift = 18, + .n_bits = 5, + .n_offset = 1, + .od_shift = 16, + .od_bits = 2, + .od_max = 8, + .od_encoding = pll_od_encoding, + .bypass_bit = 6, + .enable_bit = 7, + .stable_bit = 0, + }, + }, + + /* Muxes & dividers */ + + [X1000_CLK_SCLKA] = { + "sclk_a", CGU_CLK_MUX, + .parents = { -1, X1000_CLK_EXCLK, X1000_CLK_APLL, -1 }, + .mux = { CGU_REG_CPCCR, 30, 2 }, + }, + + [X1000_CLK_CPUMUX] = { + "cpu_mux", CGU_CLK_MUX, + .parents = { -1, X1000_CLK_SCLKA, X1000_CLK_MPLL, -1 }, + .mux = { CGU_REG_CPCCR, 28, 2 }, + }, + + [X1000_CLK_CPU] = { + "cpu", CGU_CLK_DIV, + .parents = { X1000_CLK_CPUMUX, -1, -1, -1 }, + .div = { CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1 }, + }, + + [X1000_CLK_L2CACHE] = { + "l2cache", CGU_CLK_DIV, + .parents = { X1000_CLK_CPUMUX, -1, -1, -1 }, + .div = { CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1 }, + }, + + [X1000_CLK_AHB0] = { + "ahb0", CGU_CLK_MUX | CGU_CLK_DIV, + .parents = { -1, X1000_CLK_SCLKA, X1000_CLK_MPLL, -1 }, + .mux = { CGU_REG_CPCCR, 26, 2 }, + .div = { CGU_REG_CPCCR, 8, 1, 4, 21, -1, -1 }, + }, + + [X1000_CLK_AHB2PMUX] = { + "ahb2_apb_mux", CGU_CLK_MUX, + .parents = { -1, X1000_CLK_SCLKA, X1000_CLK_MPLL, -1 }, + .mux = { CGU_REG_CPCCR, 24, 2 }, + }, + + [X1000_CLK_AHB2] = { + "ahb2", CGU_CLK_DIV, + .parents = { X1000_CLK_AHB2PMUX, -1, -1, -1 }, + .div = { CGU_REG_CPCCR, 12, 1, 4, 20, -1, -1 }, + }, + + [X1000_CLK_PCLK] = { + "pclk", CGU_CLK_DIV, + .parents = { X1000_CLK_AHB2PMUX, -1, -1, -1 }, + .div = { CGU_REG_CPCCR, 16, 1, 4, 20, -1, -1 }, + }, + + [X1000_CLK_DDR] = { + "ddr", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE, + .parents = { -1, X1000_CLK_SCLKA, X1000_CLK_MPLL, -1 }, + .mux = { CGU_REG_DDRCDR, 30, 2 }, + .div = { CGU_REG_DDRCDR, 0, 1, 4, 29, 28, 27 }, + .gate = { CGU_REG_CLKGR, 31 }, + }, + + [X1000_CLK_MAC] = { + "mac", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE, + .parents = { X1000_CLK_SCLKA, X1000_CLK_MPLL}, + .mux = { CGU_REG_MACCDR, 31, 1 }, + .div = { CGU_REG_MACCDR, 0, 1, 8, 29, 28, 27 }, + .gate = { CGU_REG_CLKGR, 25 }, + }, + + [X1000_CLK_MSCMUX] = { + "msc_mux", CGU_CLK_MUX, + .parents = { X1000_CLK_SCLKA, X1000_CLK_MPLL}, + .mux = { CGU_REG_MSC0CDR, 31, 1 }, + }, + + [X1000_CLK_MSC0] = { + "msc0", CGU_CLK_DIV | CGU_CLK_GATE, + .parents = { X1000_CLK_MSCMUX, -1, -1, -1 }, + .div = { CGU_REG_MSC0CDR, 0, 2, 8, 29, 28, 27 }, + .gate = { CGU_REG_CLKGR, 4 }, + }, + + [X1000_CLK_MSC1] = { + "msc1", CGU_CLK_DIV | CGU_CLK_GATE, + .parents = { X1000_CLK_MSCMUX, -1, -1, -1 }, + .div = { CGU_REG_MSC1CDR, 0, 2, 8, 29, 28, 27 }, + .gate = { CGU_REG_CLKGR, 5 }, + }, + + [X1000_CLK_SSIPLL] = { + "ssi_pll", CGU_CLK_MUX | CGU_CLK_DIV, + .parents = { X1000_CLK_SCLKA, X1000_CLK_MPLL, -1, -1 }, + .mux = { CGU_REG_SSICDR, 31, 1 }, + .div = { CGU_REG_SSICDR, 0, 1, 8, 29, 28, 27 }, + }, + + [X1000_CLK_SSIMUX] = { + "ssi_mux", CGU_CLK_MUX, + .parents = { X1000_CLK_EXCLK, X1000_CLK_SSIPLL, -1, -1 }, + .mux = { CGU_REG_SSICDR, 30, 1 }, + }, + + /* Gate-only clocks */ + + [X1000_CLK_SFC] = { + "sfc", CGU_CLK_GATE, + .parents = { X1000_CLK_SSIPLL, -1, -1, -1 }, + .gate = { CGU_REG_CLKGR, 2 }, + }, + + [X1000_CLK_I2C0] = { + "i2c0", CGU_CLK_GATE, + .parents = { X1000_CLK_PCLK, -1, -1, -1 }, + .gate = { CGU_REG_CLKGR, 7 }, + }, + + [X1000_CLK_I2C1] = { + "i2c1", CGU_CLK_GATE, + .parents = { X1000_CLK_PCLK, -1, -1, -1 }, + .gate = { CGU_REG_CLKGR, 8 }, + }, + + [X1000_CLK_I2C2] = { + "i2c2", CGU_CLK_GATE, + .parents = { X1000_CLK_PCLK, -1, -1, -1 }, + .gate = { CGU_REG_CLKGR, 9 }, + }, + + [X1000_CLK_UART0] = { + "uart0", CGU_CLK_GATE, + .parents = { X1000_CLK_EXCLK, -1, -1, -1 }, + .gate = { CGU_REG_CLKGR, 14 }, + }, + + [X1000_CLK_UART1] = { + "uart1", CGU_CLK_GATE, + .parents = { X1000_CLK_EXCLK, -1, -1, -1 }, + .gate = { CGU_REG_CLKGR, 15 }, + }, + + [X1000_CLK_UART2] = { + "uart2", CGU_CLK_GATE, + .parents = { X1000_CLK_EXCLK, -1, -1, -1 }, + .gate = { CGU_REG_CLKGR, 16 }, + }, + + [X1000_CLK_SSI] = { + "ssi", CGU_CLK_GATE, + .parents = { X1000_CLK_SSIMUX, -1, -1, -1 }, + .gate = { CGU_REG_CLKGR, 19 }, + }, + + [X1000_CLK_PDMA] = { + "pdma", CGU_CLK_GATE, + .parents = { X1000_CLK_EXCLK, -1, -1, -1 }, + .gate = { CGU_REG_CLKGR, 21 }, + }, +}; + +static void __init x1000_cgu_init(struct device_node *np) +{ + int retval; + + cgu = ingenic_cgu_new(x1000_cgu_clocks, + ARRAY_SIZE(x1000_cgu_clocks), np); + if (!cgu) { + pr_err("%s: failed to initialise CGU\n", __func__); + return; + } + + retval = ingenic_cgu_register_clocks(cgu); + if (retval) { + pr_err("%s: failed to register CGU Clocks\n", __func__); + return; + } + + ingenic_cgu_register_syscore_ops(cgu); +} +CLK_OF_DECLARE(x1000_cgu, "ingenic,x1000-cgu", x1000_cgu_init); diff --git a/drivers/clk/mediatek/clk-mt2712.c b/drivers/clk/mediatek/clk-mt2712.c index 354c26f663b4..a3bd9a107209 100644 --- a/drivers/clk/mediatek/clk-mt2712.c +++ b/drivers/clk/mediatek/clk-mt2712.c @@ -1306,9 +1306,8 @@ static int clk_mt2712_top_probe(struct platform_device *pdev) int r, i; struct device_node *node = pdev->dev.of_node; void __iomem *base; - struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(&pdev->dev, res); + base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) { pr_err("%s(): ioremap failed\n", __func__); return PTR_ERR(base); @@ -1394,9 +1393,8 @@ static int clk_mt2712_mcu_probe(struct platform_device *pdev) int r; struct device_node *node = pdev->dev.of_node; void __iomem *base; - struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(&pdev->dev, res); + base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) { pr_err("%s(): ioremap failed\n", __func__); return PTR_ERR(base); diff --git a/drivers/clk/mediatek/clk-mt6779.c b/drivers/clk/mediatek/clk-mt6779.c index 608a9a6621a3..9766cccf5844 100644 --- a/drivers/clk/mediatek/clk-mt6779.c +++ b/drivers/clk/mediatek/clk-mt6779.c @@ -1225,12 +1225,11 @@ static int clk_mt6779_apmixed_probe(struct platform_device *pdev) static int clk_mt6779_top_probe(struct platform_device *pdev) { - struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); void __iomem *base; struct clk_onecell_data *clk_data; struct device_node *node = pdev->dev.of_node; - base = devm_ioremap_resource(&pdev->dev, res); + base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) return PTR_ERR(base); diff --git a/drivers/clk/mediatek/clk-mt6797.c b/drivers/clk/mediatek/clk-mt6797.c index f62b0428da0e..f35389a11af1 100644 --- a/drivers/clk/mediatek/clk-mt6797.c +++ b/drivers/clk/mediatek/clk-mt6797.c @@ -385,9 +385,8 @@ static int mtk_topckgen_init(struct platform_device *pdev) struct clk_onecell_data *clk_data; void __iomem *base; struct device_node *node = pdev->dev.of_node; - struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(&pdev->dev, res); + base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) return PTR_ERR(base); diff --git a/drivers/clk/mediatek/clk-mt7622.c b/drivers/clk/mediatek/clk-mt7622.c index 8190dab179d7..ef5947e15c75 100644 --- a/drivers/clk/mediatek/clk-mt7622.c +++ b/drivers/clk/mediatek/clk-mt7622.c @@ -614,9 +614,8 @@ static int mtk_topckgen_init(struct platform_device *pdev) struct clk_onecell_data *clk_data; void __iomem *base; struct device_node *node = pdev->dev.of_node; - struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(&pdev->dev, res); + base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) return PTR_ERR(base); @@ -695,9 +694,8 @@ static int mtk_pericfg_init(struct platform_device *pdev) void __iomem *base; int r; struct device_node *node = pdev->dev.of_node; - struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(&pdev->dev, res); + base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) return PTR_ERR(base); diff --git a/drivers/clk/mediatek/clk-mt7629.c b/drivers/clk/mediatek/clk-mt7629.c index d6233994af5a..b73bdf152836 100644 --- a/drivers/clk/mediatek/clk-mt7629.c +++ b/drivers/clk/mediatek/clk-mt7629.c @@ -574,9 +574,8 @@ static int mtk_topckgen_init(struct platform_device *pdev) struct clk_onecell_data *clk_data; void __iomem *base; struct device_node *node = pdev->dev.of_node; - struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(&pdev->dev, res); + base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) return PTR_ERR(base); @@ -626,9 +625,8 @@ static int mtk_pericfg_init(struct platform_device *pdev) void __iomem *base; int r; struct device_node *node = pdev->dev.of_node; - struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(&pdev->dev, res); + base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) return PTR_ERR(base); diff --git a/drivers/clk/mediatek/clk-mt8183.c b/drivers/clk/mediatek/clk-mt8183.c index 51c8d5c9a030..5046852eb0fd 100644 --- a/drivers/clk/mediatek/clk-mt8183.c +++ b/drivers/clk/mediatek/clk-mt8183.c @@ -1189,11 +1189,10 @@ CLK_OF_DECLARE_DRIVER(mt8183_topckgen, "mediatek,mt8183-topckgen", static int clk_mt8183_top_probe(struct platform_device *pdev) { - struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); void __iomem *base; struct device_node *node = pdev->dev.of_node; - base = devm_ioremap_resource(&pdev->dev, res); + base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) return PTR_ERR(base); @@ -1262,9 +1261,8 @@ static int clk_mt8183_mcu_probe(struct platform_device *pdev) struct clk_onecell_data *clk_data; struct device_node *node = pdev->dev.of_node; void __iomem *base; - struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(&pdev->dev, res); + base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) return PTR_ERR(base); diff --git a/drivers/clk/meson/axg-audio.c b/drivers/clk/meson/axg-audio.c index 18b23cdf679c..53715e36326c 100644 --- a/drivers/clk/meson/axg-audio.c +++ b/drivers/clk/meson/axg-audio.c @@ -20,12 +20,7 @@ #include "clk-phase.h" #include "sclk-div.h" -#define AUD_MST_IN_COUNT 8 -#define AUD_SLV_SCLK_COUNT 10 -#define AUD_SLV_LRCLK_COUNT 10 - -#define AUD_GATE(_name, _reg, _bit, _phws, _iflags) \ -struct clk_regmap aud_##_name = { \ +#define AUD_GATE(_name, _reg, _bit, _pname, _iflags) { \ .data = &(struct clk_regmap_gate_data){ \ .offset = (_reg), \ .bit_idx = (_bit), \ @@ -33,14 +28,13 @@ struct clk_regmap aud_##_name = { \ .hw.init = &(struct clk_init_data) { \ .name = "aud_"#_name, \ .ops = &clk_regmap_gate_ops, \ - .parent_hws = (const struct clk_hw *[]) { &_phws.hw }, \ + .parent_names = (const char *[]){ #_pname }, \ .num_parents = 1, \ .flags = CLK_DUTY_CYCLE_PARENT | (_iflags), \ }, \ } -#define AUD_MUX(_name, _reg, _mask, _shift, _dflags, _pdata, _iflags) \ -struct clk_regmap aud_##_name = { \ +#define AUD_MUX(_name, _reg, _mask, _shift, _dflags, _pdata, _iflags) { \ .data = &(struct clk_regmap_mux_data){ \ .offset = (_reg), \ .mask = (_mask), \ @@ -56,8 +50,7 @@ struct clk_regmap aud_##_name = { \ }, \ } -#define AUD_DIV(_name, _reg, _shift, _width, _dflags, _phws, _iflags) \ -struct clk_regmap aud_##_name = { \ +#define AUD_DIV(_name, _reg, _shift, _width, _dflags, _pname, _iflags) { \ .data = &(struct clk_regmap_div_data){ \ .offset = (_reg), \ .shift = (_shift), \ @@ -67,137 +60,27 @@ struct clk_regmap aud_##_name = { \ .hw.init = &(struct clk_init_data){ \ .name = "aud_"#_name, \ .ops = &clk_regmap_divider_ops, \ - .parent_hws = (const struct clk_hw *[]) { &_phws.hw }, \ + .parent_names = (const char *[]){ #_pname }, \ .num_parents = 1, \ .flags = (_iflags), \ }, \ } -#define AUD_PCLK_GATE(_name, _bit) \ -struct clk_regmap aud_##_name = { \ +#define AUD_PCLK_GATE(_name, _reg, _bit) { \ .data = &(struct clk_regmap_gate_data){ \ - .offset = (AUDIO_CLK_GATE_EN), \ + .offset = (_reg), \ .bit_idx = (_bit), \ }, \ .hw.init = &(struct clk_init_data) { \ .name = "aud_"#_name, \ .ops = &clk_regmap_gate_ops, \ - .parent_data = &(const struct clk_parent_data) { \ - .fw_name = "pclk", \ - }, \ + .parent_names = (const char *[]){ "aud_top" }, \ .num_parents = 1, \ }, \ } -/* Audio peripheral clocks */ -static AUD_PCLK_GATE(ddr_arb, 0); -static AUD_PCLK_GATE(pdm, 1); -static AUD_PCLK_GATE(tdmin_a, 2); -static AUD_PCLK_GATE(tdmin_b, 3); -static AUD_PCLK_GATE(tdmin_c, 4); -static AUD_PCLK_GATE(tdmin_lb, 5); -static AUD_PCLK_GATE(tdmout_a, 6); -static AUD_PCLK_GATE(tdmout_b, 7); -static AUD_PCLK_GATE(tdmout_c, 8); -static AUD_PCLK_GATE(frddr_a, 9); -static AUD_PCLK_GATE(frddr_b, 10); -static AUD_PCLK_GATE(frddr_c, 11); -static AUD_PCLK_GATE(toddr_a, 12); -static AUD_PCLK_GATE(toddr_b, 13); -static AUD_PCLK_GATE(toddr_c, 14); -static AUD_PCLK_GATE(loopback, 15); -static AUD_PCLK_GATE(spdifin, 16); -static AUD_PCLK_GATE(spdifout, 17); -static AUD_PCLK_GATE(resample, 18); -static AUD_PCLK_GATE(power_detect, 19); -static AUD_PCLK_GATE(spdifout_b, 21); - -/* Audio Master Clocks */ -static const struct clk_parent_data mst_mux_parent_data[] = { - { .fw_name = "mst_in0", }, - { .fw_name = "mst_in1", }, - { .fw_name = "mst_in2", }, - { .fw_name = "mst_in3", }, - { .fw_name = "mst_in4", }, - { .fw_name = "mst_in5", }, - { .fw_name = "mst_in6", }, - { .fw_name = "mst_in7", }, -}; - -#define AUD_MST_MUX(_name, _reg, _flag) \ - AUD_MUX(_name##_sel, _reg, 0x7, 24, _flag, \ - mst_mux_parent_data, 0) - -#define AUD_MST_MCLK_MUX(_name, _reg) \ - AUD_MST_MUX(_name, _reg, CLK_MUX_ROUND_CLOSEST) - -#define AUD_MST_SYS_MUX(_name, _reg) \ - AUD_MST_MUX(_name, _reg, 0) - -static AUD_MST_MCLK_MUX(mst_a_mclk, AUDIO_MCLK_A_CTRL); -static AUD_MST_MCLK_MUX(mst_b_mclk, AUDIO_MCLK_B_CTRL); -static AUD_MST_MCLK_MUX(mst_c_mclk, AUDIO_MCLK_C_CTRL); -static AUD_MST_MCLK_MUX(mst_d_mclk, AUDIO_MCLK_D_CTRL); -static AUD_MST_MCLK_MUX(mst_e_mclk, AUDIO_MCLK_E_CTRL); -static AUD_MST_MCLK_MUX(mst_f_mclk, AUDIO_MCLK_F_CTRL); -static AUD_MST_MCLK_MUX(spdifout_clk, AUDIO_CLK_SPDIFOUT_CTRL); -static AUD_MST_MCLK_MUX(pdm_dclk, AUDIO_CLK_PDMIN_CTRL0); -static AUD_MST_SYS_MUX(spdifin_clk, AUDIO_CLK_SPDIFIN_CTRL); -static AUD_MST_SYS_MUX(pdm_sysclk, AUDIO_CLK_PDMIN_CTRL1); -static AUD_MST_MCLK_MUX(spdifout_b_clk, AUDIO_CLK_SPDIFOUT_B_CTRL); - -#define AUD_MST_DIV(_name, _reg, _flag) \ - AUD_DIV(_name##_div, _reg, 0, 16, _flag, \ - aud_##_name##_sel, CLK_SET_RATE_PARENT) \ - -#define AUD_MST_MCLK_DIV(_name, _reg) \ - AUD_MST_DIV(_name, _reg, CLK_DIVIDER_ROUND_CLOSEST) - -#define AUD_MST_SYS_DIV(_name, _reg) \ - AUD_MST_DIV(_name, _reg, 0) - -static AUD_MST_MCLK_DIV(mst_a_mclk, AUDIO_MCLK_A_CTRL); -static AUD_MST_MCLK_DIV(mst_b_mclk, AUDIO_MCLK_B_CTRL); -static AUD_MST_MCLK_DIV(mst_c_mclk, AUDIO_MCLK_C_CTRL); -static AUD_MST_MCLK_DIV(mst_d_mclk, AUDIO_MCLK_D_CTRL); -static AUD_MST_MCLK_DIV(mst_e_mclk, AUDIO_MCLK_E_CTRL); -static AUD_MST_MCLK_DIV(mst_f_mclk, AUDIO_MCLK_F_CTRL); -static AUD_MST_MCLK_DIV(spdifout_clk, AUDIO_CLK_SPDIFOUT_CTRL); -static AUD_MST_MCLK_DIV(pdm_dclk, AUDIO_CLK_PDMIN_CTRL0); -static AUD_MST_SYS_DIV(spdifin_clk, AUDIO_CLK_SPDIFIN_CTRL); -static AUD_MST_SYS_DIV(pdm_sysclk, AUDIO_CLK_PDMIN_CTRL1); -static AUD_MST_MCLK_DIV(spdifout_b_clk, AUDIO_CLK_SPDIFOUT_B_CTRL); - -#define AUD_MST_MCLK_GATE(_name, _reg) \ - AUD_GATE(_name, _reg, 31, aud_##_name##_div, \ - CLK_SET_RATE_PARENT) - -static AUD_MST_MCLK_GATE(mst_a_mclk, AUDIO_MCLK_A_CTRL); -static AUD_MST_MCLK_GATE(mst_b_mclk, AUDIO_MCLK_B_CTRL); -static AUD_MST_MCLK_GATE(mst_c_mclk, AUDIO_MCLK_C_CTRL); -static AUD_MST_MCLK_GATE(mst_d_mclk, AUDIO_MCLK_D_CTRL); -static AUD_MST_MCLK_GATE(mst_e_mclk, AUDIO_MCLK_E_CTRL); -static AUD_MST_MCLK_GATE(mst_f_mclk, AUDIO_MCLK_F_CTRL); -static AUD_MST_MCLK_GATE(spdifout_clk, AUDIO_CLK_SPDIFOUT_CTRL); -static AUD_MST_MCLK_GATE(spdifin_clk, AUDIO_CLK_SPDIFIN_CTRL); -static AUD_MST_MCLK_GATE(pdm_dclk, AUDIO_CLK_PDMIN_CTRL0); -static AUD_MST_MCLK_GATE(pdm_sysclk, AUDIO_CLK_PDMIN_CTRL1); -static AUD_MST_MCLK_GATE(spdifout_b_clk, AUDIO_CLK_SPDIFOUT_B_CTRL); - -/* Sample Clocks */ -#define AUD_MST_SCLK_PRE_EN(_name, _reg) \ - AUD_GATE(mst_##_name##_sclk_pre_en, _reg, 31, \ - aud_mst_##_name##_mclk, 0) - -static AUD_MST_SCLK_PRE_EN(a, AUDIO_MST_A_SCLK_CTRL0); -static AUD_MST_SCLK_PRE_EN(b, AUDIO_MST_B_SCLK_CTRL0); -static AUD_MST_SCLK_PRE_EN(c, AUDIO_MST_C_SCLK_CTRL0); -static AUD_MST_SCLK_PRE_EN(d, AUDIO_MST_D_SCLK_CTRL0); -static AUD_MST_SCLK_PRE_EN(e, AUDIO_MST_E_SCLK_CTRL0); -static AUD_MST_SCLK_PRE_EN(f, AUDIO_MST_F_SCLK_CTRL0); #define AUD_SCLK_DIV(_name, _reg, _div_shift, _div_width, \ - _hi_shift, _hi_width, _phws, _iflags) \ -struct clk_regmap aud_##_name = { \ + _hi_shift, _hi_width, _pname, _iflags) { \ .data = &(struct meson_sclk_div_data) { \ .div = { \ .reg_off = (_reg), \ @@ -213,38 +96,14 @@ struct clk_regmap aud_##_name = { \ .hw.init = &(struct clk_init_data) { \ .name = "aud_"#_name, \ .ops = &meson_sclk_div_ops, \ - .parent_hws = (const struct clk_hw *[]) { &_phws.hw }, \ + .parent_names = (const char *[]){ #_pname }, \ .num_parents = 1, \ .flags = (_iflags), \ }, \ } -#define AUD_MST_SCLK_DIV(_name, _reg) \ - AUD_SCLK_DIV(mst_##_name##_sclk_div, _reg, 20, 10, 0, 0, \ - aud_mst_##_name##_sclk_pre_en, \ - CLK_SET_RATE_PARENT) - -static AUD_MST_SCLK_DIV(a, AUDIO_MST_A_SCLK_CTRL0); -static AUD_MST_SCLK_DIV(b, AUDIO_MST_B_SCLK_CTRL0); -static AUD_MST_SCLK_DIV(c, AUDIO_MST_C_SCLK_CTRL0); -static AUD_MST_SCLK_DIV(d, AUDIO_MST_D_SCLK_CTRL0); -static AUD_MST_SCLK_DIV(e, AUDIO_MST_E_SCLK_CTRL0); -static AUD_MST_SCLK_DIV(f, AUDIO_MST_F_SCLK_CTRL0); - -#define AUD_MST_SCLK_POST_EN(_name, _reg) \ - AUD_GATE(mst_##_name##_sclk_post_en, _reg, 30, \ - aud_mst_##_name##_sclk_div, CLK_SET_RATE_PARENT) - -static AUD_MST_SCLK_POST_EN(a, AUDIO_MST_A_SCLK_CTRL0); -static AUD_MST_SCLK_POST_EN(b, AUDIO_MST_B_SCLK_CTRL0); -static AUD_MST_SCLK_POST_EN(c, AUDIO_MST_C_SCLK_CTRL0); -static AUD_MST_SCLK_POST_EN(d, AUDIO_MST_D_SCLK_CTRL0); -static AUD_MST_SCLK_POST_EN(e, AUDIO_MST_E_SCLK_CTRL0); -static AUD_MST_SCLK_POST_EN(f, AUDIO_MST_F_SCLK_CTRL0); - #define AUD_TRIPHASE(_name, _reg, _width, _shift0, _shift1, _shift2, \ - _phws, _iflags) \ -struct clk_regmap aud_##_name = { \ + _pname, _iflags) { \ .data = &(struct meson_clk_triphase_data) { \ .ph0 = { \ .reg_off = (_reg), \ @@ -265,52 +124,91 @@ struct clk_regmap aud_##_name = { \ .hw.init = &(struct clk_init_data) { \ .name = "aud_"#_name, \ .ops = &meson_clk_triphase_ops, \ - .parent_hws = (const struct clk_hw *[]) { &_phws.hw }, \ + .parent_names = (const char *[]){ #_pname }, \ .num_parents = 1, \ .flags = CLK_DUTY_CYCLE_PARENT | (_iflags), \ }, \ } +#define AUD_PHASE(_name, _reg, _width, _shift, _pname, _iflags) { \ + .data = &(struct meson_clk_phase_data) { \ + .ph = { \ + .reg_off = (_reg), \ + .shift = (_shift), \ + .width = (_width), \ + }, \ + }, \ + .hw.init = &(struct clk_init_data) { \ + .name = "aud_"#_name, \ + .ops = &meson_clk_phase_ops, \ + .parent_names = (const char *[]){ #_pname }, \ + .num_parents = 1, \ + .flags = (_iflags), \ + }, \ +} + +/* Audio Master Clocks */ +static const struct clk_parent_data mst_mux_parent_data[] = { + { .fw_name = "mst_in0", }, + { .fw_name = "mst_in1", }, + { .fw_name = "mst_in2", }, + { .fw_name = "mst_in3", }, + { .fw_name = "mst_in4", }, + { .fw_name = "mst_in5", }, + { .fw_name = "mst_in6", }, + { .fw_name = "mst_in7", }, +}; + +#define AUD_MST_MUX(_name, _reg, _flag) \ + AUD_MUX(_name##_sel, _reg, 0x7, 24, _flag, \ + mst_mux_parent_data, 0) +#define AUD_MST_DIV(_name, _reg, _flag) \ + AUD_DIV(_name##_div, _reg, 0, 16, _flag, \ + aud_##_name##_sel, CLK_SET_RATE_PARENT) +#define AUD_MST_MCLK_GATE(_name, _reg) \ + AUD_GATE(_name, _reg, 31, aud_##_name##_div, \ + CLK_SET_RATE_PARENT) + +#define AUD_MST_MCLK_MUX(_name, _reg) \ + AUD_MST_MUX(_name, _reg, CLK_MUX_ROUND_CLOSEST) +#define AUD_MST_MCLK_DIV(_name, _reg) \ + AUD_MST_DIV(_name, _reg, CLK_DIVIDER_ROUND_CLOSEST) + +#define AUD_MST_SYS_MUX(_name, _reg) \ + AUD_MST_MUX(_name, _reg, 0) +#define AUD_MST_SYS_DIV(_name, _reg) \ + AUD_MST_DIV(_name, _reg, 0) + +/* Sample Clocks */ +#define AUD_MST_SCLK_PRE_EN(_name, _reg) \ + AUD_GATE(mst_##_name##_sclk_pre_en, _reg, 31, \ + aud_mst_##_name##_mclk, 0) +#define AUD_MST_SCLK_DIV(_name, _reg) \ + AUD_SCLK_DIV(mst_##_name##_sclk_div, _reg, 20, 10, 0, 0, \ + aud_mst_##_name##_sclk_pre_en, \ + CLK_SET_RATE_PARENT) +#define AUD_MST_SCLK_POST_EN(_name, _reg) \ + AUD_GATE(mst_##_name##_sclk_post_en, _reg, 30, \ + aud_mst_##_name##_sclk_div, CLK_SET_RATE_PARENT) #define AUD_MST_SCLK(_name, _reg) \ AUD_TRIPHASE(mst_##_name##_sclk, _reg, 1, 0, 2, 4, \ aud_mst_##_name##_sclk_post_en, CLK_SET_RATE_PARENT) -static AUD_MST_SCLK(a, AUDIO_MST_A_SCLK_CTRL1); -static AUD_MST_SCLK(b, AUDIO_MST_B_SCLK_CTRL1); -static AUD_MST_SCLK(c, AUDIO_MST_C_SCLK_CTRL1); -static AUD_MST_SCLK(d, AUDIO_MST_D_SCLK_CTRL1); -static AUD_MST_SCLK(e, AUDIO_MST_E_SCLK_CTRL1); -static AUD_MST_SCLK(f, AUDIO_MST_F_SCLK_CTRL1); - #define AUD_MST_LRCLK_DIV(_name, _reg) \ AUD_SCLK_DIV(mst_##_name##_lrclk_div, _reg, 0, 10, 10, 10, \ - aud_mst_##_name##_sclk_post_en, 0) \ - -static AUD_MST_LRCLK_DIV(a, AUDIO_MST_A_SCLK_CTRL0); -static AUD_MST_LRCLK_DIV(b, AUDIO_MST_B_SCLK_CTRL0); -static AUD_MST_LRCLK_DIV(c, AUDIO_MST_C_SCLK_CTRL0); -static AUD_MST_LRCLK_DIV(d, AUDIO_MST_D_SCLK_CTRL0); -static AUD_MST_LRCLK_DIV(e, AUDIO_MST_E_SCLK_CTRL0); -static AUD_MST_LRCLK_DIV(f, AUDIO_MST_F_SCLK_CTRL0); - + aud_mst_##_name##_sclk_post_en, 0) #define AUD_MST_LRCLK(_name, _reg) \ AUD_TRIPHASE(mst_##_name##_lrclk, _reg, 1, 1, 3, 5, \ aud_mst_##_name##_lrclk_div, CLK_SET_RATE_PARENT) -static AUD_MST_LRCLK(a, AUDIO_MST_A_SCLK_CTRL1); -static AUD_MST_LRCLK(b, AUDIO_MST_B_SCLK_CTRL1); -static AUD_MST_LRCLK(c, AUDIO_MST_C_SCLK_CTRL1); -static AUD_MST_LRCLK(d, AUDIO_MST_D_SCLK_CTRL1); -static AUD_MST_LRCLK(e, AUDIO_MST_E_SCLK_CTRL1); -static AUD_MST_LRCLK(f, AUDIO_MST_F_SCLK_CTRL1); - +/* TDM bit clock sources */ static const struct clk_parent_data tdm_sclk_parent_data[] = { - { .hw = &aud_mst_a_sclk.hw, }, - { .hw = &aud_mst_b_sclk.hw, }, - { .hw = &aud_mst_c_sclk.hw, }, - { .hw = &aud_mst_d_sclk.hw, }, - { .hw = &aud_mst_e_sclk.hw, }, - { .hw = &aud_mst_f_sclk.hw, }, + { .name = "aud_mst_a_sclk", .index = -1, }, + { .name = "aud_mst_b_sclk", .index = -1, }, + { .name = "aud_mst_c_sclk", .index = -1, }, + { .name = "aud_mst_d_sclk", .index = -1, }, + { .name = "aud_mst_e_sclk", .index = -1, }, + { .name = "aud_mst_f_sclk", .index = -1, }, { .fw_name = "slv_sclk0", }, { .fw_name = "slv_sclk1", }, { .fw_name = "slv_sclk2", }, @@ -323,78 +221,14 @@ static const struct clk_parent_data tdm_sclk_parent_data[] = { { .fw_name = "slv_sclk9", }, }; -#define AUD_TDM_SCLK_MUX(_name, _reg) \ - AUD_MUX(tdm##_name##_sclk_sel, _reg, 0xf, 24, \ - CLK_MUX_ROUND_CLOSEST, \ - tdm_sclk_parent_data, 0) - -static AUD_TDM_SCLK_MUX(in_a, AUDIO_CLK_TDMIN_A_CTRL); -static AUD_TDM_SCLK_MUX(in_b, AUDIO_CLK_TDMIN_B_CTRL); -static AUD_TDM_SCLK_MUX(in_c, AUDIO_CLK_TDMIN_C_CTRL); -static AUD_TDM_SCLK_MUX(in_lb, AUDIO_CLK_TDMIN_LB_CTRL); -static AUD_TDM_SCLK_MUX(out_a, AUDIO_CLK_TDMOUT_A_CTRL); -static AUD_TDM_SCLK_MUX(out_b, AUDIO_CLK_TDMOUT_B_CTRL); -static AUD_TDM_SCLK_MUX(out_c, AUDIO_CLK_TDMOUT_C_CTRL); - -#define AUD_TDM_SCLK_PRE_EN(_name, _reg) \ - AUD_GATE(tdm##_name##_sclk_pre_en, _reg, 31, \ - aud_tdm##_name##_sclk_sel, CLK_SET_RATE_PARENT) - -static AUD_TDM_SCLK_PRE_EN(in_a, AUDIO_CLK_TDMIN_A_CTRL); -static AUD_TDM_SCLK_PRE_EN(in_b, AUDIO_CLK_TDMIN_B_CTRL); -static AUD_TDM_SCLK_PRE_EN(in_c, AUDIO_CLK_TDMIN_C_CTRL); -static AUD_TDM_SCLK_PRE_EN(in_lb, AUDIO_CLK_TDMIN_LB_CTRL); -static AUD_TDM_SCLK_PRE_EN(out_a, AUDIO_CLK_TDMOUT_A_CTRL); -static AUD_TDM_SCLK_PRE_EN(out_b, AUDIO_CLK_TDMOUT_B_CTRL); -static AUD_TDM_SCLK_PRE_EN(out_c, AUDIO_CLK_TDMOUT_C_CTRL); - -#define AUD_TDM_SCLK_POST_EN(_name, _reg) \ - AUD_GATE(tdm##_name##_sclk_post_en, _reg, 30, \ - aud_tdm##_name##_sclk_pre_en, CLK_SET_RATE_PARENT) - -static AUD_TDM_SCLK_POST_EN(in_a, AUDIO_CLK_TDMIN_A_CTRL); -static AUD_TDM_SCLK_POST_EN(in_b, AUDIO_CLK_TDMIN_B_CTRL); -static AUD_TDM_SCLK_POST_EN(in_c, AUDIO_CLK_TDMIN_C_CTRL); -static AUD_TDM_SCLK_POST_EN(in_lb, AUDIO_CLK_TDMIN_LB_CTRL); -static AUD_TDM_SCLK_POST_EN(out_a, AUDIO_CLK_TDMOUT_A_CTRL); -static AUD_TDM_SCLK_POST_EN(out_b, AUDIO_CLK_TDMOUT_B_CTRL); -static AUD_TDM_SCLK_POST_EN(out_c, AUDIO_CLK_TDMOUT_C_CTRL); - -#define AUD_TDM_SCLK(_name, _reg) \ - struct clk_regmap aud_tdm##_name##_sclk = { \ - .data = &(struct meson_clk_phase_data) { \ - .ph = { \ - .reg_off = (_reg), \ - .shift = 29, \ - .width = 1, \ - }, \ - }, \ - .hw.init = &(struct clk_init_data) { \ - .name = "aud_tdm"#_name"_sclk", \ - .ops = &meson_clk_phase_ops, \ - .parent_hws = (const struct clk_hw *[]) { \ - &aud_tdm##_name##_sclk_post_en.hw \ - }, \ - .num_parents = 1, \ - .flags = CLK_DUTY_CYCLE_PARENT | CLK_SET_RATE_PARENT, \ - }, \ -} - -static AUD_TDM_SCLK(in_a, AUDIO_CLK_TDMIN_A_CTRL); -static AUD_TDM_SCLK(in_b, AUDIO_CLK_TDMIN_B_CTRL); -static AUD_TDM_SCLK(in_c, AUDIO_CLK_TDMIN_C_CTRL); -static AUD_TDM_SCLK(in_lb, AUDIO_CLK_TDMIN_LB_CTRL); -static AUD_TDM_SCLK(out_a, AUDIO_CLK_TDMOUT_A_CTRL); -static AUD_TDM_SCLK(out_b, AUDIO_CLK_TDMOUT_B_CTRL); -static AUD_TDM_SCLK(out_c, AUDIO_CLK_TDMOUT_C_CTRL); - +/* TDM sample clock sources */ static const struct clk_parent_data tdm_lrclk_parent_data[] = { - { .hw = &aud_mst_a_lrclk.hw, }, - { .hw = &aud_mst_b_lrclk.hw, }, - { .hw = &aud_mst_c_lrclk.hw, }, - { .hw = &aud_mst_d_lrclk.hw, }, - { .hw = &aud_mst_e_lrclk.hw, }, - { .hw = &aud_mst_f_lrclk.hw, }, + { .name = "aud_mst_a_lrclk", .index = -1, }, + { .name = "aud_mst_b_lrclk", .index = -1, }, + { .name = "aud_mst_c_lrclk", .index = -1, }, + { .name = "aud_mst_d_lrclk", .index = -1, }, + { .name = "aud_mst_e_lrclk", .index = -1, }, + { .name = "aud_mst_f_lrclk", .index = -1, }, { .fw_name = "slv_lrclk0", }, { .fw_name = "slv_lrclk1", }, { .fw_name = "slv_lrclk2", }, @@ -407,69 +241,536 @@ static const struct clk_parent_data tdm_lrclk_parent_data[] = { { .fw_name = "slv_lrclk9", }, }; -#define AUD_TDM_LRLCK(_name, _reg) \ - AUD_MUX(tdm##_name##_lrclk, _reg, 0xf, 20, \ - CLK_MUX_ROUND_CLOSEST, \ - tdm_lrclk_parent_data, 0) +#define AUD_TDM_SCLK_MUX(_name, _reg) \ + AUD_MUX(tdm##_name##_sclk_sel, _reg, 0xf, 24, \ + CLK_MUX_ROUND_CLOSEST, tdm_sclk_parent_data, 0) +#define AUD_TDM_SCLK_PRE_EN(_name, _reg) \ + AUD_GATE(tdm##_name##_sclk_pre_en, _reg, 31, \ + aud_tdm##_name##_sclk_sel, CLK_SET_RATE_PARENT) +#define AUD_TDM_SCLK_POST_EN(_name, _reg) \ + AUD_GATE(tdm##_name##_sclk_post_en, _reg, 30, \ + aud_tdm##_name##_sclk_pre_en, CLK_SET_RATE_PARENT) +#define AUD_TDM_SCLK(_name, _reg) \ + AUD_PHASE(tdm##_name##_sclk, _reg, 1, 29, \ + aud_tdm##_name##_sclk_post_en, \ + CLK_DUTY_CYCLE_PARENT | CLK_SET_RATE_PARENT) + +#define AUD_TDM_LRLCK(_name, _reg) \ + AUD_MUX(tdm##_name##_lrclk, _reg, 0xf, 20, \ + CLK_MUX_ROUND_CLOSEST, tdm_lrclk_parent_data, 0) + +/* Pad master clock sources */ +static const struct clk_parent_data mclk_pad_ctrl_parent_data[] = { + { .name = "aud_mst_a_mclk", .index = -1, }, + { .name = "aud_mst_b_mclk", .index = -1, }, + { .name = "aud_mst_c_mclk", .index = -1, }, + { .name = "aud_mst_d_mclk", .index = -1, }, + { .name = "aud_mst_e_mclk", .index = -1, }, + { .name = "aud_mst_f_mclk", .index = -1, }, +}; + +/* Pad bit clock sources */ +static const struct clk_parent_data sclk_pad_ctrl_parent_data[] = { + { .name = "aud_mst_a_sclk", .index = -1, }, + { .name = "aud_mst_b_sclk", .index = -1, }, + { .name = "aud_mst_c_sclk", .index = -1, }, + { .name = "aud_mst_d_sclk", .index = -1, }, + { .name = "aud_mst_e_sclk", .index = -1, }, + { .name = "aud_mst_f_sclk", .index = -1, }, +}; -static AUD_TDM_LRLCK(in_a, AUDIO_CLK_TDMIN_A_CTRL); -static AUD_TDM_LRLCK(in_b, AUDIO_CLK_TDMIN_B_CTRL); -static AUD_TDM_LRLCK(in_c, AUDIO_CLK_TDMIN_C_CTRL); -static AUD_TDM_LRLCK(in_lb, AUDIO_CLK_TDMIN_LB_CTRL); -static AUD_TDM_LRLCK(out_a, AUDIO_CLK_TDMOUT_A_CTRL); -static AUD_TDM_LRLCK(out_b, AUDIO_CLK_TDMOUT_B_CTRL); -static AUD_TDM_LRLCK(out_c, AUDIO_CLK_TDMOUT_C_CTRL); +/* Pad sample clock sources */ +static const struct clk_parent_data lrclk_pad_ctrl_parent_data[] = { + { .name = "aud_mst_a_lrclk", .index = -1, }, + { .name = "aud_mst_b_lrclk", .index = -1, }, + { .name = "aud_mst_c_lrclk", .index = -1, }, + { .name = "aud_mst_d_lrclk", .index = -1, }, + { .name = "aud_mst_e_lrclk", .index = -1, }, + { .name = "aud_mst_f_lrclk", .index = -1, }, +}; -/* G12a Pad control */ #define AUD_TDM_PAD_CTRL(_name, _reg, _shift, _parents) \ - AUD_MUX(tdm_##_name, _reg, 0x7, _shift, 0, _parents, \ + AUD_MUX(_name, _reg, 0x7, _shift, 0, _parents, \ CLK_SET_RATE_NO_REPARENT) -static const struct clk_parent_data mclk_pad_ctrl_parent_data[] = { - { .hw = &aud_mst_a_mclk.hw }, - { .hw = &aud_mst_b_mclk.hw }, - { .hw = &aud_mst_c_mclk.hw }, - { .hw = &aud_mst_d_mclk.hw }, - { .hw = &aud_mst_e_mclk.hw }, - { .hw = &aud_mst_f_mclk.hw }, +/* Common Clocks */ +static struct clk_regmap ddr_arb = + AUD_PCLK_GATE(ddr_arb, AUDIO_CLK_GATE_EN, 0); +static struct clk_regmap pdm = + AUD_PCLK_GATE(pdm, AUDIO_CLK_GATE_EN, 1); +static struct clk_regmap tdmin_a = + AUD_PCLK_GATE(tdmin_a, AUDIO_CLK_GATE_EN, 2); +static struct clk_regmap tdmin_b = + AUD_PCLK_GATE(tdmin_b, AUDIO_CLK_GATE_EN, 3); +static struct clk_regmap tdmin_c = + AUD_PCLK_GATE(tdmin_c, AUDIO_CLK_GATE_EN, 4); +static struct clk_regmap tdmin_lb = + AUD_PCLK_GATE(tdmin_lb, AUDIO_CLK_GATE_EN, 5); +static struct clk_regmap tdmout_a = + AUD_PCLK_GATE(tdmout_a, AUDIO_CLK_GATE_EN, 6); +static struct clk_regmap tdmout_b = + AUD_PCLK_GATE(tdmout_b, AUDIO_CLK_GATE_EN, 7); +static struct clk_regmap tdmout_c = + AUD_PCLK_GATE(tdmout_c, AUDIO_CLK_GATE_EN, 8); +static struct clk_regmap frddr_a = + AUD_PCLK_GATE(frddr_a, AUDIO_CLK_GATE_EN, 9); +static struct clk_regmap frddr_b = + AUD_PCLK_GATE(frddr_b, AUDIO_CLK_GATE_EN, 10); +static struct clk_regmap frddr_c = + AUD_PCLK_GATE(frddr_c, AUDIO_CLK_GATE_EN, 11); +static struct clk_regmap toddr_a = + AUD_PCLK_GATE(toddr_a, AUDIO_CLK_GATE_EN, 12); +static struct clk_regmap toddr_b = + AUD_PCLK_GATE(toddr_b, AUDIO_CLK_GATE_EN, 13); +static struct clk_regmap toddr_c = + AUD_PCLK_GATE(toddr_c, AUDIO_CLK_GATE_EN, 14); +static struct clk_regmap loopback = + AUD_PCLK_GATE(loopback, AUDIO_CLK_GATE_EN, 15); +static struct clk_regmap spdifin = + AUD_PCLK_GATE(spdifin, AUDIO_CLK_GATE_EN, 16); +static struct clk_regmap spdifout = + AUD_PCLK_GATE(spdifout, AUDIO_CLK_GATE_EN, 17); +static struct clk_regmap resample = + AUD_PCLK_GATE(resample, AUDIO_CLK_GATE_EN, 18); +static struct clk_regmap power_detect = + AUD_PCLK_GATE(power_detect, AUDIO_CLK_GATE_EN, 19); + +static struct clk_regmap spdifout_clk_sel = + AUD_MST_MCLK_MUX(spdifout_clk, AUDIO_CLK_SPDIFOUT_CTRL); +static struct clk_regmap pdm_dclk_sel = + AUD_MST_MCLK_MUX(pdm_dclk, AUDIO_CLK_PDMIN_CTRL0); +static struct clk_regmap spdifin_clk_sel = + AUD_MST_SYS_MUX(spdifin_clk, AUDIO_CLK_SPDIFIN_CTRL); +static struct clk_regmap pdm_sysclk_sel = + AUD_MST_SYS_MUX(pdm_sysclk, AUDIO_CLK_PDMIN_CTRL1); +static struct clk_regmap spdifout_b_clk_sel = + AUD_MST_MCLK_MUX(spdifout_b_clk, AUDIO_CLK_SPDIFOUT_B_CTRL); + +static struct clk_regmap spdifout_clk_div = + AUD_MST_MCLK_DIV(spdifout_clk, AUDIO_CLK_SPDIFOUT_CTRL); +static struct clk_regmap pdm_dclk_div = + AUD_MST_MCLK_DIV(pdm_dclk, AUDIO_CLK_PDMIN_CTRL0); +static struct clk_regmap spdifin_clk_div = + AUD_MST_SYS_DIV(spdifin_clk, AUDIO_CLK_SPDIFIN_CTRL); +static struct clk_regmap pdm_sysclk_div = + AUD_MST_SYS_DIV(pdm_sysclk, AUDIO_CLK_PDMIN_CTRL1); +static struct clk_regmap spdifout_b_clk_div = + AUD_MST_MCLK_DIV(spdifout_b_clk, AUDIO_CLK_SPDIFOUT_B_CTRL); + +static struct clk_regmap spdifout_clk = + AUD_MST_MCLK_GATE(spdifout_clk, AUDIO_CLK_SPDIFOUT_CTRL); +static struct clk_regmap spdifin_clk = + AUD_MST_MCLK_GATE(spdifin_clk, AUDIO_CLK_SPDIFIN_CTRL); +static struct clk_regmap pdm_dclk = + AUD_MST_MCLK_GATE(pdm_dclk, AUDIO_CLK_PDMIN_CTRL0); +static struct clk_regmap pdm_sysclk = + AUD_MST_MCLK_GATE(pdm_sysclk, AUDIO_CLK_PDMIN_CTRL1); +static struct clk_regmap spdifout_b_clk = + AUD_MST_MCLK_GATE(spdifout_b_clk, AUDIO_CLK_SPDIFOUT_B_CTRL); + +static struct clk_regmap mst_a_sclk_pre_en = + AUD_MST_SCLK_PRE_EN(a, AUDIO_MST_A_SCLK_CTRL0); +static struct clk_regmap mst_b_sclk_pre_en = + AUD_MST_SCLK_PRE_EN(b, AUDIO_MST_B_SCLK_CTRL0); +static struct clk_regmap mst_c_sclk_pre_en = + AUD_MST_SCLK_PRE_EN(c, AUDIO_MST_C_SCLK_CTRL0); +static struct clk_regmap mst_d_sclk_pre_en = + AUD_MST_SCLK_PRE_EN(d, AUDIO_MST_D_SCLK_CTRL0); +static struct clk_regmap mst_e_sclk_pre_en = + AUD_MST_SCLK_PRE_EN(e, AUDIO_MST_E_SCLK_CTRL0); +static struct clk_regmap mst_f_sclk_pre_en = + AUD_MST_SCLK_PRE_EN(f, AUDIO_MST_F_SCLK_CTRL0); + +static struct clk_regmap mst_a_sclk_div = + AUD_MST_SCLK_DIV(a, AUDIO_MST_A_SCLK_CTRL0); +static struct clk_regmap mst_b_sclk_div = + AUD_MST_SCLK_DIV(b, AUDIO_MST_B_SCLK_CTRL0); +static struct clk_regmap mst_c_sclk_div = + AUD_MST_SCLK_DIV(c, AUDIO_MST_C_SCLK_CTRL0); +static struct clk_regmap mst_d_sclk_div = + AUD_MST_SCLK_DIV(d, AUDIO_MST_D_SCLK_CTRL0); +static struct clk_regmap mst_e_sclk_div = + AUD_MST_SCLK_DIV(e, AUDIO_MST_E_SCLK_CTRL0); +static struct clk_regmap mst_f_sclk_div = + AUD_MST_SCLK_DIV(f, AUDIO_MST_F_SCLK_CTRL0); + +static struct clk_regmap mst_a_sclk_post_en = + AUD_MST_SCLK_POST_EN(a, AUDIO_MST_A_SCLK_CTRL0); +static struct clk_regmap mst_b_sclk_post_en = + AUD_MST_SCLK_POST_EN(b, AUDIO_MST_B_SCLK_CTRL0); +static struct clk_regmap mst_c_sclk_post_en = + AUD_MST_SCLK_POST_EN(c, AUDIO_MST_C_SCLK_CTRL0); +static struct clk_regmap mst_d_sclk_post_en = + AUD_MST_SCLK_POST_EN(d, AUDIO_MST_D_SCLK_CTRL0); +static struct clk_regmap mst_e_sclk_post_en = + AUD_MST_SCLK_POST_EN(e, AUDIO_MST_E_SCLK_CTRL0); +static struct clk_regmap mst_f_sclk_post_en = + AUD_MST_SCLK_POST_EN(f, AUDIO_MST_F_SCLK_CTRL0); + +static struct clk_regmap mst_a_sclk = + AUD_MST_SCLK(a, AUDIO_MST_A_SCLK_CTRL1); +static struct clk_regmap mst_b_sclk = + AUD_MST_SCLK(b, AUDIO_MST_B_SCLK_CTRL1); +static struct clk_regmap mst_c_sclk = + AUD_MST_SCLK(c, AUDIO_MST_C_SCLK_CTRL1); +static struct clk_regmap mst_d_sclk = + AUD_MST_SCLK(d, AUDIO_MST_D_SCLK_CTRL1); +static struct clk_regmap mst_e_sclk = + AUD_MST_SCLK(e, AUDIO_MST_E_SCLK_CTRL1); +static struct clk_regmap mst_f_sclk = + AUD_MST_SCLK(f, AUDIO_MST_F_SCLK_CTRL1); + +static struct clk_regmap mst_a_lrclk_div = + AUD_MST_LRCLK_DIV(a, AUDIO_MST_A_SCLK_CTRL0); +static struct clk_regmap mst_b_lrclk_div = + AUD_MST_LRCLK_DIV(b, AUDIO_MST_B_SCLK_CTRL0); +static struct clk_regmap mst_c_lrclk_div = + AUD_MST_LRCLK_DIV(c, AUDIO_MST_C_SCLK_CTRL0); +static struct clk_regmap mst_d_lrclk_div = + AUD_MST_LRCLK_DIV(d, AUDIO_MST_D_SCLK_CTRL0); +static struct clk_regmap mst_e_lrclk_div = + AUD_MST_LRCLK_DIV(e, AUDIO_MST_E_SCLK_CTRL0); +static struct clk_regmap mst_f_lrclk_div = + AUD_MST_LRCLK_DIV(f, AUDIO_MST_F_SCLK_CTRL0); + +static struct clk_regmap mst_a_lrclk = + AUD_MST_LRCLK(a, AUDIO_MST_A_SCLK_CTRL1); +static struct clk_regmap mst_b_lrclk = + AUD_MST_LRCLK(b, AUDIO_MST_B_SCLK_CTRL1); +static struct clk_regmap mst_c_lrclk = + AUD_MST_LRCLK(c, AUDIO_MST_C_SCLK_CTRL1); +static struct clk_regmap mst_d_lrclk = + AUD_MST_LRCLK(d, AUDIO_MST_D_SCLK_CTRL1); +static struct clk_regmap mst_e_lrclk = + AUD_MST_LRCLK(e, AUDIO_MST_E_SCLK_CTRL1); +static struct clk_regmap mst_f_lrclk = + AUD_MST_LRCLK(f, AUDIO_MST_F_SCLK_CTRL1); + +static struct clk_regmap tdmin_a_sclk_sel = + AUD_TDM_SCLK_MUX(in_a, AUDIO_CLK_TDMIN_A_CTRL); +static struct clk_regmap tdmin_b_sclk_sel = + AUD_TDM_SCLK_MUX(in_b, AUDIO_CLK_TDMIN_B_CTRL); +static struct clk_regmap tdmin_c_sclk_sel = + AUD_TDM_SCLK_MUX(in_c, AUDIO_CLK_TDMIN_C_CTRL); +static struct clk_regmap tdmin_lb_sclk_sel = + AUD_TDM_SCLK_MUX(in_lb, AUDIO_CLK_TDMIN_LB_CTRL); +static struct clk_regmap tdmout_a_sclk_sel = + AUD_TDM_SCLK_MUX(out_a, AUDIO_CLK_TDMOUT_A_CTRL); +static struct clk_regmap tdmout_b_sclk_sel = + AUD_TDM_SCLK_MUX(out_b, AUDIO_CLK_TDMOUT_B_CTRL); +static struct clk_regmap tdmout_c_sclk_sel = + AUD_TDM_SCLK_MUX(out_c, AUDIO_CLK_TDMOUT_C_CTRL); + +static struct clk_regmap tdmin_a_sclk_pre_en = + AUD_TDM_SCLK_PRE_EN(in_a, AUDIO_CLK_TDMIN_A_CTRL); +static struct clk_regmap tdmin_b_sclk_pre_en = + AUD_TDM_SCLK_PRE_EN(in_b, AUDIO_CLK_TDMIN_B_CTRL); +static struct clk_regmap tdmin_c_sclk_pre_en = + AUD_TDM_SCLK_PRE_EN(in_c, AUDIO_CLK_TDMIN_C_CTRL); +static struct clk_regmap tdmin_lb_sclk_pre_en = + AUD_TDM_SCLK_PRE_EN(in_lb, AUDIO_CLK_TDMIN_LB_CTRL); +static struct clk_regmap tdmout_a_sclk_pre_en = + AUD_TDM_SCLK_PRE_EN(out_a, AUDIO_CLK_TDMOUT_A_CTRL); +static struct clk_regmap tdmout_b_sclk_pre_en = + AUD_TDM_SCLK_PRE_EN(out_b, AUDIO_CLK_TDMOUT_B_CTRL); +static struct clk_regmap tdmout_c_sclk_pre_en = + AUD_TDM_SCLK_PRE_EN(out_c, AUDIO_CLK_TDMOUT_C_CTRL); + +static struct clk_regmap tdmin_a_sclk_post_en = + AUD_TDM_SCLK_POST_EN(in_a, AUDIO_CLK_TDMIN_A_CTRL); +static struct clk_regmap tdmin_b_sclk_post_en = + AUD_TDM_SCLK_POST_EN(in_b, AUDIO_CLK_TDMIN_B_CTRL); +static struct clk_regmap tdmin_c_sclk_post_en = + AUD_TDM_SCLK_POST_EN(in_c, AUDIO_CLK_TDMIN_C_CTRL); +static struct clk_regmap tdmin_lb_sclk_post_en = + AUD_TDM_SCLK_POST_EN(in_lb, AUDIO_CLK_TDMIN_LB_CTRL); +static struct clk_regmap tdmout_a_sclk_post_en = + AUD_TDM_SCLK_POST_EN(out_a, AUDIO_CLK_TDMOUT_A_CTRL); +static struct clk_regmap tdmout_b_sclk_post_en = + AUD_TDM_SCLK_POST_EN(out_b, AUDIO_CLK_TDMOUT_B_CTRL); +static struct clk_regmap tdmout_c_sclk_post_en = + AUD_TDM_SCLK_POST_EN(out_c, AUDIO_CLK_TDMOUT_C_CTRL); + +static struct clk_regmap tdmin_a_sclk = + AUD_TDM_SCLK(in_a, AUDIO_CLK_TDMIN_A_CTRL); +static struct clk_regmap tdmin_b_sclk = + AUD_TDM_SCLK(in_b, AUDIO_CLK_TDMIN_B_CTRL); +static struct clk_regmap tdmin_c_sclk = + AUD_TDM_SCLK(in_c, AUDIO_CLK_TDMIN_C_CTRL); +static struct clk_regmap tdmin_lb_sclk = + AUD_TDM_SCLK(in_lb, AUDIO_CLK_TDMIN_LB_CTRL); +static struct clk_regmap tdmout_a_sclk = + AUD_TDM_SCLK(out_a, AUDIO_CLK_TDMOUT_A_CTRL); +static struct clk_regmap tdmout_b_sclk = + AUD_TDM_SCLK(out_b, AUDIO_CLK_TDMOUT_B_CTRL); +static struct clk_regmap tdmout_c_sclk = + AUD_TDM_SCLK(out_c, AUDIO_CLK_TDMOUT_C_CTRL); + +static struct clk_regmap tdmin_a_lrclk = + AUD_TDM_LRLCK(in_a, AUDIO_CLK_TDMIN_A_CTRL); +static struct clk_regmap tdmin_b_lrclk = + AUD_TDM_LRLCK(in_b, AUDIO_CLK_TDMIN_B_CTRL); +static struct clk_regmap tdmin_c_lrclk = + AUD_TDM_LRLCK(in_c, AUDIO_CLK_TDMIN_C_CTRL); +static struct clk_regmap tdmin_lb_lrclk = + AUD_TDM_LRLCK(in_lb, AUDIO_CLK_TDMIN_LB_CTRL); +static struct clk_regmap tdmout_a_lrclk = + AUD_TDM_LRLCK(out_a, AUDIO_CLK_TDMOUT_A_CTRL); +static struct clk_regmap tdmout_b_lrclk = + AUD_TDM_LRLCK(out_b, AUDIO_CLK_TDMOUT_B_CTRL); +static struct clk_regmap tdmout_c_lrclk = + AUD_TDM_LRLCK(out_c, AUDIO_CLK_TDMOUT_C_CTRL); + +/* AXG/G12A Clocks */ +static struct clk_hw axg_aud_top = { + .init = &(struct clk_init_data) { + /* Provide aud_top signal name on axg and g12a */ + .name = "aud_top", + .ops = &(const struct clk_ops) {}, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "pclk", + }, + .num_parents = 1, + }, }; -static AUD_TDM_PAD_CTRL(mclk_pad_0, AUDIO_MST_PAD_CTRL0, 0, - mclk_pad_ctrl_parent_data); -static AUD_TDM_PAD_CTRL(mclk_pad_1, AUDIO_MST_PAD_CTRL0, 4, - mclk_pad_ctrl_parent_data); +static struct clk_regmap mst_a_mclk_sel = + AUD_MST_MCLK_MUX(mst_a_mclk, AUDIO_MCLK_A_CTRL); +static struct clk_regmap mst_b_mclk_sel = + AUD_MST_MCLK_MUX(mst_b_mclk, AUDIO_MCLK_B_CTRL); +static struct clk_regmap mst_c_mclk_sel = + AUD_MST_MCLK_MUX(mst_c_mclk, AUDIO_MCLK_C_CTRL); +static struct clk_regmap mst_d_mclk_sel = + AUD_MST_MCLK_MUX(mst_d_mclk, AUDIO_MCLK_D_CTRL); +static struct clk_regmap mst_e_mclk_sel = + AUD_MST_MCLK_MUX(mst_e_mclk, AUDIO_MCLK_E_CTRL); +static struct clk_regmap mst_f_mclk_sel = + AUD_MST_MCLK_MUX(mst_f_mclk, AUDIO_MCLK_F_CTRL); + +static struct clk_regmap mst_a_mclk_div = + AUD_MST_MCLK_DIV(mst_a_mclk, AUDIO_MCLK_A_CTRL); +static struct clk_regmap mst_b_mclk_div = + AUD_MST_MCLK_DIV(mst_b_mclk, AUDIO_MCLK_B_CTRL); +static struct clk_regmap mst_c_mclk_div = + AUD_MST_MCLK_DIV(mst_c_mclk, AUDIO_MCLK_C_CTRL); +static struct clk_regmap mst_d_mclk_div = + AUD_MST_MCLK_DIV(mst_d_mclk, AUDIO_MCLK_D_CTRL); +static struct clk_regmap mst_e_mclk_div = + AUD_MST_MCLK_DIV(mst_e_mclk, AUDIO_MCLK_E_CTRL); +static struct clk_regmap mst_f_mclk_div = + AUD_MST_MCLK_DIV(mst_f_mclk, AUDIO_MCLK_F_CTRL); + +static struct clk_regmap mst_a_mclk = + AUD_MST_MCLK_GATE(mst_a_mclk, AUDIO_MCLK_A_CTRL); +static struct clk_regmap mst_b_mclk = + AUD_MST_MCLK_GATE(mst_b_mclk, AUDIO_MCLK_B_CTRL); +static struct clk_regmap mst_c_mclk = + AUD_MST_MCLK_GATE(mst_c_mclk, AUDIO_MCLK_C_CTRL); +static struct clk_regmap mst_d_mclk = + AUD_MST_MCLK_GATE(mst_d_mclk, AUDIO_MCLK_D_CTRL); +static struct clk_regmap mst_e_mclk = + AUD_MST_MCLK_GATE(mst_e_mclk, AUDIO_MCLK_E_CTRL); +static struct clk_regmap mst_f_mclk = + AUD_MST_MCLK_GATE(mst_f_mclk, AUDIO_MCLK_F_CTRL); + +/* G12a clocks */ +static struct clk_regmap g12a_tdm_mclk_pad_0 = AUD_TDM_PAD_CTRL( + mclk_pad_0, AUDIO_MST_PAD_CTRL0, 0, mclk_pad_ctrl_parent_data); +static struct clk_regmap g12a_tdm_mclk_pad_1 = AUD_TDM_PAD_CTRL( + mclk_pad_1, AUDIO_MST_PAD_CTRL0, 4, mclk_pad_ctrl_parent_data); +static struct clk_regmap g12a_tdm_lrclk_pad_0 = AUD_TDM_PAD_CTRL( + lrclk_pad_0, AUDIO_MST_PAD_CTRL1, 16, lrclk_pad_ctrl_parent_data); +static struct clk_regmap g12a_tdm_lrclk_pad_1 = AUD_TDM_PAD_CTRL( + lrclk_pad_1, AUDIO_MST_PAD_CTRL1, 20, lrclk_pad_ctrl_parent_data); +static struct clk_regmap g12a_tdm_lrclk_pad_2 = AUD_TDM_PAD_CTRL( + lrclk_pad_2, AUDIO_MST_PAD_CTRL1, 24, lrclk_pad_ctrl_parent_data); +static struct clk_regmap g12a_tdm_sclk_pad_0 = AUD_TDM_PAD_CTRL( + sclk_pad_0, AUDIO_MST_PAD_CTRL1, 0, sclk_pad_ctrl_parent_data); +static struct clk_regmap g12a_tdm_sclk_pad_1 = AUD_TDM_PAD_CTRL( + sclk_pad_1, AUDIO_MST_PAD_CTRL1, 4, sclk_pad_ctrl_parent_data); +static struct clk_regmap g12a_tdm_sclk_pad_2 = AUD_TDM_PAD_CTRL( + sclk_pad_2, AUDIO_MST_PAD_CTRL1, 8, sclk_pad_ctrl_parent_data); + +/* G12a/SM1 clocks */ +static struct clk_regmap toram = + AUD_PCLK_GATE(toram, AUDIO_CLK_GATE_EN, 20); +static struct clk_regmap spdifout_b = + AUD_PCLK_GATE(spdifout_b, AUDIO_CLK_GATE_EN, 21); +static struct clk_regmap eqdrc = + AUD_PCLK_GATE(eqdrc, AUDIO_CLK_GATE_EN, 22); + +/* SM1 Clocks */ +static struct clk_regmap sm1_clk81_en = { + .data = &(struct clk_regmap_gate_data){ + .offset = AUDIO_CLK81_EN, + .bit_idx = 31, + }, + .hw.init = &(struct clk_init_data) { + .name = "aud_clk81_en", + .ops = &clk_regmap_gate_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "pclk", + }, + .num_parents = 1, + }, +}; -static const struct clk_parent_data lrclk_pad_ctrl_parent_data[] = { - { .hw = &aud_mst_a_lrclk.hw }, - { .hw = &aud_mst_b_lrclk.hw }, - { .hw = &aud_mst_c_lrclk.hw }, - { .hw = &aud_mst_d_lrclk.hw }, - { .hw = &aud_mst_e_lrclk.hw }, - { .hw = &aud_mst_f_lrclk.hw }, +static struct clk_regmap sm1_sysclk_a_div = { + .data = &(struct clk_regmap_div_data){ + .offset = AUDIO_CLK81_CTRL, + .shift = 0, + .width = 8, + }, + .hw.init = &(struct clk_init_data) { + .name = "aud_sysclk_a_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &sm1_clk81_en.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, }; -static AUD_TDM_PAD_CTRL(lrclk_pad_0, AUDIO_MST_PAD_CTRL1, 16, - lrclk_pad_ctrl_parent_data); -static AUD_TDM_PAD_CTRL(lrclk_pad_1, AUDIO_MST_PAD_CTRL1, 20, - lrclk_pad_ctrl_parent_data); -static AUD_TDM_PAD_CTRL(lrclk_pad_2, AUDIO_MST_PAD_CTRL1, 24, - lrclk_pad_ctrl_parent_data); +static struct clk_regmap sm1_sysclk_a_en = { + .data = &(struct clk_regmap_gate_data){ + .offset = AUDIO_CLK81_CTRL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data) { + .name = "aud_sysclk_a_en", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &sm1_sysclk_a_div.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; -static const struct clk_parent_data sclk_pad_ctrl_parent_data[] = { - { .hw = &aud_mst_a_sclk.hw }, - { .hw = &aud_mst_b_sclk.hw }, - { .hw = &aud_mst_c_sclk.hw }, - { .hw = &aud_mst_d_sclk.hw }, - { .hw = &aud_mst_e_sclk.hw }, - { .hw = &aud_mst_f_sclk.hw }, +static struct clk_regmap sm1_sysclk_b_div = { + .data = &(struct clk_regmap_div_data){ + .offset = AUDIO_CLK81_CTRL, + .shift = 16, + .width = 8, + }, + .hw.init = &(struct clk_init_data) { + .name = "aud_sysclk_b_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &sm1_clk81_en.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, }; -static AUD_TDM_PAD_CTRL(sclk_pad_0, AUDIO_MST_PAD_CTRL1, 0, - sclk_pad_ctrl_parent_data); -static AUD_TDM_PAD_CTRL(sclk_pad_1, AUDIO_MST_PAD_CTRL1, 4, - sclk_pad_ctrl_parent_data); -static AUD_TDM_PAD_CTRL(sclk_pad_2, AUDIO_MST_PAD_CTRL1, 8, - sclk_pad_ctrl_parent_data); +static struct clk_regmap sm1_sysclk_b_en = { + .data = &(struct clk_regmap_gate_data){ + .offset = AUDIO_CLK81_CTRL, + .bit_idx = 24, + }, + .hw.init = &(struct clk_init_data) { + .name = "aud_sysclk_b_en", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &sm1_sysclk_b_div.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct clk_hw *sm1_aud_top_parents[] = { + &sm1_sysclk_a_en.hw, + &sm1_sysclk_b_en.hw, +}; + +static struct clk_regmap sm1_aud_top = { + .data = &(struct clk_regmap_mux_data){ + .offset = AUDIO_CLK81_CTRL, + .mask = 0x1, + .shift = 31, + }, + .hw.init = &(struct clk_init_data){ + .name = "aud_top", + .ops = &clk_regmap_mux_ops, + .parent_hws = sm1_aud_top_parents, + .num_parents = ARRAY_SIZE(sm1_aud_top_parents), + .flags = CLK_SET_RATE_NO_REPARENT, + }, +}; + +static struct clk_regmap resample_b = + AUD_PCLK_GATE(resample_b, AUDIO_CLK_GATE_EN, 26); +static struct clk_regmap tovad = + AUD_PCLK_GATE(tovad, AUDIO_CLK_GATE_EN, 27); +static struct clk_regmap locker = + AUD_PCLK_GATE(locker, AUDIO_CLK_GATE_EN, 28); +static struct clk_regmap spdifin_lb = + AUD_PCLK_GATE(spdifin_lb, AUDIO_CLK_GATE_EN, 29); +static struct clk_regmap frddr_d = + AUD_PCLK_GATE(frddr_d, AUDIO_CLK_GATE_EN1, 0); +static struct clk_regmap toddr_d = + AUD_PCLK_GATE(toddr_d, AUDIO_CLK_GATE_EN1, 1); +static struct clk_regmap loopback_b = + AUD_PCLK_GATE(loopback_b, AUDIO_CLK_GATE_EN1, 2); + +static struct clk_regmap sm1_mst_a_mclk_sel = + AUD_MST_MCLK_MUX(mst_a_mclk, AUDIO_SM1_MCLK_A_CTRL); +static struct clk_regmap sm1_mst_b_mclk_sel = + AUD_MST_MCLK_MUX(mst_b_mclk, AUDIO_SM1_MCLK_B_CTRL); +static struct clk_regmap sm1_mst_c_mclk_sel = + AUD_MST_MCLK_MUX(mst_c_mclk, AUDIO_SM1_MCLK_C_CTRL); +static struct clk_regmap sm1_mst_d_mclk_sel = + AUD_MST_MCLK_MUX(mst_d_mclk, AUDIO_SM1_MCLK_D_CTRL); +static struct clk_regmap sm1_mst_e_mclk_sel = + AUD_MST_MCLK_MUX(mst_e_mclk, AUDIO_SM1_MCLK_E_CTRL); +static struct clk_regmap sm1_mst_f_mclk_sel = + AUD_MST_MCLK_MUX(mst_f_mclk, AUDIO_SM1_MCLK_F_CTRL); + +static struct clk_regmap sm1_mst_a_mclk_div = + AUD_MST_MCLK_DIV(mst_a_mclk, AUDIO_SM1_MCLK_A_CTRL); +static struct clk_regmap sm1_mst_b_mclk_div = + AUD_MST_MCLK_DIV(mst_b_mclk, AUDIO_SM1_MCLK_B_CTRL); +static struct clk_regmap sm1_mst_c_mclk_div = + AUD_MST_MCLK_DIV(mst_c_mclk, AUDIO_SM1_MCLK_C_CTRL); +static struct clk_regmap sm1_mst_d_mclk_div = + AUD_MST_MCLK_DIV(mst_d_mclk, AUDIO_SM1_MCLK_D_CTRL); +static struct clk_regmap sm1_mst_e_mclk_div = + AUD_MST_MCLK_DIV(mst_e_mclk, AUDIO_SM1_MCLK_E_CTRL); +static struct clk_regmap sm1_mst_f_mclk_div = + AUD_MST_MCLK_DIV(mst_f_mclk, AUDIO_SM1_MCLK_F_CTRL); + +static struct clk_regmap sm1_mst_a_mclk = + AUD_MST_MCLK_GATE(mst_a_mclk, AUDIO_SM1_MCLK_A_CTRL); +static struct clk_regmap sm1_mst_b_mclk = + AUD_MST_MCLK_GATE(mst_b_mclk, AUDIO_SM1_MCLK_B_CTRL); +static struct clk_regmap sm1_mst_c_mclk = + AUD_MST_MCLK_GATE(mst_c_mclk, AUDIO_SM1_MCLK_C_CTRL); +static struct clk_regmap sm1_mst_d_mclk = + AUD_MST_MCLK_GATE(mst_d_mclk, AUDIO_SM1_MCLK_D_CTRL); +static struct clk_regmap sm1_mst_e_mclk = + AUD_MST_MCLK_GATE(mst_e_mclk, AUDIO_SM1_MCLK_E_CTRL); +static struct clk_regmap sm1_mst_f_mclk = + AUD_MST_MCLK_GATE(mst_f_mclk, AUDIO_SM1_MCLK_F_CTRL); + +static struct clk_regmap sm1_tdm_mclk_pad_0 = AUD_TDM_PAD_CTRL( + tdm_mclk_pad_0, AUDIO_SM1_MST_PAD_CTRL0, 0, mclk_pad_ctrl_parent_data); +static struct clk_regmap sm1_tdm_mclk_pad_1 = AUD_TDM_PAD_CTRL( + tdm_mclk_pad_1, AUDIO_SM1_MST_PAD_CTRL0, 4, mclk_pad_ctrl_parent_data); +static struct clk_regmap sm1_tdm_lrclk_pad_0 = AUD_TDM_PAD_CTRL( + tdm_lrclk_pad_0, AUDIO_SM1_MST_PAD_CTRL1, 16, lrclk_pad_ctrl_parent_data); +static struct clk_regmap sm1_tdm_lrclk_pad_1 = AUD_TDM_PAD_CTRL( + tdm_lrclk_pad_1, AUDIO_SM1_MST_PAD_CTRL1, 20, lrclk_pad_ctrl_parent_data); +static struct clk_regmap sm1_tdm_lrclk_pad_2 = AUD_TDM_PAD_CTRL( + tdm_lrclk_pad_2, AUDIO_SM1_MST_PAD_CTRL1, 24, lrclk_pad_ctrl_parent_data); +static struct clk_regmap sm1_tdm_sclk_pad_0 = AUD_TDM_PAD_CTRL( + tdm_sclk_pad_0, AUDIO_SM1_MST_PAD_CTRL1, 0, sclk_pad_ctrl_parent_data); +static struct clk_regmap sm1_tdm_sclk_pad_1 = AUD_TDM_PAD_CTRL( + tdm_sclk_pad_1, AUDIO_SM1_MST_PAD_CTRL1, 4, sclk_pad_ctrl_parent_data); +static struct clk_regmap sm1_tdm_sclk_pad_2 = AUD_TDM_PAD_CTRL( + tdm_sclk_pad_2, AUDIO_SM1_MST_PAD_CTRL1, 8, sclk_pad_ctrl_parent_data); /* * Array of all clocks provided by this provider @@ -477,127 +778,128 @@ static AUD_TDM_PAD_CTRL(sclk_pad_2, AUDIO_MST_PAD_CTRL1, 8, */ static struct clk_hw_onecell_data axg_audio_hw_onecell_data = { .hws = { - [AUD_CLKID_DDR_ARB] = &aud_ddr_arb.hw, - [AUD_CLKID_PDM] = &aud_pdm.hw, - [AUD_CLKID_TDMIN_A] = &aud_tdmin_a.hw, - [AUD_CLKID_TDMIN_B] = &aud_tdmin_b.hw, - [AUD_CLKID_TDMIN_C] = &aud_tdmin_c.hw, - [AUD_CLKID_TDMIN_LB] = &aud_tdmin_lb.hw, - [AUD_CLKID_TDMOUT_A] = &aud_tdmout_a.hw, - [AUD_CLKID_TDMOUT_B] = &aud_tdmout_b.hw, - [AUD_CLKID_TDMOUT_C] = &aud_tdmout_c.hw, - [AUD_CLKID_FRDDR_A] = &aud_frddr_a.hw, - [AUD_CLKID_FRDDR_B] = &aud_frddr_b.hw, - [AUD_CLKID_FRDDR_C] = &aud_frddr_c.hw, - [AUD_CLKID_TODDR_A] = &aud_toddr_a.hw, - [AUD_CLKID_TODDR_B] = &aud_toddr_b.hw, - [AUD_CLKID_TODDR_C] = &aud_toddr_c.hw, - [AUD_CLKID_LOOPBACK] = &aud_loopback.hw, - [AUD_CLKID_SPDIFIN] = &aud_spdifin.hw, - [AUD_CLKID_SPDIFOUT] = &aud_spdifout.hw, - [AUD_CLKID_RESAMPLE] = &aud_resample.hw, - [AUD_CLKID_POWER_DETECT] = &aud_power_detect.hw, - [AUD_CLKID_MST_A_MCLK_SEL] = &aud_mst_a_mclk_sel.hw, - [AUD_CLKID_MST_B_MCLK_SEL] = &aud_mst_b_mclk_sel.hw, - [AUD_CLKID_MST_C_MCLK_SEL] = &aud_mst_c_mclk_sel.hw, - [AUD_CLKID_MST_D_MCLK_SEL] = &aud_mst_d_mclk_sel.hw, - [AUD_CLKID_MST_E_MCLK_SEL] = &aud_mst_e_mclk_sel.hw, - [AUD_CLKID_MST_F_MCLK_SEL] = &aud_mst_f_mclk_sel.hw, - [AUD_CLKID_MST_A_MCLK_DIV] = &aud_mst_a_mclk_div.hw, - [AUD_CLKID_MST_B_MCLK_DIV] = &aud_mst_b_mclk_div.hw, - [AUD_CLKID_MST_C_MCLK_DIV] = &aud_mst_c_mclk_div.hw, - [AUD_CLKID_MST_D_MCLK_DIV] = &aud_mst_d_mclk_div.hw, - [AUD_CLKID_MST_E_MCLK_DIV] = &aud_mst_e_mclk_div.hw, - [AUD_CLKID_MST_F_MCLK_DIV] = &aud_mst_f_mclk_div.hw, - [AUD_CLKID_MST_A_MCLK] = &aud_mst_a_mclk.hw, - [AUD_CLKID_MST_B_MCLK] = &aud_mst_b_mclk.hw, - [AUD_CLKID_MST_C_MCLK] = &aud_mst_c_mclk.hw, - [AUD_CLKID_MST_D_MCLK] = &aud_mst_d_mclk.hw, - [AUD_CLKID_MST_E_MCLK] = &aud_mst_e_mclk.hw, - [AUD_CLKID_MST_F_MCLK] = &aud_mst_f_mclk.hw, - [AUD_CLKID_SPDIFOUT_CLK_SEL] = &aud_spdifout_clk_sel.hw, - [AUD_CLKID_SPDIFOUT_CLK_DIV] = &aud_spdifout_clk_div.hw, - [AUD_CLKID_SPDIFOUT_CLK] = &aud_spdifout_clk.hw, - [AUD_CLKID_SPDIFIN_CLK_SEL] = &aud_spdifin_clk_sel.hw, - [AUD_CLKID_SPDIFIN_CLK_DIV] = &aud_spdifin_clk_div.hw, - [AUD_CLKID_SPDIFIN_CLK] = &aud_spdifin_clk.hw, - [AUD_CLKID_PDM_DCLK_SEL] = &aud_pdm_dclk_sel.hw, - [AUD_CLKID_PDM_DCLK_DIV] = &aud_pdm_dclk_div.hw, - [AUD_CLKID_PDM_DCLK] = &aud_pdm_dclk.hw, - [AUD_CLKID_PDM_SYSCLK_SEL] = &aud_pdm_sysclk_sel.hw, - [AUD_CLKID_PDM_SYSCLK_DIV] = &aud_pdm_sysclk_div.hw, - [AUD_CLKID_PDM_SYSCLK] = &aud_pdm_sysclk.hw, - [AUD_CLKID_MST_A_SCLK_PRE_EN] = &aud_mst_a_sclk_pre_en.hw, - [AUD_CLKID_MST_B_SCLK_PRE_EN] = &aud_mst_b_sclk_pre_en.hw, - [AUD_CLKID_MST_C_SCLK_PRE_EN] = &aud_mst_c_sclk_pre_en.hw, - [AUD_CLKID_MST_D_SCLK_PRE_EN] = &aud_mst_d_sclk_pre_en.hw, - [AUD_CLKID_MST_E_SCLK_PRE_EN] = &aud_mst_e_sclk_pre_en.hw, - [AUD_CLKID_MST_F_SCLK_PRE_EN] = &aud_mst_f_sclk_pre_en.hw, - [AUD_CLKID_MST_A_SCLK_DIV] = &aud_mst_a_sclk_div.hw, - [AUD_CLKID_MST_B_SCLK_DIV] = &aud_mst_b_sclk_div.hw, - [AUD_CLKID_MST_C_SCLK_DIV] = &aud_mst_c_sclk_div.hw, - [AUD_CLKID_MST_D_SCLK_DIV] = &aud_mst_d_sclk_div.hw, - [AUD_CLKID_MST_E_SCLK_DIV] = &aud_mst_e_sclk_div.hw, - [AUD_CLKID_MST_F_SCLK_DIV] = &aud_mst_f_sclk_div.hw, - [AUD_CLKID_MST_A_SCLK_POST_EN] = &aud_mst_a_sclk_post_en.hw, - [AUD_CLKID_MST_B_SCLK_POST_EN] = &aud_mst_b_sclk_post_en.hw, - [AUD_CLKID_MST_C_SCLK_POST_EN] = &aud_mst_c_sclk_post_en.hw, - [AUD_CLKID_MST_D_SCLK_POST_EN] = &aud_mst_d_sclk_post_en.hw, - [AUD_CLKID_MST_E_SCLK_POST_EN] = &aud_mst_e_sclk_post_en.hw, - [AUD_CLKID_MST_F_SCLK_POST_EN] = &aud_mst_f_sclk_post_en.hw, - [AUD_CLKID_MST_A_SCLK] = &aud_mst_a_sclk.hw, - [AUD_CLKID_MST_B_SCLK] = &aud_mst_b_sclk.hw, - [AUD_CLKID_MST_C_SCLK] = &aud_mst_c_sclk.hw, - [AUD_CLKID_MST_D_SCLK] = &aud_mst_d_sclk.hw, - [AUD_CLKID_MST_E_SCLK] = &aud_mst_e_sclk.hw, - [AUD_CLKID_MST_F_SCLK] = &aud_mst_f_sclk.hw, - [AUD_CLKID_MST_A_LRCLK_DIV] = &aud_mst_a_lrclk_div.hw, - [AUD_CLKID_MST_B_LRCLK_DIV] = &aud_mst_b_lrclk_div.hw, - [AUD_CLKID_MST_C_LRCLK_DIV] = &aud_mst_c_lrclk_div.hw, - [AUD_CLKID_MST_D_LRCLK_DIV] = &aud_mst_d_lrclk_div.hw, - [AUD_CLKID_MST_E_LRCLK_DIV] = &aud_mst_e_lrclk_div.hw, - [AUD_CLKID_MST_F_LRCLK_DIV] = &aud_mst_f_lrclk_div.hw, - [AUD_CLKID_MST_A_LRCLK] = &aud_mst_a_lrclk.hw, - [AUD_CLKID_MST_B_LRCLK] = &aud_mst_b_lrclk.hw, - [AUD_CLKID_MST_C_LRCLK] = &aud_mst_c_lrclk.hw, - [AUD_CLKID_MST_D_LRCLK] = &aud_mst_d_lrclk.hw, - [AUD_CLKID_MST_E_LRCLK] = &aud_mst_e_lrclk.hw, - [AUD_CLKID_MST_F_LRCLK] = &aud_mst_f_lrclk.hw, - [AUD_CLKID_TDMIN_A_SCLK_SEL] = &aud_tdmin_a_sclk_sel.hw, - [AUD_CLKID_TDMIN_B_SCLK_SEL] = &aud_tdmin_b_sclk_sel.hw, - [AUD_CLKID_TDMIN_C_SCLK_SEL] = &aud_tdmin_c_sclk_sel.hw, - [AUD_CLKID_TDMIN_LB_SCLK_SEL] = &aud_tdmin_lb_sclk_sel.hw, - [AUD_CLKID_TDMOUT_A_SCLK_SEL] = &aud_tdmout_a_sclk_sel.hw, - [AUD_CLKID_TDMOUT_B_SCLK_SEL] = &aud_tdmout_b_sclk_sel.hw, - [AUD_CLKID_TDMOUT_C_SCLK_SEL] = &aud_tdmout_c_sclk_sel.hw, - [AUD_CLKID_TDMIN_A_SCLK_PRE_EN] = &aud_tdmin_a_sclk_pre_en.hw, - [AUD_CLKID_TDMIN_B_SCLK_PRE_EN] = &aud_tdmin_b_sclk_pre_en.hw, - [AUD_CLKID_TDMIN_C_SCLK_PRE_EN] = &aud_tdmin_c_sclk_pre_en.hw, - [AUD_CLKID_TDMIN_LB_SCLK_PRE_EN] = &aud_tdmin_lb_sclk_pre_en.hw, - [AUD_CLKID_TDMOUT_A_SCLK_PRE_EN] = &aud_tdmout_a_sclk_pre_en.hw, - [AUD_CLKID_TDMOUT_B_SCLK_PRE_EN] = &aud_tdmout_b_sclk_pre_en.hw, - [AUD_CLKID_TDMOUT_C_SCLK_PRE_EN] = &aud_tdmout_c_sclk_pre_en.hw, - [AUD_CLKID_TDMIN_A_SCLK_POST_EN] = &aud_tdmin_a_sclk_post_en.hw, - [AUD_CLKID_TDMIN_B_SCLK_POST_EN] = &aud_tdmin_b_sclk_post_en.hw, - [AUD_CLKID_TDMIN_C_SCLK_POST_EN] = &aud_tdmin_c_sclk_post_en.hw, - [AUD_CLKID_TDMIN_LB_SCLK_POST_EN] = &aud_tdmin_lb_sclk_post_en.hw, - [AUD_CLKID_TDMOUT_A_SCLK_POST_EN] = &aud_tdmout_a_sclk_post_en.hw, - [AUD_CLKID_TDMOUT_B_SCLK_POST_EN] = &aud_tdmout_b_sclk_post_en.hw, - [AUD_CLKID_TDMOUT_C_SCLK_POST_EN] = &aud_tdmout_c_sclk_post_en.hw, - [AUD_CLKID_TDMIN_A_SCLK] = &aud_tdmin_a_sclk.hw, - [AUD_CLKID_TDMIN_B_SCLK] = &aud_tdmin_b_sclk.hw, - [AUD_CLKID_TDMIN_C_SCLK] = &aud_tdmin_c_sclk.hw, - [AUD_CLKID_TDMIN_LB_SCLK] = &aud_tdmin_lb_sclk.hw, - [AUD_CLKID_TDMOUT_A_SCLK] = &aud_tdmout_a_sclk.hw, - [AUD_CLKID_TDMOUT_B_SCLK] = &aud_tdmout_b_sclk.hw, - [AUD_CLKID_TDMOUT_C_SCLK] = &aud_tdmout_c_sclk.hw, - [AUD_CLKID_TDMIN_A_LRCLK] = &aud_tdmin_a_lrclk.hw, - [AUD_CLKID_TDMIN_B_LRCLK] = &aud_tdmin_b_lrclk.hw, - [AUD_CLKID_TDMIN_C_LRCLK] = &aud_tdmin_c_lrclk.hw, - [AUD_CLKID_TDMIN_LB_LRCLK] = &aud_tdmin_lb_lrclk.hw, - [AUD_CLKID_TDMOUT_A_LRCLK] = &aud_tdmout_a_lrclk.hw, - [AUD_CLKID_TDMOUT_B_LRCLK] = &aud_tdmout_b_lrclk.hw, - [AUD_CLKID_TDMOUT_C_LRCLK] = &aud_tdmout_c_lrclk.hw, + [AUD_CLKID_DDR_ARB] = &ddr_arb.hw, + [AUD_CLKID_PDM] = &pdm.hw, + [AUD_CLKID_TDMIN_A] = &tdmin_a.hw, + [AUD_CLKID_TDMIN_B] = &tdmin_b.hw, + [AUD_CLKID_TDMIN_C] = &tdmin_c.hw, + [AUD_CLKID_TDMIN_LB] = &tdmin_lb.hw, + [AUD_CLKID_TDMOUT_A] = &tdmout_a.hw, + [AUD_CLKID_TDMOUT_B] = &tdmout_b.hw, + [AUD_CLKID_TDMOUT_C] = &tdmout_c.hw, + [AUD_CLKID_FRDDR_A] = &frddr_a.hw, + [AUD_CLKID_FRDDR_B] = &frddr_b.hw, + [AUD_CLKID_FRDDR_C] = &frddr_c.hw, + [AUD_CLKID_TODDR_A] = &toddr_a.hw, + [AUD_CLKID_TODDR_B] = &toddr_b.hw, + [AUD_CLKID_TODDR_C] = &toddr_c.hw, + [AUD_CLKID_LOOPBACK] = &loopback.hw, + [AUD_CLKID_SPDIFIN] = &spdifin.hw, + [AUD_CLKID_SPDIFOUT] = &spdifout.hw, + [AUD_CLKID_RESAMPLE] = &resample.hw, + [AUD_CLKID_POWER_DETECT] = &power_detect.hw, + [AUD_CLKID_MST_A_MCLK_SEL] = &mst_a_mclk_sel.hw, + [AUD_CLKID_MST_B_MCLK_SEL] = &mst_b_mclk_sel.hw, + [AUD_CLKID_MST_C_MCLK_SEL] = &mst_c_mclk_sel.hw, + [AUD_CLKID_MST_D_MCLK_SEL] = &mst_d_mclk_sel.hw, + [AUD_CLKID_MST_E_MCLK_SEL] = &mst_e_mclk_sel.hw, + [AUD_CLKID_MST_F_MCLK_SEL] = &mst_f_mclk_sel.hw, + [AUD_CLKID_MST_A_MCLK_DIV] = &mst_a_mclk_div.hw, + [AUD_CLKID_MST_B_MCLK_DIV] = &mst_b_mclk_div.hw, + [AUD_CLKID_MST_C_MCLK_DIV] = &mst_c_mclk_div.hw, + [AUD_CLKID_MST_D_MCLK_DIV] = &mst_d_mclk_div.hw, + [AUD_CLKID_MST_E_MCLK_DIV] = &mst_e_mclk_div.hw, + [AUD_CLKID_MST_F_MCLK_DIV] = &mst_f_mclk_div.hw, + [AUD_CLKID_MST_A_MCLK] = &mst_a_mclk.hw, + [AUD_CLKID_MST_B_MCLK] = &mst_b_mclk.hw, + [AUD_CLKID_MST_C_MCLK] = &mst_c_mclk.hw, + [AUD_CLKID_MST_D_MCLK] = &mst_d_mclk.hw, + [AUD_CLKID_MST_E_MCLK] = &mst_e_mclk.hw, + [AUD_CLKID_MST_F_MCLK] = &mst_f_mclk.hw, + [AUD_CLKID_SPDIFOUT_CLK_SEL] = &spdifout_clk_sel.hw, + [AUD_CLKID_SPDIFOUT_CLK_DIV] = &spdifout_clk_div.hw, + [AUD_CLKID_SPDIFOUT_CLK] = &spdifout_clk.hw, + [AUD_CLKID_SPDIFIN_CLK_SEL] = &spdifin_clk_sel.hw, + [AUD_CLKID_SPDIFIN_CLK_DIV] = &spdifin_clk_div.hw, + [AUD_CLKID_SPDIFIN_CLK] = &spdifin_clk.hw, + [AUD_CLKID_PDM_DCLK_SEL] = &pdm_dclk_sel.hw, + [AUD_CLKID_PDM_DCLK_DIV] = &pdm_dclk_div.hw, + [AUD_CLKID_PDM_DCLK] = &pdm_dclk.hw, + [AUD_CLKID_PDM_SYSCLK_SEL] = &pdm_sysclk_sel.hw, + [AUD_CLKID_PDM_SYSCLK_DIV] = &pdm_sysclk_div.hw, + [AUD_CLKID_PDM_SYSCLK] = &pdm_sysclk.hw, + [AUD_CLKID_MST_A_SCLK_PRE_EN] = &mst_a_sclk_pre_en.hw, + [AUD_CLKID_MST_B_SCLK_PRE_EN] = &mst_b_sclk_pre_en.hw, + [AUD_CLKID_MST_C_SCLK_PRE_EN] = &mst_c_sclk_pre_en.hw, + [AUD_CLKID_MST_D_SCLK_PRE_EN] = &mst_d_sclk_pre_en.hw, + [AUD_CLKID_MST_E_SCLK_PRE_EN] = &mst_e_sclk_pre_en.hw, + [AUD_CLKID_MST_F_SCLK_PRE_EN] = &mst_f_sclk_pre_en.hw, + [AUD_CLKID_MST_A_SCLK_DIV] = &mst_a_sclk_div.hw, + [AUD_CLKID_MST_B_SCLK_DIV] = &mst_b_sclk_div.hw, + [AUD_CLKID_MST_C_SCLK_DIV] = &mst_c_sclk_div.hw, + [AUD_CLKID_MST_D_SCLK_DIV] = &mst_d_sclk_div.hw, + [AUD_CLKID_MST_E_SCLK_DIV] = &mst_e_sclk_div.hw, + [AUD_CLKID_MST_F_SCLK_DIV] = &mst_f_sclk_div.hw, + [AUD_CLKID_MST_A_SCLK_POST_EN] = &mst_a_sclk_post_en.hw, + [AUD_CLKID_MST_B_SCLK_POST_EN] = &mst_b_sclk_post_en.hw, + [AUD_CLKID_MST_C_SCLK_POST_EN] = &mst_c_sclk_post_en.hw, + [AUD_CLKID_MST_D_SCLK_POST_EN] = &mst_d_sclk_post_en.hw, + [AUD_CLKID_MST_E_SCLK_POST_EN] = &mst_e_sclk_post_en.hw, + [AUD_CLKID_MST_F_SCLK_POST_EN] = &mst_f_sclk_post_en.hw, + [AUD_CLKID_MST_A_SCLK] = &mst_a_sclk.hw, + [AUD_CLKID_MST_B_SCLK] = &mst_b_sclk.hw, + [AUD_CLKID_MST_C_SCLK] = &mst_c_sclk.hw, + [AUD_CLKID_MST_D_SCLK] = &mst_d_sclk.hw, + [AUD_CLKID_MST_E_SCLK] = &mst_e_sclk.hw, + [AUD_CLKID_MST_F_SCLK] = &mst_f_sclk.hw, + [AUD_CLKID_MST_A_LRCLK_DIV] = &mst_a_lrclk_div.hw, + [AUD_CLKID_MST_B_LRCLK_DIV] = &mst_b_lrclk_div.hw, + [AUD_CLKID_MST_C_LRCLK_DIV] = &mst_c_lrclk_div.hw, + [AUD_CLKID_MST_D_LRCLK_DIV] = &mst_d_lrclk_div.hw, + [AUD_CLKID_MST_E_LRCLK_DIV] = &mst_e_lrclk_div.hw, + [AUD_CLKID_MST_F_LRCLK_DIV] = &mst_f_lrclk_div.hw, + [AUD_CLKID_MST_A_LRCLK] = &mst_a_lrclk.hw, + [AUD_CLKID_MST_B_LRCLK] = &mst_b_lrclk.hw, + [AUD_CLKID_MST_C_LRCLK] = &mst_c_lrclk.hw, + [AUD_CLKID_MST_D_LRCLK] = &mst_d_lrclk.hw, + [AUD_CLKID_MST_E_LRCLK] = &mst_e_lrclk.hw, + [AUD_CLKID_MST_F_LRCLK] = &mst_f_lrclk.hw, + [AUD_CLKID_TDMIN_A_SCLK_SEL] = &tdmin_a_sclk_sel.hw, + [AUD_CLKID_TDMIN_B_SCLK_SEL] = &tdmin_b_sclk_sel.hw, + [AUD_CLKID_TDMIN_C_SCLK_SEL] = &tdmin_c_sclk_sel.hw, + [AUD_CLKID_TDMIN_LB_SCLK_SEL] = &tdmin_lb_sclk_sel.hw, + [AUD_CLKID_TDMOUT_A_SCLK_SEL] = &tdmout_a_sclk_sel.hw, + [AUD_CLKID_TDMOUT_B_SCLK_SEL] = &tdmout_b_sclk_sel.hw, + [AUD_CLKID_TDMOUT_C_SCLK_SEL] = &tdmout_c_sclk_sel.hw, + [AUD_CLKID_TDMIN_A_SCLK_PRE_EN] = &tdmin_a_sclk_pre_en.hw, + [AUD_CLKID_TDMIN_B_SCLK_PRE_EN] = &tdmin_b_sclk_pre_en.hw, + [AUD_CLKID_TDMIN_C_SCLK_PRE_EN] = &tdmin_c_sclk_pre_en.hw, + [AUD_CLKID_TDMIN_LB_SCLK_PRE_EN] = &tdmin_lb_sclk_pre_en.hw, + [AUD_CLKID_TDMOUT_A_SCLK_PRE_EN] = &tdmout_a_sclk_pre_en.hw, + [AUD_CLKID_TDMOUT_B_SCLK_PRE_EN] = &tdmout_b_sclk_pre_en.hw, + [AUD_CLKID_TDMOUT_C_SCLK_PRE_EN] = &tdmout_c_sclk_pre_en.hw, + [AUD_CLKID_TDMIN_A_SCLK_POST_EN] = &tdmin_a_sclk_post_en.hw, + [AUD_CLKID_TDMIN_B_SCLK_POST_EN] = &tdmin_b_sclk_post_en.hw, + [AUD_CLKID_TDMIN_C_SCLK_POST_EN] = &tdmin_c_sclk_post_en.hw, + [AUD_CLKID_TDMIN_LB_SCLK_POST_EN] = &tdmin_lb_sclk_post_en.hw, + [AUD_CLKID_TDMOUT_A_SCLK_POST_EN] = &tdmout_a_sclk_post_en.hw, + [AUD_CLKID_TDMOUT_B_SCLK_POST_EN] = &tdmout_b_sclk_post_en.hw, + [AUD_CLKID_TDMOUT_C_SCLK_POST_EN] = &tdmout_c_sclk_post_en.hw, + [AUD_CLKID_TDMIN_A_SCLK] = &tdmin_a_sclk.hw, + [AUD_CLKID_TDMIN_B_SCLK] = &tdmin_b_sclk.hw, + [AUD_CLKID_TDMIN_C_SCLK] = &tdmin_c_sclk.hw, + [AUD_CLKID_TDMIN_LB_SCLK] = &tdmin_lb_sclk.hw, + [AUD_CLKID_TDMOUT_A_SCLK] = &tdmout_a_sclk.hw, + [AUD_CLKID_TDMOUT_B_SCLK] = &tdmout_b_sclk.hw, + [AUD_CLKID_TDMOUT_C_SCLK] = &tdmout_c_sclk.hw, + [AUD_CLKID_TDMIN_A_LRCLK] = &tdmin_a_lrclk.hw, + [AUD_CLKID_TDMIN_B_LRCLK] = &tdmin_b_lrclk.hw, + [AUD_CLKID_TDMIN_C_LRCLK] = &tdmin_c_lrclk.hw, + [AUD_CLKID_TDMIN_LB_LRCLK] = &tdmin_lb_lrclk.hw, + [AUD_CLKID_TDMOUT_A_LRCLK] = &tdmout_a_lrclk.hw, + [AUD_CLKID_TDMOUT_B_LRCLK] = &tdmout_b_lrclk.hw, + [AUD_CLKID_TDMOUT_C_LRCLK] = &tdmout_c_lrclk.hw, + [AUD_CLKID_TOP] = &axg_aud_top, [NR_CLKS] = NULL, }, .num = NR_CLKS, @@ -609,284 +911,596 @@ static struct clk_hw_onecell_data axg_audio_hw_onecell_data = { */ static struct clk_hw_onecell_data g12a_audio_hw_onecell_data = { .hws = { - [AUD_CLKID_DDR_ARB] = &aud_ddr_arb.hw, - [AUD_CLKID_PDM] = &aud_pdm.hw, - [AUD_CLKID_TDMIN_A] = &aud_tdmin_a.hw, - [AUD_CLKID_TDMIN_B] = &aud_tdmin_b.hw, - [AUD_CLKID_TDMIN_C] = &aud_tdmin_c.hw, - [AUD_CLKID_TDMIN_LB] = &aud_tdmin_lb.hw, - [AUD_CLKID_TDMOUT_A] = &aud_tdmout_a.hw, - [AUD_CLKID_TDMOUT_B] = &aud_tdmout_b.hw, - [AUD_CLKID_TDMOUT_C] = &aud_tdmout_c.hw, - [AUD_CLKID_FRDDR_A] = &aud_frddr_a.hw, - [AUD_CLKID_FRDDR_B] = &aud_frddr_b.hw, - [AUD_CLKID_FRDDR_C] = &aud_frddr_c.hw, - [AUD_CLKID_TODDR_A] = &aud_toddr_a.hw, - [AUD_CLKID_TODDR_B] = &aud_toddr_b.hw, - [AUD_CLKID_TODDR_C] = &aud_toddr_c.hw, - [AUD_CLKID_LOOPBACK] = &aud_loopback.hw, - [AUD_CLKID_SPDIFIN] = &aud_spdifin.hw, - [AUD_CLKID_SPDIFOUT] = &aud_spdifout.hw, - [AUD_CLKID_RESAMPLE] = &aud_resample.hw, - [AUD_CLKID_POWER_DETECT] = &aud_power_detect.hw, - [AUD_CLKID_SPDIFOUT_B] = &aud_spdifout_b.hw, - [AUD_CLKID_MST_A_MCLK_SEL] = &aud_mst_a_mclk_sel.hw, - [AUD_CLKID_MST_B_MCLK_SEL] = &aud_mst_b_mclk_sel.hw, - [AUD_CLKID_MST_C_MCLK_SEL] = &aud_mst_c_mclk_sel.hw, - [AUD_CLKID_MST_D_MCLK_SEL] = &aud_mst_d_mclk_sel.hw, - [AUD_CLKID_MST_E_MCLK_SEL] = &aud_mst_e_mclk_sel.hw, - [AUD_CLKID_MST_F_MCLK_SEL] = &aud_mst_f_mclk_sel.hw, - [AUD_CLKID_MST_A_MCLK_DIV] = &aud_mst_a_mclk_div.hw, - [AUD_CLKID_MST_B_MCLK_DIV] = &aud_mst_b_mclk_div.hw, - [AUD_CLKID_MST_C_MCLK_DIV] = &aud_mst_c_mclk_div.hw, - [AUD_CLKID_MST_D_MCLK_DIV] = &aud_mst_d_mclk_div.hw, - [AUD_CLKID_MST_E_MCLK_DIV] = &aud_mst_e_mclk_div.hw, - [AUD_CLKID_MST_F_MCLK_DIV] = &aud_mst_f_mclk_div.hw, - [AUD_CLKID_MST_A_MCLK] = &aud_mst_a_mclk.hw, - [AUD_CLKID_MST_B_MCLK] = &aud_mst_b_mclk.hw, - [AUD_CLKID_MST_C_MCLK] = &aud_mst_c_mclk.hw, - [AUD_CLKID_MST_D_MCLK] = &aud_mst_d_mclk.hw, - [AUD_CLKID_MST_E_MCLK] = &aud_mst_e_mclk.hw, - [AUD_CLKID_MST_F_MCLK] = &aud_mst_f_mclk.hw, - [AUD_CLKID_SPDIFOUT_CLK_SEL] = &aud_spdifout_clk_sel.hw, - [AUD_CLKID_SPDIFOUT_CLK_DIV] = &aud_spdifout_clk_div.hw, - [AUD_CLKID_SPDIFOUT_CLK] = &aud_spdifout_clk.hw, - [AUD_CLKID_SPDIFOUT_B_CLK_SEL] = &aud_spdifout_b_clk_sel.hw, - [AUD_CLKID_SPDIFOUT_B_CLK_DIV] = &aud_spdifout_b_clk_div.hw, - [AUD_CLKID_SPDIFOUT_B_CLK] = &aud_spdifout_b_clk.hw, - [AUD_CLKID_SPDIFIN_CLK_SEL] = &aud_spdifin_clk_sel.hw, - [AUD_CLKID_SPDIFIN_CLK_DIV] = &aud_spdifin_clk_div.hw, - [AUD_CLKID_SPDIFIN_CLK] = &aud_spdifin_clk.hw, - [AUD_CLKID_PDM_DCLK_SEL] = &aud_pdm_dclk_sel.hw, - [AUD_CLKID_PDM_DCLK_DIV] = &aud_pdm_dclk_div.hw, - [AUD_CLKID_PDM_DCLK] = &aud_pdm_dclk.hw, - [AUD_CLKID_PDM_SYSCLK_SEL] = &aud_pdm_sysclk_sel.hw, - [AUD_CLKID_PDM_SYSCLK_DIV] = &aud_pdm_sysclk_div.hw, - [AUD_CLKID_PDM_SYSCLK] = &aud_pdm_sysclk.hw, - [AUD_CLKID_MST_A_SCLK_PRE_EN] = &aud_mst_a_sclk_pre_en.hw, - [AUD_CLKID_MST_B_SCLK_PRE_EN] = &aud_mst_b_sclk_pre_en.hw, - [AUD_CLKID_MST_C_SCLK_PRE_EN] = &aud_mst_c_sclk_pre_en.hw, - [AUD_CLKID_MST_D_SCLK_PRE_EN] = &aud_mst_d_sclk_pre_en.hw, - [AUD_CLKID_MST_E_SCLK_PRE_EN] = &aud_mst_e_sclk_pre_en.hw, - [AUD_CLKID_MST_F_SCLK_PRE_EN] = &aud_mst_f_sclk_pre_en.hw, - [AUD_CLKID_MST_A_SCLK_DIV] = &aud_mst_a_sclk_div.hw, - [AUD_CLKID_MST_B_SCLK_DIV] = &aud_mst_b_sclk_div.hw, - [AUD_CLKID_MST_C_SCLK_DIV] = &aud_mst_c_sclk_div.hw, - [AUD_CLKID_MST_D_SCLK_DIV] = &aud_mst_d_sclk_div.hw, - [AUD_CLKID_MST_E_SCLK_DIV] = &aud_mst_e_sclk_div.hw, - [AUD_CLKID_MST_F_SCLK_DIV] = &aud_mst_f_sclk_div.hw, - [AUD_CLKID_MST_A_SCLK_POST_EN] = &aud_mst_a_sclk_post_en.hw, - [AUD_CLKID_MST_B_SCLK_POST_EN] = &aud_mst_b_sclk_post_en.hw, - [AUD_CLKID_MST_C_SCLK_POST_EN] = &aud_mst_c_sclk_post_en.hw, - [AUD_CLKID_MST_D_SCLK_POST_EN] = &aud_mst_d_sclk_post_en.hw, - [AUD_CLKID_MST_E_SCLK_POST_EN] = &aud_mst_e_sclk_post_en.hw, - [AUD_CLKID_MST_F_SCLK_POST_EN] = &aud_mst_f_sclk_post_en.hw, - [AUD_CLKID_MST_A_SCLK] = &aud_mst_a_sclk.hw, - [AUD_CLKID_MST_B_SCLK] = &aud_mst_b_sclk.hw, - [AUD_CLKID_MST_C_SCLK] = &aud_mst_c_sclk.hw, - [AUD_CLKID_MST_D_SCLK] = &aud_mst_d_sclk.hw, - [AUD_CLKID_MST_E_SCLK] = &aud_mst_e_sclk.hw, - [AUD_CLKID_MST_F_SCLK] = &aud_mst_f_sclk.hw, - [AUD_CLKID_MST_A_LRCLK_DIV] = &aud_mst_a_lrclk_div.hw, - [AUD_CLKID_MST_B_LRCLK_DIV] = &aud_mst_b_lrclk_div.hw, - [AUD_CLKID_MST_C_LRCLK_DIV] = &aud_mst_c_lrclk_div.hw, - [AUD_CLKID_MST_D_LRCLK_DIV] = &aud_mst_d_lrclk_div.hw, - [AUD_CLKID_MST_E_LRCLK_DIV] = &aud_mst_e_lrclk_div.hw, - [AUD_CLKID_MST_F_LRCLK_DIV] = &aud_mst_f_lrclk_div.hw, - [AUD_CLKID_MST_A_LRCLK] = &aud_mst_a_lrclk.hw, - [AUD_CLKID_MST_B_LRCLK] = &aud_mst_b_lrclk.hw, - [AUD_CLKID_MST_C_LRCLK] = &aud_mst_c_lrclk.hw, - [AUD_CLKID_MST_D_LRCLK] = &aud_mst_d_lrclk.hw, - [AUD_CLKID_MST_E_LRCLK] = &aud_mst_e_lrclk.hw, - [AUD_CLKID_MST_F_LRCLK] = &aud_mst_f_lrclk.hw, - [AUD_CLKID_TDMIN_A_SCLK_SEL] = &aud_tdmin_a_sclk_sel.hw, - [AUD_CLKID_TDMIN_B_SCLK_SEL] = &aud_tdmin_b_sclk_sel.hw, - [AUD_CLKID_TDMIN_C_SCLK_SEL] = &aud_tdmin_c_sclk_sel.hw, - [AUD_CLKID_TDMIN_LB_SCLK_SEL] = &aud_tdmin_lb_sclk_sel.hw, - [AUD_CLKID_TDMOUT_A_SCLK_SEL] = &aud_tdmout_a_sclk_sel.hw, - [AUD_CLKID_TDMOUT_B_SCLK_SEL] = &aud_tdmout_b_sclk_sel.hw, - [AUD_CLKID_TDMOUT_C_SCLK_SEL] = &aud_tdmout_c_sclk_sel.hw, - [AUD_CLKID_TDMIN_A_SCLK_PRE_EN] = &aud_tdmin_a_sclk_pre_en.hw, - [AUD_CLKID_TDMIN_B_SCLK_PRE_EN] = &aud_tdmin_b_sclk_pre_en.hw, - [AUD_CLKID_TDMIN_C_SCLK_PRE_EN] = &aud_tdmin_c_sclk_pre_en.hw, - [AUD_CLKID_TDMIN_LB_SCLK_PRE_EN] = &aud_tdmin_lb_sclk_pre_en.hw, - [AUD_CLKID_TDMOUT_A_SCLK_PRE_EN] = &aud_tdmout_a_sclk_pre_en.hw, - [AUD_CLKID_TDMOUT_B_SCLK_PRE_EN] = &aud_tdmout_b_sclk_pre_en.hw, - [AUD_CLKID_TDMOUT_C_SCLK_PRE_EN] = &aud_tdmout_c_sclk_pre_en.hw, - [AUD_CLKID_TDMIN_A_SCLK_POST_EN] = &aud_tdmin_a_sclk_post_en.hw, - [AUD_CLKID_TDMIN_B_SCLK_POST_EN] = &aud_tdmin_b_sclk_post_en.hw, - [AUD_CLKID_TDMIN_C_SCLK_POST_EN] = &aud_tdmin_c_sclk_post_en.hw, - [AUD_CLKID_TDMIN_LB_SCLK_POST_EN] = &aud_tdmin_lb_sclk_post_en.hw, - [AUD_CLKID_TDMOUT_A_SCLK_POST_EN] = &aud_tdmout_a_sclk_post_en.hw, - [AUD_CLKID_TDMOUT_B_SCLK_POST_EN] = &aud_tdmout_b_sclk_post_en.hw, - [AUD_CLKID_TDMOUT_C_SCLK_POST_EN] = &aud_tdmout_c_sclk_post_en.hw, - [AUD_CLKID_TDMIN_A_SCLK] = &aud_tdmin_a_sclk.hw, - [AUD_CLKID_TDMIN_B_SCLK] = &aud_tdmin_b_sclk.hw, - [AUD_CLKID_TDMIN_C_SCLK] = &aud_tdmin_c_sclk.hw, - [AUD_CLKID_TDMIN_LB_SCLK] = &aud_tdmin_lb_sclk.hw, - [AUD_CLKID_TDMOUT_A_SCLK] = &aud_tdmout_a_sclk.hw, - [AUD_CLKID_TDMOUT_B_SCLK] = &aud_tdmout_b_sclk.hw, - [AUD_CLKID_TDMOUT_C_SCLK] = &aud_tdmout_c_sclk.hw, - [AUD_CLKID_TDMIN_A_LRCLK] = &aud_tdmin_a_lrclk.hw, - [AUD_CLKID_TDMIN_B_LRCLK] = &aud_tdmin_b_lrclk.hw, - [AUD_CLKID_TDMIN_C_LRCLK] = &aud_tdmin_c_lrclk.hw, - [AUD_CLKID_TDMIN_LB_LRCLK] = &aud_tdmin_lb_lrclk.hw, - [AUD_CLKID_TDMOUT_A_LRCLK] = &aud_tdmout_a_lrclk.hw, - [AUD_CLKID_TDMOUT_B_LRCLK] = &aud_tdmout_b_lrclk.hw, - [AUD_CLKID_TDMOUT_C_LRCLK] = &aud_tdmout_c_lrclk.hw, - [AUD_CLKID_TDM_MCLK_PAD0] = &aud_tdm_mclk_pad_0.hw, - [AUD_CLKID_TDM_MCLK_PAD1] = &aud_tdm_mclk_pad_1.hw, - [AUD_CLKID_TDM_LRCLK_PAD0] = &aud_tdm_lrclk_pad_0.hw, - [AUD_CLKID_TDM_LRCLK_PAD1] = &aud_tdm_lrclk_pad_1.hw, - [AUD_CLKID_TDM_LRCLK_PAD2] = &aud_tdm_lrclk_pad_2.hw, - [AUD_CLKID_TDM_SCLK_PAD0] = &aud_tdm_sclk_pad_0.hw, - [AUD_CLKID_TDM_SCLK_PAD1] = &aud_tdm_sclk_pad_1.hw, - [AUD_CLKID_TDM_SCLK_PAD2] = &aud_tdm_sclk_pad_2.hw, + [AUD_CLKID_DDR_ARB] = &ddr_arb.hw, + [AUD_CLKID_PDM] = &pdm.hw, + [AUD_CLKID_TDMIN_A] = &tdmin_a.hw, + [AUD_CLKID_TDMIN_B] = &tdmin_b.hw, + [AUD_CLKID_TDMIN_C] = &tdmin_c.hw, + [AUD_CLKID_TDMIN_LB] = &tdmin_lb.hw, + [AUD_CLKID_TDMOUT_A] = &tdmout_a.hw, + [AUD_CLKID_TDMOUT_B] = &tdmout_b.hw, + [AUD_CLKID_TDMOUT_C] = &tdmout_c.hw, + [AUD_CLKID_FRDDR_A] = &frddr_a.hw, + [AUD_CLKID_FRDDR_B] = &frddr_b.hw, + [AUD_CLKID_FRDDR_C] = &frddr_c.hw, + [AUD_CLKID_TODDR_A] = &toddr_a.hw, + [AUD_CLKID_TODDR_B] = &toddr_b.hw, + [AUD_CLKID_TODDR_C] = &toddr_c.hw, + [AUD_CLKID_LOOPBACK] = &loopback.hw, + [AUD_CLKID_SPDIFIN] = &spdifin.hw, + [AUD_CLKID_SPDIFOUT] = &spdifout.hw, + [AUD_CLKID_RESAMPLE] = &resample.hw, + [AUD_CLKID_POWER_DETECT] = &power_detect.hw, + [AUD_CLKID_SPDIFOUT_B] = &spdifout_b.hw, + [AUD_CLKID_MST_A_MCLK_SEL] = &mst_a_mclk_sel.hw, + [AUD_CLKID_MST_B_MCLK_SEL] = &mst_b_mclk_sel.hw, + [AUD_CLKID_MST_C_MCLK_SEL] = &mst_c_mclk_sel.hw, + [AUD_CLKID_MST_D_MCLK_SEL] = &mst_d_mclk_sel.hw, + [AUD_CLKID_MST_E_MCLK_SEL] = &mst_e_mclk_sel.hw, + [AUD_CLKID_MST_F_MCLK_SEL] = &mst_f_mclk_sel.hw, + [AUD_CLKID_MST_A_MCLK_DIV] = &mst_a_mclk_div.hw, + [AUD_CLKID_MST_B_MCLK_DIV] = &mst_b_mclk_div.hw, + [AUD_CLKID_MST_C_MCLK_DIV] = &mst_c_mclk_div.hw, + [AUD_CLKID_MST_D_MCLK_DIV] = &mst_d_mclk_div.hw, + [AUD_CLKID_MST_E_MCLK_DIV] = &mst_e_mclk_div.hw, + [AUD_CLKID_MST_F_MCLK_DIV] = &mst_f_mclk_div.hw, + [AUD_CLKID_MST_A_MCLK] = &mst_a_mclk.hw, + [AUD_CLKID_MST_B_MCLK] = &mst_b_mclk.hw, + [AUD_CLKID_MST_C_MCLK] = &mst_c_mclk.hw, + [AUD_CLKID_MST_D_MCLK] = &mst_d_mclk.hw, + [AUD_CLKID_MST_E_MCLK] = &mst_e_mclk.hw, + [AUD_CLKID_MST_F_MCLK] = &mst_f_mclk.hw, + [AUD_CLKID_SPDIFOUT_CLK_SEL] = &spdifout_clk_sel.hw, + [AUD_CLKID_SPDIFOUT_CLK_DIV] = &spdifout_clk_div.hw, + [AUD_CLKID_SPDIFOUT_CLK] = &spdifout_clk.hw, + [AUD_CLKID_SPDIFOUT_B_CLK_SEL] = &spdifout_b_clk_sel.hw, + [AUD_CLKID_SPDIFOUT_B_CLK_DIV] = &spdifout_b_clk_div.hw, + [AUD_CLKID_SPDIFOUT_B_CLK] = &spdifout_b_clk.hw, + [AUD_CLKID_SPDIFIN_CLK_SEL] = &spdifin_clk_sel.hw, + [AUD_CLKID_SPDIFIN_CLK_DIV] = &spdifin_clk_div.hw, + [AUD_CLKID_SPDIFIN_CLK] = &spdifin_clk.hw, + [AUD_CLKID_PDM_DCLK_SEL] = &pdm_dclk_sel.hw, + [AUD_CLKID_PDM_DCLK_DIV] = &pdm_dclk_div.hw, + [AUD_CLKID_PDM_DCLK] = &pdm_dclk.hw, + [AUD_CLKID_PDM_SYSCLK_SEL] = &pdm_sysclk_sel.hw, + [AUD_CLKID_PDM_SYSCLK_DIV] = &pdm_sysclk_div.hw, + [AUD_CLKID_PDM_SYSCLK] = &pdm_sysclk.hw, + [AUD_CLKID_MST_A_SCLK_PRE_EN] = &mst_a_sclk_pre_en.hw, + [AUD_CLKID_MST_B_SCLK_PRE_EN] = &mst_b_sclk_pre_en.hw, + [AUD_CLKID_MST_C_SCLK_PRE_EN] = &mst_c_sclk_pre_en.hw, + [AUD_CLKID_MST_D_SCLK_PRE_EN] = &mst_d_sclk_pre_en.hw, + [AUD_CLKID_MST_E_SCLK_PRE_EN] = &mst_e_sclk_pre_en.hw, + [AUD_CLKID_MST_F_SCLK_PRE_EN] = &mst_f_sclk_pre_en.hw, + [AUD_CLKID_MST_A_SCLK_DIV] = &mst_a_sclk_div.hw, + [AUD_CLKID_MST_B_SCLK_DIV] = &mst_b_sclk_div.hw, + [AUD_CLKID_MST_C_SCLK_DIV] = &mst_c_sclk_div.hw, + [AUD_CLKID_MST_D_SCLK_DIV] = &mst_d_sclk_div.hw, + [AUD_CLKID_MST_E_SCLK_DIV] = &mst_e_sclk_div.hw, + [AUD_CLKID_MST_F_SCLK_DIV] = &mst_f_sclk_div.hw, + [AUD_CLKID_MST_A_SCLK_POST_EN] = &mst_a_sclk_post_en.hw, + [AUD_CLKID_MST_B_SCLK_POST_EN] = &mst_b_sclk_post_en.hw, + [AUD_CLKID_MST_C_SCLK_POST_EN] = &mst_c_sclk_post_en.hw, + [AUD_CLKID_MST_D_SCLK_POST_EN] = &mst_d_sclk_post_en.hw, + [AUD_CLKID_MST_E_SCLK_POST_EN] = &mst_e_sclk_post_en.hw, + [AUD_CLKID_MST_F_SCLK_POST_EN] = &mst_f_sclk_post_en.hw, + [AUD_CLKID_MST_A_SCLK] = &mst_a_sclk.hw, + [AUD_CLKID_MST_B_SCLK] = &mst_b_sclk.hw, + [AUD_CLKID_MST_C_SCLK] = &mst_c_sclk.hw, + [AUD_CLKID_MST_D_SCLK] = &mst_d_sclk.hw, + [AUD_CLKID_MST_E_SCLK] = &mst_e_sclk.hw, + [AUD_CLKID_MST_F_SCLK] = &mst_f_sclk.hw, + [AUD_CLKID_MST_A_LRCLK_DIV] = &mst_a_lrclk_div.hw, + [AUD_CLKID_MST_B_LRCLK_DIV] = &mst_b_lrclk_div.hw, + [AUD_CLKID_MST_C_LRCLK_DIV] = &mst_c_lrclk_div.hw, + [AUD_CLKID_MST_D_LRCLK_DIV] = &mst_d_lrclk_div.hw, + [AUD_CLKID_MST_E_LRCLK_DIV] = &mst_e_lrclk_div.hw, + [AUD_CLKID_MST_F_LRCLK_DIV] = &mst_f_lrclk_div.hw, + [AUD_CLKID_MST_A_LRCLK] = &mst_a_lrclk.hw, + [AUD_CLKID_MST_B_LRCLK] = &mst_b_lrclk.hw, + [AUD_CLKID_MST_C_LRCLK] = &mst_c_lrclk.hw, + [AUD_CLKID_MST_D_LRCLK] = &mst_d_lrclk.hw, + [AUD_CLKID_MST_E_LRCLK] = &mst_e_lrclk.hw, + [AUD_CLKID_MST_F_LRCLK] = &mst_f_lrclk.hw, + [AUD_CLKID_TDMIN_A_SCLK_SEL] = &tdmin_a_sclk_sel.hw, + [AUD_CLKID_TDMIN_B_SCLK_SEL] = &tdmin_b_sclk_sel.hw, + [AUD_CLKID_TDMIN_C_SCLK_SEL] = &tdmin_c_sclk_sel.hw, + [AUD_CLKID_TDMIN_LB_SCLK_SEL] = &tdmin_lb_sclk_sel.hw, + [AUD_CLKID_TDMOUT_A_SCLK_SEL] = &tdmout_a_sclk_sel.hw, + [AUD_CLKID_TDMOUT_B_SCLK_SEL] = &tdmout_b_sclk_sel.hw, + [AUD_CLKID_TDMOUT_C_SCLK_SEL] = &tdmout_c_sclk_sel.hw, + [AUD_CLKID_TDMIN_A_SCLK_PRE_EN] = &tdmin_a_sclk_pre_en.hw, + [AUD_CLKID_TDMIN_B_SCLK_PRE_EN] = &tdmin_b_sclk_pre_en.hw, + [AUD_CLKID_TDMIN_C_SCLK_PRE_EN] = &tdmin_c_sclk_pre_en.hw, + [AUD_CLKID_TDMIN_LB_SCLK_PRE_EN] = &tdmin_lb_sclk_pre_en.hw, + [AUD_CLKID_TDMOUT_A_SCLK_PRE_EN] = &tdmout_a_sclk_pre_en.hw, + [AUD_CLKID_TDMOUT_B_SCLK_PRE_EN] = &tdmout_b_sclk_pre_en.hw, + [AUD_CLKID_TDMOUT_C_SCLK_PRE_EN] = &tdmout_c_sclk_pre_en.hw, + [AUD_CLKID_TDMIN_A_SCLK_POST_EN] = &tdmin_a_sclk_post_en.hw, + [AUD_CLKID_TDMIN_B_SCLK_POST_EN] = &tdmin_b_sclk_post_en.hw, + [AUD_CLKID_TDMIN_C_SCLK_POST_EN] = &tdmin_c_sclk_post_en.hw, + [AUD_CLKID_TDMIN_LB_SCLK_POST_EN] = &tdmin_lb_sclk_post_en.hw, + [AUD_CLKID_TDMOUT_A_SCLK_POST_EN] = &tdmout_a_sclk_post_en.hw, + [AUD_CLKID_TDMOUT_B_SCLK_POST_EN] = &tdmout_b_sclk_post_en.hw, + [AUD_CLKID_TDMOUT_C_SCLK_POST_EN] = &tdmout_c_sclk_post_en.hw, + [AUD_CLKID_TDMIN_A_SCLK] = &tdmin_a_sclk.hw, + [AUD_CLKID_TDMIN_B_SCLK] = &tdmin_b_sclk.hw, + [AUD_CLKID_TDMIN_C_SCLK] = &tdmin_c_sclk.hw, + [AUD_CLKID_TDMIN_LB_SCLK] = &tdmin_lb_sclk.hw, + [AUD_CLKID_TDMOUT_A_SCLK] = &tdmout_a_sclk.hw, + [AUD_CLKID_TDMOUT_B_SCLK] = &tdmout_b_sclk.hw, + [AUD_CLKID_TDMOUT_C_SCLK] = &tdmout_c_sclk.hw, + [AUD_CLKID_TDMIN_A_LRCLK] = &tdmin_a_lrclk.hw, + [AUD_CLKID_TDMIN_B_LRCLK] = &tdmin_b_lrclk.hw, + [AUD_CLKID_TDMIN_C_LRCLK] = &tdmin_c_lrclk.hw, + [AUD_CLKID_TDMIN_LB_LRCLK] = &tdmin_lb_lrclk.hw, + [AUD_CLKID_TDMOUT_A_LRCLK] = &tdmout_a_lrclk.hw, + [AUD_CLKID_TDMOUT_B_LRCLK] = &tdmout_b_lrclk.hw, + [AUD_CLKID_TDMOUT_C_LRCLK] = &tdmout_c_lrclk.hw, + [AUD_CLKID_TDM_MCLK_PAD0] = &g12a_tdm_mclk_pad_0.hw, + [AUD_CLKID_TDM_MCLK_PAD1] = &g12a_tdm_mclk_pad_1.hw, + [AUD_CLKID_TDM_LRCLK_PAD0] = &g12a_tdm_lrclk_pad_0.hw, + [AUD_CLKID_TDM_LRCLK_PAD1] = &g12a_tdm_lrclk_pad_1.hw, + [AUD_CLKID_TDM_LRCLK_PAD2] = &g12a_tdm_lrclk_pad_2.hw, + [AUD_CLKID_TDM_SCLK_PAD0] = &g12a_tdm_sclk_pad_0.hw, + [AUD_CLKID_TDM_SCLK_PAD1] = &g12a_tdm_sclk_pad_1.hw, + [AUD_CLKID_TDM_SCLK_PAD2] = &g12a_tdm_sclk_pad_2.hw, + [AUD_CLKID_TOP] = &axg_aud_top, [NR_CLKS] = NULL, }, .num = NR_CLKS, }; +/* + * Array of all SM1 clocks provided by this provider + * The input clocks of the controller will be populated at runtime + */ +static struct clk_hw_onecell_data sm1_audio_hw_onecell_data = { + .hws = { + [AUD_CLKID_DDR_ARB] = &ddr_arb.hw, + [AUD_CLKID_PDM] = &pdm.hw, + [AUD_CLKID_TDMIN_A] = &tdmin_a.hw, + [AUD_CLKID_TDMIN_B] = &tdmin_b.hw, + [AUD_CLKID_TDMIN_C] = &tdmin_c.hw, + [AUD_CLKID_TDMIN_LB] = &tdmin_lb.hw, + [AUD_CLKID_TDMOUT_A] = &tdmout_a.hw, + [AUD_CLKID_TDMOUT_B] = &tdmout_b.hw, + [AUD_CLKID_TDMOUT_C] = &tdmout_c.hw, + [AUD_CLKID_FRDDR_A] = &frddr_a.hw, + [AUD_CLKID_FRDDR_B] = &frddr_b.hw, + [AUD_CLKID_FRDDR_C] = &frddr_c.hw, + [AUD_CLKID_TODDR_A] = &toddr_a.hw, + [AUD_CLKID_TODDR_B] = &toddr_b.hw, + [AUD_CLKID_TODDR_C] = &toddr_c.hw, + [AUD_CLKID_LOOPBACK] = &loopback.hw, + [AUD_CLKID_SPDIFIN] = &spdifin.hw, + [AUD_CLKID_SPDIFOUT] = &spdifout.hw, + [AUD_CLKID_RESAMPLE] = &resample.hw, + [AUD_CLKID_SPDIFOUT_B] = &spdifout_b.hw, + [AUD_CLKID_MST_A_MCLK_SEL] = &sm1_mst_a_mclk_sel.hw, + [AUD_CLKID_MST_B_MCLK_SEL] = &sm1_mst_b_mclk_sel.hw, + [AUD_CLKID_MST_C_MCLK_SEL] = &sm1_mst_c_mclk_sel.hw, + [AUD_CLKID_MST_D_MCLK_SEL] = &sm1_mst_d_mclk_sel.hw, + [AUD_CLKID_MST_E_MCLK_SEL] = &sm1_mst_e_mclk_sel.hw, + [AUD_CLKID_MST_F_MCLK_SEL] = &sm1_mst_f_mclk_sel.hw, + [AUD_CLKID_MST_A_MCLK_DIV] = &sm1_mst_a_mclk_div.hw, + [AUD_CLKID_MST_B_MCLK_DIV] = &sm1_mst_b_mclk_div.hw, + [AUD_CLKID_MST_C_MCLK_DIV] = &sm1_mst_c_mclk_div.hw, + [AUD_CLKID_MST_D_MCLK_DIV] = &sm1_mst_d_mclk_div.hw, + [AUD_CLKID_MST_E_MCLK_DIV] = &sm1_mst_e_mclk_div.hw, + [AUD_CLKID_MST_F_MCLK_DIV] = &sm1_mst_f_mclk_div.hw, + [AUD_CLKID_MST_A_MCLK] = &sm1_mst_a_mclk.hw, + [AUD_CLKID_MST_B_MCLK] = &sm1_mst_b_mclk.hw, + [AUD_CLKID_MST_C_MCLK] = &sm1_mst_c_mclk.hw, + [AUD_CLKID_MST_D_MCLK] = &sm1_mst_d_mclk.hw, + [AUD_CLKID_MST_E_MCLK] = &sm1_mst_e_mclk.hw, + [AUD_CLKID_MST_F_MCLK] = &sm1_mst_f_mclk.hw, + [AUD_CLKID_SPDIFOUT_CLK_SEL] = &spdifout_clk_sel.hw, + [AUD_CLKID_SPDIFOUT_CLK_DIV] = &spdifout_clk_div.hw, + [AUD_CLKID_SPDIFOUT_CLK] = &spdifout_clk.hw, + [AUD_CLKID_SPDIFOUT_B_CLK_SEL] = &spdifout_b_clk_sel.hw, + [AUD_CLKID_SPDIFOUT_B_CLK_DIV] = &spdifout_b_clk_div.hw, + [AUD_CLKID_SPDIFOUT_B_CLK] = &spdifout_b_clk.hw, + [AUD_CLKID_SPDIFIN_CLK_SEL] = &spdifin_clk_sel.hw, + [AUD_CLKID_SPDIFIN_CLK_DIV] = &spdifin_clk_div.hw, + [AUD_CLKID_SPDIFIN_CLK] = &spdifin_clk.hw, + [AUD_CLKID_PDM_DCLK_SEL] = &pdm_dclk_sel.hw, + [AUD_CLKID_PDM_DCLK_DIV] = &pdm_dclk_div.hw, + [AUD_CLKID_PDM_DCLK] = &pdm_dclk.hw, + [AUD_CLKID_PDM_SYSCLK_SEL] = &pdm_sysclk_sel.hw, + [AUD_CLKID_PDM_SYSCLK_DIV] = &pdm_sysclk_div.hw, + [AUD_CLKID_PDM_SYSCLK] = &pdm_sysclk.hw, + [AUD_CLKID_MST_A_SCLK_PRE_EN] = &mst_a_sclk_pre_en.hw, + [AUD_CLKID_MST_B_SCLK_PRE_EN] = &mst_b_sclk_pre_en.hw, + [AUD_CLKID_MST_C_SCLK_PRE_EN] = &mst_c_sclk_pre_en.hw, + [AUD_CLKID_MST_D_SCLK_PRE_EN] = &mst_d_sclk_pre_en.hw, + [AUD_CLKID_MST_E_SCLK_PRE_EN] = &mst_e_sclk_pre_en.hw, + [AUD_CLKID_MST_F_SCLK_PRE_EN] = &mst_f_sclk_pre_en.hw, + [AUD_CLKID_MST_A_SCLK_DIV] = &mst_a_sclk_div.hw, + [AUD_CLKID_MST_B_SCLK_DIV] = &mst_b_sclk_div.hw, + [AUD_CLKID_MST_C_SCLK_DIV] = &mst_c_sclk_div.hw, + [AUD_CLKID_MST_D_SCLK_DIV] = &mst_d_sclk_div.hw, + [AUD_CLKID_MST_E_SCLK_DIV] = &mst_e_sclk_div.hw, + [AUD_CLKID_MST_F_SCLK_DIV] = &mst_f_sclk_div.hw, + [AUD_CLKID_MST_A_SCLK_POST_EN] = &mst_a_sclk_post_en.hw, + [AUD_CLKID_MST_B_SCLK_POST_EN] = &mst_b_sclk_post_en.hw, + [AUD_CLKID_MST_C_SCLK_POST_EN] = &mst_c_sclk_post_en.hw, + [AUD_CLKID_MST_D_SCLK_POST_EN] = &mst_d_sclk_post_en.hw, + [AUD_CLKID_MST_E_SCLK_POST_EN] = &mst_e_sclk_post_en.hw, + [AUD_CLKID_MST_F_SCLK_POST_EN] = &mst_f_sclk_post_en.hw, + [AUD_CLKID_MST_A_SCLK] = &mst_a_sclk.hw, + [AUD_CLKID_MST_B_SCLK] = &mst_b_sclk.hw, + [AUD_CLKID_MST_C_SCLK] = &mst_c_sclk.hw, + [AUD_CLKID_MST_D_SCLK] = &mst_d_sclk.hw, + [AUD_CLKID_MST_E_SCLK] = &mst_e_sclk.hw, + [AUD_CLKID_MST_F_SCLK] = &mst_f_sclk.hw, + [AUD_CLKID_MST_A_LRCLK_DIV] = &mst_a_lrclk_div.hw, + [AUD_CLKID_MST_B_LRCLK_DIV] = &mst_b_lrclk_div.hw, + [AUD_CLKID_MST_C_LRCLK_DIV] = &mst_c_lrclk_div.hw, + [AUD_CLKID_MST_D_LRCLK_DIV] = &mst_d_lrclk_div.hw, + [AUD_CLKID_MST_E_LRCLK_DIV] = &mst_e_lrclk_div.hw, + [AUD_CLKID_MST_F_LRCLK_DIV] = &mst_f_lrclk_div.hw, + [AUD_CLKID_MST_A_LRCLK] = &mst_a_lrclk.hw, + [AUD_CLKID_MST_B_LRCLK] = &mst_b_lrclk.hw, + [AUD_CLKID_MST_C_LRCLK] = &mst_c_lrclk.hw, + [AUD_CLKID_MST_D_LRCLK] = &mst_d_lrclk.hw, + [AUD_CLKID_MST_E_LRCLK] = &mst_e_lrclk.hw, + [AUD_CLKID_MST_F_LRCLK] = &mst_f_lrclk.hw, + [AUD_CLKID_TDMIN_A_SCLK_SEL] = &tdmin_a_sclk_sel.hw, + [AUD_CLKID_TDMIN_B_SCLK_SEL] = &tdmin_b_sclk_sel.hw, + [AUD_CLKID_TDMIN_C_SCLK_SEL] = &tdmin_c_sclk_sel.hw, + [AUD_CLKID_TDMIN_LB_SCLK_SEL] = &tdmin_lb_sclk_sel.hw, + [AUD_CLKID_TDMOUT_A_SCLK_SEL] = &tdmout_a_sclk_sel.hw, + [AUD_CLKID_TDMOUT_B_SCLK_SEL] = &tdmout_b_sclk_sel.hw, + [AUD_CLKID_TDMOUT_C_SCLK_SEL] = &tdmout_c_sclk_sel.hw, + [AUD_CLKID_TDMIN_A_SCLK_PRE_EN] = &tdmin_a_sclk_pre_en.hw, + [AUD_CLKID_TDMIN_B_SCLK_PRE_EN] = &tdmin_b_sclk_pre_en.hw, + [AUD_CLKID_TDMIN_C_SCLK_PRE_EN] = &tdmin_c_sclk_pre_en.hw, + [AUD_CLKID_TDMIN_LB_SCLK_PRE_EN] = &tdmin_lb_sclk_pre_en.hw, + [AUD_CLKID_TDMOUT_A_SCLK_PRE_EN] = &tdmout_a_sclk_pre_en.hw, + [AUD_CLKID_TDMOUT_B_SCLK_PRE_EN] = &tdmout_b_sclk_pre_en.hw, + [AUD_CLKID_TDMOUT_C_SCLK_PRE_EN] = &tdmout_c_sclk_pre_en.hw, + [AUD_CLKID_TDMIN_A_SCLK_POST_EN] = &tdmin_a_sclk_post_en.hw, + [AUD_CLKID_TDMIN_B_SCLK_POST_EN] = &tdmin_b_sclk_post_en.hw, + [AUD_CLKID_TDMIN_C_SCLK_POST_EN] = &tdmin_c_sclk_post_en.hw, + [AUD_CLKID_TDMIN_LB_SCLK_POST_EN] = &tdmin_lb_sclk_post_en.hw, + [AUD_CLKID_TDMOUT_A_SCLK_POST_EN] = &tdmout_a_sclk_post_en.hw, + [AUD_CLKID_TDMOUT_B_SCLK_POST_EN] = &tdmout_b_sclk_post_en.hw, + [AUD_CLKID_TDMOUT_C_SCLK_POST_EN] = &tdmout_c_sclk_post_en.hw, + [AUD_CLKID_TDMIN_A_SCLK] = &tdmin_a_sclk.hw, + [AUD_CLKID_TDMIN_B_SCLK] = &tdmin_b_sclk.hw, + [AUD_CLKID_TDMIN_C_SCLK] = &tdmin_c_sclk.hw, + [AUD_CLKID_TDMIN_LB_SCLK] = &tdmin_lb_sclk.hw, + [AUD_CLKID_TDMOUT_A_SCLK] = &tdmout_a_sclk.hw, + [AUD_CLKID_TDMOUT_B_SCLK] = &tdmout_b_sclk.hw, + [AUD_CLKID_TDMOUT_C_SCLK] = &tdmout_c_sclk.hw, + [AUD_CLKID_TDMIN_A_LRCLK] = &tdmin_a_lrclk.hw, + [AUD_CLKID_TDMIN_B_LRCLK] = &tdmin_b_lrclk.hw, + [AUD_CLKID_TDMIN_C_LRCLK] = &tdmin_c_lrclk.hw, + [AUD_CLKID_TDMIN_LB_LRCLK] = &tdmin_lb_lrclk.hw, + [AUD_CLKID_TDMOUT_A_LRCLK] = &tdmout_a_lrclk.hw, + [AUD_CLKID_TDMOUT_B_LRCLK] = &tdmout_b_lrclk.hw, + [AUD_CLKID_TDMOUT_C_LRCLK] = &tdmout_c_lrclk.hw, + [AUD_CLKID_TDM_MCLK_PAD0] = &sm1_tdm_mclk_pad_0.hw, + [AUD_CLKID_TDM_MCLK_PAD1] = &sm1_tdm_mclk_pad_1.hw, + [AUD_CLKID_TDM_LRCLK_PAD0] = &sm1_tdm_lrclk_pad_0.hw, + [AUD_CLKID_TDM_LRCLK_PAD1] = &sm1_tdm_lrclk_pad_1.hw, + [AUD_CLKID_TDM_LRCLK_PAD2] = &sm1_tdm_lrclk_pad_2.hw, + [AUD_CLKID_TDM_SCLK_PAD0] = &sm1_tdm_sclk_pad_0.hw, + [AUD_CLKID_TDM_SCLK_PAD1] = &sm1_tdm_sclk_pad_1.hw, + [AUD_CLKID_TDM_SCLK_PAD2] = &sm1_tdm_sclk_pad_2.hw, + [AUD_CLKID_TOP] = &sm1_aud_top.hw, + [AUD_CLKID_TORAM] = &toram.hw, + [AUD_CLKID_EQDRC] = &eqdrc.hw, + [AUD_CLKID_RESAMPLE_B] = &resample_b.hw, + [AUD_CLKID_TOVAD] = &tovad.hw, + [AUD_CLKID_LOCKER] = &locker.hw, + [AUD_CLKID_SPDIFIN_LB] = &spdifin_lb.hw, + [AUD_CLKID_FRDDR_D] = &frddr_d.hw, + [AUD_CLKID_TODDR_D] = &toddr_d.hw, + [AUD_CLKID_LOOPBACK_B] = &loopback_b.hw, + [AUD_CLKID_CLK81_EN] = &sm1_clk81_en.hw, + [AUD_CLKID_SYSCLK_A_DIV] = &sm1_sysclk_a_div.hw, + [AUD_CLKID_SYSCLK_A_EN] = &sm1_sysclk_a_en.hw, + [AUD_CLKID_SYSCLK_B_DIV] = &sm1_sysclk_b_div.hw, + [AUD_CLKID_SYSCLK_B_EN] = &sm1_sysclk_b_en.hw, + [NR_CLKS] = NULL, + }, + .num = NR_CLKS, +}; + + /* Convenience table to populate regmap in .probe() * Note that this table is shared between both AXG and G12A, * with spdifout_b clocks being exclusive to G12A. Since those * clocks are not declared within the AXG onecell table, we do not * feel the need to have separate AXG/G12A regmap tables. */ -static struct clk_regmap *const aud_clk_regmaps[] = { - &aud_ddr_arb, - &aud_pdm, - &aud_tdmin_a, - &aud_tdmin_b, - &aud_tdmin_c, - &aud_tdmin_lb, - &aud_tdmout_a, - &aud_tdmout_b, - &aud_tdmout_c, - &aud_frddr_a, - &aud_frddr_b, - &aud_frddr_c, - &aud_toddr_a, - &aud_toddr_b, - &aud_toddr_c, - &aud_loopback, - &aud_spdifin, - &aud_spdifout, - &aud_resample, - &aud_power_detect, - &aud_spdifout_b, - &aud_mst_a_mclk_sel, - &aud_mst_b_mclk_sel, - &aud_mst_c_mclk_sel, - &aud_mst_d_mclk_sel, - &aud_mst_e_mclk_sel, - &aud_mst_f_mclk_sel, - &aud_mst_a_mclk_div, - &aud_mst_b_mclk_div, - &aud_mst_c_mclk_div, - &aud_mst_d_mclk_div, - &aud_mst_e_mclk_div, - &aud_mst_f_mclk_div, - &aud_mst_a_mclk, - &aud_mst_b_mclk, - &aud_mst_c_mclk, - &aud_mst_d_mclk, - &aud_mst_e_mclk, - &aud_mst_f_mclk, - &aud_spdifout_clk_sel, - &aud_spdifout_clk_div, - &aud_spdifout_clk, - &aud_spdifin_clk_sel, - &aud_spdifin_clk_div, - &aud_spdifin_clk, - &aud_pdm_dclk_sel, - &aud_pdm_dclk_div, - &aud_pdm_dclk, - &aud_pdm_sysclk_sel, - &aud_pdm_sysclk_div, - &aud_pdm_sysclk, - &aud_mst_a_sclk_pre_en, - &aud_mst_b_sclk_pre_en, - &aud_mst_c_sclk_pre_en, - &aud_mst_d_sclk_pre_en, - &aud_mst_e_sclk_pre_en, - &aud_mst_f_sclk_pre_en, - &aud_mst_a_sclk_div, - &aud_mst_b_sclk_div, - &aud_mst_c_sclk_div, - &aud_mst_d_sclk_div, - &aud_mst_e_sclk_div, - &aud_mst_f_sclk_div, - &aud_mst_a_sclk_post_en, - &aud_mst_b_sclk_post_en, - &aud_mst_c_sclk_post_en, - &aud_mst_d_sclk_post_en, - &aud_mst_e_sclk_post_en, - &aud_mst_f_sclk_post_en, - &aud_mst_a_sclk, - &aud_mst_b_sclk, - &aud_mst_c_sclk, - &aud_mst_d_sclk, - &aud_mst_e_sclk, - &aud_mst_f_sclk, - &aud_mst_a_lrclk_div, - &aud_mst_b_lrclk_div, - &aud_mst_c_lrclk_div, - &aud_mst_d_lrclk_div, - &aud_mst_e_lrclk_div, - &aud_mst_f_lrclk_div, - &aud_mst_a_lrclk, - &aud_mst_b_lrclk, - &aud_mst_c_lrclk, - &aud_mst_d_lrclk, - &aud_mst_e_lrclk, - &aud_mst_f_lrclk, - &aud_tdmin_a_sclk_sel, - &aud_tdmin_b_sclk_sel, - &aud_tdmin_c_sclk_sel, - &aud_tdmin_lb_sclk_sel, - &aud_tdmout_a_sclk_sel, - &aud_tdmout_b_sclk_sel, - &aud_tdmout_c_sclk_sel, - &aud_tdmin_a_sclk_pre_en, - &aud_tdmin_b_sclk_pre_en, - &aud_tdmin_c_sclk_pre_en, - &aud_tdmin_lb_sclk_pre_en, - &aud_tdmout_a_sclk_pre_en, - &aud_tdmout_b_sclk_pre_en, - &aud_tdmout_c_sclk_pre_en, - &aud_tdmin_a_sclk_post_en, - &aud_tdmin_b_sclk_post_en, - &aud_tdmin_c_sclk_post_en, - &aud_tdmin_lb_sclk_post_en, - &aud_tdmout_a_sclk_post_en, - &aud_tdmout_b_sclk_post_en, - &aud_tdmout_c_sclk_post_en, - &aud_tdmin_a_sclk, - &aud_tdmin_b_sclk, - &aud_tdmin_c_sclk, - &aud_tdmin_lb_sclk, - &aud_tdmout_a_sclk, - &aud_tdmout_b_sclk, - &aud_tdmout_c_sclk, - &aud_tdmin_a_lrclk, - &aud_tdmin_b_lrclk, - &aud_tdmin_c_lrclk, - &aud_tdmin_lb_lrclk, - &aud_tdmout_a_lrclk, - &aud_tdmout_b_lrclk, - &aud_tdmout_c_lrclk, - &aud_spdifout_b_clk_sel, - &aud_spdifout_b_clk_div, - &aud_spdifout_b_clk, - &aud_tdm_mclk_pad_0, - &aud_tdm_mclk_pad_1, - &aud_tdm_lrclk_pad_0, - &aud_tdm_lrclk_pad_1, - &aud_tdm_lrclk_pad_2, - &aud_tdm_sclk_pad_0, - &aud_tdm_sclk_pad_1, - &aud_tdm_sclk_pad_2, +static struct clk_regmap *const axg_clk_regmaps[] = { + &ddr_arb, + &pdm, + &tdmin_a, + &tdmin_b, + &tdmin_c, + &tdmin_lb, + &tdmout_a, + &tdmout_b, + &tdmout_c, + &frddr_a, + &frddr_b, + &frddr_c, + &toddr_a, + &toddr_b, + &toddr_c, + &loopback, + &spdifin, + &spdifout, + &resample, + &power_detect, + &spdifout_b, + &mst_a_mclk_sel, + &mst_b_mclk_sel, + &mst_c_mclk_sel, + &mst_d_mclk_sel, + &mst_e_mclk_sel, + &mst_f_mclk_sel, + &mst_a_mclk_div, + &mst_b_mclk_div, + &mst_c_mclk_div, + &mst_d_mclk_div, + &mst_e_mclk_div, + &mst_f_mclk_div, + &mst_a_mclk, + &mst_b_mclk, + &mst_c_mclk, + &mst_d_mclk, + &mst_e_mclk, + &mst_f_mclk, + &spdifout_clk_sel, + &spdifout_clk_div, + &spdifout_clk, + &spdifin_clk_sel, + &spdifin_clk_div, + &spdifin_clk, + &pdm_dclk_sel, + &pdm_dclk_div, + &pdm_dclk, + &pdm_sysclk_sel, + &pdm_sysclk_div, + &pdm_sysclk, + &mst_a_sclk_pre_en, + &mst_b_sclk_pre_en, + &mst_c_sclk_pre_en, + &mst_d_sclk_pre_en, + &mst_e_sclk_pre_en, + &mst_f_sclk_pre_en, + &mst_a_sclk_div, + &mst_b_sclk_div, + &mst_c_sclk_div, + &mst_d_sclk_div, + &mst_e_sclk_div, + &mst_f_sclk_div, + &mst_a_sclk_post_en, + &mst_b_sclk_post_en, + &mst_c_sclk_post_en, + &mst_d_sclk_post_en, + &mst_e_sclk_post_en, + &mst_f_sclk_post_en, + &mst_a_sclk, + &mst_b_sclk, + &mst_c_sclk, + &mst_d_sclk, + &mst_e_sclk, + &mst_f_sclk, + &mst_a_lrclk_div, + &mst_b_lrclk_div, + &mst_c_lrclk_div, + &mst_d_lrclk_div, + &mst_e_lrclk_div, + &mst_f_lrclk_div, + &mst_a_lrclk, + &mst_b_lrclk, + &mst_c_lrclk, + &mst_d_lrclk, + &mst_e_lrclk, + &mst_f_lrclk, + &tdmin_a_sclk_sel, + &tdmin_b_sclk_sel, + &tdmin_c_sclk_sel, + &tdmin_lb_sclk_sel, + &tdmout_a_sclk_sel, + &tdmout_b_sclk_sel, + &tdmout_c_sclk_sel, + &tdmin_a_sclk_pre_en, + &tdmin_b_sclk_pre_en, + &tdmin_c_sclk_pre_en, + &tdmin_lb_sclk_pre_en, + &tdmout_a_sclk_pre_en, + &tdmout_b_sclk_pre_en, + &tdmout_c_sclk_pre_en, + &tdmin_a_sclk_post_en, + &tdmin_b_sclk_post_en, + &tdmin_c_sclk_post_en, + &tdmin_lb_sclk_post_en, + &tdmout_a_sclk_post_en, + &tdmout_b_sclk_post_en, + &tdmout_c_sclk_post_en, + &tdmin_a_sclk, + &tdmin_b_sclk, + &tdmin_c_sclk, + &tdmin_lb_sclk, + &tdmout_a_sclk, + &tdmout_b_sclk, + &tdmout_c_sclk, + &tdmin_a_lrclk, + &tdmin_b_lrclk, + &tdmin_c_lrclk, + &tdmin_lb_lrclk, + &tdmout_a_lrclk, + &tdmout_b_lrclk, + &tdmout_c_lrclk, + &spdifout_b_clk_sel, + &spdifout_b_clk_div, + &spdifout_b_clk, + &g12a_tdm_mclk_pad_0, + &g12a_tdm_mclk_pad_1, + &g12a_tdm_lrclk_pad_0, + &g12a_tdm_lrclk_pad_1, + &g12a_tdm_lrclk_pad_2, + &g12a_tdm_sclk_pad_0, + &g12a_tdm_sclk_pad_1, + &g12a_tdm_sclk_pad_2, + &toram, + &eqdrc, +}; + +static struct clk_regmap *const sm1_clk_regmaps[] = { + &ddr_arb, + &pdm, + &tdmin_a, + &tdmin_b, + &tdmin_c, + &tdmin_lb, + &tdmout_a, + &tdmout_b, + &tdmout_c, + &frddr_a, + &frddr_b, + &frddr_c, + &toddr_a, + &toddr_b, + &toddr_c, + &loopback, + &spdifin, + &spdifout, + &resample, + &spdifout_b, + &sm1_mst_a_mclk_sel, + &sm1_mst_b_mclk_sel, + &sm1_mst_c_mclk_sel, + &sm1_mst_d_mclk_sel, + &sm1_mst_e_mclk_sel, + &sm1_mst_f_mclk_sel, + &sm1_mst_a_mclk_div, + &sm1_mst_b_mclk_div, + &sm1_mst_c_mclk_div, + &sm1_mst_d_mclk_div, + &sm1_mst_e_mclk_div, + &sm1_mst_f_mclk_div, + &sm1_mst_a_mclk, + &sm1_mst_b_mclk, + &sm1_mst_c_mclk, + &sm1_mst_d_mclk, + &sm1_mst_e_mclk, + &sm1_mst_f_mclk, + &spdifout_clk_sel, + &spdifout_clk_div, + &spdifout_clk, + &spdifin_clk_sel, + &spdifin_clk_div, + &spdifin_clk, + &pdm_dclk_sel, + &pdm_dclk_div, + &pdm_dclk, + &pdm_sysclk_sel, + &pdm_sysclk_div, + &pdm_sysclk, + &mst_a_sclk_pre_en, + &mst_b_sclk_pre_en, + &mst_c_sclk_pre_en, + &mst_d_sclk_pre_en, + &mst_e_sclk_pre_en, + &mst_f_sclk_pre_en, + &mst_a_sclk_div, + &mst_b_sclk_div, + &mst_c_sclk_div, + &mst_d_sclk_div, + &mst_e_sclk_div, + &mst_f_sclk_div, + &mst_a_sclk_post_en, + &mst_b_sclk_post_en, + &mst_c_sclk_post_en, + &mst_d_sclk_post_en, + &mst_e_sclk_post_en, + &mst_f_sclk_post_en, + &mst_a_sclk, + &mst_b_sclk, + &mst_c_sclk, + &mst_d_sclk, + &mst_e_sclk, + &mst_f_sclk, + &mst_a_lrclk_div, + &mst_b_lrclk_div, + &mst_c_lrclk_div, + &mst_d_lrclk_div, + &mst_e_lrclk_div, + &mst_f_lrclk_div, + &mst_a_lrclk, + &mst_b_lrclk, + &mst_c_lrclk, + &mst_d_lrclk, + &mst_e_lrclk, + &mst_f_lrclk, + &tdmin_a_sclk_sel, + &tdmin_b_sclk_sel, + &tdmin_c_sclk_sel, + &tdmin_lb_sclk_sel, + &tdmout_a_sclk_sel, + &tdmout_b_sclk_sel, + &tdmout_c_sclk_sel, + &tdmin_a_sclk_pre_en, + &tdmin_b_sclk_pre_en, + &tdmin_c_sclk_pre_en, + &tdmin_lb_sclk_pre_en, + &tdmout_a_sclk_pre_en, + &tdmout_b_sclk_pre_en, + &tdmout_c_sclk_pre_en, + &tdmin_a_sclk_post_en, + &tdmin_b_sclk_post_en, + &tdmin_c_sclk_post_en, + &tdmin_lb_sclk_post_en, + &tdmout_a_sclk_post_en, + &tdmout_b_sclk_post_en, + &tdmout_c_sclk_post_en, + &tdmin_a_sclk, + &tdmin_b_sclk, + &tdmin_c_sclk, + &tdmin_lb_sclk, + &tdmout_a_sclk, + &tdmout_b_sclk, + &tdmout_c_sclk, + &tdmin_a_lrclk, + &tdmin_b_lrclk, + &tdmin_c_lrclk, + &tdmin_lb_lrclk, + &tdmout_a_lrclk, + &tdmout_b_lrclk, + &tdmout_c_lrclk, + &spdifout_b_clk_sel, + &spdifout_b_clk_div, + &spdifout_b_clk, + &sm1_tdm_mclk_pad_0, + &sm1_tdm_mclk_pad_1, + &sm1_tdm_lrclk_pad_0, + &sm1_tdm_lrclk_pad_1, + &sm1_tdm_lrclk_pad_2, + &sm1_tdm_sclk_pad_0, + &sm1_tdm_sclk_pad_1, + &sm1_tdm_sclk_pad_2, + &sm1_aud_top, + &toram, + &eqdrc, + &resample_b, + &tovad, + &locker, + &spdifin_lb, + &frddr_d, + &toddr_d, + &loopback_b, + &sm1_clk81_en, + &sm1_sysclk_a_div, + &sm1_sysclk_a_en, + &sm1_sysclk_b_div, + &sm1_sysclk_b_en, }; static int devm_clk_get_enable(struct device *dev, char *id) @@ -1001,10 +1615,12 @@ static const struct regmap_config axg_audio_regmap_cfg = { .reg_bits = 32, .val_bits = 32, .reg_stride = 4, - .max_register = AUDIO_CLK_PDMIN_CTRL1, + .max_register = AUDIO_CLK_SPDIFOUT_B_CTRL, }; struct audioclk_data { + struct clk_regmap *const *regmap_clks; + unsigned int regmap_clk_num; struct clk_hw_onecell_data *hw_onecell_data; unsigned int reset_offset; unsigned int reset_num; @@ -1016,7 +1632,6 @@ static int axg_audio_clkc_probe(struct platform_device *pdev) const struct audioclk_data *data; struct axg_audio_reset_data *rst; struct regmap *map; - struct resource *res; void __iomem *regs; struct clk_hw *hw; int ret, i; @@ -1025,8 +1640,7 @@ static int axg_audio_clkc_probe(struct platform_device *pdev) if (!data) return -EINVAL; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - regs = devm_ioremap_resource(dev, res); + regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(regs)) return PTR_ERR(regs); @@ -1048,8 +1662,8 @@ static int axg_audio_clkc_probe(struct platform_device *pdev) } /* Populate regmap for the regmap backed clocks */ - for (i = 0; i < ARRAY_SIZE(aud_clk_regmaps); i++) - aud_clk_regmaps[i]->map = map; + for (i = 0; i < data->regmap_clk_num; i++) + data->regmap_clks[i]->map = map; /* Take care to skip the registered input clocks */ for (i = AUD_CLKID_DDR_ARB; i < data->hw_onecell_data->num; i++) { @@ -1093,15 +1707,27 @@ static int axg_audio_clkc_probe(struct platform_device *pdev) } static const struct audioclk_data axg_audioclk_data = { + .regmap_clks = axg_clk_regmaps, + .regmap_clk_num = ARRAY_SIZE(axg_clk_regmaps), .hw_onecell_data = &axg_audio_hw_onecell_data, }; static const struct audioclk_data g12a_audioclk_data = { + .regmap_clks = axg_clk_regmaps, + .regmap_clk_num = ARRAY_SIZE(axg_clk_regmaps), .hw_onecell_data = &g12a_audio_hw_onecell_data, .reset_offset = AUDIO_SW_RESET, .reset_num = 26, }; +static const struct audioclk_data sm1_audioclk_data = { + .regmap_clks = sm1_clk_regmaps, + .regmap_clk_num = ARRAY_SIZE(sm1_clk_regmaps), + .hw_onecell_data = &sm1_audio_hw_onecell_data, + .reset_offset = AUDIO_SM1_SW_RESET0, + .reset_num = 39, +}; + static const struct of_device_id clkc_match_table[] = { { .compatible = "amlogic,axg-audio-clkc", @@ -1109,6 +1735,9 @@ static const struct of_device_id clkc_match_table[] = { }, { .compatible = "amlogic,g12a-audio-clkc", .data = &g12a_audioclk_data + }, { + .compatible = "amlogic,sm1-audio-clkc", + .data = &sm1_audioclk_data }, {} }; MODULE_DEVICE_TABLE(of, clkc_match_table); @@ -1122,6 +1751,6 @@ static struct platform_driver axg_audio_driver = { }; module_platform_driver(axg_audio_driver); -MODULE_DESCRIPTION("Amlogic AXG/G12A Audio Clock driver"); +MODULE_DESCRIPTION("Amlogic AXG/G12A/SM1 Audio Clock driver"); MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/meson/axg-audio.h b/drivers/clk/meson/axg-audio.h index c00e28b2e1a9..fd65a7d0704b 100644 --- a/drivers/clk/meson/axg-audio.h +++ b/drivers/clk/meson/axg-audio.h @@ -50,6 +50,20 @@ #define AUDIO_CLK_PDMIN_CTRL1 0x0B0 #define AUDIO_CLK_SPDIFOUT_B_CTRL 0x0B4 +/* SM1 introduce new register and some shifts :( */ +#define AUDIO_CLK_GATE_EN1 0x004 +#define AUDIO_SM1_MCLK_A_CTRL 0x008 +#define AUDIO_SM1_MCLK_B_CTRL 0x00C +#define AUDIO_SM1_MCLK_C_CTRL 0x010 +#define AUDIO_SM1_MCLK_D_CTRL 0x014 +#define AUDIO_SM1_MCLK_E_CTRL 0x018 +#define AUDIO_SM1_MCLK_F_CTRL 0x01C +#define AUDIO_SM1_MST_PAD_CTRL0 0x020 +#define AUDIO_SM1_MST_PAD_CTRL1 0x024 +#define AUDIO_SM1_SW_RESET0 0x028 +#define AUDIO_SM1_SW_RESET1 0x02C +#define AUDIO_CLK81_CTRL 0x030 +#define AUDIO_CLK81_EN 0x034 /* * CLKID index values * These indices are entirely contrived and do not map onto the hardware. @@ -115,10 +129,15 @@ #define AUD_CLKID_TDMOUT_C_SCLK_POST_EN 150 #define AUD_CLKID_SPDIFOUT_B_CLK_SEL 153 #define AUD_CLKID_SPDIFOUT_B_CLK_DIV 154 +#define AUD_CLKID_CLK81_EN 173 +#define AUD_CLKID_SYSCLK_A_DIV 174 +#define AUD_CLKID_SYSCLK_B_DIV 175 +#define AUD_CLKID_SYSCLK_A_EN 176 +#define AUD_CLKID_SYSCLK_B_EN 177 /* include the CLKIDs which are part of the DT bindings */ #include <dt-bindings/clock/axg-audio-clkc.h> -#define NR_CLKS 163 +#define NR_CLKS 178 #endif /*__AXG_AUDIO_CLKC_H */ diff --git a/drivers/clk/mvebu/ap-cpu-clk.c b/drivers/clk/mvebu/ap-cpu-clk.c index af5e5acad370..6b394302c76a 100644 --- a/drivers/clk/mvebu/ap-cpu-clk.c +++ b/drivers/clk/mvebu/ap-cpu-clk.c @@ -274,8 +274,8 @@ static int ap_cpu_clock_probe(struct platform_device *pdev) if (!ap_cpu_clk) return -ENOMEM; - ap_cpu_data = devm_kzalloc(dev, sizeof(*ap_cpu_data) + - sizeof(struct clk_hw *) * nclusters, + ap_cpu_data = devm_kzalloc(dev, struct_size(ap_cpu_data, hws, + nclusters), GFP_KERNEL); if (!ap_cpu_data) return -ENOMEM; diff --git a/drivers/clk/mvebu/armada-37xx-periph.c b/drivers/clk/mvebu/armada-37xx-periph.c index 5fc6d486a381..f5746f9ea929 100644 --- a/drivers/clk/mvebu/armada-37xx-periph.c +++ b/drivers/clk/mvebu/armada-37xx-periph.c @@ -303,6 +303,7 @@ PERIPH_CLK_GATE_DIV(gbe_bm, 12, DIV_SEL1, 0, clk_table1); PERIPH_CLK_FULL_DD(sdio, 11, 14, DIV_SEL0, DIV_SEL0, 3, 6); PERIPH_CLK_FULL_DD(usb32_usb2_sys, 16, 16, DIV_SEL0, DIV_SEL0, 9, 12); PERIPH_CLK_FULL_DD(usb32_ss_sys, 17, 18, DIV_SEL0, DIV_SEL0, 15, 18); +static PERIPH_GATE(pcie, 14); static struct clk_periph_data data_sb[] = { REF_CLK_MUX_DD(gbe_50), @@ -318,6 +319,7 @@ static struct clk_periph_data data_sb[] = { REF_CLK_FULL_DD(sdio), REF_CLK_FULL_DD(usb32_usb2_sys), REF_CLK_FULL_DD(usb32_ss_sys), + REF_CLK_GATE(pcie, "gbe_core"), { }, }; @@ -712,8 +714,8 @@ static int __maybe_unused armada_3700_periph_clock_resume(struct device *dev) } static const struct dev_pm_ops armada_3700_periph_clock_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(armada_3700_periph_clock_suspend, - armada_3700_periph_clock_resume) + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(armada_3700_periph_clock_suspend, + armada_3700_periph_clock_resume) }; static int armada_3700_periph_clock_probe(struct platform_device *pdev) diff --git a/drivers/clk/mvebu/armada-xp.c b/drivers/clk/mvebu/armada-xp.c index fa1568279c23..45665655a258 100644 --- a/drivers/clk/mvebu/armada-xp.c +++ b/drivers/clk/mvebu/armada-xp.c @@ -50,12 +50,6 @@ static u32 __init axp_get_tclk_freq(void __iomem *sar) return 250000000; } -/* MV98DX3236 TCLK frequency is fixed to 200MHz */ -static u32 __init mv98dx3236_get_tclk_freq(void __iomem *sar) -{ - return 200000000; -} - static const u32 axp_cpu_freqs[] __initconst = { 1000000000, 1066000000, @@ -93,12 +87,6 @@ static u32 __init axp_get_cpu_freq(void __iomem *sar) return cpu_freq; } -/* MV98DX3236 CLK frequency is fixed to 800MHz */ -static u32 __init mv98dx3236_get_cpu_freq(void __iomem *sar) -{ - return 800000000; -} - static const int axp_nbclk_ratios[32][2] __initconst = { {0, 1}, {1, 2}, {2, 2}, {2, 2}, {1, 2}, {1, 2}, {1, 1}, {2, 3}, @@ -168,11 +156,6 @@ static const struct coreclk_soc_desc axp_coreclks = { .num_ratios = ARRAY_SIZE(axp_coreclk_ratios), }; -static const struct coreclk_soc_desc mv98dx3236_coreclks = { - .get_tclk_freq = mv98dx3236_get_tclk_freq, - .get_cpu_freq = mv98dx3236_get_cpu_freq, -}; - /* * Clock Gating Control */ @@ -210,15 +193,6 @@ static const struct clk_gating_soc_desc axp_gating_desc[] __initconst = { { } }; -static const struct clk_gating_soc_desc mv98dx3236_gating_desc[] __initconst = { - { "ge1", NULL, 3, 0 }, - { "ge0", NULL, 4, 0 }, - { "pex00", NULL, 5, 0 }, - { "sdio", NULL, 17, 0 }, - { "xor0", NULL, 22, 0 }, - { } -}; - static void __init axp_clk_init(struct device_node *np) { struct device_node *cgnp = diff --git a/drivers/clk/mvebu/cp110-system-controller.c b/drivers/clk/mvebu/cp110-system-controller.c index 808463276145..84c8900542e4 100644 --- a/drivers/clk/mvebu/cp110-system-controller.c +++ b/drivers/clk/mvebu/cp110-system-controller.c @@ -235,8 +235,8 @@ static int cp110_syscon_common_probe(struct platform_device *pdev, if (ret) return ret; - cp110_clk_data = devm_kzalloc(dev, sizeof(*cp110_clk_data) + - sizeof(struct clk_hw *) * CP110_CLK_NUM, + cp110_clk_data = devm_kzalloc(dev, struct_size(cp110_clk_data, hws, + CP110_CLK_NUM), GFP_KERNEL); if (!cp110_clk_data) return -ENOMEM; diff --git a/drivers/clk/pxa/clk-pxa27x.c b/drivers/clk/pxa/clk-pxa27x.c index 287fdeae7c7c..7b123105b5de 100644 --- a/drivers/clk/pxa/clk-pxa27x.c +++ b/drivers/clk/pxa/clk-pxa27x.c @@ -459,6 +459,7 @@ struct dummy_clk { }; static struct dummy_clk dummy_clks[] __initdata = { DUMMY_CLK(NULL, "pxa27x-gpio", "osc_32_768khz"), + DUMMY_CLK(NULL, "pxa-rtc", "osc_32_768khz"), DUMMY_CLK(NULL, "sa1100-rtc", "osc_32_768khz"), DUMMY_CLK("UARTCLK", "pxa2xx-ir", "STUART"), }; diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 32dbb4f09492..3b33ef129274 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -220,6 +220,15 @@ config MSM_GCC_8998 Say Y if you want to use peripheral devices such as UART, SPI, i2c, USB, UFS, SD/eMMC, PCIe, etc. +config MSM_GPUCC_8998 + tristate "MSM8998 Graphics Clock Controller" + select MSM_GCC_8998 + select QCOM_GDSC + help + Support for the graphics clock controller on MSM8998 devices. + Say Y if you want to support graphics controller devices and + functionality such as 3D graphics. + config QCS_GCC_404 tristate "QCS404 Global Clock Controller" help @@ -227,6 +236,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_GCC_7180 + tristate "SC7180 Global Clock Controller" + select QCOM_GDSC + depends on COMMON_CLK_QCOM + help + Support for the global clock controller on SC7180 devices. + Say Y if you want to use peripheral devices such as UART, SPI, + I2C, USB, UFS, SDCC, etc. + config SDM_CAMCC_845 tristate "SDM845 Camera Clock Controller" select SDM_GCC_845 @@ -248,6 +266,14 @@ config QCS_TURING_404 Support for the Turing Clock Controller on QCS404, provides clocks and resets for the Turing subsystem. +config QCS_Q6SSTOP_404 + tristate "QCS404 Q6SSTOP Clock Controller" + select QCS_GCC_404 + help + Support for the Q6SSTOP clock controller on QCS404 devices. + Say Y if you want to use the Q6SSTOP branch clocks of the WCSS clock + controller to reset the Q6SSTOP subsystem. + config SDM_GCC_845 tristate "SDM845 Global Clock Controller" select QCOM_GDSC diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 4a813b4055d0..d899661d0f44 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -33,6 +33,7 @@ obj-$(CONFIG_MSM_GCC_8994) += gcc-msm8994.o obj-$(CONFIG_MSM_GCC_8996) += gcc-msm8996.o obj-$(CONFIG_MSM_LCC_8960) += lcc-msm8960.o obj-$(CONFIG_MSM_GCC_8998) += gcc-msm8998.o +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 @@ -42,7 +43,9 @@ obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o obj-$(CONFIG_QCOM_CLK_RPMH) += clk-rpmh.o 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_GCC_7180) += gcc-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/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h index c25b57c3cbc8..78358b81d249 100644 --- a/drivers/clk/qcom/clk-rcg.h +++ b/drivers/clk/qcom/clk-rcg.h @@ -168,7 +168,7 @@ struct clk_rcg_dfs_data { }; #define DEFINE_RCG_DFS(r) \ - { .rcg = &r##_src, .init = &r##_init } + { .rcg = &r, .init = &r##_init } extern int qcom_cc_register_rcg_dfs(struct regmap *regmap, const struct clk_rcg_dfs_data *rcgs, diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index b98b81ef43a1..8f4b9bec2956 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c @@ -206,7 +206,7 @@ static int _freq_tbl_determine_rate(struct clk_hw *hw, const struct freq_tbl *f, break; default: return -EINVAL; - }; + } if (!f) return -EINVAL; @@ -220,6 +220,8 @@ static int _freq_tbl_determine_rate(struct clk_hw *hw, const struct freq_tbl *f, if (clk_flags & CLK_SET_RATE_PARENT) { rate = f->freq; if (f->pre_div) { + if (!rate) + rate = req->rate; rate /= 2; rate *= f->pre_div + 1; } @@ -319,7 +321,7 @@ static int __clk_rcg2_set_rate(struct clk_hw *hw, unsigned long rate, break; default: return -EINVAL; - }; + } if (!f) return -EINVAL; diff --git a/drivers/clk/qcom/clk-rpmh.c b/drivers/clk/qcom/clk-rpmh.c index 96a36f6ff667..2dbbe47e8d4f 100644 --- a/drivers/clk/qcom/clk-rpmh.c +++ b/drivers/clk/qcom/clk-rpmh.c @@ -334,13 +334,14 @@ static const struct clk_ops clk_rpmh_bcm_ops = { .recalc_rate = clk_rpmh_bcm_recalc_rate, }; -/* Resource name must match resource id present in cmd-db. */ +/* Resource name must match resource id present in cmd-db */ DEFINE_CLK_RPMH_ARC(sdm845, bi_tcxo, bi_tcxo_ao, "xo.lvl", 0x3, 2); DEFINE_CLK_RPMH_VRM(sdm845, ln_bb_clk2, ln_bb_clk2_ao, "lnbclka2", 2); DEFINE_CLK_RPMH_VRM(sdm845, ln_bb_clk3, ln_bb_clk3_ao, "lnbclka3", 2); DEFINE_CLK_RPMH_VRM(sdm845, rf_clk1, rf_clk1_ao, "rfclka1", 1); DEFINE_CLK_RPMH_VRM(sdm845, rf_clk2, rf_clk2_ao, "rfclka2", 1); DEFINE_CLK_RPMH_VRM(sdm845, rf_clk3, rf_clk3_ao, "rfclka3", 1); +DEFINE_CLK_RPMH_VRM(sm8150, rf_clk3, rf_clk3_ao, "rfclka3", 1); DEFINE_CLK_RPMH_BCM(sdm845, ipa, "IP0"); static struct clk_hw *sdm845_rpmh_clocks[] = { @@ -364,26 +365,19 @@ static const struct clk_rpmh_desc clk_rpmh_sdm845 = { .num_clks = ARRAY_SIZE(sdm845_rpmh_clocks), }; -DEFINE_CLK_RPMH_ARC(sm8150, bi_tcxo, bi_tcxo_ao, "xo.lvl", 0x3, 2); -DEFINE_CLK_RPMH_VRM(sm8150, ln_bb_clk2, ln_bb_clk2_ao, "lnbclka2", 2); -DEFINE_CLK_RPMH_VRM(sm8150, ln_bb_clk3, ln_bb_clk3_ao, "lnbclka3", 2); -DEFINE_CLK_RPMH_VRM(sm8150, rf_clk1, rf_clk1_ao, "rfclka1", 1); -DEFINE_CLK_RPMH_VRM(sm8150, rf_clk2, rf_clk2_ao, "rfclka2", 1); -DEFINE_CLK_RPMH_VRM(sm8150, rf_clk3, rf_clk3_ao, "rfclka3", 1); - static struct clk_hw *sm8150_rpmh_clocks[] = { - [RPMH_CXO_CLK] = &sm8150_bi_tcxo.hw, - [RPMH_CXO_CLK_A] = &sm8150_bi_tcxo_ao.hw, - [RPMH_LN_BB_CLK2] = &sm8150_ln_bb_clk2.hw, - [RPMH_LN_BB_CLK2_A] = &sm8150_ln_bb_clk2_ao.hw, - [RPMH_LN_BB_CLK3] = &sm8150_ln_bb_clk3.hw, - [RPMH_LN_BB_CLK3_A] = &sm8150_ln_bb_clk3_ao.hw, - [RPMH_RF_CLK1] = &sm8150_rf_clk1.hw, - [RPMH_RF_CLK1_A] = &sm8150_rf_clk1_ao.hw, - [RPMH_RF_CLK2] = &sm8150_rf_clk2.hw, - [RPMH_RF_CLK2_A] = &sm8150_rf_clk2_ao.hw, - [RPMH_RF_CLK3] = &sm8150_rf_clk3.hw, - [RPMH_RF_CLK3_A] = &sm8150_rf_clk3_ao.hw, + [RPMH_CXO_CLK] = &sdm845_bi_tcxo.hw, + [RPMH_CXO_CLK_A] = &sdm845_bi_tcxo_ao.hw, + [RPMH_LN_BB_CLK2] = &sdm845_ln_bb_clk2.hw, + [RPMH_LN_BB_CLK2_A] = &sdm845_ln_bb_clk2_ao.hw, + [RPMH_LN_BB_CLK3] = &sdm845_ln_bb_clk3.hw, + [RPMH_LN_BB_CLK3_A] = &sdm845_ln_bb_clk3_ao.hw, + [RPMH_RF_CLK1] = &sdm845_rf_clk1.hw, + [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_RF_CLK3] = &sdm845_rf_clk3.hw, + [RPMH_RF_CLK3_A] = &sdm845_rf_clk3_ao.hw, }; static const struct clk_rpmh_desc clk_rpmh_sm8150 = { @@ -391,6 +385,24 @@ static const struct clk_rpmh_desc clk_rpmh_sm8150 = { .num_clks = ARRAY_SIZE(sm8150_rpmh_clocks), }; +static struct clk_hw *sc7180_rpmh_clocks[] = { + [RPMH_CXO_CLK] = &sdm845_bi_tcxo.hw, + [RPMH_CXO_CLK_A] = &sdm845_bi_tcxo_ao.hw, + [RPMH_LN_BB_CLK2] = &sdm845_ln_bb_clk2.hw, + [RPMH_LN_BB_CLK2_A] = &sdm845_ln_bb_clk2_ao.hw, + [RPMH_LN_BB_CLK3] = &sdm845_ln_bb_clk3.hw, + [RPMH_LN_BB_CLK3_A] = &sdm845_ln_bb_clk3_ao.hw, + [RPMH_RF_CLK1] = &sdm845_rf_clk1.hw, + [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, +}; + +static const struct clk_rpmh_desc clk_rpmh_sc7180 = { + .clks = sc7180_rpmh_clocks, + .num_clks = ARRAY_SIZE(sc7180_rpmh_clocks), +}; + static struct clk_hw *of_clk_rpmh_hw_get(struct of_phandle_args *clkspec, void *data) { @@ -471,6 +483,7 @@ static int clk_rpmh_probe(struct platform_device *pdev) static const struct of_device_id clk_rpmh_match_table[] = { { .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 fef5e8157061..930fa4a4c52a 100644 --- a/drivers/clk/qcom/clk-smd-rpm.c +++ b/drivers/clk/qcom/clk-smd-rpm.c @@ -648,6 +648,7 @@ static const struct rpm_smd_clk_desc rpm_clk_qcs404 = { }; /* msm8998 */ +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); DEFINE_CLK_SMD_RPM(msm8998, ce1_clk, ce1_a_clk, QCOM_SMD_RPM_CE_CLK, 0); @@ -670,6 +671,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_PCNOC_CLK] = &msm8998_pcnoc_clk, + [RPM_SMD_PCNOC_A_CLK] = &msm8998_pcnoc_a_clk, [RPM_SMD_SNOC_CLK] = &msm8998_snoc_clk, [RPM_SMD_SNOC_A_CLK] = &msm8998_snoc_a_clk, [RPM_SMD_CNOC_CLK] = &msm8998_cnoc_clk, diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c index 28ddc747d703..60d2a78d1395 100644 --- a/drivers/clk/qcom/common.c +++ b/drivers/clk/qcom/common.c @@ -29,6 +29,9 @@ struct freq_tbl *qcom_find_freq(const struct freq_tbl *f, unsigned long rate) if (!f) return NULL; + if (!f->freq) + return f; + for (; f->freq; f++) if (rate <= f->freq) return f; @@ -218,7 +221,7 @@ static struct clk_hw *qcom_cc_clk_hw_get(struct of_phandle_args *clkspec, return ERR_PTR(-EINVAL); } - return cc->rclks[idx] ? &cc->rclks[idx]->hw : ERR_PTR(-ENOENT); + return cc->rclks[idx] ? &cc->rclks[idx]->hw : NULL; } int qcom_cc_really_probe(struct platform_device *pdev, diff --git a/drivers/clk/qcom/gcc-msm8998.c b/drivers/clk/qcom/gcc-msm8998.c index 091acd59c1d6..cf31b5d03270 100644 --- a/drivers/clk/qcom/gcc-msm8998.c +++ b/drivers/clk/qcom/gcc-msm8998.c @@ -1266,6 +1266,72 @@ static struct clk_branch gcc_bimc_mss_q6_axi_clk = { }, }; +static struct clk_branch gcc_mss_cfg_ahb_clk = { + .halt_reg = 0x8a000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8a000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mss_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mss_snoc_axi_clk = { + .halt_reg = 0x8a03c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8a03c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mss_snoc_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mss_mnoc_bimc_axi_clk = { + .halt_reg = 0x8a004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8a004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mss_mnoc_bimc_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_boot_rom_ahb_clk = { + .halt_reg = 0x38004, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x38004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52004, + .enable_mask = BIT(10), + .hw.init = &(struct clk_init_data){ + .name = "gcc_boot_rom_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mss_gpll0_div_clk_src = { + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mss_gpll0_div_clk_src", + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_branch gcc_blsp1_ahb_clk = { .halt_reg = 0x17004, .halt_check = BRANCH_HALT_VOTED, @@ -2832,6 +2898,11 @@ static struct clk_regmap *gcc_msm8998_clocks[] = { [GCC_USB3_CLKREF_CLK] = &gcc_usb3_clkref_clk.clkr, [GCC_PCIE_CLKREF_CLK] = &gcc_pcie_clkref_clk.clkr, [GCC_RX1_USB2_CLKREF_CLK] = &gcc_rx1_usb2_clkref_clk.clkr, + [GCC_MSS_CFG_AHB_CLK] = &gcc_mss_cfg_ahb_clk.clkr, + [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr, + [GCC_MSS_GPLL0_DIV_CLK_SRC] = &gcc_mss_gpll0_div_clk_src.clkr, + [GCC_MSS_SNOC_AXI_CLK] = &gcc_mss_snoc_axi_clk.clkr, + [GCC_MSS_MNOC_BIMC_AXI_CLK] = &gcc_mss_mnoc_bimc_axi_clk.clkr, }; static struct gdsc *gcc_msm8998_gdscs[] = { @@ -2928,6 +2999,7 @@ static const struct qcom_reset_map gcc_msm8998_resets[] = { [GCC_GPU_BCR] = { 0x71000 }, [GCC_SPSS_BCR] = { 0x72000 }, [GCC_OBT_ODT_BCR] = { 0x73000 }, + [GCC_MSS_RESTART] = { 0x79000 }, [GCC_VS_BCR] = { 0x7a000 }, [GCC_MSS_VS_RESET] = { 0x7a100 }, [GCC_GPU_VS_RESET] = { 0x7a104 }, diff --git a/drivers/clk/qcom/gcc-sc7180.c b/drivers/clk/qcom/gcc-sc7180.c new file mode 100644 index 000000000000..38424e63bcae --- /dev/null +++ b/drivers/clk/qcom/gcc-sc7180.c @@ -0,0 +1,2450 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + */ + +#include <linux/clk-provider.h> +#include <linux/err.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/regmap.h> + +#include <dt-bindings/clock/qcom,gcc-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" +#include "reset.h" + +enum { + P_BI_TCXO, + P_CORE_BI_PLL_TEST_SE, + P_GPLL0_OUT_EVEN, + P_GPLL0_OUT_MAIN, + P_GPLL1_OUT_MAIN, + P_GPLL4_OUT_MAIN, + P_GPLL6_OUT_MAIN, + P_GPLL7_OUT_MAIN, + P_SLEEP_CLK, +}; + +static struct clk_alpha_pll gpll0 = { + .offset = 0x0, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpll0", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + .name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_fabia_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_gpll0_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv gpll0_out_even = { + .offset = 0x0, + .post_div_shift = 8, + .post_div_table = post_div_table_gpll0_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_gpll0_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpll0_out_even", + .parent_data = &(const struct clk_parent_data){ + .hw = &gpll0.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_fabia_ops, + }, +}; + +static struct clk_fixed_factor gcc_pll0_main_div_cdiv = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data){ + .name = "gcc_pll0_main_div_cdiv", + .parent_data = &(const struct clk_parent_data){ + .hw = &gpll0.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_fixed_factor_ops, + }, +}; + +static struct clk_alpha_pll gpll1 = { + .offset = 0x01000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(1), + .hw.init = &(struct clk_init_data){ + .name = "gpll1", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + .name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_fabia_ops, + }, + }, +}; + +static struct clk_alpha_pll gpll4 = { + .offset = 0x76000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gpll4", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + .name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_fabia_ops, + }, + }, +}; + +static struct clk_alpha_pll gpll6 = { + .offset = 0x13000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(6), + .hw.init = &(struct clk_init_data){ + .name = "gpll6", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + .name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_fabia_ops, + }, + }, +}; + +static struct clk_alpha_pll gpll7 = { + .offset = 0x27000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(7), + .hw.init = &(struct clk_init_data){ + .name = "gpll7", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + .name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_fabia_ops, + }, + }, +}; + +static const struct parent_map gcc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_GPLL0_OUT_EVEN, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const struct clk_parent_data gcc_parent_data_0[] = { + { .fw_name = "bi_tcxo", .name = "bi_tcxo" }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll0_out_even.clkr.hw }, + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, +}; + +static const struct clk_parent_data gcc_parent_data_0_ao[] = { + { .fw_name = "bi_tcxo_ao", .name = "bi_tcxo_ao" }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll0_out_even.clkr.hw }, + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, +}; + +static const struct parent_map gcc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_GPLL6_OUT_MAIN, 2 }, + { P_GPLL0_OUT_EVEN, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const struct clk_parent_data gcc_parent_data_1[] = { + { .fw_name = "bi_tcxo", .name = "bi_tcxo" }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll6.clkr.hw }, + { .hw = &gpll0_out_even.clkr.hw }, + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, +}; + +static const struct parent_map gcc_parent_map_2[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_GPLL1_OUT_MAIN, 4 }, + { P_GPLL4_OUT_MAIN, 5 }, + { P_GPLL0_OUT_EVEN, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const struct clk_parent_data gcc_parent_data_2[] = { + { .fw_name = "bi_tcxo", .name = "bi_tcxo" }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll1.clkr.hw }, + { .hw = &gpll4.clkr.hw }, + { .hw = &gpll0_out_even.clkr.hw }, + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, +}; + +static const struct parent_map gcc_parent_map_3[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const struct clk_parent_data gcc_parent_data_3[] = { + { .fw_name = "bi_tcxo", .name = "bi_tcxo" }, + { .hw = &gpll0.clkr.hw }, + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, +}; + +static const struct parent_map gcc_parent_map_4[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_SLEEP_CLK, 5 }, + { P_GPLL0_OUT_EVEN, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const struct clk_parent_data gcc_parent_data_4[] = { + { .fw_name = "bi_tcxo", .name = "bi_tcxo" }, + { .hw = &gpll0.clkr.hw }, + { .fw_name = "sleep_clk", .name = "sleep_clk" }, + { .hw = &gpll0_out_even.clkr.hw }, + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, +}; + +static const struct parent_map gcc_parent_map_5[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_GPLL7_OUT_MAIN, 3 }, + { P_GPLL0_OUT_EVEN, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const struct clk_parent_data gcc_parent_data_5[] = { + { .fw_name = "bi_tcxo", .name = "bi_tcxo" }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll7.clkr.hw }, + { .hw = &gpll0_out_even.clkr.hw }, + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, +}; + +static const struct parent_map gcc_parent_map_6[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_SLEEP_CLK, 5 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const struct clk_parent_data gcc_parent_data_6[] = { + { .fw_name = "bi_tcxo", .name = "bi_tcxo" }, + { .hw = &gpll0.clkr.hw }, + { .fw_name = "sleep_clk", .name = "sleep_clk" }, + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, +}; + +static const struct freq_tbl ftbl_gcc_cpuss_ahb_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_cpuss_ahb_clk_src = { + .cmd_rcgr = 0x48014, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_cpuss_ahb_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_cpuss_ahb_clk_src", + .parent_data = gcc_parent_data_0_ao, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_gp1_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(25000000, P_GPLL0_OUT_EVEN, 12, 0, 0), + F(50000000, P_GPLL0_OUT_EVEN, 6, 0, 0), + F(100000000, P_GPLL0_OUT_EVEN, 3, 0, 0), + F(200000000, P_GPLL0_OUT_EVEN, 1.5, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_gp1_clk_src = { + .cmd_rcgr = 0x64004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_4, + .freq_tbl = ftbl_gcc_gp1_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_gp1_clk_src", + .parent_data = gcc_parent_data_4, + .num_parents = 5, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_gp2_clk_src = { + .cmd_rcgr = 0x65004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_4, + .freq_tbl = ftbl_gcc_gp1_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_gp2_clk_src", + .parent_data = gcc_parent_data_4, + .num_parents = 5, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_gp3_clk_src = { + .cmd_rcgr = 0x66004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_4, + .freq_tbl = ftbl_gcc_gp1_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_gp3_clk_src", + .parent_data = gcc_parent_data_4, + .num_parents = 5, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_pdm2_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(60000000, P_GPLL0_OUT_EVEN, 5, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_pdm2_clk_src = { + .cmd_rcgr = 0x33010, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pdm2_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_pdm2_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_qspi_core_clk_src[] = { + F(75000000, P_GPLL0_OUT_EVEN, 4, 0, 0), + F(150000000, P_GPLL0_OUT_EVEN, 2, 0, 0), + F(300000000, P_GPLL0_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_qspi_core_clk_src = { + .cmd_rcgr = 0x4b00c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gcc_qspi_core_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_qspi_core_clk_src", + .parent_data = gcc_parent_data_2, + .num_parents = 6, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = { + F(7372800, P_GPLL0_OUT_EVEN, 1, 384, 15625), + F(14745600, P_GPLL0_OUT_EVEN, 1, 768, 15625), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(29491200, P_GPLL0_OUT_EVEN, 1, 1536, 15625), + F(32000000, P_GPLL0_OUT_EVEN, 1, 8, 75), + F(48000000, P_GPLL0_OUT_EVEN, 1, 4, 25), + F(64000000, P_GPLL0_OUT_EVEN, 1, 16, 75), + F(75000000, P_GPLL0_OUT_EVEN, 4, 0, 0), + F(80000000, P_GPLL0_OUT_EVEN, 1, 4, 15), + F(96000000, P_GPLL0_OUT_EVEN, 1, 8, 25), + F(100000000, P_GPLL0_OUT_EVEN, 3, 0, 0), + F(102400000, P_GPLL0_OUT_EVEN, 1, 128, 375), + F(112000000, P_GPLL0_OUT_EVEN, 1, 28, 75), + F(117964800, P_GPLL0_OUT_EVEN, 1, 6144, 15625), + F(120000000, P_GPLL0_OUT_EVEN, 2.5, 0, 0), + F(128000000, P_GPLL6_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_init_data gcc_qupv3_wrap0_s0_clk_src_init = { + .name = "gcc_qupv3_wrap0_s0_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 4, + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s0_clk_src = { + .cmd_rcgr = 0x17034, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap0_s0_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s1_clk_src_init = { + .name = "gcc_qupv3_wrap0_s1_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 4, + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s1_clk_src = { + .cmd_rcgr = 0x17164, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap0_s1_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s2_clk_src_init = { + .name = "gcc_qupv3_wrap0_s2_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 4, + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s2_clk_src = { + .cmd_rcgr = 0x17294, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap0_s2_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s3_clk_src_init = { + .name = "gcc_qupv3_wrap0_s3_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 4, + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s3_clk_src = { + .cmd_rcgr = 0x173c4, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap0_s3_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s4_clk_src_init = { + .name = "gcc_qupv3_wrap0_s4_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 4, + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s4_clk_src = { + .cmd_rcgr = 0x174f4, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap0_s4_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s5_clk_src_init = { + .name = "gcc_qupv3_wrap0_s5_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 4, + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s5_clk_src = { + .cmd_rcgr = 0x17624, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap0_s5_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s0_clk_src_init = { + .name = "gcc_qupv3_wrap1_s0_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 4, + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s0_clk_src = { + .cmd_rcgr = 0x18018, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s0_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s1_clk_src_init = { + .name = "gcc_qupv3_wrap1_s1_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 4, + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s1_clk_src = { + .cmd_rcgr = 0x18148, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s1_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s2_clk_src_init = { + .name = "gcc_qupv3_wrap1_s2_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 4, + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s2_clk_src = { + .cmd_rcgr = 0x18278, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s2_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s3_clk_src_init = { + .name = "gcc_qupv3_wrap1_s3_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 4, + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s3_clk_src = { + .cmd_rcgr = 0x183a8, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s3_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s4_clk_src_init = { + .name = "gcc_qupv3_wrap1_s4_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 4, + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s4_clk_src = { + .cmd_rcgr = 0x184d8, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s4_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s5_clk_src_init = { + .name = "gcc_qupv3_wrap1_s5_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 4, + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s5_clk_src = { + .cmd_rcgr = 0x18608, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s5_clk_src_init, +}; + + +static const struct freq_tbl ftbl_gcc_sdcc1_apps_clk_src[] = { + F(144000, P_BI_TCXO, 16, 3, 25), + F(400000, P_BI_TCXO, 12, 1, 4), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(20000000, P_GPLL0_OUT_EVEN, 5, 1, 3), + F(25000000, P_GPLL0_OUT_EVEN, 6, 1, 2), + F(50000000, P_GPLL0_OUT_EVEN, 6, 0, 0), + F(100000000, P_GPLL0_OUT_EVEN, 3, 0, 0), + F(192000000, P_GPLL6_OUT_MAIN, 2, 0, 0), + F(384000000, P_GPLL6_OUT_MAIN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_sdcc1_apps_clk_src = { + .cmd_rcgr = 0x12028, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_sdcc1_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_apps_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = 5, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_sdcc1_ice_core_clk_src[] = { + F(100000000, P_GPLL0_OUT_EVEN, 3, 0, 0), + F(150000000, P_GPLL0_OUT_EVEN, 2, 0, 0), + F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), + F(300000000, P_GPLL0_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_sdcc1_ice_core_clk_src = { + .cmd_rcgr = 0x12010, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_sdcc1_ice_core_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_ice_core_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src[] = { + F(400000, P_BI_TCXO, 12, 1, 4), + F(9600000, P_BI_TCXO, 2, 0, 0), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(25000000, P_GPLL0_OUT_EVEN, 12, 0, 0), + F(100000000, P_GPLL0_OUT_EVEN, 3, 0, 0), + F(202000000, P_GPLL7_OUT_MAIN, 4, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { + .cmd_rcgr = 0x1400c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_5, + .freq_tbl = ftbl_gcc_sdcc2_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc2_apps_clk_src", + .parent_data = gcc_parent_data_5, + .num_parents = 5, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_ufs_phy_axi_clk_src[] = { + F(25000000, P_GPLL0_OUT_EVEN, 12, 0, 0), + F(50000000, P_GPLL0_OUT_EVEN, 6, 0, 0), + F(100000000, P_GPLL0_OUT_EVEN, 3, 0, 0), + F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), + F(240000000, P_GPLL0_OUT_MAIN, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_ufs_phy_axi_clk_src = { + .cmd_rcgr = 0x77020, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_ufs_phy_axi_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_axi_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_ufs_phy_ice_core_clk_src[] = { + F(37500000, P_GPLL0_OUT_EVEN, 8, 0, 0), + F(75000000, P_GPLL0_OUT_EVEN, 4, 0, 0), + F(150000000, P_GPLL0_OUT_EVEN, 2, 0, 0), + F(300000000, P_GPLL0_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_ufs_phy_ice_core_clk_src = { + .cmd_rcgr = 0x77048, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_ufs_phy_ice_core_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_ice_core_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_ufs_phy_phy_aux_clk_src[] = { + F(9600000, P_BI_TCXO, 2, 0, 0), + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_ufs_phy_phy_aux_clk_src = { + .cmd_rcgr = 0x77098, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_3, + .freq_tbl = ftbl_gcc_ufs_phy_phy_aux_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_phy_aux_clk_src", + .parent_data = gcc_parent_data_3, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_ufs_phy_unipro_core_clk_src[] = { + F(37500000, P_GPLL0_OUT_EVEN, 8, 0, 0), + F(75000000, P_GPLL0_OUT_EVEN, 4, 0, 0), + F(150000000, P_GPLL0_OUT_EVEN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_ufs_phy_unipro_core_clk_src = { + .cmd_rcgr = 0x77060, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_ufs_phy_unipro_core_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_unipro_core_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_usb30_prim_master_clk_src[] = { + F(66666667, P_GPLL0_OUT_EVEN, 4.5, 0, 0), + F(133333333, P_GPLL0_OUT_MAIN, 4.5, 0, 0), + F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), + F(240000000, P_GPLL0_OUT_MAIN, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_usb30_prim_master_clk_src = { + .cmd_rcgr = 0xf01c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_usb30_prim_master_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_prim_master_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_usb30_prim_mock_utmi_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(20000000, P_GPLL0_OUT_EVEN, 15, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_usb30_prim_mock_utmi_clk_src = { + .cmd_rcgr = 0xf034, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_usb30_prim_mock_utmi_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_prim_mock_utmi_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_usb3_prim_phy_aux_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_usb3_prim_phy_aux_clk_src = { + .cmd_rcgr = 0xf060, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_6, + .freq_tbl = ftbl_gcc_usb3_prim_phy_aux_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_prim_phy_aux_clk_src", + .parent_data = gcc_parent_data_6, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch gcc_aggre_ufs_phy_axi_clk = { + .halt_reg = 0x82024, + .halt_check = BRANCH_HALT_DELAY, + .hwcg_reg = 0x82024, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x82024, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_aggre_ufs_phy_axi_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_ufs_phy_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_aggre_usb3_prim_axi_clk = { + .halt_reg = 0x8201c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8201c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_aggre_usb3_prim_axi_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_usb30_prim_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_boot_rom_ahb_clk = { + .halt_reg = 0x38004, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x38004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(10), + .hw.init = &(struct clk_init_data){ + .name = "gcc_boot_rom_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camera_ahb_clk = { + .halt_reg = 0xb008, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0xb008, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xb008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camera_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camera_hf_axi_clk = { + .halt_reg = 0xb020, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb020, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camera_hf_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camera_throttle_hf_axi_clk = { + .halt_reg = 0xb080, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0xb080, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xb080, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camera_throttle_hf_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camera_xo_clk = { + .halt_reg = 0xb02c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb02c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camera_xo_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ce1_ahb_clk = { + .halt_reg = 0x4100c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x4100c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(3), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ce1_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ce1_axi_clk = { + .halt_reg = 0x41008, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ce1_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ce1_clk = { + .halt_reg = 0x41004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(5), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ce1_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cfg_noc_usb3_prim_axi_clk = { + .halt_reg = 0x502c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x502c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_cfg_noc_usb3_prim_axi_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_usb30_prim_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +/* For CPUSS functionality the AHB clock needs to be left enabled */ +static struct clk_branch gcc_cpuss_ahb_clk = { + .halt_reg = 0x48000, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(21), + .hw.init = &(struct clk_init_data){ + .name = "gcc_cpuss_ahb_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_cpuss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cpuss_rbcpr_clk = { + .halt_reg = 0x48008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x48008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_cpuss_rbcpr_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ddrss_gpu_axi_clk = { + .halt_reg = 0x4452c, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x4452c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ddrss_gpu_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_disp_gpll0_clk_src = { + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(18), + .hw.init = &(struct clk_init_data){ + .name = "gcc_disp_gpll0_clk_src", + .parent_data = &(const struct clk_parent_data){ + .hw = &gpll0.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_disp_gpll0_div_clk_src = { + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(19), + .hw.init = &(struct clk_init_data){ + .name = "gcc_disp_gpll0_div_clk_src", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_pll0_main_div_cdiv.hw, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_disp_hf_axi_clk = { + .halt_reg = 0xb024, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb024, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_disp_hf_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_disp_throttle_hf_axi_clk = { + .halt_reg = 0xb084, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0xb084, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xb084, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_disp_throttle_hf_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_disp_xo_clk = { + .halt_reg = 0xb030, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb030, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_disp_xo_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp1_clk = { + .halt_reg = 0x64000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x64000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gp1_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_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 = 0x65000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x65000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gp2_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_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 = 0x66000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x66000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gp3_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_gp3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_gpll0_clk_src = { + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(15), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gpu_gpll0_clk_src", + .parent_data = &(const struct clk_parent_data){ + .hw = &gpll0.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_gpll0_div_clk_src = { + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(16), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gpu_gpll0_div_clk_src", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_pll0_main_div_cdiv.hw, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_memnoc_gfx_clk = { + .halt_reg = 0x7100c, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x7100c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gpu_memnoc_gfx_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_snoc_dvm_gfx_clk = { + .halt_reg = 0x71018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x71018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gpu_snoc_dvm_gfx_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_npu_axi_clk = { + .halt_reg = 0x4d008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4d008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_npu_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_npu_bwmon_axi_clk = { + .halt_reg = 0x73008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x73008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_npu_bwmon_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_npu_bwmon_dma_cfg_ahb_clk = { + .halt_reg = 0x73018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x73018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_npu_bwmon_dma_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_npu_bwmon_dsp_cfg_ahb_clk = { + .halt_reg = 0x7301c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x7301c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_npu_bwmon_dsp_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_npu_cfg_ahb_clk = { + .halt_reg = 0x4d004, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x4d004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x4d004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_npu_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_npu_dma_clk = { + .halt_reg = 0x4d1a0, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x4d1a0, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x4d1a0, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_npu_dma_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_npu_gpll0_clk_src = { + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(25), + .hw.init = &(struct clk_init_data){ + .name = "gcc_npu_gpll0_clk_src", + .parent_data = &(const struct clk_parent_data){ + .hw = &gpll0.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_npu_gpll0_div_clk_src = { + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(26), + .hw.init = &(struct clk_init_data){ + .name = "gcc_npu_gpll0_div_clk_src", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_pll0_main_div_cdiv.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pdm2_clk = { + .halt_reg = 0x3300c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3300c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pdm2_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_pdm2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pdm_ahb_clk = { + .halt_reg = 0x33004, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x33004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x33004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pdm_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pdm_xo4_clk = { + .halt_reg = 0x33008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x33008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pdm_xo4_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_prng_ahb_clk = { + .halt_reg = 0x34004, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x34004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(13), + .hw.init = &(struct clk_init_data){ + .name = "gcc_prng_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qspi_cnoc_periph_ahb_clk = { + .halt_reg = 0x4b004, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x4b004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x4b004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qspi_cnoc_periph_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qspi_core_clk = { + .halt_reg = 0x4b008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4b008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qspi_core_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_qspi_core_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_core_2x_clk = { + .halt_reg = 0x17014, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_core_2x_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_core_clk = { + .halt_reg = 0x1700c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(8), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_core_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s0_clk = { + .halt_reg = 0x17030, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(10), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_s0_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_qupv3_wrap0_s0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s1_clk = { + .halt_reg = 0x17160, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_s1_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_qupv3_wrap0_s1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s2_clk = { + .halt_reg = 0x17290, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(12), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_s2_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_qupv3_wrap0_s2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s3_clk = { + .halt_reg = 0x173c0, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(13), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_s3_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_qupv3_wrap0_s3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s4_clk = { + .halt_reg = 0x174f0, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(14), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_s4_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_qupv3_wrap0_s4_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s5_clk = { + .halt_reg = 0x17620, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(15), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_s5_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_qupv3_wrap0_s5_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_core_2x_clk = { + .halt_reg = 0x18004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(18), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap1_core_2x_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_core_clk = { + .halt_reg = 0x18008, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(19), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap1_core_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s0_clk = { + .halt_reg = 0x18014, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(22), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap1_s0_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_qupv3_wrap1_s0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s1_clk = { + .halt_reg = 0x18144, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(23), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap1_s1_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_qupv3_wrap1_s1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s2_clk = { + .halt_reg = 0x18274, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(24), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap1_s2_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_qupv3_wrap1_s2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s3_clk = { + .halt_reg = 0x183a4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(25), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap1_s3_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_qupv3_wrap1_s3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s4_clk = { + .halt_reg = 0x184d4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(26), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap1_s4_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_qupv3_wrap1_s4_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s5_clk = { + .halt_reg = 0x18604, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(27), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap1_s5_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_qupv3_wrap1_s5_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_0_m_ahb_clk = { + .halt_reg = 0x17004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(6), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap_0_m_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_0_s_ahb_clk = { + .halt_reg = 0x17008, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x17008, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(7), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap_0_s_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_1_m_ahb_clk = { + .halt_reg = 0x1800c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(20), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap_1_m_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_1_s_ahb_clk = { + .halt_reg = 0x18010, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x18010, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(21), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap_1_s_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc1_ahb_clk = { + .halt_reg = 0x12008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x12008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc1_apps_clk = { + .halt_reg = 0x1200c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1200c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_apps_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_sdcc1_apps_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 = 0x12040, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x12040, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_ice_core_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_sdcc1_ice_core_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc2_ahb_clk = { + .halt_reg = 0x14008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x14008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc2_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc2_apps_clk = { + .halt_reg = 0x14004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x14004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc2_apps_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_sdcc2_apps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +/* For CPUSS functionality the SYS NOC clock needs to be left enabled */ +static struct clk_branch gcc_sys_noc_cpuss_ahb_clk = { + .halt_reg = 0x4144, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sys_noc_cpuss_ahb_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_cpuss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_mem_clkref_clk = { + .halt_reg = 0x8c000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8c000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_mem_clkref_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_ahb_clk = { + .halt_reg = 0x77014, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x77014, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x77014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_axi_clk = { + .halt_reg = 0x77038, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x77038, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x77038, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_axi_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_ufs_phy_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_ice_core_clk = { + .halt_reg = 0x77090, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x77090, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x77090, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_ice_core_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_ufs_phy_ice_core_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_phy_aux_clk = { + .halt_reg = 0x77094, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x77094, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x77094, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_phy_aux_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_ufs_phy_phy_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_rx_symbol_0_clk = { + .halt_reg = 0x7701c, + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x7701c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_rx_symbol_0_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_tx_symbol_0_clk = { + .halt_reg = 0x77018, + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x77018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_tx_symbol_0_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_unipro_core_clk = { + .halt_reg = 0x7708c, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x7708c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x7708c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_unipro_core_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_ufs_phy_unipro_core_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_prim_master_clk = { + .halt_reg = 0xf010, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xf010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_prim_master_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_usb30_prim_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_prim_mock_utmi_clk = { + .halt_reg = 0xf018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xf018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_prim_mock_utmi_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = + &gcc_usb30_prim_mock_utmi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_prim_sleep_clk = { + .halt_reg = 0xf014, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xf014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_prim_sleep_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_prim_clkref_clk = { + .halt_reg = 0x8c010, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8c010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_prim_clkref_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_prim_phy_aux_clk = { + .halt_reg = 0xf050, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xf050, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_prim_phy_aux_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_usb3_prim_phy_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_prim_phy_com_aux_clk = { + .halt_reg = 0xf054, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xf054, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_prim_phy_com_aux_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_usb3_prim_phy_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_prim_phy_pipe_clk = { + .halt_reg = 0xf058, + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0xf058, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_prim_phy_pipe_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb_phy_cfg_ahb2phy_clk = { + .halt_reg = 0x6a004, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x6a004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x6a004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb_phy_cfg_ahb2phy_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_video_axi_clk = { + .halt_reg = 0xb01c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb01c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_video_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_video_gpll0_div_clk_src = { + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(20), + .hw.init = &(struct clk_init_data){ + .name = "gcc_video_gpll0_div_clk_src", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_pll0_main_div_cdiv.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_video_throttle_axi_clk = { + .halt_reg = 0xb07c, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0xb07c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xb07c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_video_throttle_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_video_xo_clk = { + .halt_reg = 0xb028, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb028, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_video_xo_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc ufs_phy_gdsc = { + .gdscr = 0x77004, + .pd = { + .name = "ufs_phy_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc usb30_prim_gdsc = { + .gdscr = 0x0f004, + .pd = { + .name = "usb30_prim_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc = { + .gdscr = 0x7d040, + .pd = { + .name = "hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON | VOTABLE, +}; + +static struct gdsc hlos1_vote_mmnoc_mmu_tbu_sf_gdsc = { + .gdscr = 0x7d044, + .pd = { + .name = "hlos1_vote_mmnoc_mmu_tbu_sf_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON | VOTABLE, +}; + +static struct gdsc *gcc_sc7180_gdscs[] = { + [UFS_PHY_GDSC] = &ufs_phy_gdsc, + [USB30_PRIM_GDSC] = &usb30_prim_gdsc, + [HLOS1_VOTE_MMNOC_MMU_TBU_HF0_GDSC] = + &hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc, + [HLOS1_VOTE_MMNOC_MMU_TBU_SF_GDSC] = + &hlos1_vote_mmnoc_mmu_tbu_sf_gdsc, +}; + + +static struct clk_hw *gcc_sc7180_hws[] = { + [GCC_GPLL0_MAIN_DIV_CDIV] = &gcc_pll0_main_div_cdiv.hw, +}; + +static struct clk_regmap *gcc_sc7180_clocks[] = { + [GCC_AGGRE_UFS_PHY_AXI_CLK] = &gcc_aggre_ufs_phy_axi_clk.clkr, + [GCC_AGGRE_USB3_PRIM_AXI_CLK] = &gcc_aggre_usb3_prim_axi_clk.clkr, + [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr, + [GCC_CAMERA_AHB_CLK] = &gcc_camera_ahb_clk.clkr, + [GCC_CAMERA_HF_AXI_CLK] = &gcc_camera_hf_axi_clk.clkr, + [GCC_CAMERA_THROTTLE_HF_AXI_CLK] = &gcc_camera_throttle_hf_axi_clk.clkr, + [GCC_CAMERA_XO_CLK] = &gcc_camera_xo_clk.clkr, + [GCC_CE1_AHB_CLK] = &gcc_ce1_ahb_clk.clkr, + [GCC_CE1_AXI_CLK] = &gcc_ce1_axi_clk.clkr, + [GCC_CE1_CLK] = &gcc_ce1_clk.clkr, + [GCC_CFG_NOC_USB3_PRIM_AXI_CLK] = &gcc_cfg_noc_usb3_prim_axi_clk.clkr, + [GCC_CPUSS_AHB_CLK] = &gcc_cpuss_ahb_clk.clkr, + [GCC_CPUSS_AHB_CLK_SRC] = &gcc_cpuss_ahb_clk_src.clkr, + [GCC_CPUSS_RBCPR_CLK] = &gcc_cpuss_rbcpr_clk.clkr, + [GCC_DDRSS_GPU_AXI_CLK] = &gcc_ddrss_gpu_axi_clk.clkr, + [GCC_DISP_GPLL0_CLK_SRC] = &gcc_disp_gpll0_clk_src.clkr, + [GCC_DISP_GPLL0_DIV_CLK_SRC] = &gcc_disp_gpll0_div_clk_src.clkr, + [GCC_DISP_HF_AXI_CLK] = &gcc_disp_hf_axi_clk.clkr, + [GCC_DISP_THROTTLE_HF_AXI_CLK] = &gcc_disp_throttle_hf_axi_clk.clkr, + [GCC_DISP_XO_CLK] = &gcc_disp_xo_clk.clkr, + [GCC_GP1_CLK] = &gcc_gp1_clk.clkr, + [GCC_GP1_CLK_SRC] = &gcc_gp1_clk_src.clkr, + [GCC_GP2_CLK] = &gcc_gp2_clk.clkr, + [GCC_GP2_CLK_SRC] = &gcc_gp2_clk_src.clkr, + [GCC_GP3_CLK] = &gcc_gp3_clk.clkr, + [GCC_GP3_CLK_SRC] = &gcc_gp3_clk_src.clkr, + [GCC_GPU_GPLL0_CLK_SRC] = &gcc_gpu_gpll0_clk_src.clkr, + [GCC_GPU_GPLL0_DIV_CLK_SRC] = &gcc_gpu_gpll0_div_clk_src.clkr, + [GCC_GPU_MEMNOC_GFX_CLK] = &gcc_gpu_memnoc_gfx_clk.clkr, + [GCC_GPU_SNOC_DVM_GFX_CLK] = &gcc_gpu_snoc_dvm_gfx_clk.clkr, + [GCC_NPU_AXI_CLK] = &gcc_npu_axi_clk.clkr, + [GCC_NPU_BWMON_AXI_CLK] = &gcc_npu_bwmon_axi_clk.clkr, + [GCC_NPU_BWMON_DMA_CFG_AHB_CLK] = &gcc_npu_bwmon_dma_cfg_ahb_clk.clkr, + [GCC_NPU_BWMON_DSP_CFG_AHB_CLK] = &gcc_npu_bwmon_dsp_cfg_ahb_clk.clkr, + [GCC_NPU_CFG_AHB_CLK] = &gcc_npu_cfg_ahb_clk.clkr, + [GCC_NPU_DMA_CLK] = &gcc_npu_dma_clk.clkr, + [GCC_NPU_GPLL0_CLK_SRC] = &gcc_npu_gpll0_clk_src.clkr, + [GCC_NPU_GPLL0_DIV_CLK_SRC] = &gcc_npu_gpll0_div_clk_src.clkr, + [GCC_PDM2_CLK] = &gcc_pdm2_clk.clkr, + [GCC_PDM2_CLK_SRC] = &gcc_pdm2_clk_src.clkr, + [GCC_PDM_AHB_CLK] = &gcc_pdm_ahb_clk.clkr, + [GCC_PDM_XO4_CLK] = &gcc_pdm_xo4_clk.clkr, + [GCC_PRNG_AHB_CLK] = &gcc_prng_ahb_clk.clkr, + [GCC_QSPI_CNOC_PERIPH_AHB_CLK] = &gcc_qspi_cnoc_periph_ahb_clk.clkr, + [GCC_QSPI_CORE_CLK] = &gcc_qspi_core_clk.clkr, + [GCC_QSPI_CORE_CLK_SRC] = &gcc_qspi_core_clk_src.clkr, + [GCC_QUPV3_WRAP0_CORE_2X_CLK] = &gcc_qupv3_wrap0_core_2x_clk.clkr, + [GCC_QUPV3_WRAP0_CORE_CLK] = &gcc_qupv3_wrap0_core_clk.clkr, + [GCC_QUPV3_WRAP0_S0_CLK] = &gcc_qupv3_wrap0_s0_clk.clkr, + [GCC_QUPV3_WRAP0_S0_CLK_SRC] = &gcc_qupv3_wrap0_s0_clk_src.clkr, + [GCC_QUPV3_WRAP0_S1_CLK] = &gcc_qupv3_wrap0_s1_clk.clkr, + [GCC_QUPV3_WRAP0_S1_CLK_SRC] = &gcc_qupv3_wrap0_s1_clk_src.clkr, + [GCC_QUPV3_WRAP0_S2_CLK] = &gcc_qupv3_wrap0_s2_clk.clkr, + [GCC_QUPV3_WRAP0_S2_CLK_SRC] = &gcc_qupv3_wrap0_s2_clk_src.clkr, + [GCC_QUPV3_WRAP0_S3_CLK] = &gcc_qupv3_wrap0_s3_clk.clkr, + [GCC_QUPV3_WRAP0_S3_CLK_SRC] = &gcc_qupv3_wrap0_s3_clk_src.clkr, + [GCC_QUPV3_WRAP0_S4_CLK] = &gcc_qupv3_wrap0_s4_clk.clkr, + [GCC_QUPV3_WRAP0_S4_CLK_SRC] = &gcc_qupv3_wrap0_s4_clk_src.clkr, + [GCC_QUPV3_WRAP0_S5_CLK] = &gcc_qupv3_wrap0_s5_clk.clkr, + [GCC_QUPV3_WRAP0_S5_CLK_SRC] = &gcc_qupv3_wrap0_s5_clk_src.clkr, + [GCC_QUPV3_WRAP1_CORE_2X_CLK] = &gcc_qupv3_wrap1_core_2x_clk.clkr, + [GCC_QUPV3_WRAP1_CORE_CLK] = &gcc_qupv3_wrap1_core_clk.clkr, + [GCC_QUPV3_WRAP1_S0_CLK] = &gcc_qupv3_wrap1_s0_clk.clkr, + [GCC_QUPV3_WRAP1_S0_CLK_SRC] = &gcc_qupv3_wrap1_s0_clk_src.clkr, + [GCC_QUPV3_WRAP1_S1_CLK] = &gcc_qupv3_wrap1_s1_clk.clkr, + [GCC_QUPV3_WRAP1_S1_CLK_SRC] = &gcc_qupv3_wrap1_s1_clk_src.clkr, + [GCC_QUPV3_WRAP1_S2_CLK] = &gcc_qupv3_wrap1_s2_clk.clkr, + [GCC_QUPV3_WRAP1_S2_CLK_SRC] = &gcc_qupv3_wrap1_s2_clk_src.clkr, + [GCC_QUPV3_WRAP1_S3_CLK] = &gcc_qupv3_wrap1_s3_clk.clkr, + [GCC_QUPV3_WRAP1_S3_CLK_SRC] = &gcc_qupv3_wrap1_s3_clk_src.clkr, + [GCC_QUPV3_WRAP1_S4_CLK] = &gcc_qupv3_wrap1_s4_clk.clkr, + [GCC_QUPV3_WRAP1_S4_CLK_SRC] = &gcc_qupv3_wrap1_s4_clk_src.clkr, + [GCC_QUPV3_WRAP1_S5_CLK] = &gcc_qupv3_wrap1_s5_clk.clkr, + [GCC_QUPV3_WRAP1_S5_CLK_SRC] = &gcc_qupv3_wrap1_s5_clk_src.clkr, + [GCC_QUPV3_WRAP_0_M_AHB_CLK] = &gcc_qupv3_wrap_0_m_ahb_clk.clkr, + [GCC_QUPV3_WRAP_0_S_AHB_CLK] = &gcc_qupv3_wrap_0_s_ahb_clk.clkr, + [GCC_QUPV3_WRAP_1_M_AHB_CLK] = &gcc_qupv3_wrap_1_m_ahb_clk.clkr, + [GCC_QUPV3_WRAP_1_S_AHB_CLK] = &gcc_qupv3_wrap_1_s_ahb_clk.clkr, + [GCC_SDCC1_AHB_CLK] = &gcc_sdcc1_ahb_clk.clkr, + [GCC_SDCC1_APPS_CLK] = &gcc_sdcc1_apps_clk.clkr, + [GCC_SDCC1_APPS_CLK_SRC] = &gcc_sdcc1_apps_clk_src.clkr, + [GCC_SDCC1_ICE_CORE_CLK] = &gcc_sdcc1_ice_core_clk.clkr, + [GCC_SDCC1_ICE_CORE_CLK_SRC] = &gcc_sdcc1_ice_core_clk_src.clkr, + [GCC_SDCC2_AHB_CLK] = &gcc_sdcc2_ahb_clk.clkr, + [GCC_SDCC2_APPS_CLK] = &gcc_sdcc2_apps_clk.clkr, + [GCC_SDCC2_APPS_CLK_SRC] = &gcc_sdcc2_apps_clk_src.clkr, + [GCC_SYS_NOC_CPUSS_AHB_CLK] = &gcc_sys_noc_cpuss_ahb_clk.clkr, + [GCC_UFS_MEM_CLKREF_CLK] = &gcc_ufs_mem_clkref_clk.clkr, + [GCC_UFS_PHY_AHB_CLK] = &gcc_ufs_phy_ahb_clk.clkr, + [GCC_UFS_PHY_AXI_CLK] = &gcc_ufs_phy_axi_clk.clkr, + [GCC_UFS_PHY_AXI_CLK_SRC] = &gcc_ufs_phy_axi_clk_src.clkr, + [GCC_UFS_PHY_ICE_CORE_CLK] = &gcc_ufs_phy_ice_core_clk.clkr, + [GCC_UFS_PHY_ICE_CORE_CLK_SRC] = &gcc_ufs_phy_ice_core_clk_src.clkr, + [GCC_UFS_PHY_PHY_AUX_CLK] = &gcc_ufs_phy_phy_aux_clk.clkr, + [GCC_UFS_PHY_PHY_AUX_CLK_SRC] = &gcc_ufs_phy_phy_aux_clk_src.clkr, + [GCC_UFS_PHY_RX_SYMBOL_0_CLK] = &gcc_ufs_phy_rx_symbol_0_clk.clkr, + [GCC_UFS_PHY_TX_SYMBOL_0_CLK] = &gcc_ufs_phy_tx_symbol_0_clk.clkr, + [GCC_UFS_PHY_UNIPRO_CORE_CLK] = &gcc_ufs_phy_unipro_core_clk.clkr, + [GCC_UFS_PHY_UNIPRO_CORE_CLK_SRC] = + &gcc_ufs_phy_unipro_core_clk_src.clkr, + [GCC_USB30_PRIM_MASTER_CLK] = &gcc_usb30_prim_master_clk.clkr, + [GCC_USB30_PRIM_MASTER_CLK_SRC] = &gcc_usb30_prim_master_clk_src.clkr, + [GCC_USB30_PRIM_MOCK_UTMI_CLK] = &gcc_usb30_prim_mock_utmi_clk.clkr, + [GCC_USB30_PRIM_MOCK_UTMI_CLK_SRC] = + &gcc_usb30_prim_mock_utmi_clk_src.clkr, + [GCC_USB30_PRIM_SLEEP_CLK] = &gcc_usb30_prim_sleep_clk.clkr, + [GCC_USB3_PRIM_CLKREF_CLK] = &gcc_usb3_prim_clkref_clk.clkr, + [GCC_USB3_PRIM_PHY_AUX_CLK] = &gcc_usb3_prim_phy_aux_clk.clkr, + [GCC_USB3_PRIM_PHY_AUX_CLK_SRC] = &gcc_usb3_prim_phy_aux_clk_src.clkr, + [GCC_USB3_PRIM_PHY_COM_AUX_CLK] = &gcc_usb3_prim_phy_com_aux_clk.clkr, + [GCC_USB3_PRIM_PHY_PIPE_CLK] = &gcc_usb3_prim_phy_pipe_clk.clkr, + [GCC_USB_PHY_CFG_AHB2PHY_CLK] = &gcc_usb_phy_cfg_ahb2phy_clk.clkr, + [GCC_VIDEO_AXI_CLK] = &gcc_video_axi_clk.clkr, + [GCC_VIDEO_GPLL0_DIV_CLK_SRC] = &gcc_video_gpll0_div_clk_src.clkr, + [GCC_VIDEO_THROTTLE_AXI_CLK] = &gcc_video_throttle_axi_clk.clkr, + [GCC_VIDEO_XO_CLK] = &gcc_video_xo_clk.clkr, + [GPLL0] = &gpll0.clkr, + [GPLL0_OUT_EVEN] = &gpll0_out_even.clkr, + [GPLL6] = &gpll6.clkr, + [GPLL7] = &gpll7.clkr, + [GPLL4] = &gpll4.clkr, + [GPLL1] = &gpll1.clkr, +}; + +static const struct qcom_reset_map gcc_sc7180_resets[] = { + [GCC_QUSB2PHY_PRIM_BCR] = { 0x26000 }, + [GCC_QUSB2PHY_SEC_BCR] = { 0x26004 }, + [GCC_UFS_PHY_BCR] = { 0x77000 }, + [GCC_USB30_PRIM_BCR] = { 0xf000 }, + [GCC_USB3_PHY_PRIM_BCR] = { 0x50000 }, + [GCC_USB3PHY_PHY_PRIM_BCR] = { 0x50004 }, + [GCC_USB3_PHY_SEC_BCR] = { 0x5000c }, + [GCC_USB3_DP_PHY_PRIM_BCR] = { 0x50008 }, + [GCC_USB3PHY_PHY_SEC_BCR] = { 0x50010 }, + [GCC_USB3_DP_PHY_SEC_BCR] = { 0x50014 }, + [GCC_USB_PHY_CFG_AHB2PHY_BCR] = { 0x6a000 }, +}; + +static struct clk_rcg_dfs_data gcc_dfs_clocks[] = { + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s0_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s1_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s2_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s3_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s4_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s5_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s0_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s1_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s2_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s3_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s4_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s5_clk_src), +}; + +static const struct regmap_config gcc_sc7180_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x18208c, + .fast_io = true, +}; + +static const struct qcom_cc_desc gcc_sc7180_desc = { + .config = &gcc_sc7180_regmap_config, + .clk_hws = gcc_sc7180_hws, + .num_clk_hws = ARRAY_SIZE(gcc_sc7180_hws), + .clks = gcc_sc7180_clocks, + .num_clks = ARRAY_SIZE(gcc_sc7180_clocks), + .resets = gcc_sc7180_resets, + .num_resets = ARRAY_SIZE(gcc_sc7180_resets), + .gdscs = gcc_sc7180_gdscs, + .num_gdscs = ARRAY_SIZE(gcc_sc7180_gdscs), +}; + +static const struct of_device_id gcc_sc7180_match_table[] = { + { .compatible = "qcom,gcc-sc7180" }, + { } +}; +MODULE_DEVICE_TABLE(of, gcc_sc7180_match_table); + +static int gcc_sc7180_probe(struct platform_device *pdev) +{ + struct regmap *regmap; + int ret; + + regmap = qcom_cc_map(pdev, &gcc_sc7180_desc); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + /* + * Disable the GPLL0 active input to MM blocks, NPU + * and GPU via MISC registers. + */ + regmap_update_bits(regmap, 0x09ffc, 0x3, 0x3); + regmap_update_bits(regmap, 0x4d110, 0x3, 0x3); + regmap_update_bits(regmap, 0x71028, 0x3, 0x3); + + /* + * Keep the clocks always-ON + * GCC_CPUSS_GNOC_CLK, GCC_VIDEO_AHB_CLK, GCC_DISP_AHB_CLK + * GCC_GPU_CFG_AHB_CLK + */ + regmap_update_bits(regmap, 0x48004, BIT(0), BIT(0)); + regmap_update_bits(regmap, 0x0b004, BIT(0), BIT(0)); + regmap_update_bits(regmap, 0x0b00c, BIT(0), BIT(0)); + regmap_update_bits(regmap, 0x71004, BIT(0), BIT(0)); + + ret = qcom_cc_register_rcg_dfs(regmap, gcc_dfs_clocks, + ARRAY_SIZE(gcc_dfs_clocks)); + if (ret) + return ret; + + return qcom_cc_really_probe(pdev, &gcc_sc7180_desc, regmap); +} + +static struct platform_driver gcc_sc7180_driver = { + .probe = gcc_sc7180_probe, + .driver = { + .name = "gcc-sc7180", + .of_match_table = gcc_sc7180_match_table, + }, +}; + +static int __init gcc_sc7180_init(void) +{ + return platform_driver_register(&gcc_sc7180_driver); +} +core_initcall(gcc_sc7180_init); + +static void __exit gcc_sc7180_exit(void) +{ + platform_driver_unregister(&gcc_sc7180_driver); +} +module_exit(gcc_sc7180_exit); + +MODULE_DESCRIPTION("QTI GCC SC7180 Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c index 95be125c3bdd..d2142fe46a8e 100644 --- a/drivers/clk/qcom/gcc-sdm845.c +++ b/drivers/clk/qcom/gcc-sdm845.c @@ -408,7 +408,7 @@ static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = { { } }; -static struct clk_init_data gcc_qupv3_wrap0_s0_clk_init = { +static struct clk_init_data gcc_qupv3_wrap0_s0_clk_src_init = { .name = "gcc_qupv3_wrap0_s0_clk_src", .parent_names = gcc_parent_names_0, .num_parents = 4, @@ -421,10 +421,10 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s0_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &gcc_qupv3_wrap0_s0_clk_init, + .clkr.hw.init = &gcc_qupv3_wrap0_s0_clk_src_init, }; -static struct clk_init_data gcc_qupv3_wrap0_s1_clk_init = { +static struct clk_init_data gcc_qupv3_wrap0_s1_clk_src_init = { .name = "gcc_qupv3_wrap0_s1_clk_src", .parent_names = gcc_parent_names_0, .num_parents = 4, @@ -437,10 +437,10 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s1_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &gcc_qupv3_wrap0_s1_clk_init, + .clkr.hw.init = &gcc_qupv3_wrap0_s1_clk_src_init, }; -static struct clk_init_data gcc_qupv3_wrap0_s2_clk_init = { +static struct clk_init_data gcc_qupv3_wrap0_s2_clk_src_init = { .name = "gcc_qupv3_wrap0_s2_clk_src", .parent_names = gcc_parent_names_0, .num_parents = 4, @@ -453,10 +453,10 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s2_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &gcc_qupv3_wrap0_s2_clk_init, + .clkr.hw.init = &gcc_qupv3_wrap0_s2_clk_src_init, }; -static struct clk_init_data gcc_qupv3_wrap0_s3_clk_init = { +static struct clk_init_data gcc_qupv3_wrap0_s3_clk_src_init = { .name = "gcc_qupv3_wrap0_s3_clk_src", .parent_names = gcc_parent_names_0, .num_parents = 4, @@ -469,10 +469,10 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s3_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &gcc_qupv3_wrap0_s3_clk_init, + .clkr.hw.init = &gcc_qupv3_wrap0_s3_clk_src_init, }; -static struct clk_init_data gcc_qupv3_wrap0_s4_clk_init = { +static struct clk_init_data gcc_qupv3_wrap0_s4_clk_src_init = { .name = "gcc_qupv3_wrap0_s4_clk_src", .parent_names = gcc_parent_names_0, .num_parents = 4, @@ -485,10 +485,10 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s4_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &gcc_qupv3_wrap0_s4_clk_init, + .clkr.hw.init = &gcc_qupv3_wrap0_s4_clk_src_init, }; -static struct clk_init_data gcc_qupv3_wrap0_s5_clk_init = { +static struct clk_init_data gcc_qupv3_wrap0_s5_clk_src_init = { .name = "gcc_qupv3_wrap0_s5_clk_src", .parent_names = gcc_parent_names_0, .num_parents = 4, @@ -501,10 +501,10 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s5_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &gcc_qupv3_wrap0_s5_clk_init, + .clkr.hw.init = &gcc_qupv3_wrap0_s5_clk_src_init, }; -static struct clk_init_data gcc_qupv3_wrap0_s6_clk_init = { +static struct clk_init_data gcc_qupv3_wrap0_s6_clk_src_init = { .name = "gcc_qupv3_wrap0_s6_clk_src", .parent_names = gcc_parent_names_0, .num_parents = 4, @@ -517,10 +517,10 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s6_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &gcc_qupv3_wrap0_s6_clk_init, + .clkr.hw.init = &gcc_qupv3_wrap0_s6_clk_src_init, }; -static struct clk_init_data gcc_qupv3_wrap0_s7_clk_init = { +static struct clk_init_data gcc_qupv3_wrap0_s7_clk_src_init = { .name = "gcc_qupv3_wrap0_s7_clk_src", .parent_names = gcc_parent_names_0, .num_parents = 4, @@ -533,10 +533,10 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s7_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &gcc_qupv3_wrap0_s7_clk_init, + .clkr.hw.init = &gcc_qupv3_wrap0_s7_clk_src_init, }; -static struct clk_init_data gcc_qupv3_wrap1_s0_clk_init = { +static struct clk_init_data gcc_qupv3_wrap1_s0_clk_src_init = { .name = "gcc_qupv3_wrap1_s0_clk_src", .parent_names = gcc_parent_names_0, .num_parents = 4, @@ -549,10 +549,10 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s0_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &gcc_qupv3_wrap1_s0_clk_init, + .clkr.hw.init = &gcc_qupv3_wrap1_s0_clk_src_init, }; -static struct clk_init_data gcc_qupv3_wrap1_s1_clk_init = { +static struct clk_init_data gcc_qupv3_wrap1_s1_clk_src_init = { .name = "gcc_qupv3_wrap1_s1_clk_src", .parent_names = gcc_parent_names_0, .num_parents = 4, @@ -565,10 +565,10 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s1_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &gcc_qupv3_wrap1_s1_clk_init, + .clkr.hw.init = &gcc_qupv3_wrap1_s1_clk_src_init, }; -static struct clk_init_data gcc_qupv3_wrap1_s2_clk_init = { +static struct clk_init_data gcc_qupv3_wrap1_s2_clk_src_init = { .name = "gcc_qupv3_wrap1_s2_clk_src", .parent_names = gcc_parent_names_0, .num_parents = 4, @@ -581,10 +581,10 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s2_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &gcc_qupv3_wrap1_s2_clk_init, + .clkr.hw.init = &gcc_qupv3_wrap1_s2_clk_src_init, }; -static struct clk_init_data gcc_qupv3_wrap1_s3_clk_init = { +static struct clk_init_data gcc_qupv3_wrap1_s3_clk_src_init = { .name = "gcc_qupv3_wrap1_s3_clk_src", .parent_names = gcc_parent_names_0, .num_parents = 4, @@ -597,10 +597,10 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s3_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &gcc_qupv3_wrap1_s3_clk_init, + .clkr.hw.init = &gcc_qupv3_wrap1_s3_clk_src_init, }; -static struct clk_init_data gcc_qupv3_wrap1_s4_clk_init = { +static struct clk_init_data gcc_qupv3_wrap1_s4_clk_src_init = { .name = "gcc_qupv3_wrap1_s4_clk_src", .parent_names = gcc_parent_names_0, .num_parents = 4, @@ -613,10 +613,10 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s4_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &gcc_qupv3_wrap1_s4_clk_init, + .clkr.hw.init = &gcc_qupv3_wrap1_s4_clk_src_init, }; -static struct clk_init_data gcc_qupv3_wrap1_s5_clk_init = { +static struct clk_init_data gcc_qupv3_wrap1_s5_clk_src_init = { .name = "gcc_qupv3_wrap1_s5_clk_src", .parent_names = gcc_parent_names_0, .num_parents = 4, @@ -629,10 +629,10 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s5_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &gcc_qupv3_wrap1_s5_clk_init, + .clkr.hw.init = &gcc_qupv3_wrap1_s5_clk_src_init, }; -static struct clk_init_data gcc_qupv3_wrap1_s6_clk_init = { +static struct clk_init_data gcc_qupv3_wrap1_s6_clk_src_init = { .name = "gcc_qupv3_wrap1_s6_clk_src", .parent_names = gcc_parent_names_0, .num_parents = 4, @@ -645,10 +645,10 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s6_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &gcc_qupv3_wrap1_s6_clk_init, + .clkr.hw.init = &gcc_qupv3_wrap1_s6_clk_src_init, }; -static struct clk_init_data gcc_qupv3_wrap1_s7_clk_init = { +static struct clk_init_data gcc_qupv3_wrap1_s7_clk_src_init = { .name = "gcc_qupv3_wrap1_s7_clk_src", .parent_names = gcc_parent_names_0, .num_parents = 4, @@ -661,7 +661,7 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s7_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &gcc_qupv3_wrap1_s7_clk_init, + .clkr.hw.init = &gcc_qupv3_wrap1_s7_clk_src_init, }; static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src[] = { @@ -3577,22 +3577,22 @@ static const struct of_device_id gcc_sdm845_match_table[] = { MODULE_DEVICE_TABLE(of, gcc_sdm845_match_table); static const struct clk_rcg_dfs_data gcc_dfs_clocks[] = { - DEFINE_RCG_DFS(gcc_qupv3_wrap0_s0_clk), - DEFINE_RCG_DFS(gcc_qupv3_wrap0_s1_clk), - DEFINE_RCG_DFS(gcc_qupv3_wrap0_s2_clk), - DEFINE_RCG_DFS(gcc_qupv3_wrap0_s3_clk), - DEFINE_RCG_DFS(gcc_qupv3_wrap0_s4_clk), - DEFINE_RCG_DFS(gcc_qupv3_wrap0_s5_clk), - DEFINE_RCG_DFS(gcc_qupv3_wrap0_s6_clk), - DEFINE_RCG_DFS(gcc_qupv3_wrap0_s7_clk), - DEFINE_RCG_DFS(gcc_qupv3_wrap1_s0_clk), - DEFINE_RCG_DFS(gcc_qupv3_wrap1_s1_clk), - DEFINE_RCG_DFS(gcc_qupv3_wrap1_s2_clk), - DEFINE_RCG_DFS(gcc_qupv3_wrap1_s3_clk), - DEFINE_RCG_DFS(gcc_qupv3_wrap1_s4_clk), - DEFINE_RCG_DFS(gcc_qupv3_wrap1_s5_clk), - DEFINE_RCG_DFS(gcc_qupv3_wrap1_s6_clk), - DEFINE_RCG_DFS(gcc_qupv3_wrap1_s7_clk), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s0_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s1_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s2_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s3_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s4_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s5_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s6_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s7_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s0_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s1_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s2_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s3_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s4_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s5_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s6_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s7_clk_src), }; static int gcc_sdm845_probe(struct platform_device *pdev) diff --git a/drivers/clk/qcom/gpucc-msm8998.c b/drivers/clk/qcom/gpucc-msm8998.c new file mode 100644 index 000000000000..e5e2492b20c5 --- /dev/null +++ b/drivers/clk/qcom/gpucc-msm8998.c @@ -0,0 +1,338 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019, Jeffrey Hugo + */ + +#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,gpucc-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_GPUPLL0_OUT_EVEN, +}; + +/* Instead of going directly to the block, XO is routed through this branch */ +static struct clk_branch gpucc_cxo_clk = { + .halt_reg = 0x1020, + .clkr = { + .enable_reg = 0x1020, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpucc_cxo_clk", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "xo", + .name = "xo" + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_IS_CRITICAL, + }, + }, +}; + +static const struct clk_div_table post_div_table_fabia_even[] = { + { 0x0, 1 }, + { 0x1, 2 }, + { 0x3, 4 }, + { 0x7, 8 }, + { } +}; + +static struct clk_alpha_pll gpupll0 = { + .offset = 0x0, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpupll0", + .parent_hws = (const struct clk_hw *[]){ &gpucc_cxo_clk.clkr.hw }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_fabia_ops, + }, +}; + +static struct clk_alpha_pll_postdiv gpupll0_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 = "gpupll0_out_even", + .parent_hws = (const struct clk_hw *[]){ &gpupll0.clkr.hw }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_fabia_ops, + }, +}; + +static const struct parent_map gpu_xo_gpll0_map[] = { + { P_XO, 0 }, + { P_GPLL0, 5 }, +}; + +static const struct clk_parent_data gpu_xo_gpll0[] = { + { .hw = &gpucc_cxo_clk.clkr.hw }, + { .fw_name = "gpll0", .name = "gpll0" }, +}; + +static const struct parent_map gpu_xo_gpupll0_map[] = { + { P_XO, 0 }, + { P_GPUPLL0_OUT_EVEN, 1 }, +}; + +static const struct clk_parent_data gpu_xo_gpupll0[] = { + { .hw = &gpucc_cxo_clk.clkr.hw }, + { .hw = &gpupll0_out_even.clkr.hw }, +}; + +static const struct freq_tbl ftbl_rbcpr_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(50000000, P_GPLL0, 12, 0, 0), + { } +}; + +static struct clk_rcg2 rbcpr_clk_src = { + .cmd_rcgr = 0x1030, + .hid_width = 5, + .parent_map = gpu_xo_gpll0_map, + .freq_tbl = ftbl_rbcpr_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "rbcpr_clk_src", + .parent_data = gpu_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gfx3d_clk_src[] = { + { .src = P_GPUPLL0_OUT_EVEN, .pre_div = 3 }, + { } +}; + +static struct clk_rcg2 gfx3d_clk_src = { + .cmd_rcgr = 0x1070, + .hid_width = 5, + .parent_map = gpu_xo_gpupll0_map, + .freq_tbl = ftbl_gfx3d_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gfx3d_clk_src", + .parent_data = gpu_xo_gpupll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, + }, +}; + +static const struct freq_tbl ftbl_rbbmtimer_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 rbbmtimer_clk_src = { + .cmd_rcgr = 0x10b0, + .hid_width = 5, + .parent_map = gpu_xo_gpll0_map, + .freq_tbl = ftbl_rbbmtimer_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "rbbmtimer_clk_src", + .parent_data = gpu_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gfx3d_isense_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(40000000, P_GPLL0, 15, 0, 0), + F(200000000, P_GPLL0, 3, 0, 0), + F(300000000, P_GPLL0, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gfx3d_isense_clk_src = { + .cmd_rcgr = 0x1100, + .hid_width = 5, + .parent_map = gpu_xo_gpll0_map, + .freq_tbl = ftbl_gfx3d_isense_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gfx3d_isense_clk_src", + .parent_data = gpu_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch rbcpr_clk = { + .halt_reg = 0x1054, + .clkr = { + .enable_reg = 0x1054, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "rbcpr_clk", + .parent_hws = (const struct clk_hw *[]){ &rbcpr_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch gfx3d_clk = { + .halt_reg = 0x1098, + .clkr = { + .enable_reg = 0x1098, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gfx3d_clk", + .parent_hws = (const struct clk_hw *[]){ &gfx3d_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch rbbmtimer_clk = { + .halt_reg = 0x10d0, + .clkr = { + .enable_reg = 0x10d0, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "rbbmtimer_clk", + .parent_hws = (const struct clk_hw *[]){ &rbbmtimer_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch gfx3d_isense_clk = { + .halt_reg = 0x1124, + .clkr = { + .enable_reg = 0x1124, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gfx3d_isense_clk", + .parent_hws = (const struct clk_hw *[]){ &gfx3d_isense_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc gpu_cx_gdsc = { + .gdscr = 0x1004, + .pd = { + .name = "gpu_cx", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc gpu_gx_gdsc = { + .gdscr = 0x1094, + .clamp_io_ctrl = 0x130, + .pd = { + .name = "gpu_gx", + }, + .parent = &gpu_cx_gdsc.pd, + .pwrsts = PWRSTS_OFF_ON, + .flags = CLAMP_IO | AON_RESET, +}; + +static struct clk_regmap *gpucc_msm8998_clocks[] = { + [GPUPLL0] = &gpupll0.clkr, + [GPUPLL0_OUT_EVEN] = &gpupll0_out_even.clkr, + [RBCPR_CLK_SRC] = &rbcpr_clk_src.clkr, + [GFX3D_CLK_SRC] = &gfx3d_clk_src.clkr, + [RBBMTIMER_CLK_SRC] = &rbbmtimer_clk_src.clkr, + [GFX3D_ISENSE_CLK_SRC] = &gfx3d_isense_clk_src.clkr, + [RBCPR_CLK] = &rbcpr_clk.clkr, + [GFX3D_CLK] = &gfx3d_clk.clkr, + [RBBMTIMER_CLK] = &rbbmtimer_clk.clkr, + [GFX3D_ISENSE_CLK] = &gfx3d_isense_clk.clkr, + [GPUCC_CXO_CLK] = &gpucc_cxo_clk.clkr, +}; + +static struct gdsc *gpucc_msm8998_gdscs[] = { + [GPU_CX_GDSC] = &gpu_cx_gdsc, + [GPU_GX_GDSC] = &gpu_gx_gdsc, +}; + +static const struct qcom_reset_map gpucc_msm8998_resets[] = { + [GPU_CX_BCR] = { 0x1000 }, + [RBCPR_BCR] = { 0x1050 }, + [GPU_GX_BCR] = { 0x1090 }, + [GPU_ISENSE_BCR] = { 0x1120 }, +}; + +static const struct regmap_config gpucc_msm8998_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x9000, + .fast_io = true, +}; + +static const struct qcom_cc_desc gpucc_msm8998_desc = { + .config = &gpucc_msm8998_regmap_config, + .clks = gpucc_msm8998_clocks, + .num_clks = ARRAY_SIZE(gpucc_msm8998_clocks), + .resets = gpucc_msm8998_resets, + .num_resets = ARRAY_SIZE(gpucc_msm8998_resets), + .gdscs = gpucc_msm8998_gdscs, + .num_gdscs = ARRAY_SIZE(gpucc_msm8998_gdscs), +}; + +static const struct of_device_id gpucc_msm8998_match_table[] = { + { .compatible = "qcom,msm8998-gpucc" }, + { } +}; +MODULE_DEVICE_TABLE(of, gpucc_msm8998_match_table); + +static int gpucc_msm8998_probe(struct platform_device *pdev) +{ + struct regmap *regmap; + + regmap = qcom_cc_map(pdev, &gpucc_msm8998_desc); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + /* force periph logic on to avoid perf counter corruption */ + regmap_write_bits(regmap, gfx3d_clk.clkr.enable_reg, BIT(13), BIT(13)); + /* tweak droop detector (GPUCC_GPU_DD_WRAP_CTRL) to reduce leakage */ + regmap_write_bits(regmap, gfx3d_clk.clkr.enable_reg, BIT(0), BIT(0)); + + return qcom_cc_really_probe(pdev, &gpucc_msm8998_desc, regmap); +} + +static struct platform_driver gpucc_msm8998_driver = { + .probe = gpucc_msm8998_probe, + .driver = { + .name = "gpucc-msm8998", + .of_match_table = gpucc_msm8998_match_table, + }, +}; +module_platform_driver(gpucc_msm8998_driver); + +MODULE_DESCRIPTION("QCOM GPUCC MSM8998 Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/qcom/q6sstop-qcs404.c b/drivers/clk/qcom/q6sstop-qcs404.c new file mode 100644 index 000000000000..723f932fbf7d --- /dev/null +++ b/drivers/clk/qcom/q6sstop-qcs404.c @@ -0,0 +1,223 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#include <linux/bitops.h> +#include <linux/err.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/pm_clock.h> +#include <linux/pm_runtime.h> +#include <linux/regmap.h> + +#include <dt-bindings/clock/qcom,q6sstopcc-qcs404.h> + +#include "clk-regmap.h" +#include "clk-branch.h" +#include "common.h" +#include "reset.h" + +static struct clk_branch lcc_ahbfabric_cbc_clk = { + .halt_reg = 0x1b004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1b004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "lcc_ahbfabric_cbc_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch lcc_q6ss_ahbs_cbc_clk = { + .halt_reg = 0x22000, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x22000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "lcc_q6ss_ahbs_cbc_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch lcc_q6ss_tcm_slave_cbc_clk = { + .halt_reg = 0x1c000, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x1c000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "lcc_q6ss_tcm_slave_cbc_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch lcc_q6ss_ahbm_cbc_clk = { + .halt_reg = 0x22004, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x22004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "lcc_q6ss_ahbm_cbc_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch lcc_q6ss_axim_cbc_clk = { + .halt_reg = 0x1c004, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x1c004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "lcc_q6ss_axim_cbc_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch lcc_q6ss_bcr_sleep_clk = { + .halt_reg = 0x6004, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x6004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "lcc_q6ss_bcr_sleep_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +/* TCSR clock */ +static struct clk_branch tcsr_lcc_csr_cbcr_clk = { + .halt_reg = 0x8008, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x8008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "tcsr_lcc_csr_cbcr_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct regmap_config q6sstop_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .fast_io = true, +}; + +static struct clk_regmap *q6sstop_qcs404_clocks[] = { + [LCC_AHBFABRIC_CBC_CLK] = &lcc_ahbfabric_cbc_clk.clkr, + [LCC_Q6SS_AHBS_CBC_CLK] = &lcc_q6ss_ahbs_cbc_clk.clkr, + [LCC_Q6SS_TCM_SLAVE_CBC_CLK] = &lcc_q6ss_tcm_slave_cbc_clk.clkr, + [LCC_Q6SS_AHBM_CBC_CLK] = &lcc_q6ss_ahbm_cbc_clk.clkr, + [LCC_Q6SS_AXIM_CBC_CLK] = &lcc_q6ss_axim_cbc_clk.clkr, + [LCC_Q6SS_BCR_SLEEP_CLK] = &lcc_q6ss_bcr_sleep_clk.clkr, +}; + +static const struct qcom_reset_map q6sstop_qcs404_resets[] = { + [Q6SSTOP_BCR_RESET] = { 0x6000 }, +}; + +static const struct qcom_cc_desc q6sstop_qcs404_desc = { + .config = &q6sstop_regmap_config, + .clks = q6sstop_qcs404_clocks, + .num_clks = ARRAY_SIZE(q6sstop_qcs404_clocks), + .resets = q6sstop_qcs404_resets, + .num_resets = ARRAY_SIZE(q6sstop_qcs404_resets), +}; + +static struct clk_regmap *tcsr_qcs404_clocks[] = { + [TCSR_Q6SS_LCC_CBCR_CLK] = &tcsr_lcc_csr_cbcr_clk.clkr, +}; + +static const struct qcom_cc_desc tcsr_qcs404_desc = { + .config = &q6sstop_regmap_config, + .clks = tcsr_qcs404_clocks, + .num_clks = ARRAY_SIZE(tcsr_qcs404_clocks), +}; + +static const struct of_device_id q6sstopcc_qcs404_match_table[] = { + { .compatible = "qcom,qcs404-q6sstopcc" }, + { } +}; +MODULE_DEVICE_TABLE(of, q6sstopcc_qcs404_match_table); + +static int q6sstopcc_qcs404_probe(struct platform_device *pdev) +{ + const struct qcom_cc_desc *desc; + int ret; + + pm_runtime_enable(&pdev->dev); + ret = pm_clk_create(&pdev->dev); + if (ret) + goto disable_pm_runtime; + + ret = pm_clk_add(&pdev->dev, NULL); + if (ret < 0) { + dev_err(&pdev->dev, "failed to acquire iface clock\n"); + goto destroy_pm_clk; + } + + q6sstop_regmap_config.name = "q6sstop_tcsr"; + desc = &tcsr_qcs404_desc; + + ret = qcom_cc_probe_by_index(pdev, 1, desc); + if (ret) + goto destroy_pm_clk; + + q6sstop_regmap_config.name = "q6sstop_cc"; + desc = &q6sstop_qcs404_desc; + + ret = qcom_cc_probe_by_index(pdev, 0, desc); + if (ret) + goto destroy_pm_clk; + + return 0; + +destroy_pm_clk: + pm_clk_destroy(&pdev->dev); + +disable_pm_runtime: + pm_runtime_disable(&pdev->dev); + + return ret; +} + +static int q6sstopcc_qcs404_remove(struct platform_device *pdev) +{ + pm_clk_destroy(&pdev->dev); + pm_runtime_disable(&pdev->dev); + + return 0; +} + +static const struct dev_pm_ops q6sstopcc_pm_ops = { + SET_RUNTIME_PM_OPS(pm_clk_suspend, pm_clk_resume, NULL) +}; + +static struct platform_driver q6sstopcc_qcs404_driver = { + .probe = q6sstopcc_qcs404_probe, + .remove = q6sstopcc_qcs404_remove, + .driver = { + .name = "qcs404-q6sstopcc", + .of_match_table = q6sstopcc_qcs404_match_table, + .pm = &q6sstopcc_pm_ops, + }, +}; + +module_platform_driver(q6sstopcc_qcs404_driver); + +MODULE_DESCRIPTION("QTI QCS404 Q6SSTOP Clock Controller Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig index b879e3e3a6b4..4cd846bc98cc 100644 --- a/drivers/clk/renesas/Kconfig +++ b/drivers/clk/renesas/Kconfig @@ -12,6 +12,7 @@ config CLK_RENESAS select CLK_R8A7745 if ARCH_R8A7745 select CLK_R8A77470 if ARCH_R8A77470 select CLK_R8A774A1 if ARCH_R8A774A1 + select CLK_R8A774B1 if ARCH_R8A774B1 select CLK_R8A774C0 if ARCH_R8A774C0 select CLK_R8A7778 if ARCH_R8A7778 select CLK_R8A7779 if ARCH_R8A7779 @@ -20,7 +21,8 @@ config CLK_RENESAS select CLK_R8A7792 if ARCH_R8A7792 select CLK_R8A7794 if ARCH_R8A7794 select CLK_R8A7795 if ARCH_R8A7795 - select CLK_R8A7796 if ARCH_R8A7796 + select CLK_R8A77960 if ARCH_R8A77960 || ARCH_R8A7796 + select CLK_R8A77961 if ARCH_R8A77961 select CLK_R8A77965 if ARCH_R8A77965 select CLK_R8A77970 if ARCH_R8A77970 select CLK_R8A77980 if ARCH_R8A77980 @@ -31,17 +33,6 @@ config CLK_RENESAS if CLK_RENESAS -config CLK_RENESAS_LEGACY - bool "Legacy DT clock support" - depends on CLK_R8A7790 || CLK_R8A7791 || CLK_R8A7792 || CLK_R8A7794 - help - Enable backward compatibility with old device trees describing a - hierarchical representation of the various CPG and MSTP clocks. - - Say Y if you want your kernel to work with old DTBs. - It is safe to say N if you use the DTS that is supplied with the - current kernel source tree. - # SoC config CLK_EMEV2 bool "Emma Mobile EV2 clock support" if COMPILE_TEST @@ -80,6 +71,10 @@ config CLK_R8A774A1 bool "RZ/G2M clock support" if COMPILE_TEST select CLK_RCAR_GEN3_CPG +config CLK_R8A774B1 + bool "RZ/G2N clock support" if COMPILE_TEST + select CLK_RCAR_GEN3_CPG + config CLK_R8A774C0 bool "RZ/G2E clock support" if COMPILE_TEST select CLK_RCAR_GEN3_CPG @@ -94,24 +89,20 @@ config CLK_R8A7779 config CLK_R8A7790 bool "R-Car H2 clock support" if COMPILE_TEST - select CLK_RCAR_GEN2 if CLK_RENESAS_LEGACY select CLK_RCAR_GEN2_CPG select CLK_RENESAS_DIV6 config CLK_R8A7791 bool "R-Car M2-W/N clock support" if COMPILE_TEST - select CLK_RCAR_GEN2 if CLK_RENESAS_LEGACY select CLK_RCAR_GEN2_CPG select CLK_RENESAS_DIV6 config CLK_R8A7792 bool "R-Car V2H clock support" if COMPILE_TEST - select CLK_RCAR_GEN2 if CLK_RENESAS_LEGACY select CLK_RCAR_GEN2_CPG config CLK_R8A7794 bool "R-Car E2 clock support" if COMPILE_TEST - select CLK_RCAR_GEN2 if CLK_RENESAS_LEGACY select CLK_RCAR_GEN2_CPG select CLK_RENESAS_DIV6 @@ -119,10 +110,14 @@ config CLK_R8A7795 bool "R-Car H3 clock support" if COMPILE_TEST select CLK_RCAR_GEN3_CPG -config CLK_R8A7796 +config CLK_R8A77960 bool "R-Car M3-W clock support" if COMPILE_TEST select CLK_RCAR_GEN3_CPG +config CLK_R8A77961 + bool "R-Car M3-W+ clock support" if COMPILE_TEST + select CLK_RCAR_GEN3_CPG + config CLK_R8A77965 bool "R-Car M3-N clock support" if COMPILE_TEST select CLK_RCAR_GEN3_CPG @@ -155,11 +150,6 @@ config CLK_SH73A0 # Family -config CLK_RCAR_GEN2 - bool "R-Car Gen2 legacy clock support" if COMPILE_TEST - select CLK_RENESAS_CPG_MSTP - select CLK_RENESAS_DIV6 - config CLK_RCAR_GEN2_CPG bool "R-Car Gen2 CPG clock support" if COMPILE_TEST select CLK_RENESAS_CPG_MSSR diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile index c793e3cc9452..4a722bc5aac7 100644 --- a/drivers/clk/renesas/Makefile +++ b/drivers/clk/renesas/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_CLK_R8A7743) += r8a7743-cpg-mssr.o obj-$(CONFIG_CLK_R8A7745) += r8a7745-cpg-mssr.o obj-$(CONFIG_CLK_R8A77470) += r8a77470-cpg-mssr.o obj-$(CONFIG_CLK_R8A774A1) += r8a774a1-cpg-mssr.o +obj-$(CONFIG_CLK_R8A774B1) += r8a774b1-cpg-mssr.o obj-$(CONFIG_CLK_R8A774C0) += r8a774c0-cpg-mssr.o obj-$(CONFIG_CLK_R8A7778) += clk-r8a7778.o obj-$(CONFIG_CLK_R8A7779) += clk-r8a7779.o @@ -17,7 +18,8 @@ obj-$(CONFIG_CLK_R8A7791) += r8a7791-cpg-mssr.o obj-$(CONFIG_CLK_R8A7792) += r8a7792-cpg-mssr.o obj-$(CONFIG_CLK_R8A7794) += r8a7794-cpg-mssr.o obj-$(CONFIG_CLK_R8A7795) += r8a7795-cpg-mssr.o -obj-$(CONFIG_CLK_R8A7796) += r8a7796-cpg-mssr.o +obj-$(CONFIG_CLK_R8A77960) += r8a7796-cpg-mssr.o +obj-$(CONFIG_CLK_R8A77961) += r8a7796-cpg-mssr.o obj-$(CONFIG_CLK_R8A77965) += r8a77965-cpg-mssr.o obj-$(CONFIG_CLK_R8A77970) += r8a77970-cpg-mssr.o obj-$(CONFIG_CLK_R8A77980) += r8a77980-cpg-mssr.o @@ -27,7 +29,6 @@ obj-$(CONFIG_CLK_R9A06G032) += r9a06g032-clocks.o obj-$(CONFIG_CLK_SH73A0) += clk-sh73a0.o # Family -obj-$(CONFIG_CLK_RCAR_GEN2) += clk-rcar-gen2.o obj-$(CONFIG_CLK_RCAR_GEN2_CPG) += rcar-gen2-cpg.o obj-$(CONFIG_CLK_RCAR_GEN3_CPG) += rcar-gen3-cpg.o obj-$(CONFIG_CLK_RCAR_USB2_CLOCK_SEL) += rcar-usb2-clock-sel.o diff --git a/drivers/clk/renesas/clk-mstp.c b/drivers/clk/renesas/clk-mstp.c index e326e6dc09fc..003e9ce45757 100644 --- a/drivers/clk/renesas/clk-mstp.c +++ b/drivers/clk/renesas/clk-mstp.c @@ -189,10 +189,8 @@ static void __init cpg_mstp_clocks_init(struct device_node *np) unsigned int i; group = kzalloc(struct_size(group, clks, MSTP_MAX_CLOCKS), GFP_KERNEL); - if (group == NULL) { - kfree(group); + if (!group) return; - } clks = group->clks; spin_lock_init(&group->lock); diff --git a/drivers/clk/renesas/clk-rcar-gen2.c b/drivers/clk/renesas/clk-rcar-gen2.c deleted file mode 100644 index da9fe3f032eb..000000000000 --- a/drivers/clk/renesas/clk-rcar-gen2.c +++ /dev/null @@ -1,457 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * rcar_gen2 Core CPG Clocks - * - * Copyright (C) 2013 Ideas On Board SPRL - * - * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com> - */ - -#include <linux/clk-provider.h> -#include <linux/clk/renesas.h> -#include <linux/init.h> -#include <linux/io.h> -#include <linux/kernel.h> -#include <linux/math64.h> -#include <linux/of.h> -#include <linux/of_address.h> -#include <linux/slab.h> -#include <linux/spinlock.h> -#include <linux/soc/renesas/rcar-rst.h> - -struct rcar_gen2_cpg { - struct clk_onecell_data data; - spinlock_t lock; - void __iomem *reg; -}; - -#define CPG_FRQCRB 0x00000004 -#define CPG_FRQCRB_KICK BIT(31) -#define CPG_SDCKCR 0x00000074 -#define CPG_PLL0CR 0x000000d8 -#define CPG_FRQCRC 0x000000e0 -#define CPG_FRQCRC_ZFC_MASK (0x1f << 8) -#define CPG_FRQCRC_ZFC_SHIFT 8 -#define CPG_ADSPCKCR 0x0000025c -#define CPG_RCANCKCR 0x00000270 - -/* ----------------------------------------------------------------------------- - * Z Clock - * - * Traits of this clock: - * prepare - clk_prepare only ensures that parents are prepared - * enable - clk_enable only ensures that parents are enabled - * rate - rate is adjustable. clk->rate = parent->rate * mult / 32 - * parent - fixed parent. No clk_set_parent support - */ - -struct cpg_z_clk { - struct clk_hw hw; - void __iomem *reg; - void __iomem *kick_reg; -}; - -#define to_z_clk(_hw) container_of(_hw, struct cpg_z_clk, hw) - -static unsigned long cpg_z_clk_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct cpg_z_clk *zclk = to_z_clk(hw); - unsigned int mult; - unsigned int val; - - val = (readl(zclk->reg) & CPG_FRQCRC_ZFC_MASK) >> CPG_FRQCRC_ZFC_SHIFT; - mult = 32 - val; - - return div_u64((u64)parent_rate * mult, 32); -} - -static long cpg_z_clk_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) -{ - unsigned long prate = *parent_rate; - unsigned int mult; - - if (!prate) - prate = 1; - - mult = div_u64((u64)rate * 32, prate); - mult = clamp(mult, 1U, 32U); - - return *parent_rate / 32 * mult; -} - -static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) -{ - struct cpg_z_clk *zclk = to_z_clk(hw); - unsigned int mult; - u32 val, kick; - unsigned int i; - - mult = div_u64((u64)rate * 32, parent_rate); - mult = clamp(mult, 1U, 32U); - - if (readl(zclk->kick_reg) & CPG_FRQCRB_KICK) - return -EBUSY; - - val = readl(zclk->reg); - val &= ~CPG_FRQCRC_ZFC_MASK; - val |= (32 - mult) << CPG_FRQCRC_ZFC_SHIFT; - writel(val, zclk->reg); - - /* - * Set KICK bit in FRQCRB to update hardware setting and wait for - * clock change completion. - */ - kick = readl(zclk->kick_reg); - kick |= CPG_FRQCRB_KICK; - writel(kick, zclk->kick_reg); - - /* - * Note: There is no HW information about the worst case latency. - * - * Using experimental measurements, it seems that no more than - * ~10 iterations are needed, independently of the CPU rate. - * Since this value might be dependent on external xtal rate, pll1 - * rate or even the other emulation clocks rate, use 1000 as a - * "super" safe value. - */ - for (i = 1000; i; i--) { - if (!(readl(zclk->kick_reg) & CPG_FRQCRB_KICK)) - return 0; - - cpu_relax(); - } - - return -ETIMEDOUT; -} - -static const struct clk_ops cpg_z_clk_ops = { - .recalc_rate = cpg_z_clk_recalc_rate, - .round_rate = cpg_z_clk_round_rate, - .set_rate = cpg_z_clk_set_rate, -}; - -static struct clk * __init cpg_z_clk_register(struct rcar_gen2_cpg *cpg) -{ - static const char *parent_name = "pll0"; - struct clk_init_data init; - struct cpg_z_clk *zclk; - struct clk *clk; - - zclk = kzalloc(sizeof(*zclk), GFP_KERNEL); - if (!zclk) - return ERR_PTR(-ENOMEM); - - init.name = "z"; - init.ops = &cpg_z_clk_ops; - init.flags = 0; - init.parent_names = &parent_name; - init.num_parents = 1; - - zclk->reg = cpg->reg + CPG_FRQCRC; - zclk->kick_reg = cpg->reg + CPG_FRQCRB; - zclk->hw.init = &init; - - clk = clk_register(NULL, &zclk->hw); - if (IS_ERR(clk)) - kfree(zclk); - - return clk; -} - -static struct clk * __init cpg_rcan_clk_register(struct rcar_gen2_cpg *cpg, - struct device_node *np) -{ - const char *parent_name = of_clk_get_parent_name(np, 1); - struct clk_fixed_factor *fixed; - struct clk_gate *gate; - struct clk *clk; - - fixed = kzalloc(sizeof(*fixed), GFP_KERNEL); - if (!fixed) - return ERR_PTR(-ENOMEM); - - fixed->mult = 1; - fixed->div = 6; - - gate = kzalloc(sizeof(*gate), GFP_KERNEL); - if (!gate) { - kfree(fixed); - return ERR_PTR(-ENOMEM); - } - - gate->reg = cpg->reg + CPG_RCANCKCR; - gate->bit_idx = 8; - gate->flags = CLK_GATE_SET_TO_DISABLE; - gate->lock = &cpg->lock; - - clk = clk_register_composite(NULL, "rcan", &parent_name, 1, NULL, NULL, - &fixed->hw, &clk_fixed_factor_ops, - &gate->hw, &clk_gate_ops, 0); - if (IS_ERR(clk)) { - kfree(gate); - kfree(fixed); - } - - return clk; -} - -/* ADSP divisors */ -static const struct clk_div_table cpg_adsp_div_table[] = { - { 1, 3 }, { 2, 4 }, { 3, 6 }, { 4, 8 }, - { 5, 12 }, { 6, 16 }, { 7, 18 }, { 8, 24 }, - { 10, 36 }, { 11, 48 }, { 0, 0 }, -}; - -static struct clk * __init cpg_adsp_clk_register(struct rcar_gen2_cpg *cpg) -{ - const char *parent_name = "pll1"; - struct clk_divider *div; - struct clk_gate *gate; - struct clk *clk; - - div = kzalloc(sizeof(*div), GFP_KERNEL); - if (!div) - return ERR_PTR(-ENOMEM); - - div->reg = cpg->reg + CPG_ADSPCKCR; - div->width = 4; - div->table = cpg_adsp_div_table; - div->lock = &cpg->lock; - - gate = kzalloc(sizeof(*gate), GFP_KERNEL); - if (!gate) { - kfree(div); - return ERR_PTR(-ENOMEM); - } - - gate->reg = cpg->reg + CPG_ADSPCKCR; - gate->bit_idx = 8; - gate->flags = CLK_GATE_SET_TO_DISABLE; - gate->lock = &cpg->lock; - - clk = clk_register_composite(NULL, "adsp", &parent_name, 1, NULL, NULL, - &div->hw, &clk_divider_ops, - &gate->hw, &clk_gate_ops, 0); - if (IS_ERR(clk)) { - kfree(gate); - kfree(div); - } - - return clk; -} - -/* ----------------------------------------------------------------------------- - * CPG Clock Data - */ - -/* - * MD EXTAL PLL0 PLL1 PLL3 - * 14 13 19 (MHz) *1 *1 - *--------------------------------------------------- - * 0 0 0 15 x 1 x172/2 x208/2 x106 - * 0 0 1 15 x 1 x172/2 x208/2 x88 - * 0 1 0 20 x 1 x130/2 x156/2 x80 - * 0 1 1 20 x 1 x130/2 x156/2 x66 - * 1 0 0 26 / 2 x200/2 x240/2 x122 - * 1 0 1 26 / 2 x200/2 x240/2 x102 - * 1 1 0 30 / 2 x172/2 x208/2 x106 - * 1 1 1 30 / 2 x172/2 x208/2 x88 - * - * *1 : Table 7.6 indicates VCO output (PLLx = VCO/2) - */ -#define CPG_PLL_CONFIG_INDEX(md) ((((md) & BIT(14)) >> 12) | \ - (((md) & BIT(13)) >> 12) | \ - (((md) & BIT(19)) >> 19)) -struct cpg_pll_config { - unsigned int extal_div; - unsigned int pll1_mult; - unsigned int pll3_mult; - unsigned int pll0_mult; /* For R-Car V2H and E2 only */ -}; - -static const struct cpg_pll_config cpg_pll_configs[8] __initconst = { - { 1, 208, 106, 200 }, { 1, 208, 88, 200 }, - { 1, 156, 80, 150 }, { 1, 156, 66, 150 }, - { 2, 240, 122, 230 }, { 2, 240, 102, 230 }, - { 2, 208, 106, 200 }, { 2, 208, 88, 200 }, -}; - -/* SDHI divisors */ -static const struct clk_div_table cpg_sdh_div_table[] = { - { 0, 2 }, { 1, 3 }, { 2, 4 }, { 3, 6 }, - { 4, 8 }, { 5, 12 }, { 6, 16 }, { 7, 18 }, - { 8, 24 }, { 10, 36 }, { 11, 48 }, { 0, 0 }, -}; - -static const struct clk_div_table cpg_sd01_div_table[] = { - { 4, 8 }, - { 5, 12 }, { 6, 16 }, { 7, 18 }, { 8, 24 }, - { 10, 36 }, { 11, 48 }, { 12, 10 }, { 0, 0 }, -}; - -/* ----------------------------------------------------------------------------- - * Initialization - */ - -static u32 cpg_mode __initdata; - -static const char * const pll0_mult_match[] = { - "renesas,r8a7792-cpg-clocks", - "renesas,r8a7794-cpg-clocks", - NULL -}; - -static struct clk * __init -rcar_gen2_cpg_register_clock(struct device_node *np, struct rcar_gen2_cpg *cpg, - const struct cpg_pll_config *config, - const char *name) -{ - const struct clk_div_table *table = NULL; - const char *parent_name; - unsigned int shift; - unsigned int mult = 1; - unsigned int div = 1; - - if (!strcmp(name, "main")) { - parent_name = of_clk_get_parent_name(np, 0); - div = config->extal_div; - } else if (!strcmp(name, "pll0")) { - /* PLL0 is a configurable multiplier clock. Register it as a - * fixed factor clock for now as there's no generic multiplier - * clock implementation and we currently have no need to change - * the multiplier value. - */ - if (of_device_compatible_match(np, pll0_mult_match)) { - /* R-Car V2H and E2 do not have PLL0CR */ - mult = config->pll0_mult; - div = 3; - } else { - u32 value = readl(cpg->reg + CPG_PLL0CR); - mult = ((value >> 24) & ((1 << 7) - 1)) + 1; - } - parent_name = "main"; - } else if (!strcmp(name, "pll1")) { - parent_name = "main"; - mult = config->pll1_mult / 2; - } else if (!strcmp(name, "pll3")) { - parent_name = "main"; - mult = config->pll3_mult; - } else if (!strcmp(name, "lb")) { - parent_name = "pll1"; - div = cpg_mode & BIT(18) ? 36 : 24; - } else if (!strcmp(name, "qspi")) { - parent_name = "pll1_div2"; - div = (cpg_mode & (BIT(3) | BIT(2) | BIT(1))) == BIT(2) - ? 8 : 10; - } else if (!strcmp(name, "sdh")) { - parent_name = "pll1"; - table = cpg_sdh_div_table; - shift = 8; - } else if (!strcmp(name, "sd0")) { - parent_name = "pll1"; - table = cpg_sd01_div_table; - shift = 4; - } else if (!strcmp(name, "sd1")) { - parent_name = "pll1"; - table = cpg_sd01_div_table; - shift = 0; - } else if (!strcmp(name, "z")) { - return cpg_z_clk_register(cpg); - } else if (!strcmp(name, "rcan")) { - return cpg_rcan_clk_register(cpg, np); - } else if (!strcmp(name, "adsp")) { - return cpg_adsp_clk_register(cpg); - } else { - return ERR_PTR(-EINVAL); - } - - if (!table) - return clk_register_fixed_factor(NULL, name, parent_name, 0, - mult, div); - else - return clk_register_divider_table(NULL, name, parent_name, 0, - cpg->reg + CPG_SDCKCR, shift, - 4, 0, table, &cpg->lock); -} - -/* - * Reset register definitions. - */ -#define MODEMR 0xe6160060 - -static u32 __init rcar_gen2_read_mode_pins(void) -{ - void __iomem *modemr = ioremap_nocache(MODEMR, 4); - u32 mode; - - BUG_ON(!modemr); - mode = ioread32(modemr); - iounmap(modemr); - - return mode; -} - -static void __init rcar_gen2_cpg_clocks_init(struct device_node *np) -{ - const struct cpg_pll_config *config; - struct rcar_gen2_cpg *cpg; - struct clk **clks; - unsigned int i; - int num_clks; - - if (rcar_rst_read_mode_pins(&cpg_mode)) { - /* Backward-compatibility with old DT */ - pr_warn("%pOF: failed to obtain mode pins from RST\n", np); - cpg_mode = rcar_gen2_read_mode_pins(); - } - - num_clks = of_property_count_strings(np, "clock-output-names"); - if (num_clks < 0) { - pr_err("%s: failed to count clocks\n", __func__); - return; - } - - cpg = kzalloc(sizeof(*cpg), GFP_KERNEL); - clks = kcalloc(num_clks, sizeof(*clks), GFP_KERNEL); - if (cpg == NULL || clks == NULL) { - /* We're leaking memory on purpose, there's no point in cleaning - * up as the system won't boot anyway. - */ - return; - } - - spin_lock_init(&cpg->lock); - - cpg->data.clks = clks; - cpg->data.clk_num = num_clks; - - cpg->reg = of_iomap(np, 0); - if (WARN_ON(cpg->reg == NULL)) - return; - - config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)]; - - for (i = 0; i < num_clks; ++i) { - const char *name; - struct clk *clk; - - of_property_read_string_index(np, "clock-output-names", i, - &name); - - clk = rcar_gen2_cpg_register_clock(np, cpg, config, name); - if (IS_ERR(clk)) - pr_err("%s: failed to register %pOFn %s clock (%ld)\n", - __func__, np, name, PTR_ERR(clk)); - else - cpg->data.clks[i] = clk; - } - - of_clk_add_provider(np, of_clk_src_onecell_get, &cpg->data); - - cpg_mstp_add_clk_domain(np); -} -CLK_OF_DECLARE(rcar_gen2_cpg_clks, "renesas,rcar-gen2-cpg-clocks", - rcar_gen2_cpg_clocks_init); diff --git a/drivers/clk/renesas/r8a774b1-cpg-mssr.c b/drivers/clk/renesas/r8a774b1-cpg-mssr.c new file mode 100644 index 000000000000..c9af70917312 --- /dev/null +++ b/drivers/clk/renesas/r8a774b1-cpg-mssr.c @@ -0,0 +1,327 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * r8a774b1 Clock Pulse Generator / Module Standby and Software Reset + * + * Copyright (C) 2019 Renesas Electronics Corp. + * + * Based on r8a7796-cpg-mssr.c + * + * Copyright (C) 2016 Glider bvba + */ + +#include <linux/device.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/soc/renesas/rcar-rst.h> + +#include <dt-bindings/clock/r8a774b1-cpg-mssr.h> + +#include "renesas-cpg-mssr.h" +#include "rcar-gen3-cpg.h" + +enum clk_ids { + /* Core Clock Outputs exported to DT */ + LAST_DT_CORE_CLK = R8A774B1_CLK_CANFD, + + /* External Input Clocks */ + CLK_EXTAL, + CLK_EXTALR, + + /* Internal Core Clocks */ + CLK_MAIN, + CLK_PLL0, + CLK_PLL1, + CLK_PLL3, + CLK_PLL4, + CLK_PLL1_DIV2, + CLK_PLL1_DIV4, + CLK_S0, + CLK_S1, + CLK_S2, + CLK_S3, + CLK_SDSRC, + CLK_RINT, + + /* Module Clocks */ + MOD_CLK_BASE +}; + +static const struct cpg_core_clk r8a774b1_core_clks[] __initconst = { + /* External Clock Inputs */ + DEF_INPUT("extal", CLK_EXTAL), + DEF_INPUT("extalr", CLK_EXTALR), + + /* Internal Core Clocks */ + DEF_BASE(".main", CLK_MAIN, CLK_TYPE_GEN3_MAIN, CLK_EXTAL), + DEF_BASE(".pll0", CLK_PLL0, CLK_TYPE_GEN3_PLL0, CLK_MAIN), + DEF_BASE(".pll1", CLK_PLL1, CLK_TYPE_GEN3_PLL1, CLK_MAIN), + DEF_BASE(".pll3", CLK_PLL3, CLK_TYPE_GEN3_PLL3, CLK_MAIN), + DEF_BASE(".pll4", CLK_PLL4, CLK_TYPE_GEN3_PLL4, CLK_MAIN), + + DEF_FIXED(".pll1_div2", CLK_PLL1_DIV2, CLK_PLL1, 2, 1), + DEF_FIXED(".pll1_div4", CLK_PLL1_DIV4, CLK_PLL1_DIV2, 2, 1), + DEF_FIXED(".s0", CLK_S0, CLK_PLL1_DIV2, 2, 1), + DEF_FIXED(".s1", CLK_S1, CLK_PLL1_DIV2, 3, 1), + DEF_FIXED(".s2", CLK_S2, CLK_PLL1_DIV2, 4, 1), + DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 6, 1), + DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1_DIV2, 2, 1), + + DEF_GEN3_OSC(".r", CLK_RINT, CLK_EXTAL, 32), + + /* Core Clock Outputs */ + DEF_GEN3_Z("z", R8A774B1_CLK_Z, CLK_TYPE_GEN3_Z, CLK_PLL0, 2, 8), + DEF_FIXED("ztr", R8A774B1_CLK_ZTR, CLK_PLL1_DIV2, 6, 1), + DEF_FIXED("ztrd2", R8A774B1_CLK_ZTRD2, CLK_PLL1_DIV2, 12, 1), + DEF_FIXED("zt", R8A774B1_CLK_ZT, CLK_PLL1_DIV2, 4, 1), + DEF_FIXED("zx", R8A774B1_CLK_ZX, CLK_PLL1_DIV2, 2, 1), + DEF_FIXED("s0d1", R8A774B1_CLK_S0D1, CLK_S0, 1, 1), + DEF_FIXED("s0d2", R8A774B1_CLK_S0D2, CLK_S0, 2, 1), + DEF_FIXED("s0d3", R8A774B1_CLK_S0D3, CLK_S0, 3, 1), + DEF_FIXED("s0d4", R8A774B1_CLK_S0D4, CLK_S0, 4, 1), + DEF_FIXED("s0d6", R8A774B1_CLK_S0D6, CLK_S0, 6, 1), + DEF_FIXED("s0d8", R8A774B1_CLK_S0D8, CLK_S0, 8, 1), + DEF_FIXED("s0d12", R8A774B1_CLK_S0D12, CLK_S0, 12, 1), + DEF_FIXED("s1d2", R8A774B1_CLK_S1D2, CLK_S1, 2, 1), + DEF_FIXED("s1d4", R8A774B1_CLK_S1D4, CLK_S1, 4, 1), + DEF_FIXED("s2d1", R8A774B1_CLK_S2D1, CLK_S2, 1, 1), + DEF_FIXED("s2d2", R8A774B1_CLK_S2D2, CLK_S2, 2, 1), + DEF_FIXED("s2d4", R8A774B1_CLK_S2D4, CLK_S2, 4, 1), + DEF_FIXED("s3d1", R8A774B1_CLK_S3D1, CLK_S3, 1, 1), + DEF_FIXED("s3d2", R8A774B1_CLK_S3D2, CLK_S3, 2, 1), + DEF_FIXED("s3d4", R8A774B1_CLK_S3D4, CLK_S3, 4, 1), + + DEF_GEN3_SD("sd0", R8A774B1_CLK_SD0, CLK_SDSRC, 0x074), + DEF_GEN3_SD("sd1", R8A774B1_CLK_SD1, CLK_SDSRC, 0x078), + DEF_GEN3_SD("sd2", R8A774B1_CLK_SD2, CLK_SDSRC, 0x268), + DEF_GEN3_SD("sd3", R8A774B1_CLK_SD3, CLK_SDSRC, 0x26c), + + DEF_FIXED("cl", R8A774B1_CLK_CL, CLK_PLL1_DIV2, 48, 1), + DEF_FIXED("cp", R8A774B1_CLK_CP, CLK_EXTAL, 2, 1), + DEF_FIXED("cpex", R8A774B1_CLK_CPEX, CLK_EXTAL, 2, 1), + + DEF_DIV6P1("canfd", R8A774B1_CLK_CANFD, CLK_PLL1_DIV4, 0x244), + DEF_DIV6P1("csi0", R8A774B1_CLK_CSI0, CLK_PLL1_DIV4, 0x00c), + DEF_DIV6P1("mso", R8A774B1_CLK_MSO, CLK_PLL1_DIV4, 0x014), + DEF_DIV6P1("hdmi", R8A774B1_CLK_HDMI, CLK_PLL1_DIV4, 0x250), + + DEF_GEN3_OSC("osc", R8A774B1_CLK_OSC, CLK_EXTAL, 8), + + DEF_BASE("r", R8A774B1_CLK_R, CLK_TYPE_GEN3_R, CLK_RINT), +}; + +static const struct mssr_mod_clk r8a774b1_mod_clks[] __initconst = { + DEF_MOD("tmu4", 121, R8A774B1_CLK_S0D6), + DEF_MOD("tmu3", 122, R8A774B1_CLK_S3D2), + DEF_MOD("tmu2", 123, R8A774B1_CLK_S3D2), + DEF_MOD("tmu1", 124, R8A774B1_CLK_S3D2), + DEF_MOD("tmu0", 125, R8A774B1_CLK_CP), + DEF_MOD("fdp1-0", 119, R8A774B1_CLK_S0D1), + DEF_MOD("scif5", 202, R8A774B1_CLK_S3D4), + DEF_MOD("scif4", 203, R8A774B1_CLK_S3D4), + DEF_MOD("scif3", 204, R8A774B1_CLK_S3D4), + DEF_MOD("scif1", 206, R8A774B1_CLK_S3D4), + DEF_MOD("scif0", 207, R8A774B1_CLK_S3D4), + DEF_MOD("msiof3", 208, R8A774B1_CLK_MSO), + DEF_MOD("msiof2", 209, R8A774B1_CLK_MSO), + DEF_MOD("msiof1", 210, R8A774B1_CLK_MSO), + DEF_MOD("msiof0", 211, R8A774B1_CLK_MSO), + DEF_MOD("sys-dmac2", 217, R8A774B1_CLK_S3D1), + DEF_MOD("sys-dmac1", 218, R8A774B1_CLK_S3D1), + DEF_MOD("sys-dmac0", 219, R8A774B1_CLK_S0D3), + DEF_MOD("cmt3", 300, R8A774B1_CLK_R), + DEF_MOD("cmt2", 301, R8A774B1_CLK_R), + DEF_MOD("cmt1", 302, R8A774B1_CLK_R), + DEF_MOD("cmt0", 303, R8A774B1_CLK_R), + DEF_MOD("tpu0", 304, R8A774B1_CLK_S3D4), + DEF_MOD("scif2", 310, R8A774B1_CLK_S3D4), + DEF_MOD("sdif3", 311, R8A774B1_CLK_SD3), + DEF_MOD("sdif2", 312, R8A774B1_CLK_SD2), + DEF_MOD("sdif1", 313, R8A774B1_CLK_SD1), + DEF_MOD("sdif0", 314, R8A774B1_CLK_SD0), + DEF_MOD("pcie1", 318, R8A774B1_CLK_S3D1), + DEF_MOD("pcie0", 319, R8A774B1_CLK_S3D1), + DEF_MOD("usb3-if0", 328, R8A774B1_CLK_S3D1), + DEF_MOD("usb-dmac0", 330, R8A774B1_CLK_S3D1), + DEF_MOD("usb-dmac1", 331, R8A774B1_CLK_S3D1), + DEF_MOD("rwdt", 402, R8A774B1_CLK_R), + DEF_MOD("intc-ex", 407, R8A774B1_CLK_CP), + DEF_MOD("intc-ap", 408, R8A774B1_CLK_S0D3), + DEF_MOD("audmac1", 501, R8A774B1_CLK_S1D2), + DEF_MOD("audmac0", 502, R8A774B1_CLK_S1D2), + DEF_MOD("hscif4", 516, R8A774B1_CLK_S3D1), + DEF_MOD("hscif3", 517, R8A774B1_CLK_S3D1), + DEF_MOD("hscif2", 518, R8A774B1_CLK_S3D1), + DEF_MOD("hscif1", 519, R8A774B1_CLK_S3D1), + DEF_MOD("hscif0", 520, R8A774B1_CLK_S3D1), + DEF_MOD("thermal", 522, R8A774B1_CLK_CP), + DEF_MOD("pwm", 523, R8A774B1_CLK_S0D12), + DEF_MOD("fcpvd1", 602, R8A774B1_CLK_S0D2), + DEF_MOD("fcpvd0", 603, R8A774B1_CLK_S0D2), + DEF_MOD("fcpvb0", 607, R8A774B1_CLK_S0D1), + DEF_MOD("fcpvi0", 611, R8A774B1_CLK_S0D1), + DEF_MOD("fcpf0", 615, R8A774B1_CLK_S0D1), + DEF_MOD("fcpcs", 619, R8A774B1_CLK_S0D2), + DEF_MOD("vspd1", 622, R8A774B1_CLK_S0D2), + DEF_MOD("vspd0", 623, R8A774B1_CLK_S0D2), + DEF_MOD("vspb", 626, R8A774B1_CLK_S0D1), + DEF_MOD("vspi0", 631, R8A774B1_CLK_S0D1), + DEF_MOD("ehci1", 702, R8A774B1_CLK_S3D2), + DEF_MOD("ehci0", 703, R8A774B1_CLK_S3D2), + DEF_MOD("hsusb", 704, R8A774B1_CLK_S3D2), + DEF_MOD("csi20", 714, R8A774B1_CLK_CSI0), + DEF_MOD("csi40", 716, R8A774B1_CLK_CSI0), + DEF_MOD("du3", 721, R8A774B1_CLK_S2D1), + DEF_MOD("du1", 723, R8A774B1_CLK_S2D1), + DEF_MOD("du0", 724, R8A774B1_CLK_S2D1), + DEF_MOD("lvds", 727, R8A774B1_CLK_S2D1), + DEF_MOD("hdmi0", 729, R8A774B1_CLK_HDMI), + DEF_MOD("vin7", 804, R8A774B1_CLK_S0D2), + DEF_MOD("vin6", 805, R8A774B1_CLK_S0D2), + DEF_MOD("vin5", 806, R8A774B1_CLK_S0D2), + DEF_MOD("vin4", 807, R8A774B1_CLK_S0D2), + DEF_MOD("vin3", 808, R8A774B1_CLK_S0D2), + DEF_MOD("vin2", 809, R8A774B1_CLK_S0D2), + DEF_MOD("vin1", 810, R8A774B1_CLK_S0D2), + DEF_MOD("vin0", 811, R8A774B1_CLK_S0D2), + DEF_MOD("etheravb", 812, R8A774B1_CLK_S0D6), + DEF_MOD("sata0", 815, R8A774B1_CLK_S3D2), + DEF_MOD("gpio7", 905, R8A774B1_CLK_S3D4), + DEF_MOD("gpio6", 906, R8A774B1_CLK_S3D4), + DEF_MOD("gpio5", 907, R8A774B1_CLK_S3D4), + DEF_MOD("gpio4", 908, R8A774B1_CLK_S3D4), + DEF_MOD("gpio3", 909, R8A774B1_CLK_S3D4), + DEF_MOD("gpio2", 910, R8A774B1_CLK_S3D4), + DEF_MOD("gpio1", 911, R8A774B1_CLK_S3D4), + DEF_MOD("gpio0", 912, R8A774B1_CLK_S3D4), + DEF_MOD("can-fd", 914, R8A774B1_CLK_S3D2), + DEF_MOD("can-if1", 915, R8A774B1_CLK_S3D4), + DEF_MOD("can-if0", 916, R8A774B1_CLK_S3D4), + DEF_MOD("i2c6", 918, R8A774B1_CLK_S0D6), + DEF_MOD("i2c5", 919, R8A774B1_CLK_S0D6), + DEF_MOD("i2c-dvfs", 926, R8A774B1_CLK_CP), + DEF_MOD("i2c4", 927, R8A774B1_CLK_S0D6), + DEF_MOD("i2c3", 928, R8A774B1_CLK_S0D6), + DEF_MOD("i2c2", 929, R8A774B1_CLK_S3D2), + DEF_MOD("i2c1", 930, R8A774B1_CLK_S3D2), + DEF_MOD("i2c0", 931, R8A774B1_CLK_S3D2), + DEF_MOD("ssi-all", 1005, R8A774B1_CLK_S3D4), + DEF_MOD("ssi9", 1006, MOD_CLK_ID(1005)), + DEF_MOD("ssi8", 1007, MOD_CLK_ID(1005)), + DEF_MOD("ssi7", 1008, MOD_CLK_ID(1005)), + DEF_MOD("ssi6", 1009, MOD_CLK_ID(1005)), + DEF_MOD("ssi5", 1010, MOD_CLK_ID(1005)), + DEF_MOD("ssi4", 1011, MOD_CLK_ID(1005)), + DEF_MOD("ssi3", 1012, MOD_CLK_ID(1005)), + DEF_MOD("ssi2", 1013, MOD_CLK_ID(1005)), + DEF_MOD("ssi1", 1014, MOD_CLK_ID(1005)), + DEF_MOD("ssi0", 1015, MOD_CLK_ID(1005)), + DEF_MOD("scu-all", 1017, R8A774B1_CLK_S3D4), + DEF_MOD("scu-dvc1", 1018, MOD_CLK_ID(1017)), + DEF_MOD("scu-dvc0", 1019, MOD_CLK_ID(1017)), + DEF_MOD("scu-ctu1-mix1", 1020, MOD_CLK_ID(1017)), + DEF_MOD("scu-ctu0-mix0", 1021, MOD_CLK_ID(1017)), + DEF_MOD("scu-src9", 1022, MOD_CLK_ID(1017)), + DEF_MOD("scu-src8", 1023, MOD_CLK_ID(1017)), + DEF_MOD("scu-src7", 1024, MOD_CLK_ID(1017)), + DEF_MOD("scu-src6", 1025, MOD_CLK_ID(1017)), + DEF_MOD("scu-src5", 1026, MOD_CLK_ID(1017)), + DEF_MOD("scu-src4", 1027, MOD_CLK_ID(1017)), + DEF_MOD("scu-src3", 1028, MOD_CLK_ID(1017)), + DEF_MOD("scu-src2", 1029, MOD_CLK_ID(1017)), + DEF_MOD("scu-src1", 1030, MOD_CLK_ID(1017)), + DEF_MOD("scu-src0", 1031, MOD_CLK_ID(1017)), +}; + +static const unsigned int r8a774b1_crit_mod_clks[] __initconst = { + MOD_CLK_ID(408), /* INTC-AP (GIC) */ +}; + +/* + * CPG Clock Data + */ + +/* + * MD EXTAL PLL0 PLL1 PLL3 PLL4 OSC + * 14 13 19 17 (MHz) + *----------------------------------------------------------------- + * 0 0 0 0 16.66 x 1 x180 x192 x192 x144 /16 + * 0 0 0 1 16.66 x 1 x180 x192 x128 x144 /16 + * 0 0 1 0 Prohibited setting + * 0 0 1 1 16.66 x 1 x180 x192 x192 x144 /16 + * 0 1 0 0 20 x 1 x150 x160 x160 x120 /19 + * 0 1 0 1 20 x 1 x150 x160 x106 x120 /19 + * 0 1 1 0 Prohibited setting + * 0 1 1 1 20 x 1 x150 x160 x160 x120 /19 + * 1 0 0 0 25 x 1 x120 x128 x128 x96 /24 + * 1 0 0 1 25 x 1 x120 x128 x84 x96 /24 + * 1 0 1 0 Prohibited setting + * 1 0 1 1 25 x 1 x120 x128 x128 x96 /24 + * 1 1 0 0 33.33 / 2 x180 x192 x192 x144 /32 + * 1 1 0 1 33.33 / 2 x180 x192 x128 x144 /32 + * 1 1 1 0 Prohibited setting + * 1 1 1 1 33.33 / 2 x180 x192 x192 x144 /32 + */ +#define CPG_PLL_CONFIG_INDEX(md) ((((md) & BIT(14)) >> 11) | \ + (((md) & BIT(13)) >> 11) | \ + (((md) & BIT(19)) >> 18) | \ + (((md) & BIT(17)) >> 17)) + +static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[16] __initconst = { + /* EXTAL div PLL1 mult/div PLL3 mult/div OSC prediv */ + { 1, 192, 1, 192, 1, 16, }, + { 1, 192, 1, 128, 1, 16, }, + { 0, /* Prohibited setting */ }, + { 1, 192, 1, 192, 1, 16, }, + { 1, 160, 1, 160, 1, 19, }, + { 1, 160, 1, 106, 1, 19, }, + { 0, /* Prohibited setting */ }, + { 1, 160, 1, 160, 1, 19, }, + { 1, 128, 1, 128, 1, 24, }, + { 1, 128, 1, 84, 1, 24, }, + { 0, /* Prohibited setting */ }, + { 1, 128, 1, 128, 1, 24, }, + { 2, 192, 1, 192, 1, 32, }, + { 2, 192, 1, 128, 1, 32, }, + { 0, /* Prohibited setting */ }, + { 2, 192, 1, 192, 1, 32, }, +}; + +static int __init r8a774b1_cpg_mssr_init(struct device *dev) +{ + const struct rcar_gen3_cpg_pll_config *cpg_pll_config; + u32 cpg_mode; + int error; + + error = rcar_rst_read_mode_pins(&cpg_mode); + if (error) + return error; + + cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)]; + if (!cpg_pll_config->extal_div) { + dev_err(dev, "Prohibited setting (cpg_mode=0x%x)\n", cpg_mode); + return -EINVAL; + } + + return rcar_gen3_cpg_init(cpg_pll_config, CLK_EXTALR, cpg_mode); +} + +const struct cpg_mssr_info r8a774b1_cpg_mssr_info __initconst = { + /* Core Clocks */ + .core_clks = r8a774b1_core_clks, + .num_core_clks = ARRAY_SIZE(r8a774b1_core_clks), + .last_dt_core_clk = LAST_DT_CORE_CLK, + .num_total_core_clks = MOD_CLK_BASE, + + /* Module Clocks */ + .mod_clks = r8a774b1_mod_clks, + .num_mod_clks = ARRAY_SIZE(r8a774b1_mod_clks), + .num_hw_mod_clks = 12 * 32, + + /* Critical Module Clocks */ + .crit_mod_clks = r8a774b1_crit_mod_clks, + .num_crit_mod_clks = ARRAY_SIZE(r8a774b1_crit_mod_clks), + + /* Callbacks */ + .init = r8a774b1_cpg_mssr_init, + .cpg_clk_register = rcar_gen3_cpg_clk_register, +}; diff --git a/drivers/clk/renesas/r8a7796-cpg-mssr.c b/drivers/clk/renesas/r8a7796-cpg-mssr.c index 90cc6a102602..e8420d3ada94 100644 --- a/drivers/clk/renesas/r8a7796-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7796-cpg-mssr.c @@ -1,9 +1,10 @@ // SPDX-License-Identifier: GPL-2.0 /* - * r8a7796 Clock Pulse Generator / Module Standby and Software Reset + * r8a7796 (R-Car M3-W/W+) Clock Pulse Generator / Module Standby and Software + * Reset * - * Copyright (C) 2016 Glider bvba - * Copyright (C) 2018 Renesas Electronics Corp. + * Copyright (C) 2016-2019 Glider bvba + * Copyright (C) 2018-2019 Renesas Electronics Corp. * * Based on r8a7795-cpg-mssr.c * @@ -14,6 +15,7 @@ #include <linux/device.h> #include <linux/init.h> #include <linux/kernel.h> +#include <linux/of.h> #include <linux/soc/renesas/rcar-rst.h> #include <dt-bindings/clock/r8a7796-cpg-mssr.h> @@ -116,7 +118,7 @@ static const struct cpg_core_clk r8a7796_core_clks[] __initconst = { DEF_BASE("r", R8A7796_CLK_R, CLK_TYPE_GEN3_R, CLK_RINT), }; -static const struct mssr_mod_clk r8a7796_mod_clks[] __initconst = { +static struct mssr_mod_clk r8a7796_mod_clks[] __initdata = { DEF_MOD("fdp1-0", 119, R8A7796_CLK_S0D1), DEF_MOD("scif5", 202, R8A7796_CLK_S3D4), DEF_MOD("scif4", 203, R8A7796_CLK_S3D4), @@ -304,6 +306,14 @@ static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[16] __initconst = { { 2, 192, 1, 192, 1, 32, }, }; + /* + * Fixups for R-Car M3-W+ + */ + +static const unsigned int r8a77961_mod_nullify[] __initconst = { + MOD_CLK_ID(617), /* FCPCI0 */ +}; + static int __init r8a7796_cpg_mssr_init(struct device *dev) { const struct rcar_gen3_cpg_pll_config *cpg_pll_config; @@ -320,6 +330,12 @@ static int __init r8a7796_cpg_mssr_init(struct device *dev) return -EINVAL; } + if (of_device_is_compatible(dev->of_node, "renesas,r8a77961-cpg-mssr")) + mssr_mod_nullify(r8a7796_mod_clks, + ARRAY_SIZE(r8a7796_mod_clks), + r8a77961_mod_nullify, + ARRAY_SIZE(r8a77961_mod_nullify)); + return rcar_gen3_cpg_init(cpg_pll_config, CLK_EXTALR, cpg_mode); } diff --git a/drivers/clk/renesas/r8a77965-cpg-mssr.c b/drivers/clk/renesas/r8a77965-cpg-mssr.c index b4e8c5b7d515..b3af4da2ca74 100644 --- a/drivers/clk/renesas/r8a77965-cpg-mssr.c +++ b/drivers/clk/renesas/r8a77965-cpg-mssr.c @@ -323,7 +323,7 @@ static int __init r8a77965_cpg_mssr_init(struct device *dev) } return rcar_gen3_cpg_init(cpg_pll_config, CLK_EXTALR, cpg_mode); -}; +} const struct cpg_mssr_info r8a77965_cpg_mssr_info __initconst = { /* Core Clocks */ diff --git a/drivers/clk/renesas/rcar-gen2-cpg.c b/drivers/clk/renesas/rcar-gen2-cpg.c index f596a2dafcf4..d4fa3dc3e2a2 100644 --- a/drivers/clk/renesas/rcar-gen2-cpg.c +++ b/drivers/clk/renesas/rcar-gen2-cpg.c @@ -63,19 +63,22 @@ static unsigned long cpg_z_clk_recalc_rate(struct clk_hw *hw, return div_u64((u64)parent_rate * mult, 32); } -static long cpg_z_clk_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int cpg_z_clk_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { - unsigned long prate = *parent_rate; - unsigned int mult; + unsigned long prate = req->best_parent_rate; + unsigned int min_mult, max_mult, mult; - if (!prate) - prate = 1; + min_mult = max(div64_ul(req->min_rate * 32ULL, prate), 1ULL); + max_mult = min(div64_ul(req->max_rate * 32ULL, prate), 32ULL); + if (max_mult < min_mult) + return -EINVAL; - mult = div_u64((u64)rate * 32, prate); - mult = clamp(mult, 1U, 32U); + mult = div64_ul(req->rate * 32ULL, prate); + mult = clamp(mult, min_mult, max_mult); - return *parent_rate / 32 * mult; + req->rate = div_u64((u64)prate * mult, 32); + return 0; } static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate, @@ -86,7 +89,7 @@ static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate, u32 val, kick; unsigned int i; - mult = div_u64((u64)rate * 32, parent_rate); + mult = div64_ul(rate * 32ULL, parent_rate); mult = clamp(mult, 1U, 32U); if (readl(zclk->kick_reg) & CPG_FRQCRB_KICK) @@ -126,7 +129,7 @@ static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops cpg_z_clk_ops = { .recalc_rate = cpg_z_clk_recalc_rate, - .round_rate = cpg_z_clk_round_rate, + .determine_rate = cpg_z_clk_determine_rate, .set_rate = cpg_z_clk_set_rate, }; diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c index d25c8ba00a65..c97b647db9b6 100644 --- a/drivers/clk/renesas/rcar-gen3-cpg.c +++ b/drivers/clk/renesas/rcar-gen3-cpg.c @@ -114,18 +114,24 @@ static unsigned long cpg_z_clk_recalc_rate(struct clk_hw *hw, 32 * zclk->fixed_div); } -static long cpg_z_clk_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int cpg_z_clk_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct cpg_z_clk *zclk = to_z_clk(hw); + unsigned int min_mult, max_mult, mult; unsigned long prate; - unsigned int mult; - prate = *parent_rate / zclk->fixed_div; - mult = div_u64(rate * 32ULL, prate); - mult = clamp(mult, 1U, 32U); + prate = req->best_parent_rate / zclk->fixed_div; + min_mult = max(div64_ul(req->min_rate * 32ULL, prate), 1ULL); + max_mult = min(div64_ul(req->max_rate * 32ULL, prate), 32ULL); + if (max_mult < min_mult) + return -EINVAL; + + mult = div64_ul(req->rate * 32ULL, prate); + mult = clamp(mult, min_mult, max_mult); - return (u64)prate * mult / 32; + req->rate = div_u64((u64)prate * mult, 32); + return 0; } static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate, @@ -172,7 +178,7 @@ static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops cpg_z_clk_ops = { .recalc_rate = cpg_z_clk_recalc_rate, - .round_rate = cpg_z_clk_round_rate, + .determine_rate = cpg_z_clk_determine_rate, .set_rate = cpg_z_clk_set_rate, }; @@ -309,44 +315,44 @@ static unsigned long cpg_sd_clock_recalc_rate(struct clk_hw *hw, clock->div_table[clock->cur_div_idx].div); } -static unsigned int cpg_sd_clock_calc_div(struct sd_clock *clock, - unsigned long rate, - unsigned long parent_rate) +static int cpg_sd_clock_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { - unsigned long calc_rate, diff, diff_min = ULONG_MAX; - unsigned int i, best_div = 0; + unsigned long best_rate = ULONG_MAX, diff_min = ULONG_MAX; + struct sd_clock *clock = to_sd_clock(hw); + unsigned long calc_rate, diff; + unsigned int i; for (i = 0; i < clock->div_num; i++) { - calc_rate = DIV_ROUND_CLOSEST(parent_rate, + calc_rate = DIV_ROUND_CLOSEST(req->best_parent_rate, clock->div_table[i].div); - diff = calc_rate > rate ? calc_rate - rate : rate - calc_rate; + if (calc_rate < req->min_rate || calc_rate > req->max_rate) + continue; + + diff = calc_rate > req->rate ? calc_rate - req->rate + : req->rate - calc_rate; if (diff < diff_min) { - best_div = clock->div_table[i].div; + best_rate = calc_rate; diff_min = diff; } } - return best_div; -} - -static long cpg_sd_clock_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) -{ - struct sd_clock *clock = to_sd_clock(hw); - unsigned int div = cpg_sd_clock_calc_div(clock, rate, *parent_rate); + if (best_rate == ULONG_MAX) + return -EINVAL; - return DIV_ROUND_CLOSEST(*parent_rate, div); + req->rate = best_rate; + return 0; } static int cpg_sd_clock_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) + unsigned long parent_rate) { struct sd_clock *clock = to_sd_clock(hw); - unsigned int div = cpg_sd_clock_calc_div(clock, rate, parent_rate); unsigned int i; for (i = 0; i < clock->div_num; i++) - if (div == clock->div_table[i].div) + if (rate == DIV_ROUND_CLOSEST(parent_rate, + clock->div_table[i].div)) break; if (i >= clock->div_num) @@ -366,7 +372,7 @@ static const struct clk_ops cpg_sd_clock_ops = { .disable = cpg_sd_clock_disable, .is_enabled = cpg_sd_clock_is_enabled, .recalc_rate = cpg_sd_clock_recalc_rate, - .round_rate = cpg_sd_clock_round_rate, + .determine_rate = cpg_sd_clock_determine_rate, .set_rate = cpg_sd_clock_set_rate, }; diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index 132cc96895e3..a2663fbbd7a5 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -702,6 +702,12 @@ static const struct of_device_id cpg_mssr_match[] = { .data = &r8a774a1_cpg_mssr_info, }, #endif +#ifdef CONFIG_CLK_R8A774B1 + { + .compatible = "renesas,r8a774b1-cpg-mssr", + .data = &r8a774b1_cpg_mssr_info, + }, +#endif #ifdef CONFIG_CLK_R8A774C0 { .compatible = "renesas,r8a774c0-cpg-mssr", @@ -743,12 +749,18 @@ static const struct of_device_id cpg_mssr_match[] = { .data = &r8a7795_cpg_mssr_info, }, #endif -#ifdef CONFIG_CLK_R8A7796 +#ifdef CONFIG_CLK_R8A77960 { .compatible = "renesas,r8a7796-cpg-mssr", .data = &r8a7796_cpg_mssr_info, }, #endif +#ifdef CONFIG_CLK_R8A77961 + { + .compatible = "renesas,r8a77961-cpg-mssr", + .data = &r8a7796_cpg_mssr_info, + }, +#endif #ifdef CONFIG_CLK_R8A77965 { .compatible = "renesas,r8a77965-cpg-mssr", diff --git a/drivers/clk/renesas/renesas-cpg-mssr.h b/drivers/clk/renesas/renesas-cpg-mssr.h index 4ddcdf3bfb95..3b852ba0ecec 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.h +++ b/drivers/clk/renesas/renesas-cpg-mssr.h @@ -159,6 +159,7 @@ extern const struct cpg_mssr_info r8a7743_cpg_mssr_info; extern const struct cpg_mssr_info r8a7745_cpg_mssr_info; extern const struct cpg_mssr_info r8a77470_cpg_mssr_info; extern const struct cpg_mssr_info r8a774a1_cpg_mssr_info; +extern const struct cpg_mssr_info r8a774b1_cpg_mssr_info; extern const struct cpg_mssr_info r8a774c0_cpg_mssr_info; extern const struct cpg_mssr_info r8a7790_cpg_mssr_info; extern const struct cpg_mssr_info r8a7791_cpg_mssr_info; diff --git a/drivers/clk/rockchip/clk-half-divider.c b/drivers/clk/rockchip/clk-half-divider.c index ba9f00dc9740..b333fc28c94b 100644 --- a/drivers/clk/rockchip/clk-half-divider.c +++ b/drivers/clk/rockchip/clk-half-divider.c @@ -139,12 +139,11 @@ static int clk_half_divider_set_rate(struct clk_hw *hw, unsigned long rate, return 0; } -const struct clk_ops clk_half_divider_ops = { +static const struct clk_ops clk_half_divider_ops = { .recalc_rate = clk_half_divider_recalc_rate, .round_rate = clk_half_divider_round_rate, .set_rate = clk_half_divider_set_rate, }; -EXPORT_SYMBOL_GPL(clk_half_divider_ops); /** * Register a clock branch. diff --git a/drivers/clk/rockchip/clk-px30.c b/drivers/clk/rockchip/clk-px30.c index 3a501896b280..6fb9c98b7d24 100644 --- a/drivers/clk/rockchip/clk-px30.c +++ b/drivers/clk/rockchip/clk-px30.c @@ -167,6 +167,10 @@ PNAME(mux_uart5_p) = { "clk_uart5_src", "clk_uart5_np5", "clk_uart5_frac" }; PNAME(mux_cif_out_p) = { "xin24m", "dummy_cpll", "npll", "usb480m" }; PNAME(mux_dclk_vopb_p) = { "dclk_vopb_src", "dclk_vopb_frac", "xin24m" }; PNAME(mux_dclk_vopl_p) = { "dclk_vopl_src", "dclk_vopl_frac", "xin24m" }; +PNAME(mux_nandc_p) = { "clk_nandc_div", "clk_nandc_div50" }; +PNAME(mux_sdio_p) = { "clk_sdio_div", "clk_sdio_div50" }; +PNAME(mux_emmc_p) = { "clk_emmc_div", "clk_emmc_div50" }; +PNAME(mux_sdmmc_p) = { "clk_sdmmc_div", "clk_sdmmc_div50" }; PNAME(mux_gmac_p) = { "clk_gmac_src", "gmac_clkin" }; PNAME(mux_gmac_rmii_sel_p) = { "clk_gmac_rx_tx_div20", "clk_gmac_rx_tx_div2" }; PNAME(mux_rtc32k_pmu_p) = { "xin32k", "pmu_pvtm_32k", "clk_rtc32k_frac", }; @@ -460,16 +464,40 @@ static struct rockchip_clk_branch px30_clk_branches[] __initdata = { /* PD_MMC_NAND */ GATE(HCLK_MMC_NAND, "hclk_mmc_nand", "hclk_peri_pre", 0, PX30_CLKGATE_CON(6), 0, GFLAGS), - COMPOSITE(SCLK_NANDC, "clk_nandc", mux_gpll_cpll_npll_p, 0, + COMPOSITE(SCLK_NANDC_DIV, "clk_nandc_div", mux_gpll_cpll_npll_p, 0, PX30_CLKSEL_CON(15), 6, 2, MFLAGS, 0, 5, DFLAGS, + PX30_CLKGATE_CON(5), 11, GFLAGS), + COMPOSITE(SCLK_NANDC_DIV50, "clk_nandc_div50", mux_gpll_cpll_npll_p, 0, + PX30_CLKSEL_CON(15), 6, 2, MFLAGS, 8, 5, DFLAGS, + PX30_CLKGATE_CON(5), 12, GFLAGS), + COMPOSITE_NODIV(SCLK_NANDC, "clk_nandc", mux_nandc_p, + CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, + PX30_CLKSEL_CON(15), 15, 1, MFLAGS, PX30_CLKGATE_CON(5), 13, GFLAGS), - COMPOSITE(SCLK_SDIO, "clk_sdio", mux_gpll_cpll_npll_xin24m_p, 0, + COMPOSITE(SCLK_SDIO_DIV, "clk_sdio_div", mux_gpll_cpll_npll_xin24m_p, 0, PX30_CLKSEL_CON(18), 14, 2, MFLAGS, 0, 8, DFLAGS, + PX30_CLKGATE_CON(6), 1, GFLAGS), + COMPOSITE_DIV_OFFSET(SCLK_SDIO_DIV50, "clk_sdio_div50", + mux_gpll_cpll_npll_xin24m_p, 0, + PX30_CLKSEL_CON(18), 14, 2, MFLAGS, + PX30_CLKSEL_CON(19), 0, 8, DFLAGS, + PX30_CLKGATE_CON(6), 2, GFLAGS), + COMPOSITE_NODIV(SCLK_SDIO, "clk_sdio", mux_sdio_p, + CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, + PX30_CLKSEL_CON(19), 15, 1, MFLAGS, PX30_CLKGATE_CON(6), 3, GFLAGS), - COMPOSITE(SCLK_EMMC, "clk_emmc", mux_gpll_cpll_npll_xin24m_p, 0, + COMPOSITE(SCLK_EMMC_DIV, "clk_emmc_div", mux_gpll_cpll_npll_xin24m_p, 0, PX30_CLKSEL_CON(20), 14, 2, MFLAGS, 0, 8, DFLAGS, + PX30_CLKGATE_CON(6), 4, GFLAGS), + COMPOSITE_DIV_OFFSET(SCLK_EMMC_DIV50, "clk_emmc_div50", mux_gpll_cpll_npll_xin24m_p, 0, + PX30_CLKSEL_CON(20), 14, 2, MFLAGS, + PX30_CLKSEL_CON(21), 0, 8, DFLAGS, + PX30_CLKGATE_CON(6), 5, GFLAGS), + COMPOSITE_NODIV(SCLK_EMMC, "clk_emmc", mux_emmc_p, + CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, + PX30_CLKSEL_CON(21), 15, 1, MFLAGS, PX30_CLKGATE_CON(6), 6, GFLAGS), COMPOSITE(SCLK_SFC, "clk_sfc", mux_gpll_cpll_p, 0, @@ -494,8 +522,16 @@ static struct rockchip_clk_branch px30_clk_branches[] __initdata = { /* PD_SDCARD */ GATE(0, "hclk_sdmmc_pre", "hclk_peri_pre", 0, PX30_CLKGATE_CON(6), 12, GFLAGS), - COMPOSITE(SCLK_SDMMC, "clk_sdmmc", mux_gpll_cpll_npll_xin24m_p, 0, + COMPOSITE(SCLK_SDMMC_DIV, "clk_sdmmc_div", mux_gpll_cpll_npll_xin24m_p, 0, PX30_CLKSEL_CON(16), 14, 2, MFLAGS, 0, 8, DFLAGS, + PX30_CLKGATE_CON(6), 13, GFLAGS), + COMPOSITE_DIV_OFFSET(SCLK_SDMMC_DIV50, "clk_sdmmc_div50", mux_gpll_cpll_npll_xin24m_p, 0, + PX30_CLKSEL_CON(16), 14, 2, MFLAGS, + PX30_CLKSEL_CON(17), 0, 8, DFLAGS, + PX30_CLKGATE_CON(6), 14, GFLAGS), + COMPOSITE_NODIV(SCLK_SDMMC, "clk_sdmmc", mux_sdmmc_p, + CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, + PX30_CLKSEL_CON(17), 15, 1, MFLAGS, PX30_CLKGATE_CON(6), 15, GFLAGS), /* PD_USB */ @@ -763,29 +799,29 @@ static struct rockchip_clk_branch px30_clk_branches[] __initdata = { GATE(0, "pclk_ddrphy", "pclk_top_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(16), 3, GFLAGS), GATE(PCLK_MIPIDSIPHY, "pclk_mipidsiphy", "pclk_top_pre", 0, PX30_CLKGATE_CON(16), 4, GFLAGS), GATE(PCLK_MIPICSIPHY, "pclk_mipicsiphy", "pclk_top_pre", 0, PX30_CLKGATE_CON(16), 5, GFLAGS), - GATE(PCLK_USB_GRF, "pclk_usb_grf", "pclk_top_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(16), 6, GFLAGS), + GATE(PCLK_USB_GRF, "pclk_usb_grf", "pclk_top_pre", 0, PX30_CLKGATE_CON(16), 6, GFLAGS), GATE(0, "pclk_cpu_hoost", "pclk_top_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(16), 7, GFLAGS), /* PD_VI */ - GATE(0, "aclk_vi_niu", "aclk_vi_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(4), 15, GFLAGS), + GATE(0, "aclk_vi_niu", "aclk_vi_pre", 0, PX30_CLKGATE_CON(4), 15, GFLAGS), GATE(ACLK_CIF, "aclk_cif", "aclk_vi_pre", 0, PX30_CLKGATE_CON(5), 1, GFLAGS), GATE(ACLK_ISP, "aclk_isp", "aclk_vi_pre", 0, PX30_CLKGATE_CON(5), 3, GFLAGS), - GATE(0, "hclk_vi_niu", "hclk_vi_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(5), 0, GFLAGS), + GATE(0, "hclk_vi_niu", "hclk_vi_pre", 0, PX30_CLKGATE_CON(5), 0, GFLAGS), GATE(HCLK_CIF, "hclk_cif", "hclk_vi_pre", 0, PX30_CLKGATE_CON(5), 2, GFLAGS), GATE(HCLK_ISP, "hclk_isp", "hclk_vi_pre", 0, PX30_CLKGATE_CON(5), 4, GFLAGS), /* PD_VO */ - GATE(0, "aclk_vo_niu", "aclk_vo_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(3), 0, GFLAGS), + GATE(0, "aclk_vo_niu", "aclk_vo_pre", 0, PX30_CLKGATE_CON(3), 0, GFLAGS), GATE(ACLK_VOPB, "aclk_vopb", "aclk_vo_pre", 0, PX30_CLKGATE_CON(3), 3, GFLAGS), GATE(ACLK_RGA, "aclk_rga", "aclk_vo_pre", 0, PX30_CLKGATE_CON(3), 7, GFLAGS), GATE(ACLK_VOPL, "aclk_vopl", "aclk_vo_pre", 0, PX30_CLKGATE_CON(3), 5, GFLAGS), - GATE(0, "hclk_vo_niu", "hclk_vo_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(3), 1, GFLAGS), + GATE(0, "hclk_vo_niu", "hclk_vo_pre", 0, PX30_CLKGATE_CON(3), 1, GFLAGS), GATE(HCLK_VOPB, "hclk_vopb", "hclk_vo_pre", 0, PX30_CLKGATE_CON(3), 4, GFLAGS), GATE(HCLK_RGA, "hclk_rga", "hclk_vo_pre", 0, PX30_CLKGATE_CON(3), 8, GFLAGS), GATE(HCLK_VOPL, "hclk_vopl", "hclk_vo_pre", 0, PX30_CLKGATE_CON(3), 6, GFLAGS), - GATE(0, "pclk_vo_niu", "pclk_vo_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(3), 2, GFLAGS), + GATE(0, "pclk_vo_niu", "pclk_vo_pre", 0, PX30_CLKGATE_CON(3), 2, GFLAGS), GATE(PCLK_MIPI_DSI, "pclk_mipi_dsi", "pclk_vo_pre", 0, PX30_CLKGATE_CON(3), 9, GFLAGS), /* PD_BUS */ @@ -940,7 +976,7 @@ static struct rockchip_clk_branch px30_clk_pmu_branches[] __initdata = { GATE(0, "pclk_cru_pmu", "pclk_pmu_pre", CLK_IGNORE_UNUSED, PX30_PMU_CLKGATE_CON(0), 8, GFLAGS), }; -static const char *const px30_pmucru_critical_clocks[] __initconst = { +static const char *const px30_cru_critical_clocks[] __initconst = { "aclk_bus_pre", "pclk_bus_pre", "hclk_bus_pre", @@ -950,10 +986,16 @@ static const char *const px30_pmucru_critical_clocks[] __initconst = { "pclk_top_pre", "pclk_pmu_pre", "hclk_usb_niu", + "pclk_vo_niu", + "aclk_vo_niu", + "hclk_vo_niu", + "aclk_vi_niu", + "hclk_vi_niu", "pll_npll", "usb480m", "clk_uart2", "pclk_uart2", + "pclk_usb_grf", }; static void __init px30_clk_init(struct device_node *np) @@ -985,6 +1027,9 @@ static void __init px30_clk_init(struct device_node *np) &px30_cpuclk_data, px30_cpuclk_rates, ARRAY_SIZE(px30_cpuclk_rates)); + rockchip_clk_protect_critical(px30_cru_critical_clocks, + ARRAY_SIZE(px30_cru_critical_clocks)); + rockchip_register_softrst(np, 12, reg_base + PX30_SOFTRST_CON(0), ROCKCHIP_SOFTRST_HIWORD_MASK); @@ -1017,9 +1062,6 @@ static void __init px30_pmu_clk_init(struct device_node *np) rockchip_clk_register_branches(ctx, px30_clk_pmu_branches, ARRAY_SIZE(px30_clk_pmu_branches)); - rockchip_clk_protect_critical(px30_pmucru_critical_clocks, - ARRAY_SIZE(px30_pmucru_critical_clocks)); - rockchip_clk_of_add_provider(np, ctx); } CLK_OF_DECLARE(px30_cru_pmu, "rockchip,px30-pmucru", px30_pmu_clk_init); diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index 31466cd1842f..3a991ca1ee36 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -165,6 +165,8 @@ static const unsigned long exynos5x_clk_regs[] __initconst = { GATE_BUS_CPU, GATE_SCLK_CPU, CLKOUT_CMU_CPU, + APLL_CON0, + KPLL_CON0, CPLL_CON0, DPLL_CON0, EPLL_CON0, @@ -611,7 +613,8 @@ static const struct samsung_mux_clock exynos5x_mux_clks[] __initconst = { MUX(0, "mout_aclk66", mout_group1_p, SRC_TOP1, 8, 2), MUX(0, "mout_aclk166", mout_group1_p, SRC_TOP1, 24, 2), - MUX(0, "mout_aclk_g3d", mout_group5_p, SRC_TOP2, 16, 1), + MUX_F(0, "mout_aclk_g3d", mout_group5_p, SRC_TOP2, 16, 1, + CLK_SET_RATE_PARENT, 0), MUX(0, "mout_user_aclk400_isp", mout_user_aclk400_isp_p, SRC_TOP3, 0, 1), @@ -653,8 +656,8 @@ static const struct samsung_mux_clock exynos5x_mux_clks[] __initconst = { SRC_TOP5, 8, 1), MUX(0, "mout_user_aclk266_g2d", mout_user_aclk266_g2d_p, SRC_TOP5, 12, 1), - MUX(CLK_MOUT_G3D, "mout_user_aclk_g3d", mout_user_aclk_g3d_p, - SRC_TOP5, 16, 1), + MUX_F(CLK_MOUT_G3D, "mout_user_aclk_g3d", mout_user_aclk_g3d_p, + SRC_TOP5, 16, 1, CLK_SET_RATE_PARENT, 0), MUX(0, "mout_user_aclk300_jpeg", mout_user_aclk300_jpeg_p, SRC_TOP5, 20, 1), MUX(CLK_MOUT_USER_ACLK300_DISP1, "mout_user_aclk300_disp1", @@ -663,7 +666,8 @@ static const struct samsung_mux_clock exynos5x_mux_clks[] __initconst = { mout_user_aclk300_gscl_p, SRC_TOP5, 28, 1), MUX(0, "mout_sclk_mpll", mout_mpll_p, SRC_TOP6, 0, 1), - MUX(CLK_MOUT_VPLL, "mout_sclk_vpll", mout_vpll_p, SRC_TOP6, 4, 1), + MUX_F(CLK_MOUT_VPLL, "mout_sclk_vpll", mout_vpll_p, SRC_TOP6, 4, 1, + CLK_SET_RATE_PARENT, 0), MUX(CLK_MOUT_SCLK_SPLL, "mout_sclk_spll", mout_spll_p, SRC_TOP6, 8, 1), MUX(0, "mout_sclk_ipll", mout_ipll_p, SRC_TOP6, 12, 1), MUX(0, "mout_sclk_rpll", mout_rpll_p, SRC_TOP6, 16, 1), @@ -707,7 +711,8 @@ static const struct samsung_mux_clock exynos5x_mux_clks[] __initconst = { SRC_TOP12, 8, 1), MUX(0, "mout_sw_aclk266_g2d", mout_sw_aclk266_g2d_p, SRC_TOP12, 12, 1), - MUX(0, "mout_sw_aclk_g3d", mout_sw_aclk_g3d_p, SRC_TOP12, 16, 1), + MUX_F(0, "mout_sw_aclk_g3d", mout_sw_aclk_g3d_p, SRC_TOP12, 16, 1, + CLK_SET_RATE_PARENT, 0), MUX(0, "mout_sw_aclk300_jpeg", mout_sw_aclk300_jpeg_p, SRC_TOP12, 20, 1), MUX(CLK_MOUT_SW_ACLK300, "mout_sw_aclk300_disp1", @@ -804,8 +809,8 @@ static const struct samsung_div_clock exynos5x_div_clks[] __initconst = { DIV_TOP2, 8, 3), DIV(CLK_DOUT_ACLK266_G2D, "dout_aclk266_g2d", "mout_aclk266_g2d", DIV_TOP2, 12, 3), - DIV(CLK_DOUT_ACLK_G3D, "dout_aclk_g3d", "mout_aclk_g3d", DIV_TOP2, - 16, 3), + DIV_F(CLK_DOUT_ACLK_G3D, "dout_aclk_g3d", "mout_aclk_g3d", DIV_TOP2, + 16, 3, CLK_SET_RATE_PARENT, 0), DIV(CLK_DOUT_ACLK300_JPEG, "dout_aclk300_jpeg", "mout_aclk300_jpeg", DIV_TOP2, 20, 3), DIV(CLK_DOUT_ACLK300_DISP1, "dout_aclk300_disp1", @@ -1253,7 +1258,8 @@ static struct exynos5_subcmu_reg_dump exynos5x_gsc_suspend_regs[] = { }; static const struct samsung_gate_clock exynos5x_g3d_gate_clks[] __initconst = { - GATE(CLK_G3D, "g3d", "mout_user_aclk_g3d", GATE_IP_G3D, 9, 0, 0), + GATE(CLK_G3D, "g3d", "mout_user_aclk_g3d", GATE_IP_G3D, 9, + CLK_SET_RATE_PARENT, 0), }; static struct exynos5_subcmu_reg_dump exynos5x_g3d_suspend_regs[] = { @@ -1437,6 +1443,17 @@ static const struct samsung_pll_rate_table exynos5420_epll_24mhz_tbl[] = { PLL_36XX_RATE(24 * MHZ, 32768001U, 131, 3, 5, 4719), }; +static const struct samsung_pll_rate_table exynos5420_vpll_24mhz_tbl[] = { + PLL_35XX_RATE(24 * MHZ, 600000000U, 200, 2, 2), + PLL_35XX_RATE(24 * MHZ, 543000000U, 181, 2, 2), + PLL_35XX_RATE(24 * MHZ, 480000000U, 160, 2, 2), + PLL_35XX_RATE(24 * MHZ, 420000000U, 140, 2, 2), + PLL_35XX_RATE(24 * MHZ, 350000000U, 175, 3, 2), + PLL_35XX_RATE(24 * MHZ, 266000000U, 266, 3, 3), + PLL_35XX_RATE(24 * MHZ, 177000000U, 118, 2, 3), + PLL_35XX_RATE(24 * MHZ, 100000000U, 200, 3, 4), +}; + static struct samsung_pll_clock exynos5x_plls[nr_plls] __initdata = { [apll] = PLL(pll_2550, CLK_FOUT_APLL, "fout_apll", "fin_pll", APLL_LOCK, APLL_CON0, NULL), @@ -1561,6 +1578,7 @@ static void __init exynos5x_clk_init(struct device_node *np, exynos5x_plls[apll].rate_table = exynos5420_pll2550x_24mhz_tbl; exynos5x_plls[epll].rate_table = exynos5420_epll_24mhz_tbl; exynos5x_plls[kpll].rate_table = exynos5420_pll2550x_24mhz_tbl; + exynos5x_plls[vpll].rate_table = exynos5420_vpll_24mhz_tbl; } if (soc == EXYNOS5420) diff --git a/drivers/clk/samsung/clk-s3c2410-dclk.c b/drivers/clk/samsung/clk-s3c2410-dclk.c index 1281672cb00e..7dad9098e897 100644 --- a/drivers/clk/samsung/clk-s3c2410-dclk.c +++ b/drivers/clk/samsung/clk-s3c2410-dclk.c @@ -238,7 +238,6 @@ static SIMPLE_DEV_PM_OPS(s3c24xx_dclk_pm_ops, static int s3c24xx_dclk_probe(struct platform_device *pdev) { struct s3c24xx_dclk *s3c24xx_dclk; - struct resource *mem; struct s3c24xx_dclk_drv_data *dclk_variant; struct clk_hw **clk_table; int ret, i; @@ -257,8 +256,7 @@ static int s3c24xx_dclk_probe(struct platform_device *pdev) platform_set_drvdata(pdev, s3c24xx_dclk); spin_lock_init(&s3c24xx_dclk->dclk_lock); - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - s3c24xx_dclk->base = devm_ioremap_resource(&pdev->dev, mem); + s3c24xx_dclk->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(s3c24xx_dclk->base)) return PTR_ERR(s3c24xx_dclk->base); diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c index e544a38106dd..dad31308c071 100644 --- a/drivers/clk/samsung/clk.c +++ b/drivers/clk/samsung/clk.c @@ -60,8 +60,7 @@ struct samsung_clk_provider *__init samsung_clk_init(struct device_node *np, struct samsung_clk_provider *ctx; int i; - ctx = kzalloc(sizeof(struct samsung_clk_provider) + - sizeof(*ctx->clk_data.hws) * nr_clks, GFP_KERNEL); + ctx = kzalloc(struct_size(ctx, clk_data.hws, nr_clks), GFP_KERNEL); if (!ctx) panic("could not allocate clock provider context.\n"); diff --git a/drivers/clk/sprd/common.c b/drivers/clk/sprd/common.c index 9d56eac43832..c0af4779892b 100644 --- a/drivers/clk/sprd/common.c +++ b/drivers/clk/sprd/common.c @@ -42,17 +42,15 @@ int sprd_clk_regmap_init(struct platform_device *pdev, void __iomem *base; struct device_node *node = pdev->dev.of_node; struct regmap *regmap; - struct resource *res; if (of_find_property(node, "sprd,syscon", NULL)) { regmap = syscon_regmap_lookup_by_phandle(node, "sprd,syscon"); - if (IS_ERR_OR_NULL(regmap)) { + if (IS_ERR(regmap)) { pr_err("%s: failed to get syscon regmap\n", __func__); return PTR_ERR(regmap); } } else { - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(&pdev->dev, res); + base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) return PTR_ERR(base); diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c index d89353a3cdec..f2497d0a4683 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c +++ b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c @@ -203,12 +203,21 @@ static struct ccu_nkmp pll_hsic_clk = { * hardcode it to match with the clock names. */ #define SUN50I_H6_PLL_AUDIO_REG 0x078 + +static struct ccu_sdm_setting pll_audio_sdm_table[] = { + { .rate = 541900800, .pattern = 0xc001288d, .m = 1, .n = 22 }, + { .rate = 589824000, .pattern = 0xc00126e9, .m = 1, .n = 24 }, +}; + static struct ccu_nm pll_audio_base_clk = { .enable = BIT(31), .lock = BIT(28), .n = _SUNXI_CCU_MULT_MIN(8, 8, 12), .m = _SUNXI_CCU_DIV(1, 1), /* input divider */ + .sdm = _SUNXI_CCU_SDM(pll_audio_sdm_table, + BIT(24), 0x178, BIT(31)), .common = { + .features = CCU_FEATURE_SIGMA_DELTA_MOD, .reg = 0x078, .hw.init = CLK_HW_INIT("pll-audio-base", "osc24M", &ccu_nm_ops, @@ -290,7 +299,7 @@ static SUNXI_CCU_M_WITH_MUX_GATE(gpu_clk, "gpu", gpu_parents, 0x670, 0, 3, /* M */ 24, 1, /* mux */ BIT(31), /* gate */ - 0); + CLK_SET_RATE_PARENT); static SUNXI_CCU_GATE(bus_gpu_clk, "bus-gpu", "psi-ahb1-ahb2", 0x67c, BIT(0), 0); @@ -753,12 +762,12 @@ static const struct clk_hw *clk_parent_pll_audio[] = { }; /* - * The divider of pll-audio is fixed to 8 now, as pll-audio-4x has a - * fixed post-divider 2. + * The divider of pll-audio is fixed to 24 for now, so 24576000 and 22579200 + * rates can be set exactly in conjunction with sigma-delta modulation. */ static CLK_FIXED_FACTOR_HWS(pll_audio_clk, "pll-audio", clk_parent_pll_audio, - 8, 1, CLK_SET_RATE_PARENT); + 24, 1, CLK_SET_RATE_PARENT); static CLK_FIXED_FACTOR_HWS(pll_audio_2x_clk, "pll-audio-2x", clk_parent_pll_audio, 4, 1, CLK_SET_RATE_PARENT); @@ -1215,12 +1224,12 @@ static int sun50i_h6_ccu_probe(struct platform_device *pdev) } /* - * Force the post-divider of pll-audio to 8 and the output divider - * of it to 1, to make the clock name represents the real frequency. + * Force the post-divider of pll-audio to 12 and the output divider + * of it to 2, so 24576000 and 22579200 rates can be set exactly. */ val = readl(reg + SUN50I_H6_PLL_AUDIO_REG); val &= ~(GENMASK(21, 16) | BIT(0)); - writel(val | (7 << 16), reg + SUN50I_H6_PLL_AUDIO_REG); + writel(val | (11 << 16) | BIT(0), reg + SUN50I_H6_PLL_AUDIO_REG); /* * First clock parent (osc32K) is unusable for CEC. But since there diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-h3.h b/drivers/clk/sunxi-ng/ccu-sun8i-h3.h index b6e2680ef354..d8c38447e11b 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-h3.h +++ b/drivers/clk/sunxi-ng/ccu-sun8i-h3.h @@ -48,10 +48,6 @@ /* Some more module clocks are exported */ -#define CLK_MBUS 113 - -/* And the GPU module clock is exported */ - #define CLK_NUMBER_H3 (CLK_GPU + 1) #define CLK_NUMBER_H5 (CLK_BUS_SCR1 + 1) diff --git a/drivers/clk/tegra/Makefile b/drivers/clk/tegra/Makefile index 4812e45c2214..df966ca06788 100644 --- a/drivers/clk/tegra/Makefile +++ b/drivers/clk/tegra/Makefile @@ -17,7 +17,9 @@ obj-y += clk-tegra-fixed.o obj-y += clk-tegra-super-gen4.o obj-$(CONFIG_TEGRA_CLK_EMC) += clk-emc.o obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += clk-tegra20.o +obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += clk-tegra20-emc.o obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += clk-tegra30.o +obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += clk-tegra20-emc.o obj-$(CONFIG_ARCH_TEGRA_114_SOC) += clk-tegra114.o obj-$(CONFIG_ARCH_TEGRA_124_SOC) += clk-tegra124.o obj-$(CONFIG_TEGRA_CLK_DFLL) += clk-tegra124-dfll-fcpu.o diff --git a/drivers/clk/tegra/clk-dfll.c b/drivers/clk/tegra/clk-dfll.c index f8688c2ddf1a..c051d92c2bbf 100644 --- a/drivers/clk/tegra/clk-dfll.c +++ b/drivers/clk/tegra/clk-dfll.c @@ -1487,6 +1487,7 @@ static int dfll_init(struct tegra_dfll *td) td->last_unrounded_rate = 0; pm_runtime_enable(td->dev); + pm_runtime_irq_safe(td->dev); pm_runtime_get_sync(td->dev); dfll_set_mode(td, DFLL_DISABLED); @@ -1513,6 +1514,61 @@ di_err1: return ret; } +/** + * tegra_dfll_suspend - check DFLL is disabled + * @dev: DFLL device * + * + * DFLL clock should be disabled by the CPUFreq driver. So, make + * sure it is disabled and disable all clocks needed by the DFLL. + */ +int tegra_dfll_suspend(struct device *dev) +{ + struct tegra_dfll *td = dev_get_drvdata(dev); + + if (dfll_is_running(td)) { + dev_err(td->dev, "DFLL still enabled while suspending\n"); + return -EBUSY; + } + + reset_control_assert(td->dvco_rst); + + return 0; +} +EXPORT_SYMBOL(tegra_dfll_suspend); + +/** + * tegra_dfll_resume - reinitialize DFLL on resume + * @dev: DFLL instance + * + * DFLL is disabled and reset during suspend and resume. + * So, reinitialize the DFLL IP block back for use. + * DFLL clock is enabled later in closed loop mode by CPUFreq + * driver before switching its clock source to DFLL output. + */ +int tegra_dfll_resume(struct device *dev) +{ + struct tegra_dfll *td = dev_get_drvdata(dev); + + reset_control_deassert(td->dvco_rst); + + pm_runtime_get_sync(td->dev); + + dfll_set_mode(td, DFLL_DISABLED); + dfll_set_default_params(td); + + if (td->soc->init_clock_trimmers) + td->soc->init_clock_trimmers(); + + dfll_set_open_loop_config(td); + + dfll_init_out_if(td); + + pm_runtime_put_sync(td->dev); + + return 0; +} +EXPORT_SYMBOL(tegra_dfll_resume); + /* * DT data fetch */ diff --git a/drivers/clk/tegra/clk-dfll.h b/drivers/clk/tegra/clk-dfll.h index 1b14ebe7268b..fb209eb5f365 100644 --- a/drivers/clk/tegra/clk-dfll.h +++ b/drivers/clk/tegra/clk-dfll.h @@ -42,5 +42,7 @@ int tegra_dfll_register(struct platform_device *pdev, struct tegra_dfll_soc_data *tegra_dfll_unregister(struct platform_device *pdev); int tegra_dfll_runtime_suspend(struct device *dev); int tegra_dfll_runtime_resume(struct device *dev); +int tegra_dfll_suspend(struct device *dev); +int tegra_dfll_resume(struct device *dev); #endif /* __DRIVERS_CLK_TEGRA_CLK_DFLL_H */ diff --git a/drivers/clk/tegra/clk-divider.c b/drivers/clk/tegra/clk-divider.c index e76731fb7d69..ca0de5f11f84 100644 --- a/drivers/clk/tegra/clk-divider.c +++ b/drivers/clk/tegra/clk-divider.c @@ -109,10 +109,21 @@ static int clk_frac_div_set_rate(struct clk_hw *hw, unsigned long rate, return 0; } +static void clk_divider_restore_context(struct clk_hw *hw) +{ + struct clk_hw *parent = clk_hw_get_parent(hw); + unsigned long parent_rate = clk_hw_get_rate(parent); + unsigned long rate = clk_hw_get_rate(hw); + + if (clk_frac_div_set_rate(hw, rate, parent_rate) < 0) + WARN_ON(1); +} + const struct clk_ops tegra_clk_frac_div_ops = { .recalc_rate = clk_frac_div_recalc_rate, .set_rate = clk_frac_div_set_rate, .round_rate = clk_frac_div_round_rate, + .restore_context = clk_divider_restore_context, }; struct clk *tegra_clk_register_divider(const char *name, diff --git a/drivers/clk/tegra/clk-emc.c b/drivers/clk/tegra/clk-emc.c index ea39caf3d762..745f9faa98d8 100644 --- a/drivers/clk/tegra/clk-emc.c +++ b/drivers/clk/tegra/clk-emc.c @@ -403,20 +403,16 @@ static int load_one_timing_from_dt(struct tegra_clk_emc *tegra, } timing->parent_index = 0xff; - for (i = 0; i < ARRAY_SIZE(emc_parent_clk_names); i++) { - if (!strcmp(emc_parent_clk_names[i], - __clk_get_name(timing->parent))) { - timing->parent_index = i; - break; - } - } - if (timing->parent_index == 0xff) { + i = match_string(emc_parent_clk_names, ARRAY_SIZE(emc_parent_clk_names), + __clk_get_name(timing->parent)); + if (i < 0) { pr_err("timing %pOF: %s is not a valid parent\n", node, __clk_get_name(timing->parent)); clk_put(timing->parent); return -EINVAL; } + timing->parent_index = i; return 0; } diff --git a/drivers/clk/tegra/clk-id.h b/drivers/clk/tegra/clk-id.h index de466b4446da..c4faebd32760 100644 --- a/drivers/clk/tegra/clk-id.h +++ b/drivers/clk/tegra/clk-id.h @@ -236,9 +236,9 @@ enum clk_id { tegra_clk_soc_therm, tegra_clk_soc_therm_8, tegra_clk_sor0, - tegra_clk_sor0_lvds, + tegra_clk_sor0_out, tegra_clk_sor1, - tegra_clk_sor1_src, + tegra_clk_sor1_out, tegra_clk_spdif, tegra_clk_spdif_2x, tegra_clk_spdif_in, diff --git a/drivers/clk/tegra/clk-periph.c b/drivers/clk/tegra/clk-periph.c index 58437da25156..67620c7ecd9e 100644 --- a/drivers/clk/tegra/clk-periph.c +++ b/drivers/clk/tegra/clk-periph.c @@ -3,6 +3,7 @@ * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. */ +#include <linux/clk.h> #include <linux/clk-provider.h> #include <linux/export.h> #include <linux/slab.h> @@ -99,6 +100,23 @@ static void clk_periph_disable(struct clk_hw *hw) gate_ops->disable(gate_hw); } +static void clk_periph_restore_context(struct clk_hw *hw) +{ + struct tegra_clk_periph *periph = to_clk_periph(hw); + const struct clk_ops *div_ops = periph->div_ops; + struct clk_hw *div_hw = &periph->divider.hw; + int parent_id; + + parent_id = clk_hw_get_parent_index(hw); + if (WARN_ON(parent_id < 0)) + return; + + if (!(periph->gate.flags & TEGRA_PERIPH_NO_DIV)) + div_ops->restore_context(div_hw); + + clk_periph_set_parent(hw, parent_id); +} + const struct clk_ops tegra_clk_periph_ops = { .get_parent = clk_periph_get_parent, .set_parent = clk_periph_set_parent, @@ -108,6 +126,7 @@ const struct clk_ops tegra_clk_periph_ops = { .is_enabled = clk_periph_is_enabled, .enable = clk_periph_enable, .disable = clk_periph_disable, + .restore_context = clk_periph_restore_context, }; static const struct clk_ops tegra_clk_periph_nodiv_ops = { @@ -116,6 +135,7 @@ static const struct clk_ops tegra_clk_periph_nodiv_ops = { .is_enabled = clk_periph_is_enabled, .enable = clk_periph_enable, .disable = clk_periph_disable, + .restore_context = clk_periph_restore_context, }; static const struct clk_ops tegra_clk_periph_no_gate_ops = { @@ -124,6 +144,7 @@ static const struct clk_ops tegra_clk_periph_no_gate_ops = { .recalc_rate = clk_periph_recalc_rate, .round_rate = clk_periph_round_rate, .set_rate = clk_periph_set_rate, + .restore_context = clk_periph_restore_context, }; static struct clk *_tegra_clk_register_periph(const char *name, diff --git a/drivers/clk/tegra/clk-pll-out.c b/drivers/clk/tegra/clk-pll-out.c index 35f2bf00e1e6..d8bf89a81e6d 100644 --- a/drivers/clk/tegra/clk-pll-out.c +++ b/drivers/clk/tegra/clk-pll-out.c @@ -69,10 +69,19 @@ static void clk_pll_out_disable(struct clk_hw *hw) spin_unlock_irqrestore(pll_out->lock, flags); } +static void tegra_clk_pll_out_restore_context(struct clk_hw *hw) +{ + if (!__clk_get_enable_count(hw->clk)) + clk_pll_out_disable(hw); + else + clk_pll_out_enable(hw); +} + const struct clk_ops tegra_clk_pll_out_ops = { .is_enabled = clk_pll_out_is_enabled, .enable = clk_pll_out_enable, .disable = clk_pll_out_disable, + .restore_context = tegra_clk_pll_out_restore_context, }; struct clk *tegra_clk_register_pll_out(const char *name, diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index 1583f5fc992f..531c2b3d814e 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c @@ -1008,6 +1008,27 @@ static unsigned long clk_plle_recalc_rate(struct clk_hw *hw, return rate; } +static void tegra_clk_pll_restore_context(struct clk_hw *hw) +{ + struct tegra_clk_pll *pll = to_clk_pll(hw); + struct clk_hw *parent = clk_hw_get_parent(hw); + unsigned long parent_rate = clk_hw_get_rate(parent); + unsigned long rate = clk_hw_get_rate(hw); + + if (clk_pll_is_enabled(hw)) + return; + + if (pll->params->set_defaults) + pll->params->set_defaults(pll); + + clk_pll_set_rate(hw, rate, parent_rate); + + if (!__clk_get_enable_count(hw->clk)) + clk_pll_disable(hw); + else + clk_pll_enable(hw); +} + const struct clk_ops tegra_clk_pll_ops = { .is_enabled = clk_pll_is_enabled, .enable = clk_pll_enable, @@ -1015,6 +1036,7 @@ const struct clk_ops tegra_clk_pll_ops = { .recalc_rate = clk_pll_recalc_rate, .round_rate = clk_pll_round_rate, .set_rate = clk_pll_set_rate, + .restore_context = tegra_clk_pll_restore_context, }; const struct clk_ops tegra_clk_plle_ops = { @@ -1802,6 +1824,27 @@ out: return ret; } + +static void _clk_plle_tegra_init_parent(struct tegra_clk_pll *pll) +{ + u32 val, val_aux; + + /* ensure parent is set to pll_ref */ + val = pll_readl_base(pll); + val_aux = pll_readl(pll->params->aux_reg, pll); + + if (val & PLL_BASE_ENABLE) { + if ((val_aux & PLLE_AUX_PLLRE_SEL) || + (val_aux & PLLE_AUX_PLLP_SEL)) + WARN(1, "pll_e enabled with unsupported parent %s\n", + (val_aux & PLLE_AUX_PLLP_SEL) ? "pllp_out0" : + "pll_re_vco"); + } else { + val_aux &= ~(PLLE_AUX_PLLRE_SEL | PLLE_AUX_PLLP_SEL); + pll_writel(val_aux, pll->params->aux_reg, pll); + fence_udelay(1, pll->clk_base); + } +} #endif static struct tegra_clk_pll *_tegra_init_pll(void __iomem *clk_base, @@ -2214,27 +2257,12 @@ struct clk *tegra_clk_register_plle_tegra114(const char *name, { struct tegra_clk_pll *pll; struct clk *clk; - u32 val, val_aux; pll = _tegra_init_pll(clk_base, NULL, pll_params, lock); if (IS_ERR(pll)) return ERR_CAST(pll); - /* ensure parent is set to pll_re_vco */ - - val = pll_readl_base(pll); - val_aux = pll_readl(pll_params->aux_reg, pll); - - if (val & PLL_BASE_ENABLE) { - if ((val_aux & PLLE_AUX_PLLRE_SEL) || - (val_aux & PLLE_AUX_PLLP_SEL)) - WARN(1, "pll_e enabled with unsupported parent %s\n", - (val_aux & PLLE_AUX_PLLP_SEL) ? "pllp_out0" : - "pll_re_vco"); - } else { - val_aux &= ~(PLLE_AUX_PLLRE_SEL | PLLE_AUX_PLLP_SEL); - pll_writel(val_aux, pll_params->aux_reg, pll); - } + _clk_plle_tegra_init_parent(pll); clk = _tegra_clk_register_pll(pll, name, parent_name, flags, &tegra_clk_plle_tegra114_ops); @@ -2276,6 +2304,7 @@ static const struct clk_ops tegra_clk_pllss_ops = { .recalc_rate = clk_pll_recalc_rate, .round_rate = clk_pll_ramp_round_rate, .set_rate = clk_pllxc_set_rate, + .restore_context = tegra_clk_pll_restore_context, }; struct clk *tegra_clk_register_pllss(const char *name, const char *parent_name, @@ -2520,11 +2549,19 @@ out: spin_unlock_irqrestore(pll->lock, flags); } +static void tegra_clk_plle_t210_restore_context(struct clk_hw *hw) +{ + struct tegra_clk_pll *pll = to_clk_pll(hw); + + _clk_plle_tegra_init_parent(pll); +} + static const struct clk_ops tegra_clk_plle_tegra210_ops = { .is_enabled = clk_plle_tegra210_is_enabled, .enable = clk_plle_tegra210_enable, .disable = clk_plle_tegra210_disable, .recalc_rate = clk_pll_recalc_rate, + .restore_context = tegra_clk_plle_t210_restore_context, }; struct clk *tegra_clk_register_plle_tegra210(const char *name, @@ -2535,27 +2572,12 @@ struct clk *tegra_clk_register_plle_tegra210(const char *name, { struct tegra_clk_pll *pll; struct clk *clk; - u32 val, val_aux; pll = _tegra_init_pll(clk_base, NULL, pll_params, lock); if (IS_ERR(pll)) return ERR_CAST(pll); - /* ensure parent is set to pll_re_vco */ - - val = pll_readl_base(pll); - val_aux = pll_readl(pll_params->aux_reg, pll); - - if (val & PLLE_BASE_ENABLE) { - if ((val_aux & PLLE_AUX_PLLRE_SEL) || - (val_aux & PLLE_AUX_PLLP_SEL)) - WARN(1, "pll_e enabled with unsupported parent %s\n", - (val_aux & PLLE_AUX_PLLP_SEL) ? "pllp_out0" : - "pll_re_vco"); - } else { - val_aux &= ~(PLLE_AUX_PLLRE_SEL | PLLE_AUX_PLLP_SEL); - pll_writel(val_aux, pll_params->aux_reg, pll); - } + _clk_plle_tegra_init_parent(pll); clk = _tegra_clk_register_pll(pll, name, parent_name, flags, &tegra_clk_plle_tegra210_ops); diff --git a/drivers/clk/tegra/clk-sdmmc-mux.c b/drivers/clk/tegra/clk-sdmmc-mux.c index a5cd3e31dbae..316912d3b1a4 100644 --- a/drivers/clk/tegra/clk-sdmmc-mux.c +++ b/drivers/clk/tegra/clk-sdmmc-mux.c @@ -194,6 +194,21 @@ static void clk_sdmmc_mux_disable(struct clk_hw *hw) gate_ops->disable(gate_hw); } +static void clk_sdmmc_mux_restore_context(struct clk_hw *hw) +{ + struct clk_hw *parent = clk_hw_get_parent(hw); + unsigned long parent_rate = clk_hw_get_rate(parent); + unsigned long rate = clk_hw_get_rate(hw); + int parent_id; + + parent_id = clk_hw_get_parent_index(hw); + if (WARN_ON(parent_id < 0)) + return; + + clk_sdmmc_mux_set_parent(hw, parent_id); + clk_sdmmc_mux_set_rate(hw, rate, parent_rate); +} + static const struct clk_ops tegra_clk_sdmmc_mux_ops = { .get_parent = clk_sdmmc_mux_get_parent, .set_parent = clk_sdmmc_mux_set_parent, @@ -203,6 +218,7 @@ static const struct clk_ops tegra_clk_sdmmc_mux_ops = { .is_enabled = clk_sdmmc_mux_is_enabled, .enable = clk_sdmmc_mux_enable, .disable = clk_sdmmc_mux_disable, + .restore_context = clk_sdmmc_mux_restore_context, }; struct clk *tegra_clk_register_sdmmc_mux_div(const char *name, diff --git a/drivers/clk/tegra/clk-super.c b/drivers/clk/tegra/clk-super.c index 39ef31b46df5..6099c6e9acd4 100644 --- a/drivers/clk/tegra/clk-super.c +++ b/drivers/clk/tegra/clk-super.c @@ -28,6 +28,9 @@ #define super_state_to_src_shift(m, s) ((m->width * s)) #define super_state_to_src_mask(m) (((1 << m->width) - 1)) +#define CCLK_SRC_PLLP_OUT0 4 +#define CCLK_SRC_PLLP_OUT4 5 + static u8 clk_super_get_parent(struct clk_hw *hw) { struct tegra_clk_super_mux *mux = to_clk_super_mux(hw); @@ -97,12 +100,23 @@ static int clk_super_set_parent(struct clk_hw *hw, u8 index) if (index == mux->div2_index) index = mux->pllx_index; } + + /* enable PLLP branches to CPU before selecting PLLP source */ + if ((mux->flags & TEGRA210_CPU_CLK) && + (index == CCLK_SRC_PLLP_OUT0 || index == CCLK_SRC_PLLP_OUT4)) + tegra_clk_set_pllp_out_cpu(true); + val &= ~((super_state_to_src_mask(mux)) << shift); val |= (index & (super_state_to_src_mask(mux))) << shift; writel_relaxed(val, mux->reg); udelay(2); + /* disable PLLP branches to CPU if not used */ + if ((mux->flags & TEGRA210_CPU_CLK) && + index != CCLK_SRC_PLLP_OUT0 && index != CCLK_SRC_PLLP_OUT4) + tegra_clk_set_pllp_out_cpu(false); + out: if (mux->lock) spin_unlock_irqrestore(mux->lock, flags); @@ -110,9 +124,21 @@ out: return err; } +static void clk_super_mux_restore_context(struct clk_hw *hw) +{ + int parent_id; + + parent_id = clk_hw_get_parent_index(hw); + if (WARN_ON(parent_id < 0)) + return; + + clk_super_set_parent(hw, parent_id); +} + static const struct clk_ops tegra_clk_super_mux_ops = { .get_parent = clk_super_get_parent, .set_parent = clk_super_set_parent, + .restore_context = clk_super_mux_restore_context, }; static long clk_super_round_rate(struct clk_hw *hw, unsigned long rate, @@ -148,12 +174,27 @@ static int clk_super_set_rate(struct clk_hw *hw, unsigned long rate, return super->div_ops->set_rate(div_hw, rate, parent_rate); } +static void clk_super_restore_context(struct clk_hw *hw) +{ + struct tegra_clk_super_mux *super = to_clk_super_mux(hw); + struct clk_hw *div_hw = &super->frac_div.hw; + int parent_id; + + parent_id = clk_hw_get_parent_index(hw); + if (WARN_ON(parent_id < 0)) + return; + + super->div_ops->restore_context(div_hw); + clk_super_set_parent(hw, parent_id); +} + const struct clk_ops tegra_clk_super_ops = { .get_parent = clk_super_get_parent, .set_parent = clk_super_set_parent, .set_rate = clk_super_set_rate, .round_rate = clk_super_round_rate, .recalc_rate = clk_super_recalc_rate, + .restore_context = clk_super_restore_context, }; struct clk *tegra_clk_register_super_mux(const char *name, diff --git a/drivers/clk/tegra/clk-tegra-fixed.c b/drivers/clk/tegra/clk-tegra-fixed.c index 8d91b2b191cf..7c6c8abfcde6 100644 --- a/drivers/clk/tegra/clk-tegra-fixed.c +++ b/drivers/clk/tegra/clk-tegra-fixed.c @@ -17,6 +17,10 @@ #define OSC_CTRL 0x50 #define OSC_CTRL_OSC_FREQ_SHIFT 28 #define OSC_CTRL_PLL_REF_DIV_SHIFT 26 +#define OSC_CTRL_MASK (0x3f2 | \ + (0xf << OSC_CTRL_OSC_FREQ_SHIFT)) + +static u32 osc_ctrl_ctx; int __init tegra_osc_clk_init(void __iomem *clk_base, struct tegra_clk *clks, unsigned long *input_freqs, unsigned int num, @@ -29,6 +33,7 @@ int __init tegra_osc_clk_init(void __iomem *clk_base, struct tegra_clk *clks, unsigned osc_idx; val = readl_relaxed(clk_base + OSC_CTRL); + osc_ctrl_ctx = val & OSC_CTRL_MASK; osc_idx = val >> OSC_CTRL_OSC_FREQ_SHIFT; if (osc_idx < num) @@ -96,3 +101,13 @@ void __init tegra_fixed_clk_init(struct tegra_clk *tegra_clks) *dt_clk = clk; } } + +void tegra_clk_osc_resume(void __iomem *clk_base) +{ + u32 val; + + val = readl_relaxed(clk_base + OSC_CTRL) & ~OSC_CTRL_MASK; + val |= osc_ctrl_ctx; + writel_relaxed(val, clk_base + OSC_CTRL); + fence_udelay(2, clk_base); +} diff --git a/drivers/clk/tegra/clk-tegra-periph.c b/drivers/clk/tegra/clk-tegra-periph.c index 1ed85f120a1b..0d07c0ba49b6 100644 --- a/drivers/clk/tegra/clk-tegra-periph.c +++ b/drivers/clk/tegra/clk-tegra-periph.c @@ -262,7 +262,6 @@ static DEFINE_SPINLOCK(PLLP_OUTA_lock); static DEFINE_SPINLOCK(PLLP_OUTB_lock); static DEFINE_SPINLOCK(PLLP_OUTC_lock); -static DEFINE_SPINLOCK(sor0_lock); #define MUX_I2S_SPDIF(_id) \ static const char *mux_pllaout0_##_id##_2x_pllp_clkm[] = { "pll_a_out0", \ @@ -587,11 +586,6 @@ static u32 mux_pllp_pllre_clkm_idx[] = { [0] = 0, [1] = 2, [2] = 3, }; -static const char *mux_clkm_plldp_sor0lvds[] = { - "clk_m", "pll_dp", "sor0_lvds", -}; -#define mux_clkm_plldp_sor0lvds_idx NULL - static const char * const mux_dmic1[] = { "pll_a_out0", "dmic1_sync_clk", "pll_p", "clk_m" }; @@ -731,14 +725,12 @@ static struct tegra_periph_init_data periph_clks[] = { MUX8("hdmi_audio", mux_pllp3_pllc_clkm, CLK_SOURCE_HDMI_AUDIO, 176, TEGRA_PERIPH_NO_RESET, tegra_clk_hdmi_audio), MUX8("clk72mhz", mux_pllp3_pllc_clkm, CLK_SOURCE_CLK72MHZ, 177, TEGRA_PERIPH_NO_RESET, tegra_clk_clk72Mhz), MUX8("clk72mhz", mux_pllp_out3_pllp_pllc_clkm, CLK_SOURCE_CLK72MHZ, 177, TEGRA_PERIPH_NO_RESET, tegra_clk_clk72Mhz_8), - MUX8_NOGATE_LOCK("sor0_lvds", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_SOR0, tegra_clk_sor0_lvds, &sor0_lock), MUX_FLAGS("csite", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_CSITE, 73, TEGRA_PERIPH_ON_APB, tegra_clk_csite, CLK_IGNORE_UNUSED), MUX_FLAGS("csite", mux_pllp_pllre_clkm, CLK_SOURCE_CSITE, 73, TEGRA_PERIPH_ON_APB, tegra_clk_csite_8, CLK_IGNORE_UNUSED), NODIV("disp1", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_DISP1, 29, 7, 27, 0, tegra_clk_disp1, NULL), NODIV("disp1", mux_pllp_plld_plld2_clkm, CLK_SOURCE_DISP1, 29, 7, 27, 0, tegra_clk_disp1_8, NULL), NODIV("disp2", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_DISP2, 29, 7, 26, 0, tegra_clk_disp2, NULL), NODIV("disp2", mux_pllp_plld_plld2_clkm, CLK_SOURCE_DISP2, 29, 7, 26, 0, tegra_clk_disp2_8, NULL), - NODIV("sor0", mux_clkm_plldp_sor0lvds, CLK_SOURCE_SOR0, 14, 3, 182, 0, tegra_clk_sor0, &sor0_lock), UART("uarta", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTA, 6, tegra_clk_uarta), UART("uartb", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTB, 7, tegra_clk_uartb), UART("uartc", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTC, 55, tegra_clk_uartc), diff --git a/drivers/clk/tegra/clk-tegra-super-gen4.c b/drivers/clk/tegra/clk-tegra-super-gen4.c index cdfe7c9697e1..5760c978bef7 100644 --- a/drivers/clk/tegra/clk-tegra-super-gen4.c +++ b/drivers/clk/tegra/clk-tegra-super-gen4.c @@ -180,7 +180,7 @@ static void __init tegra_super_clk_init(void __iomem *clk_base, gen_info->num_cclk_g_parents, CLK_SET_RATE_PARENT, clk_base + CCLKG_BURST_POLICY, - 0, 4, 8, 0, NULL); + TEGRA210_CPU_CLK, 4, 8, 0, NULL); } else { clk = tegra_clk_register_super_mux("cclk_g", gen_info->cclk_g_parents, @@ -196,6 +196,11 @@ static void __init tegra_super_clk_init(void __iomem *clk_base, dt_clk = tegra_lookup_dt_id(tegra_clk_cclk_lp, tegra_clks); if (dt_clk) { if (gen_info->gen == gen5) { + /* + * TEGRA210_CPU_CLK flag is not needed for cclk_lp as + * cluster switching is not currently supported on + * Tegra210 and also cpu_lp is not used. + */ clk = tegra_clk_register_super_mux("cclk_lp", gen_info->cclk_lp_parents, gen_info->num_cclk_lp_parents, diff --git a/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c b/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c index e84b6d52cbbd..2ac2679d696d 100644 --- a/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c +++ b/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c @@ -631,6 +631,7 @@ static int tegra124_dfll_fcpu_remove(struct platform_device *pdev) static const struct dev_pm_ops tegra124_dfll_pm_ops = { SET_RUNTIME_PM_OPS(tegra_dfll_runtime_suspend, tegra_dfll_runtime_resume, NULL) + SET_SYSTEM_SLEEP_PM_OPS(tegra_dfll_suspend, tegra_dfll_resume) }; static struct platform_driver tegra124_dfll_fcpu_driver = { diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c index 0224fdc4766f..b3110d5b5a6c 100644 --- a/drivers/clk/tegra/clk-tegra124.c +++ b/drivers/clk/tegra/clk-tegra124.c @@ -27,6 +27,7 @@ #define CLK_SOURCE_CSITE 0x1d4 #define CLK_SOURCE_EMC 0x19c +#define CLK_SOURCE_SOR0 0x414 #define RST_DFLL_DVCO 0x2f4 #define DVFS_DFLL_RESET_SHIFT 0 @@ -91,6 +92,22 @@ /* Tegra CPU clock and reset control regs */ #define CLK_RST_CONTROLLER_CPU_CMPLX_STATUS 0x470 +#define MASK(x) (BIT(x) - 1) + +#define MUX8_NOGATE_LOCK(_name, _parents, _offset, _clk_id, _lock) \ + TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset, \ + 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP,\ + 0, TEGRA_PERIPH_NO_GATE, _clk_id,\ + _parents##_idx, 0, _lock) + +#define NODIV(_name, _parents, _offset, \ + _mux_shift, _mux_mask, _clk_num, \ + _gate_flags, _clk_id, _lock) \ + TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ + _mux_shift, _mux_mask, 0, 0, 0, 0, 0,\ + _clk_num, (_gate_flags) | TEGRA_PERIPH_NO_DIV,\ + _clk_id, _parents##_idx, 0, _lock) + #ifdef CONFIG_PM_SLEEP static struct cpu_clk_suspend_context { u32 clk_csite_src; @@ -110,6 +127,7 @@ static DEFINE_SPINLOCK(pll_e_lock); static DEFINE_SPINLOCK(pll_re_lock); static DEFINE_SPINLOCK(pll_u_lock); static DEFINE_SPINLOCK(emc_lock); +static DEFINE_SPINLOCK(sor0_lock); /* possible OSC frequencies in Hz */ static unsigned long tegra124_input_freq[] = { @@ -829,7 +847,7 @@ static struct tegra_clk tegra124_clks[tegra_clk_max] __initdata = { [tegra_clk_adx1] = { .dt_id = TEGRA124_CLK_ADX1, .present = true }, [tegra_clk_dpaux] = { .dt_id = TEGRA124_CLK_DPAUX, .present = true }, [tegra_clk_sor0] = { .dt_id = TEGRA124_CLK_SOR0, .present = true }, - [tegra_clk_sor0_lvds] = { .dt_id = TEGRA124_CLK_SOR0_LVDS, .present = true }, + [tegra_clk_sor0_out] = { .dt_id = TEGRA124_CLK_SOR0_OUT, .present = true }, [tegra_clk_gpu] = { .dt_id = TEGRA124_CLK_GPU, .present = true }, [tegra_clk_amx1] = { .dt_id = TEGRA124_CLK_AMX1, .present = true }, [tegra_clk_uartb] = { .dt_id = TEGRA124_CLK_UARTB, .present = true }, @@ -987,12 +1005,33 @@ static struct tegra_devclk devclks[] __initdata = { { .con_id = "hda2hdmi", .dt_id = TEGRA124_CLK_HDA2HDMI }, }; +static const char * const sor0_parents[] = { + "pll_p_out0", "pll_m_out0", "pll_d_out0", "pll_a_out0", "pll_c_out0", + "pll_d2_out0", "clk_m", +}; + +static const char * const sor0_out_parents[] = { + "clk_m", "sor0_pad_clkout", +}; + +static struct tegra_periph_init_data tegra124_periph[] = { + TEGRA_INIT_DATA_TABLE("sor0", NULL, NULL, sor0_parents, + CLK_SOURCE_SOR0, 29, 0x7, 0, 0, 0, 0, + 0, 182, 0, tegra_clk_sor0, NULL, 0, + &sor0_lock), + TEGRA_INIT_DATA_TABLE("sor0_out", NULL, NULL, sor0_out_parents, + CLK_SOURCE_SOR0, 14, 0x1, 0, 0, 0, 0, + 0, 0, TEGRA_PERIPH_NO_GATE, tegra_clk_sor0_out, + NULL, 0, &sor0_lock), +}; + static struct clk **clks; static __init void tegra124_periph_clk_init(void __iomem *clk_base, void __iomem *pmc_base) { struct clk *clk; + unsigned int i; /* xusb_ss_div2 */ clk = clk_register_fixed_factor(NULL, "xusb_ss_div2", "xusb_ss_src", 0, @@ -1033,6 +1072,20 @@ static __init void tegra124_periph_clk_init(void __iomem *clk_base, clk_register_clkdev(clk, "cml1", NULL); clks[TEGRA124_CLK_CML1] = clk; + for (i = 0; i < ARRAY_SIZE(tegra124_periph); i++) { + struct tegra_periph_init_data *init = &tegra124_periph[i]; + struct clk **clkp; + + clkp = tegra_lookup_dt_id(init->clk_id, tegra124_clks); + if (!clkp) { + pr_warn("clock %u not found\n", init->clk_id); + continue; + } + + clk = tegra_clk_register_periph_data(clk_base, init); + *clkp = clk; + } + tegra_periph_clk_init(clk_base, pmc_base, tegra124_clks, &pll_p_params); } diff --git a/drivers/clk/tegra/clk-tegra20-emc.c b/drivers/clk/tegra/clk-tegra20-emc.c new file mode 100644 index 000000000000..03bf0009a33c --- /dev/null +++ b/drivers/clk/tegra/clk-tegra20-emc.c @@ -0,0 +1,293 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Based on drivers/clk/tegra/clk-emc.c + * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. + * + * Author: Dmitry Osipenko <digetx@gmail.com> + * Copyright (C) 2019 GRATE-DRIVER project + */ + +#define pr_fmt(fmt) "tegra-emc-clk: " fmt + +#include <linux/bits.h> +#include <linux/clk-provider.h> +#include <linux/clk/tegra.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <linux/slab.h> + +#include "clk.h" + +#define CLK_SOURCE_EMC_2X_CLK_DIVISOR_MASK GENMASK(7, 0) +#define CLK_SOURCE_EMC_2X_CLK_SRC_MASK GENMASK(31, 30) +#define CLK_SOURCE_EMC_2X_CLK_SRC_SHIFT 30 + +#define MC_EMC_SAME_FREQ BIT(16) +#define USE_PLLM_UD BIT(29) + +#define EMC_SRC_PLL_M 0 +#define EMC_SRC_PLL_C 1 +#define EMC_SRC_PLL_P 2 +#define EMC_SRC_CLK_M 3 + +static const char * const emc_parent_clk_names[] = { + "pll_m", "pll_c", "pll_p", "clk_m", +}; + +struct tegra_clk_emc { + struct clk_hw hw; + void __iomem *reg; + bool mc_same_freq; + bool want_low_jitter; + + tegra20_clk_emc_round_cb *round_cb; + void *cb_arg; +}; + +static inline struct tegra_clk_emc *to_tegra_clk_emc(struct clk_hw *hw) +{ + return container_of(hw, struct tegra_clk_emc, hw); +} + +static unsigned long emc_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct tegra_clk_emc *emc = to_tegra_clk_emc(hw); + u32 val, div; + + val = readl_relaxed(emc->reg); + div = val & CLK_SOURCE_EMC_2X_CLK_DIVISOR_MASK; + + return DIV_ROUND_UP(parent_rate * 2, div + 2); +} + +static u8 emc_get_parent(struct clk_hw *hw) +{ + struct tegra_clk_emc *emc = to_tegra_clk_emc(hw); + + return readl_relaxed(emc->reg) >> CLK_SOURCE_EMC_2X_CLK_SRC_SHIFT; +} + +static int emc_set_parent(struct clk_hw *hw, u8 index) +{ + struct tegra_clk_emc *emc = to_tegra_clk_emc(hw); + u32 val, div; + + val = readl_relaxed(emc->reg); + val &= ~CLK_SOURCE_EMC_2X_CLK_SRC_MASK; + val |= index << CLK_SOURCE_EMC_2X_CLK_SRC_SHIFT; + + div = val & CLK_SOURCE_EMC_2X_CLK_DIVISOR_MASK; + + if (index == EMC_SRC_PLL_M && div == 0 && emc->want_low_jitter) + val |= USE_PLLM_UD; + else + val &= ~USE_PLLM_UD; + + if (emc->mc_same_freq) + val |= MC_EMC_SAME_FREQ; + else + val &= ~MC_EMC_SAME_FREQ; + + writel_relaxed(val, emc->reg); + + fence_udelay(1, emc->reg); + + return 0; +} + +static int emc_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct tegra_clk_emc *emc = to_tegra_clk_emc(hw); + unsigned int index; + u32 val, div; + + div = div_frac_get(rate, parent_rate, 8, 1, 0); + + val = readl_relaxed(emc->reg); + val &= ~CLK_SOURCE_EMC_2X_CLK_DIVISOR_MASK; + val |= div; + + index = val >> CLK_SOURCE_EMC_2X_CLK_SRC_SHIFT; + + if (index == EMC_SRC_PLL_M && div == 0 && emc->want_low_jitter) + val |= USE_PLLM_UD; + else + val &= ~USE_PLLM_UD; + + if (emc->mc_same_freq) + val |= MC_EMC_SAME_FREQ; + else + val &= ~MC_EMC_SAME_FREQ; + + writel_relaxed(val, emc->reg); + + fence_udelay(1, emc->reg); + + return 0; +} + +static int emc_set_rate_and_parent(struct clk_hw *hw, + unsigned long rate, + unsigned long parent_rate, + u8 index) +{ + struct tegra_clk_emc *emc = to_tegra_clk_emc(hw); + u32 val, div; + + div = div_frac_get(rate, parent_rate, 8, 1, 0); + + val = readl_relaxed(emc->reg); + + val &= ~CLK_SOURCE_EMC_2X_CLK_SRC_MASK; + val |= index << CLK_SOURCE_EMC_2X_CLK_SRC_SHIFT; + + val &= ~CLK_SOURCE_EMC_2X_CLK_DIVISOR_MASK; + val |= div; + + if (index == EMC_SRC_PLL_M && div == 0 && emc->want_low_jitter) + val |= USE_PLLM_UD; + else + val &= ~USE_PLLM_UD; + + if (emc->mc_same_freq) + val |= MC_EMC_SAME_FREQ; + else + val &= ~MC_EMC_SAME_FREQ; + + writel_relaxed(val, emc->reg); + + fence_udelay(1, emc->reg); + + return 0; +} + +static int emc_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) +{ + struct tegra_clk_emc *emc = to_tegra_clk_emc(hw); + struct clk_hw *parent_hw; + unsigned long divided_rate; + unsigned long parent_rate; + unsigned int i; + long emc_rate; + int div; + + emc_rate = emc->round_cb(req->rate, req->min_rate, req->max_rate, + emc->cb_arg); + if (emc_rate < 0) + return emc_rate; + + for (i = 0; i < ARRAY_SIZE(emc_parent_clk_names); i++) { + parent_hw = clk_hw_get_parent_by_index(hw, i); + + if (req->best_parent_hw == parent_hw) + parent_rate = req->best_parent_rate; + else + parent_rate = clk_hw_get_rate(parent_hw); + + if (emc_rate > parent_rate) + continue; + + div = div_frac_get(emc_rate, parent_rate, 8, 1, 0); + divided_rate = DIV_ROUND_UP(parent_rate * 2, div + 2); + + if (divided_rate != emc_rate) + continue; + + req->best_parent_rate = parent_rate; + req->best_parent_hw = parent_hw; + req->rate = emc_rate; + break; + } + + if (i == ARRAY_SIZE(emc_parent_clk_names)) { + pr_err_once("can't find parent for rate %lu emc_rate %lu\n", + req->rate, emc_rate); + return -EINVAL; + } + + return 0; +} + +static const struct clk_ops tegra_clk_emc_ops = { + .recalc_rate = emc_recalc_rate, + .get_parent = emc_get_parent, + .set_parent = emc_set_parent, + .set_rate = emc_set_rate, + .set_rate_and_parent = emc_set_rate_and_parent, + .determine_rate = emc_determine_rate, +}; + +void tegra20_clk_set_emc_round_callback(tegra20_clk_emc_round_cb *round_cb, + void *cb_arg) +{ + struct clk *clk = __clk_lookup("emc"); + struct tegra_clk_emc *emc; + struct clk_hw *hw; + + if (clk) { + hw = __clk_get_hw(clk); + emc = to_tegra_clk_emc(hw); + + emc->round_cb = round_cb; + emc->cb_arg = cb_arg; + } +} + +bool tegra20_clk_emc_driver_available(struct clk_hw *emc_hw) +{ + return to_tegra_clk_emc(emc_hw)->round_cb != NULL; +} + +struct clk *tegra20_clk_register_emc(void __iomem *ioaddr, bool low_jitter) +{ + struct tegra_clk_emc *emc; + struct clk_init_data init; + struct clk *clk; + + emc = kzalloc(sizeof(*emc), GFP_KERNEL); + if (!emc) + return NULL; + + /* + * EMC stands for External Memory Controller. + * + * We don't want EMC clock to be disabled ever by gating its + * parent and whatnot because system is busted immediately in that + * case, hence the clock is marked as critical. + */ + init.name = "emc"; + init.ops = &tegra_clk_emc_ops; + init.flags = CLK_IS_CRITICAL; + init.parent_names = emc_parent_clk_names; + init.num_parents = ARRAY_SIZE(emc_parent_clk_names); + + emc->reg = ioaddr; + emc->hw.init = &init; + emc->want_low_jitter = low_jitter; + + clk = clk_register(NULL, &emc->hw); + if (IS_ERR(clk)) { + kfree(emc); + return NULL; + } + + return clk; +} + +int tegra20_clk_prepare_emc_mc_same_freq(struct clk *emc_clk, bool same) +{ + struct tegra_clk_emc *emc; + struct clk_hw *hw; + + if (!emc_clk) + return -EINVAL; + + hw = __clk_get_hw(emc_clk); + emc = to_tegra_clk_emc(hw); + emc->mc_same_freq = same; + + return 0; +} diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c index bcd871134f45..4d8222f5c638 100644 --- a/drivers/clk/tegra/clk-tegra20.c +++ b/drivers/clk/tegra/clk-tegra20.c @@ -130,8 +130,6 @@ static struct cpu_clk_suspend_context { static void __iomem *clk_base; static void __iomem *pmc_base; -static DEFINE_SPINLOCK(emc_lock); - #define TEGRA_INIT_DATA_MUX(_name, _parents, _offset, \ _clk_num, _gate_flags, _clk_id) \ TEGRA_INIT_DATA(_name, NULL, NULL, _parents, _offset, \ @@ -760,7 +758,6 @@ static const char *pwm_parents[] = { "pll_p", "pll_c", "audio", "clk_m", static const char *mux_pllpcm_clkm[] = { "pll_p", "pll_c", "pll_m", "clk_m" }; static const char *mux_pllpdc_clkm[] = { "pll_p", "pll_d_out0", "pll_c", "clk_m" }; -static const char *mux_pllmcp_clkm[] = { "pll_m", "pll_c", "pll_p", "clk_m" }; static struct tegra_periph_init_data tegra_periph_clk_list[] = { TEGRA_INIT_DATA_MUX("i2s1", i2s1_parents, CLK_SOURCE_I2S1, 11, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_I2S1), @@ -787,41 +784,6 @@ static struct tegra_periph_init_data tegra_periph_nodiv_clk_list[] = { TEGRA_INIT_DATA_NODIV("disp2", mux_pllpdc_clkm, CLK_SOURCE_DISP2, 30, 2, 26, 0, TEGRA20_CLK_DISP2), }; -static void __init tegra20_emc_clk_init(void) -{ - const u32 use_pllm_ud = BIT(29); - struct clk *clk; - u32 emc_reg; - - clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm, - ARRAY_SIZE(mux_pllmcp_clkm), - CLK_SET_RATE_NO_REPARENT, - clk_base + CLK_SOURCE_EMC, - 30, 2, 0, &emc_lock); - - clk = tegra_clk_register_mc("mc", "emc_mux", clk_base + CLK_SOURCE_EMC, - &emc_lock); - clks[TEGRA20_CLK_MC] = clk; - - /* un-divided pll_m_out0 is currently unsupported */ - emc_reg = readl_relaxed(clk_base + CLK_SOURCE_EMC); - if (emc_reg & use_pllm_ud) { - pr_err("%s: un-divided PllM_out0 used as clock source\n", - __func__); - return; - } - - /* - * Note that 'emc_mux' source and 'emc' rate shouldn't be changed at - * the same time due to a HW bug, this won't happen because we're - * defining 'emc_mux' and 'emc' as distinct clocks. - */ - clk = tegra_clk_register_divider("emc", "emc_mux", - clk_base + CLK_SOURCE_EMC, CLK_IS_CRITICAL, - TEGRA_DIVIDER_INT, 0, 8, 1, &emc_lock); - clks[TEGRA20_CLK_EMC] = clk; -} - static void __init tegra20_periph_clk_init(void) { struct tegra_periph_init_data *data; @@ -835,7 +797,13 @@ static void __init tegra20_periph_clk_init(void) clks[TEGRA20_CLK_AC97] = clk; /* emc */ - tegra20_emc_clk_init(); + clk = tegra20_clk_register_emc(clk_base + CLK_SOURCE_EMC, false); + + clks[TEGRA20_CLK_EMC] = clk; + + clk = tegra_clk_register_mc("mc", "emc", clk_base + CLK_SOURCE_EMC, + NULL); + clks[TEGRA20_CLK_MC] = clk; /* dsi */ clk = tegra_clk_register_periph_gate("dsi", "pll_d", 0, clk_base, 0, @@ -987,6 +955,7 @@ static void tegra20_cpu_clock_suspend(void) static void tegra20_cpu_clock_resume(void) { unsigned int reg, policy; + u32 misc, base; /* Is CPU complex already running on PLLX? */ reg = readl(clk_base + CCLK_BURST_POLICY); @@ -1000,15 +969,21 @@ static void tegra20_cpu_clock_resume(void) BUG(); if (reg != CCLK_BURST_POLICY_PLLX) { - /* restore PLLX settings if CPU is on different PLL */ - writel(tegra20_cpu_clk_sctx.pllx_misc, - clk_base + PLLX_MISC); - writel(tegra20_cpu_clk_sctx.pllx_base, - clk_base + PLLX_BASE); - - /* wait for PLL stabilization if PLLX was enabled */ - if (tegra20_cpu_clk_sctx.pllx_base & (1 << 30)) - udelay(300); + misc = readl_relaxed(clk_base + PLLX_MISC); + base = readl_relaxed(clk_base + PLLX_BASE); + + if (misc != tegra20_cpu_clk_sctx.pllx_misc || + base != tegra20_cpu_clk_sctx.pllx_base) { + /* restore PLLX settings if CPU is on different PLL */ + writel(tegra20_cpu_clk_sctx.pllx_misc, + clk_base + PLLX_MISC); + writel(tegra20_cpu_clk_sctx.pllx_base, + clk_base + PLLX_BASE); + + /* wait for PLL stabilization if PLLX was enabled */ + if (tegra20_cpu_clk_sctx.pllx_base & (1 << 30)) + udelay(300); + } } /* @@ -1115,6 +1090,8 @@ static struct clk *tegra20_clk_src_onecell_get(struct of_phandle_args *clkspec, if (IS_ERR(clk)) return clk; + hw = __clk_get_hw(clk); + /* * Tegra20 CDEV1 and CDEV2 clocks are a bit special case, their parent * clock is created by the pinctrl driver. It is possible for clk user @@ -1124,13 +1101,16 @@ static struct clk *tegra20_clk_src_onecell_get(struct of_phandle_args *clkspec, */ if (clkspec->args[0] == TEGRA20_CLK_CDEV1 || clkspec->args[0] == TEGRA20_CLK_CDEV2) { - hw = __clk_get_hw(clk); - parent_hw = clk_hw_get_parent(hw); if (!parent_hw) return ERR_PTR(-EPROBE_DEFER); } + if (clkspec->args[0] == TEGRA20_CLK_EMC) { + if (!tegra20_clk_emc_driver_available(hw)) + return ERR_PTR(-EPROBE_DEFER); + } + return clk; } diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c index df172d5772d7..762cd186f714 100644 --- a/drivers/clk/tegra/clk-tegra210.c +++ b/drivers/clk/tegra/clk-tegra210.c @@ -9,13 +9,13 @@ #include <linux/clkdev.h> #include <linux/of.h> #include <linux/of_address.h> +#include <linux/syscore_ops.h> #include <linux/delay.h> #include <linux/export.h> #include <linux/mutex.h> #include <linux/clk/tegra.h> #include <dt-bindings/clock/tegra210-car.h> #include <dt-bindings/reset/tegra210-car.h> -#include <linux/iopoll.h> #include <linux/sizes.h> #include <soc/tegra/pmc.h> @@ -33,6 +33,7 @@ #define CLK_SOURCE_CSITE 0x1d4 #define CLK_SOURCE_EMC 0x19c #define CLK_SOURCE_SOR1 0x410 +#define CLK_SOURCE_SOR0 0x414 #define CLK_SOURCE_LA 0x1f8 #define CLK_SOURCE_SDMMC2 0x154 #define CLK_SOURCE_SDMMC4 0x164 @@ -220,11 +221,15 @@ #define CLK_M_DIVISOR_SHIFT 2 #define CLK_M_DIVISOR_MASK 0x3 +#define CLK_MASK_ARM 0x44 +#define MISC_CLK_ENB 0x48 + #define RST_DFLL_DVCO 0x2f4 #define DVFS_DFLL_RESET_SHIFT 0 #define CLK_RST_CONTROLLER_RST_DEV_Y_SET 0x2a8 #define CLK_RST_CONTROLLER_RST_DEV_Y_CLR 0x2ac +#define CPU_SOFTRST_CTRL 0x380 #define LVL2_CLK_GATE_OVRA 0xf8 #define LVL2_CLK_GATE_OVRC 0x3a0 @@ -298,6 +303,7 @@ static DEFINE_SPINLOCK(pll_d_lock); static DEFINE_SPINLOCK(pll_e_lock); static DEFINE_SPINLOCK(pll_re_lock); static DEFINE_SPINLOCK(pll_u_lock); +static DEFINE_SPINLOCK(sor0_lock); static DEFINE_SPINLOCK(sor1_lock); static DEFINE_SPINLOCK(emc_lock); static DEFINE_MUTEX(lvl2_ovr_lock); @@ -2351,9 +2357,9 @@ static struct tegra_clk tegra210_clks[tegra_clk_max] __initdata = { [tegra_clk_dpaux] = { .dt_id = TEGRA210_CLK_DPAUX, .present = true }, [tegra_clk_dpaux1] = { .dt_id = TEGRA210_CLK_DPAUX1, .present = true }, [tegra_clk_sor0] = { .dt_id = TEGRA210_CLK_SOR0, .present = true }, - [tegra_clk_sor0_lvds] = { .dt_id = TEGRA210_CLK_SOR0_LVDS, .present = true }, + [tegra_clk_sor0_out] = { .dt_id = TEGRA210_CLK_SOR0_OUT, .present = true }, [tegra_clk_sor1] = { .dt_id = TEGRA210_CLK_SOR1, .present = true }, - [tegra_clk_sor1_src] = { .dt_id = TEGRA210_CLK_SOR1_SRC, .present = true }, + [tegra_clk_sor1_out] = { .dt_id = TEGRA210_CLK_SOR1_OUT, .present = true }, [tegra_clk_gpu] = { .dt_id = TEGRA210_CLK_GPU, .present = true }, [tegra_clk_pll_g_ref] = { .dt_id = TEGRA210_CLK_PLL_G_REF, .present = true, }, [tegra_clk_uartb_8] = { .dt_id = TEGRA210_CLK_UARTB, .present = true }, @@ -2551,7 +2557,6 @@ static struct tegra_devclk devclks[] __initdata = { { .con_id = "pll_c4_out2", .dt_id = TEGRA210_CLK_PLL_C4_OUT2 }, { .con_id = "pll_c4_out3", .dt_id = TEGRA210_CLK_PLL_C4_OUT3 }, { .con_id = "dpaux", .dt_id = TEGRA210_CLK_DPAUX }, - { .con_id = "sor0", .dt_id = TEGRA210_CLK_SOR0 }, }; static struct tegra_audio_clk_info tegra210_audio_plls[] = { @@ -2825,6 +2830,7 @@ static int tegra210_enable_pllu(void) struct tegra_clk_pll_freq_table *fentry; struct tegra_clk_pll pllu; u32 reg; + int ret; for (fentry = pll_u_freq_table; fentry->input_rate; fentry++) { if (fentry->input_rate == pll_ref_freq) @@ -2841,7 +2847,7 @@ static int tegra210_enable_pllu(void) reg = readl_relaxed(clk_base + pllu.params->ext_misc_reg[0]); reg &= ~BIT(pllu.params->iddq_bit_idx); writel_relaxed(reg, clk_base + pllu.params->ext_misc_reg[0]); - udelay(5); + fence_udelay(5, clk_base); reg = readl_relaxed(clk_base + PLLU_BASE); reg &= ~GENMASK(20, 0); @@ -2849,13 +2855,18 @@ static int tegra210_enable_pllu(void) reg |= fentry->n << 8; reg |= fentry->p << 16; writel(reg, clk_base + PLLU_BASE); - udelay(1); + fence_udelay(1, clk_base); reg |= PLL_ENABLE; writel(reg, clk_base + PLLU_BASE); - readl_relaxed_poll_timeout_atomic(clk_base + PLLU_BASE, reg, - reg & PLL_BASE_LOCK, 2, 1000); - if (!(reg & PLL_BASE_LOCK)) { + /* + * During clocks resume, same PLLU init and enable sequence get + * executed. So, readx_poll_timeout_atomic can't be used here as it + * uses ktime_get() and timekeeping resume doesn't happen by that + * time. So, using tegra210_wait_for_mask for PLL LOCK. + */ + ret = tegra210_wait_for_mask(&pllu, PLLU_BASE, PLL_BASE_LOCK); + if (ret) { pr_err("Timed out waiting for PLL_U to lock\n"); return -ETIMEDOUT; } @@ -2895,12 +2906,12 @@ static int tegra210_init_pllu(void) reg = readl_relaxed(clk_base + XUSB_PLL_CFG0); reg &= ~XUSB_PLL_CFG0_PLLU_LOCK_DLY_MASK; writel_relaxed(reg, clk_base + XUSB_PLL_CFG0); - udelay(1); + fence_udelay(1, clk_base); reg = readl_relaxed(clk_base + PLLU_HW_PWRDN_CFG0); reg |= PLLU_HW_PWRDN_CFG0_SEQ_ENABLE; writel_relaxed(reg, clk_base + PLLU_HW_PWRDN_CFG0); - udelay(1); + fence_udelay(1, clk_base); reg = readl_relaxed(clk_base + PLLU_BASE); reg &= ~PLLU_BASE_CLKENABLE_USB; @@ -2915,6 +2926,39 @@ static int tegra210_init_pllu(void) return 0; } +/* + * The SOR hardware blocks are driven by two clocks: a module clock that is + * used to access registers and a pixel clock that is sourced from the same + * pixel clock that also drives the head attached to the SOR. The module + * clock is typically called sorX (with X being the SOR instance) and the + * pixel clock is called sorX_out. The source for the SOR pixel clock is + * referred to as the "parent" clock. + * + * On Tegra186 and newer, clocks are provided by the BPMP. Unfortunately the + * BPMP implementation for the SOR clocks doesn't exactly match the above in + * some aspects. For example, the SOR module is really clocked by the pad or + * sor_safe clocks, but BPMP models the sorX clock as being sourced by the + * pixel clocks. Conversely the sorX_out clock is sourced by the sor_safe or + * pad clocks on BPMP. + * + * In order to allow the display driver to deal with all SoC generations in + * a unified way, implement the BPMP semantics in this driver. + */ + +static const char * const sor0_parents[] = { + "pll_d_out0", +}; + +static const char * const sor0_out_parents[] = { + "sor_safe", "sor0_pad_clkout", +}; + +static const char * const sor1_parents[] = { + "pll_p", "pll_d_out0", "pll_d2_out0", "clk_m", +}; + +static u32 sor1_parents_idx[] = { 0, 2, 5, 6 }; + static const char * const sor1_out_parents[] = { /* * Bit 0 of the mux selects sor1_pad_clkout, irrespective of bit 1, so @@ -2923,20 +2967,31 @@ static const char * const sor1_out_parents[] = { * these bits to 0b11. While not an invalid setting, code should * always set the bits to 0b01 to select sor1_pad_clkout. */ - "sor_safe", "sor1_pad_clkout", "sor1", "sor1_pad_clkout", + "sor_safe", "sor1_pad_clkout", "sor1_out", "sor1_pad_clkout", }; -static const char * const sor1_parents[] = { - "pll_p", "pll_d_out0", "pll_d2_out0", "clk_m", -}; - -static u32 sor1_parents_idx[] = { 0, 2, 5, 6 }; - static struct tegra_periph_init_data tegra210_periph[] = { + /* + * On Tegra210, the sor0 clock doesn't have a mux it bitfield 31:29, + * but it is hardwired to the pll_d_out0 clock. + */ + TEGRA_INIT_DATA_TABLE("sor0", NULL, NULL, sor0_parents, + CLK_SOURCE_SOR0, 29, 0x0, 0, 0, 0, 0, + 0, 182, 0, tegra_clk_sor0, NULL, 0, + &sor0_lock), + TEGRA_INIT_DATA_TABLE("sor0_out", NULL, NULL, sor0_out_parents, + CLK_SOURCE_SOR0, 14, 0x1, 0, 0, 0, 0, + 0, 0, TEGRA_PERIPH_NO_GATE, tegra_clk_sor0_out, + NULL, 0, &sor0_lock), TEGRA_INIT_DATA_TABLE("sor1", NULL, NULL, sor1_parents, CLK_SOURCE_SOR1, 29, 0x7, 0, 0, 8, 1, - TEGRA_DIVIDER_ROUND_UP, 183, 0, tegra_clk_sor1, - sor1_parents_idx, 0, &sor1_lock), + TEGRA_DIVIDER_ROUND_UP, 183, 0, + tegra_clk_sor1, sor1_parents_idx, 0, + &sor1_lock), + TEGRA_INIT_DATA_TABLE("sor1_out", NULL, NULL, sor1_out_parents, + CLK_SOURCE_SOR1, 14, 0x3, 0, 0, 0, 0, + 0, 0, TEGRA_PERIPH_NO_GATE, + tegra_clk_sor1_out, NULL, 0, &sor1_lock), }; static const char * const la_parents[] = { @@ -2969,12 +3024,6 @@ static __init void tegra210_periph_clk_init(void __iomem *clk_base, 1, 17, 207); clks[TEGRA210_CLK_DPAUX1] = clk; - clk = clk_register_mux_table(NULL, "sor1_out", sor1_out_parents, - ARRAY_SIZE(sor1_out_parents), 0, - clk_base + CLK_SOURCE_SOR1, 14, 0x3, - 0, NULL, &sor1_lock); - clks[TEGRA210_CLK_SOR1_OUT] = clk; - /* pll_d_dsi_out */ clk = clk_register_gate(NULL, "pll_d_dsi_out", "pll_d_out0", 0, clk_base + PLLD_MISC0, 21, 0, &pll_d_lock); @@ -3287,6 +3336,77 @@ static void tegra210_disable_cpu_clock(u32 cpu) } #ifdef CONFIG_PM_SLEEP +#define car_readl(_base, _off) readl_relaxed(clk_base + (_base) + ((_off) * 4)) +#define car_writel(_val, _base, _off) \ + writel_relaxed(_val, clk_base + (_base) + ((_off) * 4)) + +static u32 spare_reg_ctx, misc_clk_enb_ctx, clk_msk_arm_ctx; +static u32 cpu_softrst_ctx[3]; + +static int tegra210_clk_suspend(void) +{ + unsigned int i; + + clk_save_context(); + + /* + * Save the bootloader configured clock registers SPARE_REG0, + * MISC_CLK_ENB, CLK_MASK_ARM, CPU_SOFTRST_CTRL. + */ + spare_reg_ctx = readl_relaxed(clk_base + SPARE_REG0); + misc_clk_enb_ctx = readl_relaxed(clk_base + MISC_CLK_ENB); + clk_msk_arm_ctx = readl_relaxed(clk_base + CLK_MASK_ARM); + + for (i = 0; i < ARRAY_SIZE(cpu_softrst_ctx); i++) + cpu_softrst_ctx[i] = car_readl(CPU_SOFTRST_CTRL, i); + + tegra_clk_periph_suspend(); + return 0; +} + +static void tegra210_clk_resume(void) +{ + unsigned int i; + + tegra_clk_osc_resume(clk_base); + + /* + * Restore the bootloader configured clock registers SPARE_REG0, + * MISC_CLK_ENB, CLK_MASK_ARM, CPU_SOFTRST_CTRL from saved context. + */ + writel_relaxed(spare_reg_ctx, clk_base + SPARE_REG0); + writel_relaxed(misc_clk_enb_ctx, clk_base + MISC_CLK_ENB); + writel_relaxed(clk_msk_arm_ctx, clk_base + CLK_MASK_ARM); + + for (i = 0; i < ARRAY_SIZE(cpu_softrst_ctx); i++) + car_writel(cpu_softrst_ctx[i], CPU_SOFTRST_CTRL, i); + + /* + * Tegra clock programming sequence recommends peripheral clock to + * be enabled prior to changing its clock source and divider to + * prevent glitchless frequency switch. + * So, enable all peripheral clocks before restoring their source + * and dividers. + */ + writel_relaxed(TEGRA210_CLK_ENB_VLD_MSK_L, clk_base + CLK_OUT_ENB_L); + writel_relaxed(TEGRA210_CLK_ENB_VLD_MSK_H, clk_base + CLK_OUT_ENB_H); + writel_relaxed(TEGRA210_CLK_ENB_VLD_MSK_U, clk_base + CLK_OUT_ENB_U); + writel_relaxed(TEGRA210_CLK_ENB_VLD_MSK_V, clk_base + CLK_OUT_ENB_V); + writel_relaxed(TEGRA210_CLK_ENB_VLD_MSK_W, clk_base + CLK_OUT_ENB_W); + writel_relaxed(TEGRA210_CLK_ENB_VLD_MSK_X, clk_base + CLK_OUT_ENB_X); + writel_relaxed(TEGRA210_CLK_ENB_VLD_MSK_Y, clk_base + CLK_OUT_ENB_Y); + + /* wait for all writes to happen to have all the clocks enabled */ + fence_udelay(2, clk_base); + + /* restore PLLs and all peripheral clock rates */ + tegra210_init_pllu(); + clk_restore_context(); + + /* restore saved context of peripheral clocks and reset state */ + tegra_clk_periph_resume(); +} + static void tegra210_cpu_clock_suspend(void) { /* switch coresite to clk_m, save off original source */ @@ -3302,6 +3422,13 @@ static void tegra210_cpu_clock_resume(void) } #endif +static struct syscore_ops tegra_clk_syscore_ops = { +#ifdef CONFIG_PM_SLEEP + .suspend = tegra210_clk_suspend, + .resume = tegra210_clk_resume, +#endif +}; + static struct tegra_cpu_car_ops tegra210_cpu_car_ops = { .wait_for_reset = tegra210_wait_cpu_in_reset, .disable_clock = tegra210_disable_cpu_clock, @@ -3586,5 +3713,7 @@ static void __init tegra210_clock_init(struct device_node *np) tegra210_mbist_clk_init(); tegra_cpu_car_ops = &tegra210_cpu_car_ops; + + register_syscore_ops(&tegra_clk_syscore_ops); } CLK_OF_DECLARE(tegra210, "nvidia,tegra210-car", tegra210_clock_init); diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c index 7b4c6a488527..c8bc18e4d7e5 100644 --- a/drivers/clk/tegra/clk-tegra30.c +++ b/drivers/clk/tegra/clk-tegra30.c @@ -151,7 +151,6 @@ static unsigned long input_freq; static DEFINE_SPINLOCK(cml_lock); static DEFINE_SPINLOCK(pll_d_lock); -static DEFINE_SPINLOCK(emc_lock); #define TEGRA_INIT_DATA_MUX(_name, _parents, _offset, \ _clk_num, _gate_flags, _clk_id) \ @@ -808,7 +807,7 @@ static struct tegra_clk tegra30_clks[tegra_clk_max] __initdata = { [tegra_clk_pll_a] = { .dt_id = TEGRA30_CLK_PLL_A, .present = true }, [tegra_clk_pll_a_out0] = { .dt_id = TEGRA30_CLK_PLL_A_OUT0, .present = true }, [tegra_clk_cec] = { .dt_id = TEGRA30_CLK_CEC, .present = true }, - [tegra_clk_emc] = { .dt_id = TEGRA30_CLK_EMC, .present = true }, + [tegra_clk_emc] = { .dt_id = TEGRA30_CLK_EMC, .present = false }, }; static const char *pll_e_parents[] = { "pll_ref", "pll_p" }; @@ -995,7 +994,6 @@ static void __init tegra30_super_clk_init(void) static const char *mux_pllacp_clkm[] = { "pll_a_out0", "unused", "pll_p", "clk_m" }; static const char *mux_pllpcm_clkm[] = { "pll_p", "pll_c", "pll_m", "clk_m" }; -static const char *mux_pllmcp_clkm[] = { "pll_m", "pll_c", "pll_p", "clk_m" }; static const char *spdif_out_parents[] = { "pll_a_out0", "spdif_2x", "pll_p", "clk_m" }; static const char *mux_pllmcpa[] = { "pll_m", "pll_c", "pll_p", "pll_a_out0" }; @@ -1044,14 +1042,12 @@ static void __init tegra30_periph_clk_init(void) clks[TEGRA30_CLK_AFI] = clk; /* emc */ - clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm, - ARRAY_SIZE(mux_pllmcp_clkm), - CLK_SET_RATE_NO_REPARENT, - clk_base + CLK_SOURCE_EMC, - 30, 2, 0, &emc_lock); + clk = tegra20_clk_register_emc(clk_base + CLK_SOURCE_EMC, true); + + clks[TEGRA30_CLK_EMC] = clk; - clk = tegra_clk_register_mc("mc", "emc_mux", clk_base + CLK_SOURCE_EMC, - &emc_lock); + clk = tegra_clk_register_mc("mc", "emc", clk_base + CLK_SOURCE_EMC, + NULL); clks[TEGRA30_CLK_MC] = clk; /* cml0 */ @@ -1167,6 +1163,7 @@ static void tegra30_cpu_clock_suspend(void) static void tegra30_cpu_clock_resume(void) { unsigned int reg, policy; + u32 misc, base; /* Is CPU complex already running on PLLX? */ reg = readl(clk_base + CLK_RESET_CCLK_BURST); @@ -1180,15 +1177,21 @@ static void tegra30_cpu_clock_resume(void) BUG(); if (reg != CLK_RESET_CCLK_BURST_POLICY_PLLX) { - /* restore PLLX settings if CPU is on different PLL */ - writel(tegra30_cpu_clk_sctx.pllx_misc, - clk_base + CLK_RESET_PLLX_MISC); - writel(tegra30_cpu_clk_sctx.pllx_base, - clk_base + CLK_RESET_PLLX_BASE); - - /* wait for PLL stabilization if PLLX was enabled */ - if (tegra30_cpu_clk_sctx.pllx_base & (1 << 30)) - udelay(300); + misc = readl_relaxed(clk_base + CLK_RESET_PLLX_MISC); + base = readl_relaxed(clk_base + CLK_RESET_PLLX_BASE); + + if (misc != tegra30_cpu_clk_sctx.pllx_misc || + base != tegra30_cpu_clk_sctx.pllx_base) { + /* restore PLLX settings if CPU is on different PLL */ + writel(tegra30_cpu_clk_sctx.pllx_misc, + clk_base + CLK_RESET_PLLX_MISC); + writel(tegra30_cpu_clk_sctx.pllx_base, + clk_base + CLK_RESET_PLLX_BASE); + + /* wait for PLL stabilization if PLLX was enabled */ + if (tegra30_cpu_clk_sctx.pllx_base & (1 << 30)) + udelay(300); + } } /* @@ -1302,6 +1305,26 @@ static struct tegra_audio_clk_info tegra30_audio_plls[] = { { "pll_a", &pll_a_params, tegra_clk_pll_a, "pll_p_out1" }, }; +static struct clk *tegra30_clk_src_onecell_get(struct of_phandle_args *clkspec, + void *data) +{ + struct clk_hw *hw; + struct clk *clk; + + clk = of_clk_src_onecell_get(clkspec, data); + if (IS_ERR(clk)) + return clk; + + hw = __clk_get_hw(clk); + + if (clkspec->args[0] == TEGRA30_CLK_EMC) { + if (!tegra20_clk_emc_driver_available(hw)) + return ERR_PTR(-EPROBE_DEFER); + } + + return clk; +} + static void __init tegra30_clock_init(struct device_node *np) { struct device_node *node; @@ -1345,7 +1368,7 @@ static void __init tegra30_clock_init(struct device_node *np) tegra_init_dup_clks(tegra_clk_duplicates, clks, TEGRA30_CLK_CLK_MAX); - tegra_add_of_provider(np, of_clk_src_onecell_get); + tegra_add_of_provider(np, tegra30_clk_src_onecell_get); tegra_register_devclks(devclks, ARRAY_SIZE(devclks)); tegra_clk_apply_init_table = tegra30_clock_apply_init_table; diff --git a/drivers/clk/tegra/clk.c b/drivers/clk/tegra/clk.c index 573e3c967ae1..e6bd6d1ea012 100644 --- a/drivers/clk/tegra/clk.c +++ b/drivers/clk/tegra/clk.c @@ -16,56 +16,13 @@ #include "clk.h" -#define CLK_OUT_ENB_L 0x010 -#define CLK_OUT_ENB_H 0x014 -#define CLK_OUT_ENB_U 0x018 -#define CLK_OUT_ENB_V 0x360 -#define CLK_OUT_ENB_W 0x364 -#define CLK_OUT_ENB_X 0x280 -#define CLK_OUT_ENB_Y 0x298 -#define CLK_OUT_ENB_SET_L 0x320 -#define CLK_OUT_ENB_CLR_L 0x324 -#define CLK_OUT_ENB_SET_H 0x328 -#define CLK_OUT_ENB_CLR_H 0x32c -#define CLK_OUT_ENB_SET_U 0x330 -#define CLK_OUT_ENB_CLR_U 0x334 -#define CLK_OUT_ENB_SET_V 0x440 -#define CLK_OUT_ENB_CLR_V 0x444 -#define CLK_OUT_ENB_SET_W 0x448 -#define CLK_OUT_ENB_CLR_W 0x44c -#define CLK_OUT_ENB_SET_X 0x284 -#define CLK_OUT_ENB_CLR_X 0x288 -#define CLK_OUT_ENB_SET_Y 0x29c -#define CLK_OUT_ENB_CLR_Y 0x2a0 - -#define RST_DEVICES_L 0x004 -#define RST_DEVICES_H 0x008 -#define RST_DEVICES_U 0x00C -#define RST_DEVICES_V 0x358 -#define RST_DEVICES_W 0x35C -#define RST_DEVICES_X 0x28C -#define RST_DEVICES_Y 0x2a4 -#define RST_DEVICES_SET_L 0x300 -#define RST_DEVICES_CLR_L 0x304 -#define RST_DEVICES_SET_H 0x308 -#define RST_DEVICES_CLR_H 0x30c -#define RST_DEVICES_SET_U 0x310 -#define RST_DEVICES_CLR_U 0x314 -#define RST_DEVICES_SET_V 0x430 -#define RST_DEVICES_CLR_V 0x434 -#define RST_DEVICES_SET_W 0x438 -#define RST_DEVICES_CLR_W 0x43c -#define RST_DEVICES_SET_X 0x290 -#define RST_DEVICES_CLR_X 0x294 -#define RST_DEVICES_SET_Y 0x2a8 -#define RST_DEVICES_CLR_Y 0x2ac - /* Global data of Tegra CPU CAR ops */ static struct tegra_cpu_car_ops dummy_car_ops; struct tegra_cpu_car_ops *tegra_cpu_car_ops = &dummy_car_ops; int *periph_clk_enb_refcnt; static int periph_banks; +static u32 *periph_state_ctx; static struct clk **clks; static int clk_num; static struct clk_onecell_data clk_data; @@ -199,6 +156,65 @@ const struct tegra_clk_periph_regs *get_reg_bank(int clkid) } } +void tegra_clk_set_pllp_out_cpu(bool enable) +{ + u32 val; + + val = readl_relaxed(clk_base + CLK_OUT_ENB_Y); + if (enable) + val |= CLK_ENB_PLLP_OUT_CPU; + else + val &= ~CLK_ENB_PLLP_OUT_CPU; + + writel_relaxed(val, clk_base + CLK_OUT_ENB_Y); +} + +void tegra_clk_periph_suspend(void) +{ + unsigned int i, idx; + + idx = 0; + for (i = 0; i < periph_banks; i++, idx++) + periph_state_ctx[idx] = + readl_relaxed(clk_base + periph_regs[i].enb_reg); + + for (i = 0; i < periph_banks; i++, idx++) + periph_state_ctx[idx] = + readl_relaxed(clk_base + periph_regs[i].rst_reg); +} + +void tegra_clk_periph_resume(void) +{ + unsigned int i, idx; + + idx = 0; + for (i = 0; i < periph_banks; i++, idx++) + writel_relaxed(periph_state_ctx[idx], + clk_base + periph_regs[i].enb_reg); + /* + * All non-boot peripherals will be in reset state on resume. + * Wait for 5us of reset propagation delay before de-asserting + * the peripherals based on the saved context. + */ + fence_udelay(5, clk_base); + + for (i = 0; i < periph_banks; i++, idx++) + writel_relaxed(periph_state_ctx[idx], + clk_base + periph_regs[i].rst_reg); + + fence_udelay(2, clk_base); +} + +static int tegra_clk_periph_ctx_init(int banks) +{ + periph_state_ctx = kcalloc(2 * banks, sizeof(*periph_state_ctx), + GFP_KERNEL); + if (!periph_state_ctx) + return -ENOMEM; + + return 0; +} + struct clk ** __init tegra_clk_init(void __iomem *regs, int num, int banks) { clk_base = regs; @@ -220,6 +236,14 @@ struct clk ** __init tegra_clk_init(void __iomem *regs, int num, int banks) clk_num = num; + if (IS_ENABLED(CONFIG_PM_SLEEP)) { + if (tegra_clk_periph_ctx_init(banks)) { + kfree(periph_clk_enb_refcnt); + kfree(clks); + return NULL; + } + } + return clks; } diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index 905bf1096558..416a6b09f6a3 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -10,6 +10,65 @@ #include <linux/clkdev.h> #include <linux/delay.h> +#define CLK_OUT_ENB_L 0x010 +#define CLK_OUT_ENB_H 0x014 +#define CLK_OUT_ENB_U 0x018 +#define CLK_OUT_ENB_V 0x360 +#define CLK_OUT_ENB_W 0x364 +#define CLK_OUT_ENB_X 0x280 +#define CLK_OUT_ENB_Y 0x298 +#define CLK_ENB_PLLP_OUT_CPU BIT(31) +#define CLK_OUT_ENB_SET_L 0x320 +#define CLK_OUT_ENB_CLR_L 0x324 +#define CLK_OUT_ENB_SET_H 0x328 +#define CLK_OUT_ENB_CLR_H 0x32c +#define CLK_OUT_ENB_SET_U 0x330 +#define CLK_OUT_ENB_CLR_U 0x334 +#define CLK_OUT_ENB_SET_V 0x440 +#define CLK_OUT_ENB_CLR_V 0x444 +#define CLK_OUT_ENB_SET_W 0x448 +#define CLK_OUT_ENB_CLR_W 0x44c +#define CLK_OUT_ENB_SET_X 0x284 +#define CLK_OUT_ENB_CLR_X 0x288 +#define CLK_OUT_ENB_SET_Y 0x29c +#define CLK_OUT_ENB_CLR_Y 0x2a0 + +#define RST_DEVICES_L 0x004 +#define RST_DEVICES_H 0x008 +#define RST_DEVICES_U 0x00C +#define RST_DEVICES_V 0x358 +#define RST_DEVICES_W 0x35C +#define RST_DEVICES_X 0x28C +#define RST_DEVICES_Y 0x2a4 +#define RST_DEVICES_SET_L 0x300 +#define RST_DEVICES_CLR_L 0x304 +#define RST_DEVICES_SET_H 0x308 +#define RST_DEVICES_CLR_H 0x30c +#define RST_DEVICES_SET_U 0x310 +#define RST_DEVICES_CLR_U 0x314 +#define RST_DEVICES_SET_V 0x430 +#define RST_DEVICES_CLR_V 0x434 +#define RST_DEVICES_SET_W 0x438 +#define RST_DEVICES_CLR_W 0x43c +#define RST_DEVICES_SET_X 0x290 +#define RST_DEVICES_CLR_X 0x294 +#define RST_DEVICES_SET_Y 0x2a8 +#define RST_DEVICES_CLR_Y 0x2ac + +/* + * Tegra CLK_OUT_ENB registers have some undefined bits which are not used and + * any accidental write of 1 to these bits can cause PSLVERR. + * So below are the valid mask defines for each CLK_OUT_ENB register used to + * turn ON only the valid clocks. + */ +#define TEGRA210_CLK_ENB_VLD_MSK_L 0xdcd7dff9 +#define TEGRA210_CLK_ENB_VLD_MSK_H 0x87d1f3e7 +#define TEGRA210_CLK_ENB_VLD_MSK_U 0xf3fed3fa +#define TEGRA210_CLK_ENB_VLD_MSK_V 0xffc18cfb +#define TEGRA210_CLK_ENB_VLD_MSK_W 0x793fb7ff +#define TEGRA210_CLK_ENB_VLD_MSK_X 0x3fe66fff +#define TEGRA210_CLK_ENB_VLD_MSK_Y 0xfc1fc7ff + /** * struct tegra_clk_sync_source - external clock source from codec * @@ -669,6 +728,9 @@ struct clk *tegra_clk_register_periph_data(void __iomem *clk_base, * Flags: * TEGRA_DIVIDER_2 - LP cluster has additional divider. This flag indicates * that this is LP cluster clock. + * TEGRA210_CPU_CLK - This flag is used to identify CPU cluster for gen5 + * super mux parent using PLLP branches. To use PLLP branches to CPU, need + * to configure additional bit PLLP_OUT_CPU in the clock registers. */ struct tegra_clk_super_mux { struct clk_hw hw; @@ -685,6 +747,7 @@ struct tegra_clk_super_mux { #define to_clk_super_mux(_hw) container_of(_hw, struct tegra_clk_super_mux, hw) #define TEGRA_DIVIDER_2 BIT(0) +#define TEGRA210_CPU_CLK BIT(1) extern const struct clk_ops tegra_clk_super_ops; struct clk *tegra_clk_register_super_mux(const char *name, @@ -829,6 +892,10 @@ u16 tegra_pll_get_fixed_mdiv(struct clk_hw *hw, unsigned long input_rate); int tegra_pll_p_div_to_hw(struct tegra_clk_pll *pll, u8 p_div); int div_frac_get(unsigned long rate, unsigned parent_rate, u8 width, u8 frac_width, u8 flags); +void tegra_clk_osc_resume(void __iomem *clk_base); +void tegra_clk_set_pllp_out_cpu(bool enable); +void tegra_clk_periph_suspend(void); +void tegra_clk_periph_resume(void); /* Combined read fence with delay */ @@ -838,4 +905,7 @@ int div_frac_get(unsigned long rate, unsigned parent_rate, u8 width, udelay(delay); \ } while (0) +bool tegra20_clk_emc_driver_available(struct clk_hw *emc_hw); +struct clk *tegra20_clk_register_emc(void __iomem *ioaddr, bool low_jitter); + #endif /* TEGRA_CLK_H */ diff --git a/drivers/clk/ti/adpll.c b/drivers/clk/ti/adpll.c index fdfb90058504..bb2f2836dab2 100644 --- a/drivers/clk/ti/adpll.c +++ b/drivers/clk/ti/adpll.c @@ -194,15 +194,8 @@ static const char *ti_adpll_clk_get_name(struct ti_adpll_data *d, if (err) return NULL; } else { - const char *base_name = "adpll"; - char *buf; - - buf = devm_kzalloc(d->dev, 8 + 1 + strlen(base_name) + 1 + - strlen(postfix), GFP_KERNEL); - if (!buf) - return NULL; - sprintf(buf, "%08lx.%s.%s", d->pa, base_name, postfix); - name = buf; + name = devm_kasprintf(d->dev, GFP_KERNEL, "%08lx.adpll.%s", + d->pa, postfix); } return name; diff --git a/drivers/clk/ti/clk-33xx.c b/drivers/clk/ti/clk-33xx.c index a360d3109555..e001b9bcb6bf 100644 --- a/drivers/clk/ti/clk-33xx.c +++ b/drivers/clk/ti/clk-33xx.c @@ -107,7 +107,7 @@ static const struct omap_clkctrl_reg_data am3_l4hs_clkctrl_regs[] __initconst = }; static const struct omap_clkctrl_reg_data am3_pruss_ocp_clkctrl_regs[] __initconst = { - { AM3_PRUSS_OCP_PRUSS_CLKCTRL, NULL, CLKF_SW_SUP, "pruss_ocp_gclk" }, + { AM3_PRUSS_OCP_PRUSS_CLKCTRL, NULL, CLKF_SW_SUP | CLKF_NO_IDLEST, "pruss_ocp_gclk" }, { 0 }, }; @@ -217,7 +217,7 @@ static const struct omap_clkctrl_reg_data am3_l4_rtc_clkctrl_regs[] __initconst }; static const struct omap_clkctrl_reg_data am3_gfx_l3_clkctrl_regs[] __initconst = { - { AM3_GFX_L3_GFX_CLKCTRL, NULL, CLKF_SW_SUP, "gfx_fck_div_ck" }, + { AM3_GFX_L3_GFX_CLKCTRL, NULL, CLKF_SW_SUP | CLKF_NO_IDLEST, "gfx_fck_div_ck" }, { 0 }, }; diff --git a/drivers/clk/ti/clk-43xx.c b/drivers/clk/ti/clk-43xx.c index 2782d91838ac..af3e7805769e 100644 --- a/drivers/clk/ti/clk-43xx.c +++ b/drivers/clk/ti/clk-43xx.c @@ -73,7 +73,7 @@ static const struct omap_clkctrl_reg_data am4_mpu_clkctrl_regs[] __initconst = { }; static const struct omap_clkctrl_reg_data am4_gfx_l3_clkctrl_regs[] __initconst = { - { AM4_GFX_L3_GFX_CLKCTRL, NULL, CLKF_SW_SUP, "gfx_fck_div_ck" }, + { AM4_GFX_L3_GFX_CLKCTRL, NULL, CLKF_SW_SUP | CLKF_NO_IDLEST, "gfx_fck_div_ck" }, { 0 }, }; @@ -126,7 +126,7 @@ static const struct omap_clkctrl_reg_data am4_l3s_clkctrl_regs[] __initconst = { }; static const struct omap_clkctrl_reg_data am4_pruss_ocp_clkctrl_regs[] __initconst = { - { AM4_PRUSS_OCP_PRUSS_CLKCTRL, NULL, CLKF_SW_SUP, "pruss_ocp_gclk" }, + { AM4_PRUSS_OCP_PRUSS_CLKCTRL, NULL, CLKF_SW_SUP | CLKF_NO_IDLEST, "pruss_ocp_gclk" }, { 0 }, }; diff --git a/drivers/clk/ti/clk-44xx.c b/drivers/clk/ti/clk-44xx.c index b10ed0429091..2b4dab632318 100644 --- a/drivers/clk/ti/clk-44xx.c +++ b/drivers/clk/ti/clk-44xx.c @@ -37,7 +37,7 @@ static const struct omap_clkctrl_reg_data omap4_mpuss_clkctrl_regs[] __initconst }; static const struct omap_clkctrl_reg_data omap4_tesla_clkctrl_regs[] __initconst = { - { OMAP4_DSP_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_iva_m4x2_ck" }, + { OMAP4_DSP_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_NO_IDLEST, "dpll_iva_m4x2_ck" }, { 0 }, }; @@ -219,7 +219,7 @@ static const struct omap_clkctrl_reg_data omap4_l3_2_clkctrl_regs[] __initconst }; static const struct omap_clkctrl_reg_data omap4_ducati_clkctrl_regs[] __initconst = { - { OMAP4_IPU_CLKCTRL, NULL, CLKF_HW_SUP, "ducati_clk_mux_ck" }, + { OMAP4_IPU_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_NO_IDLEST, "ducati_clk_mux_ck" }, { 0 }, }; diff --git a/drivers/clk/ti/clk-54xx.c b/drivers/clk/ti/clk-54xx.c index e675e27f1203..c9608e5d993a 100644 --- a/drivers/clk/ti/clk-54xx.c +++ b/drivers/clk/ti/clk-54xx.c @@ -31,7 +31,7 @@ static const struct omap_clkctrl_reg_data omap5_mpu_clkctrl_regs[] __initconst = }; static const struct omap_clkctrl_reg_data omap5_dsp_clkctrl_regs[] __initconst = { - { OMAP5_MMU_DSP_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_iva_h11x2_ck" }, + { OMAP5_MMU_DSP_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_NO_IDLEST, "dpll_iva_h11x2_ck" }, { 0 }, }; @@ -145,7 +145,7 @@ static const struct omap_clkctrl_reg_data omap5_l3main2_clkctrl_regs[] __initcon }; static const struct omap_clkctrl_reg_data omap5_ipu_clkctrl_regs[] __initconst = { - { OMAP5_MMU_IPU_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_core_h22x2_ck" }, + { OMAP5_MMU_IPU_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_NO_IDLEST, "dpll_core_h22x2_ck" }, { 0 }, }; @@ -286,6 +286,12 @@ static const struct omap_clkctrl_reg_data omap5_l4per_clkctrl_regs[] __initconst { 0 }, }; +static const struct omap_clkctrl_reg_data omap5_iva_clkctrl_regs[] __initconst = { + { OMAP5_IVA_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_iva_h12x2_ck" }, + { OMAP5_SL2IF_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_iva_h12x2_ck" }, + { 0 }, +}; + static const char * const omap5_dss_dss_clk_parents[] __initconst = { "dpll_per_h12x2_ck", NULL, @@ -502,6 +508,7 @@ const struct omap_clkctrl_data omap5_clkctrl_data[] __initconst = { { 0x4a008d20, omap5_l4cfg_clkctrl_regs }, { 0x4a008e20, omap5_l3instr_clkctrl_regs }, { 0x4a009020, omap5_l4per_clkctrl_regs }, + { 0x4a009220, omap5_iva_clkctrl_regs }, { 0x4a009420, omap5_dss_clkctrl_regs }, { 0x4a009520, omap5_gpu_clkctrl_regs }, { 0x4a009620, omap5_l3init_clkctrl_regs }, diff --git a/drivers/clk/ti/clk-7xx.c b/drivers/clk/ti/clk-7xx.c index 9dd6185a4b4e..5f46782cebeb 100644 --- a/drivers/clk/ti/clk-7xx.c +++ b/drivers/clk/ti/clk-7xx.c @@ -25,7 +25,7 @@ static const struct omap_clkctrl_reg_data dra7_mpu_clkctrl_regs[] __initconst = }; static const struct omap_clkctrl_reg_data dra7_dsp1_clkctrl_regs[] __initconst = { - { DRA7_DSP1_MMU0_DSP1_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_dsp_m2_ck" }, + { DRA7_DSP1_MMU0_DSP1_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_NO_IDLEST, "dpll_dsp_m2_ck" }, { 0 }, }; @@ -41,7 +41,7 @@ static const struct omap_clkctrl_bit_data dra7_mmu_ipu1_bit_data[] __initconst = }; static const struct omap_clkctrl_reg_data dra7_ipu1_clkctrl_regs[] __initconst = { - { DRA7_IPU1_MMU_IPU1_CLKCTRL, dra7_mmu_ipu1_bit_data, CLKF_HW_SUP, "ipu1-clkctrl:0000:24" }, + { DRA7_IPU1_MMU_IPU1_CLKCTRL, dra7_mmu_ipu1_bit_data, CLKF_HW_SUP | CLKF_NO_IDLEST, "ipu1-clkctrl:0000:24" }, { 0 }, }; @@ -137,7 +137,7 @@ static const struct omap_clkctrl_reg_data dra7_ipu_clkctrl_regs[] __initconst = }; static const struct omap_clkctrl_reg_data dra7_dsp2_clkctrl_regs[] __initconst = { - { DRA7_DSP2_MMU0_DSP2_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_dsp_m2_ck" }, + { DRA7_DSP2_MMU0_DSP2_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_NO_IDLEST, "dpll_dsp_m2_ck" }, { 0 }, }; @@ -164,7 +164,7 @@ static const struct omap_clkctrl_reg_data dra7_l3main1_clkctrl_regs[] __initcons }; static const struct omap_clkctrl_reg_data dra7_ipu2_clkctrl_regs[] __initconst = { - { DRA7_IPU2_MMU_IPU2_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_core_h22x2_ck" }, + { DRA7_IPU2_MMU_IPU2_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_NO_IDLEST, "dpll_core_h22x2_ck" }, { 0 }, }; diff --git a/drivers/clk/ti/clkctrl.c b/drivers/clk/ti/clkctrl.c index b0c0690a5a12..17b9a761242f 100644 --- a/drivers/clk/ti/clkctrl.c +++ b/drivers/clk/ti/clkctrl.c @@ -24,7 +24,7 @@ #include <linux/timekeeping.h> #include "clock.h" -#define NO_IDLEST 0x1 +#define NO_IDLEST 0 #define OMAP4_MODULEMODE_MASK 0x3 @@ -34,6 +34,9 @@ #define OMAP4_IDLEST_MASK (0x3 << 16) #define OMAP4_IDLEST_SHIFT 16 +#define OMAP4_STBYST_MASK BIT(18) +#define OMAP4_STBYST_SHIFT 18 + #define CLKCTRL_IDLEST_FUNCTIONAL 0x0 #define CLKCTRL_IDLEST_INTERFACE_IDLE 0x2 #define CLKCTRL_IDLEST_DISABLED 0x3 @@ -159,7 +162,7 @@ static int _omap4_clkctrl_clk_enable(struct clk_hw *hw) ti_clk_ll_ops->clk_writel(val, &clk->enable_reg); - if (clk->flags & NO_IDLEST) + if (test_bit(NO_IDLEST, &clk->flags)) return 0; /* Wait until module is enabled */ @@ -188,7 +191,7 @@ static void _omap4_clkctrl_clk_disable(struct clk_hw *hw) ti_clk_ll_ops->clk_writel(val, &clk->enable_reg); - if (clk->flags & NO_IDLEST) + if (test_bit(NO_IDLEST, &clk->flags)) goto exit; /* Wait until module is disabled */ @@ -381,7 +384,7 @@ _ti_clkctrl_setup_div(struct omap_clkctrl_provider *provider, if (ti_clk_parse_divider_data((int *)div_data->dividers, 0, div_data->max_div, div_flags, - &div->width, &div->table)) { + div)) { pr_err("%s: Data parsing for %pOF:%04x:%d failed\n", __func__, node, offset, data->bit); kfree(div); @@ -597,7 +600,7 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node) if (reg_data->flags & CLKF_HW_SUP) hw->enable_bit = MODULEMODE_HWCTRL; if (reg_data->flags & CLKF_NO_IDLEST) - hw->flags |= NO_IDLEST; + set_bit(NO_IDLEST, &hw->flags); if (reg_data->clkdm_name) hw->clkdm_name = reg_data->clkdm_name; @@ -623,7 +626,7 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node) init.ops = &omap4_clkctrl_clk_ops; hw->hw.init = &init; - clk = ti_clk_register(NULL, &hw->hw, init.name); + clk = ti_clk_register_omap_hw(NULL, &hw->hw, init.name); if (IS_ERR_OR_NULL(clk)) goto cleanup; @@ -648,3 +651,33 @@ cleanup: } CLK_OF_DECLARE(ti_omap4_clkctrl_clock, "ti,clkctrl", _ti_omap4_clkctrl_setup); + +/** + * ti_clk_is_in_standby - Check if clkctrl clock is in standby or not + * @clk: clock to check standby status for + * + * Finds whether the provided clock is in standby mode or not. Returns + * true if the provided clock is a clkctrl type clock and it is in standby, + * false otherwise. + */ +bool ti_clk_is_in_standby(struct clk *clk) +{ + struct clk_hw *hw; + struct clk_hw_omap *hwclk; + u32 val; + + hw = __clk_get_hw(clk); + + if (!omap2_clk_is_hw_omap(hw)) + return false; + + hwclk = to_clk_hw_omap(hw); + + val = ti_clk_ll_ops->clk_readl(&hwclk->enable_reg); + + if (val & OMAP4_STBYST_MASK) + return true; + + return false; +} +EXPORT_SYMBOL_GPL(ti_clk_is_in_standby); diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h index e4b8392ff63c..e6995c04001e 100644 --- a/drivers/clk/ti/clock.h +++ b/drivers/clk/ti/clock.h @@ -20,9 +20,11 @@ struct clk_omap_divider { struct clk_hw hw; struct clk_omap_reg reg; u8 shift; - u8 width; u8 flags; s8 latch; + u16 min; + u16 max; + u16 mask; const struct clk_div_table *table; u32 context; }; @@ -220,8 +222,7 @@ void ti_clk_latch(struct clk_omap_reg *reg, s8 shift); struct clk_hw *ti_clk_build_component_mux(struct ti_clk_mux *setup); int ti_clk_parse_divider_data(int *div_table, int num_dividers, int max_div, - u8 flags, u8 *width, - const struct clk_div_table **table); + u8 flags, struct clk_omap_divider *div); int ti_clk_get_reg_addr(struct device_node *node, int index, struct clk_omap_reg *reg); diff --git a/drivers/clk/ti/divider.c b/drivers/clk/ti/divider.c index 6cb863c13648..28080df92f72 100644 --- a/drivers/clk/ti/divider.c +++ b/drivers/clk/ti/divider.c @@ -26,30 +26,6 @@ #undef pr_fmt #define pr_fmt(fmt) "%s: " fmt, __func__ -#define div_mask(d) ((1 << ((d)->width)) - 1) - -static unsigned int _get_table_maxdiv(const struct clk_div_table *table) -{ - unsigned int maxdiv = 0; - const struct clk_div_table *clkt; - - for (clkt = table; clkt->div; clkt++) - if (clkt->div > maxdiv) - maxdiv = clkt->div; - return maxdiv; -} - -static unsigned int _get_maxdiv(struct clk_omap_divider *divider) -{ - if (divider->flags & CLK_DIVIDER_ONE_BASED) - return div_mask(divider); - if (divider->flags & CLK_DIVIDER_POWER_OF_TWO) - return 1 << div_mask(divider); - if (divider->table) - return _get_table_maxdiv(divider->table); - return div_mask(divider) + 1; -} - static unsigned int _get_table_div(const struct clk_div_table *table, unsigned int val) { @@ -61,6 +37,34 @@ static unsigned int _get_table_div(const struct clk_div_table *table, return 0; } +static void _setup_mask(struct clk_omap_divider *divider) +{ + u16 mask; + u32 max_val; + const struct clk_div_table *clkt; + + if (divider->table) { + max_val = 0; + + for (clkt = divider->table; clkt->div; clkt++) + if (clkt->val > max_val) + max_val = clkt->val; + } else { + max_val = divider->max; + + if (!(divider->flags & CLK_DIVIDER_ONE_BASED) && + !(divider->flags & CLK_DIVIDER_POWER_OF_TWO)) + max_val--; + } + + if (divider->flags & CLK_DIVIDER_POWER_OF_TWO) + mask = fls(max_val) - 1; + else + mask = max_val; + + divider->mask = (1 << fls(mask)) - 1; +} + static unsigned int _get_div(struct clk_omap_divider *divider, unsigned int val) { if (divider->flags & CLK_DIVIDER_ONE_BASED) @@ -101,7 +105,7 @@ static unsigned long ti_clk_divider_recalc_rate(struct clk_hw *hw, unsigned int div, val; val = ti_clk_ll_ops->clk_readl(÷r->reg) >> divider->shift; - val &= div_mask(divider); + val &= divider->mask; div = _get_div(divider, val); if (!div) { @@ -180,7 +184,7 @@ static int ti_clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate, if (!rate) rate = 1; - maxdiv = _get_maxdiv(divider); + maxdiv = divider->max; if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) { parent_rate = *best_parent_rate; @@ -219,7 +223,7 @@ static int ti_clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate, } if (!bestdiv) { - bestdiv = _get_maxdiv(divider); + bestdiv = divider->max; *best_parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw), 1); } @@ -249,17 +253,16 @@ static int ti_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate, divider = to_clk_omap_divider(hw); div = DIV_ROUND_UP(parent_rate, rate); - value = _get_val(divider, div); - if (value > div_mask(divider)) - value = div_mask(divider); + if (div > divider->max) + div = divider->max; + if (div < divider->min) + div = divider->min; - if (divider->flags & CLK_DIVIDER_HIWORD_MASK) { - val = div_mask(divider) << (divider->shift + 16); - } else { - val = ti_clk_ll_ops->clk_readl(÷r->reg); - val &= ~(div_mask(divider) << divider->shift); - } + value = _get_val(divider, div); + + val = ti_clk_ll_ops->clk_readl(÷r->reg); + val &= ~(divider->mask << divider->shift); val |= value << divider->shift; ti_clk_ll_ops->clk_writel(val, ÷r->reg); @@ -280,7 +283,7 @@ static int clk_divider_save_context(struct clk_hw *hw) u32 val; val = ti_clk_ll_ops->clk_readl(÷r->reg) >> divider->shift; - divider->context = val & div_mask(divider); + divider->context = val & divider->mask; return 0; } @@ -297,7 +300,7 @@ static void clk_divider_restore_context(struct clk_hw *hw) u32 val; val = ti_clk_ll_ops->clk_readl(÷r->reg); - val &= ~(div_mask(divider) << divider->shift); + val &= ~(divider->mask << divider->shift); val |= divider->context << divider->shift; ti_clk_ll_ops->clk_writel(val, ÷r->reg); } @@ -310,47 +313,26 @@ const struct clk_ops ti_clk_divider_ops = { .restore_context = clk_divider_restore_context, }; -static struct clk *_register_divider(struct device *dev, const char *name, - const char *parent_name, - unsigned long flags, - struct clk_omap_reg *reg, - u8 shift, u8 width, s8 latch, - u8 clk_divider_flags, - const struct clk_div_table *table) +static struct clk *_register_divider(struct device_node *node, + u32 flags, + struct clk_omap_divider *div) { - struct clk_omap_divider *div; struct clk *clk; struct clk_init_data init; + const char *parent_name; - if (clk_divider_flags & CLK_DIVIDER_HIWORD_MASK) { - if (width + shift > 16) { - pr_warn("divider value exceeds LOWORD field\n"); - return ERR_PTR(-EINVAL); - } - } - - /* allocate the divider */ - div = kzalloc(sizeof(*div), GFP_KERNEL); - if (!div) - return ERR_PTR(-ENOMEM); + parent_name = of_clk_get_parent_name(node, 0); - init.name = name; + init.name = node->name; init.ops = &ti_clk_divider_ops; init.flags = flags; init.parent_names = (parent_name ? &parent_name : NULL); init.num_parents = (parent_name ? 1 : 0); - /* struct clk_divider assignments */ - memcpy(&div->reg, reg, sizeof(*reg)); - div->shift = shift; - div->width = width; - div->latch = latch; - div->flags = clk_divider_flags; div->hw.init = &init; - div->table = table; /* register the clock */ - clk = ti_clk_register(dev, &div->hw, name); + clk = ti_clk_register(NULL, &div->hw, node->name); if (IS_ERR(clk)) kfree(div); @@ -359,34 +341,17 @@ static struct clk *_register_divider(struct device *dev, const char *name, } int ti_clk_parse_divider_data(int *div_table, int num_dividers, int max_div, - u8 flags, u8 *width, - const struct clk_div_table **table) + u8 flags, struct clk_omap_divider *divider) { int valid_div = 0; - u32 val; - int div; int i; struct clk_div_table *tmp; + u16 min_div = 0; if (!div_table) { - if (flags & CLKF_INDEX_STARTS_AT_ONE) - val = 1; - else - val = 0; - - div = 1; - - while (div < max_div) { - if (flags & CLKF_INDEX_POWER_OF_TWO) - div <<= 1; - else - div++; - val++; - } - - *width = fls(val); - *table = NULL; - + divider->min = 1; + divider->max = max_div; + _setup_mask(divider); return 0; } @@ -403,30 +368,32 @@ int ti_clk_parse_divider_data(int *div_table, int num_dividers, int max_div, num_dividers = i; tmp = kcalloc(valid_div + 1, sizeof(*tmp), GFP_KERNEL); - if (!tmp) { - *table = ERR_PTR(-ENOMEM); + if (!tmp) return -ENOMEM; - } valid_div = 0; - *width = 0; for (i = 0; i < num_dividers; i++) if (div_table[i] > 0) { tmp[valid_div].div = div_table[i]; tmp[valid_div].val = i; valid_div++; - *width = i; + if (div_table[i] > max_div) + max_div = div_table[i]; + if (!min_div || div_table[i] < min_div) + min_div = div_table[i]; } - *width = fls(*width); - *table = tmp; + divider->min = min_div; + divider->max = max_div; + divider->table = tmp; + _setup_mask(divider); return 0; } -static struct clk_div_table * -__init ti_clk_get_div_table(struct device_node *node) +static int __init ti_clk_get_div_table(struct device_node *node, + struct clk_omap_divider *div) { struct clk_div_table *table; const __be32 *divspec; @@ -438,7 +405,7 @@ __init ti_clk_get_div_table(struct device_node *node) divspec = of_get_property(node, "ti,dividers", &num_div); if (!divspec) - return NULL; + return 0; num_div /= 4; @@ -453,13 +420,12 @@ __init ti_clk_get_div_table(struct device_node *node) if (!valid_div) { pr_err("no valid dividers for %pOFn table\n", node); - return ERR_PTR(-EINVAL); + return -EINVAL; } table = kcalloc(valid_div + 1, sizeof(*table), GFP_KERNEL); - if (!table) - return ERR_PTR(-ENOMEM); + return -ENOMEM; valid_div = 0; @@ -472,19 +438,20 @@ __init ti_clk_get_div_table(struct device_node *node) } } - return table; + div->table = table; + + return 0; } -static int _get_divider_width(struct device_node *node, - const struct clk_div_table *table, - u8 flags) +static int _populate_divider_min_max(struct device_node *node, + struct clk_omap_divider *divider) { - u32 min_div; - u32 max_div; - u32 val = 0; - u32 div; + u32 min_div = 0; + u32 max_div = 0; + u32 val; + const struct clk_div_table *clkt; - if (!table) { + if (!divider->table) { /* Clk divider table not provided, determine min/max divs */ if (of_property_read_u32(node, "ti,min-div", &min_div)) min_div = 1; @@ -493,75 +460,62 @@ static int _get_divider_width(struct device_node *node, pr_err("no max-div for %pOFn!\n", node); return -EINVAL; } - - /* Determine bit width for the field */ - if (flags & CLK_DIVIDER_ONE_BASED) - val = 1; - - div = min_div; - - while (div < max_div) { - if (flags & CLK_DIVIDER_POWER_OF_TWO) - div <<= 1; - else - div++; - val++; - } } else { - div = 0; - while (table[div].div) { - val = table[div].val; - div++; + for (clkt = divider->table; clkt->div; clkt++) { + val = clkt->div; + if (val > max_div) + max_div = val; + if (!min_div || val < min_div) + min_div = val; } } - return fls(val); + divider->min = min_div; + divider->max = max_div; + _setup_mask(divider); + + return 0; } static int __init ti_clk_divider_populate(struct device_node *node, - struct clk_omap_reg *reg, const struct clk_div_table **table, - u32 *flags, u8 *div_flags, u8 *width, u8 *shift, s8 *latch) + struct clk_omap_divider *div, + u32 *flags) { u32 val; int ret; - ret = ti_clk_get_reg_addr(node, 0, reg); + ret = ti_clk_get_reg_addr(node, 0, &div->reg); if (ret) return ret; if (!of_property_read_u32(node, "ti,bit-shift", &val)) - *shift = val; + div->shift = val; else - *shift = 0; + div->shift = 0; - if (latch) { - if (!of_property_read_u32(node, "ti,latch-bit", &val)) - *latch = val; - else - *latch = -EINVAL; - } + if (!of_property_read_u32(node, "ti,latch-bit", &val)) + div->latch = val; + else + div->latch = -EINVAL; *flags = 0; - *div_flags = 0; + div->flags = 0; if (of_property_read_bool(node, "ti,index-starts-at-one")) - *div_flags |= CLK_DIVIDER_ONE_BASED; + div->flags |= CLK_DIVIDER_ONE_BASED; if (of_property_read_bool(node, "ti,index-power-of-two")) - *div_flags |= CLK_DIVIDER_POWER_OF_TWO; + div->flags |= CLK_DIVIDER_POWER_OF_TWO; if (of_property_read_bool(node, "ti,set-rate-parent")) *flags |= CLK_SET_RATE_PARENT; - *table = ti_clk_get_div_table(node); - - if (IS_ERR(*table)) - return PTR_ERR(*table); - - *width = _get_divider_width(node, *table, *div_flags); + ret = ti_clk_get_div_table(node, div); + if (ret) + return ret; - return 0; + return _populate_divider_min_max(node, div); } /** @@ -573,24 +527,17 @@ static int __init ti_clk_divider_populate(struct device_node *node, static void __init of_ti_divider_clk_setup(struct device_node *node) { struct clk *clk; - const char *parent_name; - struct clk_omap_reg reg; - u8 clk_divider_flags = 0; - u8 width = 0; - u8 shift = 0; - s8 latch = -EINVAL; - const struct clk_div_table *table = NULL; u32 flags = 0; + struct clk_omap_divider *div; - parent_name = of_clk_get_parent_name(node, 0); + div = kzalloc(sizeof(*div), GFP_KERNEL); + if (!div) + return; - if (ti_clk_divider_populate(node, ®, &table, &flags, - &clk_divider_flags, &width, &shift, &latch)) + if (ti_clk_divider_populate(node, div, &flags)) goto cleanup; - clk = _register_divider(NULL, node->name, parent_name, flags, ®, - shift, width, latch, clk_divider_flags, table); - + clk = _register_divider(node, flags, div); if (!IS_ERR(clk)) { of_clk_add_provider(node, of_clk_src_simple_get, clk); of_ti_clk_autoidle_setup(node); @@ -598,22 +545,21 @@ static void __init of_ti_divider_clk_setup(struct device_node *node) } cleanup: - kfree(table); + kfree(div->table); + kfree(div); } CLK_OF_DECLARE(divider_clk, "ti,divider-clock", of_ti_divider_clk_setup); static void __init of_ti_composite_divider_clk_setup(struct device_node *node) { struct clk_omap_divider *div; - u32 val; + u32 tmp; div = kzalloc(sizeof(*div), GFP_KERNEL); if (!div) return; - if (ti_clk_divider_populate(node, &div->reg, &div->table, &val, - &div->flags, &div->width, &div->shift, - NULL) < 0) + if (ti_clk_divider_populate(node, div, &tmp)) goto cleanup; if (!ti_clk_add_component(node, &div->hw, CLK_COMPONENT_TYPE_DIVIDER)) diff --git a/drivers/clk/uniphier/clk-uniphier-core.c b/drivers/clk/uniphier/clk-uniphier-core.c index c6aaca73cf86..12380236d7ab 100644 --- a/drivers/clk/uniphier/clk-uniphier-core.c +++ b/drivers/clk/uniphier/clk-uniphier-core.c @@ -64,8 +64,7 @@ static int uniphier_clk_probe(struct platform_device *pdev) for (p = data; p->name; p++) clk_num = max(clk_num, p->idx + 1); - hw_data = devm_kzalloc(dev, - sizeof(*hw_data) + clk_num * sizeof(struct clk_hw *), + hw_data = devm_kzalloc(dev, struct_size(hw_data, hws, clk_num), GFP_KERNEL); if (!hw_data) return -ENOMEM; |