aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/clk.txt16
-rw-r--r--Documentation/devicetree/bindings/clock/st,stm32mp1-rcc.txt60
-rw-r--r--Documentation/devicetree/bindings/clock/ti/divider.txt3
-rw-r--r--Documentation/devicetree/bindings/clock/ti/mux.txt3
-rw-r--r--MAINTAINERS1
-rw-r--r--drivers/clk/Kconfig26
-rw-r--r--drivers/clk/Makefile5
-rw-r--r--drivers/clk/clk-divider.c58
-rw-r--r--drivers/clk/clk-gpio.c4
-rw-r--r--drivers/clk/clk-mux.c75
-rw-r--r--drivers/clk/clk-stm32f4.c14
-rw-r--r--drivers/clk/clk-stm32mp1.c2117
-rw-r--r--drivers/clk/clk.c131
-rw-r--r--drivers/clk/keystone/sci-clk.c380
-rw-r--r--drivers/clk/mediatek/clk-mt2712.c69
-rw-r--r--drivers/clk/meson/Kconfig9
-rw-r--r--drivers/clk/meson/Makefile5
-rw-r--r--drivers/clk/meson/axg.c955
-rw-r--r--drivers/clk/meson/axg.h12
-rw-r--r--drivers/clk/meson/clk-audio-divider.c63
-rw-r--r--drivers/clk/meson/clk-cpu.c178
-rw-r--r--drivers/clk/meson/clk-mpll.c125
-rw-r--r--drivers/clk/meson/clk-pll.c306
-rw-r--r--drivers/clk/meson/clk-regmap.c166
-rw-r--r--drivers/clk/meson/clk-regmap.h111
-rw-r--r--drivers/clk/meson/clkc.h107
-rw-r--r--drivers/clk/meson/gxbb-aoclk-regmap.c46
-rw-r--r--drivers/clk/meson/gxbb-aoclk.c20
-rw-r--r--drivers/clk/meson/gxbb-aoclk.h11
-rw-r--r--drivers/clk/meson/gxbb.c1591
-rw-r--r--drivers/clk/meson/gxbb.h14
-rw-r--r--drivers/clk/meson/meson8b.c705
-rw-r--r--drivers/clk/meson/meson8b.h17
-rw-r--r--drivers/clk/nxp/clk-lpc32xx.c1
-rw-r--r--drivers/clk/qcom/clk-regmap-divider.c20
-rw-r--r--drivers/clk/qcom/clk-rpm.c79
-rw-r--r--drivers/clk/qcom/clk-smd-rpm.c9
-rw-r--r--drivers/clk/qcom/gcc-msm8996.c8
-rw-r--r--drivers/clk/samsung/Makefile2
-rw-r--r--drivers/clk/samsung/clk-exynos-audss.c4
-rw-r--r--drivers/clk/samsung/clk-exynos3250.c114
-rw-r--r--drivers/clk/samsung/clk-exynos4.c103
-rw-r--r--drivers/clk/samsung/clk-exynos5-subcmu.c189
-rw-r--r--drivers/clk/samsung/clk-exynos5-subcmu.h26
-rw-r--r--drivers/clk/samsung/clk-exynos5250.c111
-rw-r--r--drivers/clk/samsung/clk-exynos5260.c90
-rw-r--r--drivers/clk/samsung/clk-exynos5410.c20
-rw-r--r--drivers/clk/samsung/clk-exynos5420.c189
-rw-r--r--drivers/clk/samsung/clk-exynos5433.c121
-rw-r--r--drivers/clk/samsung/clk-exynos7.c2
-rw-r--r--drivers/clk/samsung/clk-pll.h48
-rw-r--r--drivers/clk/samsung/clk-s3c2410.c148
-rw-r--r--drivers/clk/samsung/clk-s3c2412.c25
-rw-r--r--drivers/clk/samsung/clk-s3c2443.c55
-rw-r--r--drivers/clk/samsung/clk-s3c64xx.c17
-rw-r--r--drivers/clk/sprd/sc9860-clk.c76
-rw-r--r--drivers/clk/tegra/clk-emc.c2
-rw-r--r--drivers/clk/tegra/clk-pll.c2
-rw-r--r--drivers/clk/tegra/clk-tegra-periph.c2
-rw-r--r--drivers/clk/tegra/clk-tegra-super-gen4.c8
-rw-r--r--drivers/clk/tegra/clk-tegra114.c4
-rw-r--r--drivers/clk/tegra/clk-tegra124.c9
-rw-r--r--drivers/clk/tegra/clk-tegra20.c24
-rw-r--r--drivers/clk/tegra/clk-tegra210.c361
-rw-r--r--drivers/clk/tegra/clk-tegra30.c15
-rw-r--r--drivers/clk/tegra/clk.h7
-rw-r--r--drivers/clk/ti/clk.c38
-rw-r--r--drivers/clk/ti/clock.h4
-rw-r--r--drivers/clk/ti/divider.c26
-rw-r--r--drivers/clk/ti/mux.c13
-rw-r--r--drivers/clk/versatile/clk-vexpress-osc.c5
-rw-r--r--drivers/soc/samsung/pm_domains.c11
-rw-r--r--include/dt-bindings/clock/axg-clkc.h1
-rw-r--r--include/dt-bindings/clock/mt2712-clk.h12
-rw-r--r--include/dt-bindings/clock/qcom,rpmcc.h5
-rw-r--r--include/dt-bindings/clock/sprd,sc9860-clk.h21
-rw-r--r--include/dt-bindings/clock/stm32fx-clock.h7
-rw-r--r--include/dt-bindings/clock/stm32mp1-clks.h254
-rw-r--r--include/dt-bindings/clock/tegra210-car.h2
-rw-r--r--include/linux/clk-provider.h23
-rw-r--r--include/linux/clk.h16
-rw-r--r--include/linux/clk/tegra.h1
-rw-r--r--include/linux/clk/ti.h2
83 files changed, 6740 insertions, 2995 deletions
diff --git a/Documentation/clk.txt b/Documentation/clk.txt
index be909ed45970..511628bb3d3a 100644
--- a/Documentation/clk.txt
+++ b/Documentation/clk.txt
@@ -268,9 +268,19 @@ The common clock framework uses two global locks, the prepare lock and the
268enable lock. 268enable lock.
269 269
270The enable lock is a spinlock and is held across calls to the .enable, 270The enable lock is a spinlock and is held across calls to the .enable,
271.disable and .is_enabled operations. Those operations are thus not allowed to 271.disable operations. Those operations are thus not allowed to sleep,
272sleep, and calls to the clk_enable(), clk_disable() and clk_is_enabled() API 272and calls to the clk_enable(), clk_disable() API functions are allowed in
273functions are allowed in atomic context. 273atomic context.
274
275For clk_is_enabled() API, it is also designed to be allowed to be used in
276atomic context. However, it doesn't really make any sense to hold the enable
277lock in core, unless you want to do something else with the information of
278the enable state with that lock held. Otherwise, seeing if a clk is enabled is
279a one-shot read of the enabled state, which could just as easily change after
280the function returns because the lock is released. Thus the user of this API
281needs to handle synchronizing the read of the state with whatever they're
282using it for to make sure that the enable state doesn't change during that
283time.
274 284
275The prepare lock is a mutex and is held across calls to all other operations. 285The prepare lock is a mutex and is held across calls to all other operations.
276All those operations are allowed to sleep, and calls to the corresponding API 286All those operations are allowed to sleep, and calls to the corresponding API
diff --git a/Documentation/devicetree/bindings/clock/st,stm32mp1-rcc.txt b/Documentation/devicetree/bindings/clock/st,stm32mp1-rcc.txt
new file mode 100644
index 000000000000..fb9495ea582c
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/st,stm32mp1-rcc.txt
@@ -0,0 +1,60 @@
1STMicroelectronics STM32 Peripheral Reset Clock Controller
2==========================================================
3
4The RCC IP is both a reset and a clock controller.
5
6RCC makes also power management (resume/supend and wakeup interrupt).
7
8Please also refer to reset.txt for common reset controller binding usage.
9
10Please also refer to clock-bindings.txt for common clock controller
11binding usage.
12
13
14Required properties:
15- compatible: "st,stm32mp1-rcc", "syscon"
16- reg: should be register base and length as documented in the datasheet
17- #clock-cells: 1, device nodes should specify the clock in their
18 "clocks" property, containing a phandle to the clock device node,
19 an index specifying the clock to use.
20- #reset-cells: Shall be 1
21- interrupts: Should contain a general interrupt line and a interrupt line
22 to the wake-up of processor (CSTOP).
23
24Example:
25 rcc: rcc@50000000 {
26 compatible = "st,stm32mp1-rcc", "syscon";
27 reg = <0x50000000 0x1000>;
28 #clock-cells = <1>;
29 #reset-cells = <1>;
30 interrupts = <GIC_SPI 5 IRQ_TYPE_NONE>,
31 <GIC_SPI 145 IRQ_TYPE_NONE>;
32 };
33
34Specifying clocks
35=================
36
37All available clocks are defined as preprocessor macros in
38dt-bindings/clock/stm32mp1-clks.h header and can be used in device
39tree sources.
40
41Specifying softreset control of devices
42=======================================
43
44Device nodes should specify the reset channel required in their "resets"
45property, containing a phandle to the reset device node and an index specifying
46which channel to use.
47The index is the bit number within the RCC registers bank, starting from RCC
48base address.
49It is calculated as: index = register_offset / 4 * 32 + bit_offset.
50Where bit_offset is the bit offset within the register.
51
52For example on STM32MP1, for LTDC reset:
53 ltdc = APB4_RSTSETR_offset / 4 * 32 + LTDC_bit_offset
54 = 0x180 / 4 * 32 + 0 = 3072
55
56The list of valid indices for STM32MP1 is available in:
57include/dt-bindings/reset-controller/stm32mp1-resets.h
58
59This file implements defines like:
60#define LTDC_R 3072
diff --git a/Documentation/devicetree/bindings/clock/ti/divider.txt b/Documentation/devicetree/bindings/clock/ti/divider.txt
index 35a6f5c7e5c2..9b13b32974f9 100644
--- a/Documentation/devicetree/bindings/clock/ti/divider.txt
+++ b/Documentation/devicetree/bindings/clock/ti/divider.txt
@@ -75,6 +75,9 @@ Optional properties:
75- ti,invert-autoidle-bit : autoidle is enabled by setting the bit to 0, 75- ti,invert-autoidle-bit : autoidle is enabled by setting the bit to 0,
76 see [2] 76 see [2]
77- ti,set-rate-parent : clk_set_rate is propagated to parent 77- ti,set-rate-parent : clk_set_rate is propagated to parent
78- ti,latch-bit : latch the divider value to HW, only needed if the register
79 access requires this. As an example dra76x DPLL_GMAC H14 divider implements
80 such behavior.
78 81
79Examples: 82Examples:
80dpll_usb_m2_ck: dpll_usb_m2_ck@4a008190 { 83dpll_usb_m2_ck: dpll_usb_m2_ck@4a008190 {
diff --git a/Documentation/devicetree/bindings/clock/ti/mux.txt b/Documentation/devicetree/bindings/clock/ti/mux.txt
index 2d0d170f8001..eec8994b9be8 100644
--- a/Documentation/devicetree/bindings/clock/ti/mux.txt
+++ b/Documentation/devicetree/bindings/clock/ti/mux.txt
@@ -48,6 +48,9 @@ Optional properties:
48 zero 48 zero
49- ti,set-rate-parent : clk_set_rate is propagated to parent clock, 49- ti,set-rate-parent : clk_set_rate is propagated to parent clock,
50 not supported by the composite-mux-clock subtype 50 not supported by the composite-mux-clock subtype
51- ti,latch-bit : latch the mux value to HW, only needed if the register
52 access requires this. As an example, dra7x DPLL_GMAC H14 muxing
53 implements such behavior.
51 54
52Examples: 55Examples:
53 56
diff --git a/MAINTAINERS b/MAINTAINERS
index 3bdc260e36b7..395ea06c427d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12189,6 +12189,7 @@ M: Tomasz Figa <tomasz.figa@gmail.com>
12189M: Chanwoo Choi <cw00.choi@samsung.com> 12189M: Chanwoo Choi <cw00.choi@samsung.com>
12190S: Supported 12190S: Supported
12191L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers) 12191L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers)
12192T: git git://git.kernel.org/pub/scm/linux/kernel/git/snawrocki/clk.git
12192F: drivers/clk/samsung/ 12193F: drivers/clk/samsung/
12193F: include/dt-bindings/clock/exynos*.h 12194F: include/dt-bindings/clock/exynos*.h
12194F: Documentation/devicetree/bindings/clock/exynos*.txt 12195F: Documentation/devicetree/bindings/clock/exynos*.txt
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 98ce9fc6e6c0..ede9cb0b79d6 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -55,8 +55,10 @@ config COMMON_CLK_RK808
55 by control register. 55 by control register.
56 56
57config COMMON_CLK_HI655X 57config COMMON_CLK_HI655X
58 tristate "Clock driver for Hi655x" 58 tristate "Clock driver for Hi655x" if EXPERT
59 depends on MFD_HI655X_PMIC || COMPILE_TEST 59 depends on (MFD_HI655X_PMIC || COMPILE_TEST)
60 depends on REGMAP
61 default MFD_HI655X_PMIC
60 ---help--- 62 ---help---
61 This driver supports the hi655x PMIC clock. This 63 This driver supports the hi655x PMIC clock. This
62 multi-function device has one fixed-rate oscillator, clocked 64 multi-function device has one fixed-rate oscillator, clocked
@@ -238,6 +240,26 @@ config COMMON_CLK_VC5
238 This driver supports the IDT VersaClock 5 and VersaClock 6 240 This driver supports the IDT VersaClock 5 and VersaClock 6
239 programmable clock generators. 241 programmable clock generators.
240 242
243config COMMON_CLK_STM32MP157
244 def_bool COMMON_CLK && MACH_STM32MP157
245 help
246 ---help---
247 Support for stm32mp157 SoC family clocks
248
249config COMMON_CLK_STM32F
250 bool "Clock driver for stm32f4 and stm32f7 SoC families"
251 depends on MACH_STM32F429 || MACH_STM32F469 || MACH_STM32F746
252 help
253 ---help---
254 Support for stm32f4 and stm32f7 SoC families clocks
255
256config COMMON_CLK_STM32H7
257 bool "Clock driver for stm32h7 SoC family"
258 depends on MACH_STM32H743
259 help
260 ---help---
261 Support for stm32h7 SoC family clocks
262
241source "drivers/clk/bcm/Kconfig" 263source "drivers/clk/bcm/Kconfig"
242source "drivers/clk/hisilicon/Kconfig" 264source "drivers/clk/hisilicon/Kconfig"
243source "drivers/clk/imgtec/Kconfig" 265source "drivers/clk/imgtec/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 71ec41e6364f..e0c106ed9407 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -45,8 +45,9 @@ obj-$(CONFIG_COMMON_CLK_SCPI) += clk-scpi.o
45obj-$(CONFIG_COMMON_CLK_SI5351) += clk-si5351.o 45obj-$(CONFIG_COMMON_CLK_SI5351) += clk-si5351.o
46obj-$(CONFIG_COMMON_CLK_SI514) += clk-si514.o 46obj-$(CONFIG_COMMON_CLK_SI514) += clk-si514.o
47obj-$(CONFIG_COMMON_CLK_SI570) += clk-si570.o 47obj-$(CONFIG_COMMON_CLK_SI570) += clk-si570.o
48obj-$(CONFIG_ARCH_STM32) += clk-stm32f4.o 48obj-$(CONFIG_COMMON_CLK_STM32F) += clk-stm32f4.o
49obj-$(CONFIG_ARCH_STM32) += clk-stm32h7.o 49obj-$(CONFIG_COMMON_CLK_STM32H7) += clk-stm32h7.o
50obj-$(CONFIG_COMMON_CLK_STM32MP157) += clk-stm32mp1.o
50obj-$(CONFIG_ARCH_TANGO) += clk-tango4.o 51obj-$(CONFIG_ARCH_TANGO) += clk-tango4.o
51obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o 52obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o
52obj-$(CONFIG_ARCH_U300) += clk-u300.o 53obj-$(CONFIG_ARCH_U300) += clk-u300.o
diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c
index b49942b9fe50..b6234a5da12d 100644
--- a/drivers/clk/clk-divider.c
+++ b/drivers/clk/clk-divider.c
@@ -28,12 +28,10 @@
28 * parent - fixed parent. No clk_set_parent support 28 * parent - fixed parent. No clk_set_parent support
29 */ 29 */
30 30
31#define div_mask(width) ((1 << (width)) - 1)
32
33static unsigned int _get_table_maxdiv(const struct clk_div_table *table, 31static unsigned int _get_table_maxdiv(const struct clk_div_table *table,
34 u8 width) 32 u8 width)
35{ 33{
36 unsigned int maxdiv = 0, mask = div_mask(width); 34 unsigned int maxdiv = 0, mask = clk_div_mask(width);
37 const struct clk_div_table *clkt; 35 const struct clk_div_table *clkt;
38 36
39 for (clkt = table; clkt->div; clkt++) 37 for (clkt = table; clkt->div; clkt++)
@@ -57,12 +55,12 @@ static unsigned int _get_maxdiv(const struct clk_div_table *table, u8 width,
57 unsigned long flags) 55 unsigned long flags)
58{ 56{
59 if (flags & CLK_DIVIDER_ONE_BASED) 57 if (flags & CLK_DIVIDER_ONE_BASED)
60 return div_mask(width); 58 return clk_div_mask(width);
61 if (flags & CLK_DIVIDER_POWER_OF_TWO) 59 if (flags & CLK_DIVIDER_POWER_OF_TWO)
62 return 1 << div_mask(width); 60 return 1 << clk_div_mask(width);
63 if (table) 61 if (table)
64 return _get_table_maxdiv(table, width); 62 return _get_table_maxdiv(table, width);
65 return div_mask(width) + 1; 63 return clk_div_mask(width) + 1;
66} 64}
67 65
68static unsigned int _get_table_div(const struct clk_div_table *table, 66static unsigned int _get_table_div(const struct clk_div_table *table,
@@ -84,7 +82,7 @@ static unsigned int _get_div(const struct clk_div_table *table,
84 if (flags & CLK_DIVIDER_POWER_OF_TWO) 82 if (flags & CLK_DIVIDER_POWER_OF_TWO)
85 return 1 << val; 83 return 1 << val;
86 if (flags & CLK_DIVIDER_MAX_AT_ZERO) 84 if (flags & CLK_DIVIDER_MAX_AT_ZERO)
87 return val ? val : div_mask(width) + 1; 85 return val ? val : clk_div_mask(width) + 1;
88 if (table) 86 if (table)
89 return _get_table_div(table, val); 87 return _get_table_div(table, val);
90 return val + 1; 88 return val + 1;
@@ -109,7 +107,7 @@ static unsigned int _get_val(const struct clk_div_table *table,
109 if (flags & CLK_DIVIDER_POWER_OF_TWO) 107 if (flags & CLK_DIVIDER_POWER_OF_TWO)
110 return __ffs(div); 108 return __ffs(div);
111 if (flags & CLK_DIVIDER_MAX_AT_ZERO) 109 if (flags & CLK_DIVIDER_MAX_AT_ZERO)
112 return (div == div_mask(width) + 1) ? 0 : div; 110 return (div == clk_div_mask(width) + 1) ? 0 : div;
113 if (table) 111 if (table)
114 return _get_table_val(table, div); 112 return _get_table_val(table, div);
115 return div - 1; 113 return div - 1;
@@ -141,7 +139,7 @@ static unsigned long clk_divider_recalc_rate(struct clk_hw *hw,
141 unsigned int val; 139 unsigned int val;
142 140
143 val = clk_readl(divider->reg) >> divider->shift; 141 val = clk_readl(divider->reg) >> divider->shift;
144 val &= div_mask(divider->width); 142 val &= clk_div_mask(divider->width);
145 143
146 return divider_recalc_rate(hw, parent_rate, val, divider->table, 144 return divider_recalc_rate(hw, parent_rate, val, divider->table,
147 divider->flags, divider->width); 145 divider->flags, divider->width);
@@ -344,19 +342,43 @@ long divider_round_rate_parent(struct clk_hw *hw, struct clk_hw *parent,
344} 342}
345EXPORT_SYMBOL_GPL(divider_round_rate_parent); 343EXPORT_SYMBOL_GPL(divider_round_rate_parent);
346 344
345long divider_ro_round_rate_parent(struct clk_hw *hw, struct clk_hw *parent,
346 unsigned long rate, unsigned long *prate,
347 const struct clk_div_table *table, u8 width,
348 unsigned long flags, unsigned int val)
349{
350 int div;
351
352 div = _get_div(table, val, flags, width);
353
354 /* Even a read-only clock can propagate a rate change */
355 if (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) {
356 if (!parent)
357 return -EINVAL;
358
359 *prate = clk_hw_round_rate(parent, rate * div);
360 }
361
362 return DIV_ROUND_UP_ULL((u64)*prate, div);
363}
364EXPORT_SYMBOL_GPL(divider_ro_round_rate_parent);
365
366
347static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate, 367static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
348 unsigned long *prate) 368 unsigned long *prate)
349{ 369{
350 struct clk_divider *divider = to_clk_divider(hw); 370 struct clk_divider *divider = to_clk_divider(hw);
351 int bestdiv;
352 371
353 /* if read only, just return current value */ 372 /* if read only, just return current value */
354 if (divider->flags & CLK_DIVIDER_READ_ONLY) { 373 if (divider->flags & CLK_DIVIDER_READ_ONLY) {
355 bestdiv = clk_readl(divider->reg) >> divider->shift; 374 u32 val;
356 bestdiv &= div_mask(divider->width); 375
357 bestdiv = _get_div(divider->table, bestdiv, divider->flags, 376 val = clk_readl(divider->reg) >> divider->shift;
358 divider->width); 377 val &= clk_div_mask(divider->width);
359 return DIV_ROUND_UP_ULL((u64)*prate, bestdiv); 378
379 return divider_ro_round_rate(hw, rate, prate, divider->table,
380 divider->width, divider->flags,
381 val);
360 } 382 }
361 383
362 return divider_round_rate(hw, rate, prate, divider->table, 384 return divider_round_rate(hw, rate, prate, divider->table,
@@ -376,7 +398,7 @@ int divider_get_val(unsigned long rate, unsigned long parent_rate,
376 398
377 value = _get_val(table, div, flags, width); 399 value = _get_val(table, div, flags, width);
378 400
379 return min_t(unsigned int, value, div_mask(width)); 401 return min_t(unsigned int, value, clk_div_mask(width));
380} 402}
381EXPORT_SYMBOL_GPL(divider_get_val); 403EXPORT_SYMBOL_GPL(divider_get_val);
382 404
@@ -399,10 +421,10 @@ static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
399 __acquire(divider->lock); 421 __acquire(divider->lock);
400 422
401 if (divider->flags & CLK_DIVIDER_HIWORD_MASK) { 423 if (divider->flags & CLK_DIVIDER_HIWORD_MASK) {
402 val = div_mask(divider->width) << (divider->shift + 16); 424 val = clk_div_mask(divider->width) << (divider->shift + 16);
403 } else { 425 } else {
404 val = clk_readl(divider->reg); 426 val = clk_readl(divider->reg);
405 val &= ~(div_mask(divider->width) << divider->shift); 427 val &= ~(clk_div_mask(divider->width) << divider->shift);
406 } 428 }
407 val |= (u32)value << divider->shift; 429 val |= (u32)value << divider->shift;
408 clk_writel(val, divider->reg); 430 clk_writel(val, divider->reg);
diff --git a/drivers/clk/clk-gpio.c b/drivers/clk/clk-gpio.c
index 151513c655c3..40af4fbab4d2 100644
--- a/drivers/clk/clk-gpio.c
+++ b/drivers/clk/clk-gpio.c
@@ -73,14 +73,14 @@ static u8 clk_gpio_mux_get_parent(struct clk_hw *hw)
73{ 73{
74 struct clk_gpio *clk = to_clk_gpio(hw); 74 struct clk_gpio *clk = to_clk_gpio(hw);
75 75
76 return gpiod_get_value(clk->gpiod); 76 return gpiod_get_value_cansleep(clk->gpiod);
77} 77}
78 78
79static int clk_gpio_mux_set_parent(struct clk_hw *hw, u8 index) 79static int clk_gpio_mux_set_parent(struct clk_hw *hw, u8 index)
80{ 80{
81 struct clk_gpio *clk = to_clk_gpio(hw); 81 struct clk_gpio *clk = to_clk_gpio(hw);
82 82
83 gpiod_set_value(clk->gpiod, index); 83 gpiod_set_value_cansleep(clk->gpiod, index);
84 84
85 return 0; 85 return 0;
86} 86}
diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c
index 39cabe157163..ac4a042f8658 100644
--- a/drivers/clk/clk-mux.c
+++ b/drivers/clk/clk-mux.c
@@ -26,35 +26,24 @@
26 * parent - parent is adjustable through clk_set_parent 26 * parent - parent is adjustable through clk_set_parent
27 */ 27 */
28 28
29static u8 clk_mux_get_parent(struct clk_hw *hw) 29int clk_mux_val_to_index(struct clk_hw *hw, u32 *table, unsigned int flags,
30 unsigned int val)
30{ 31{
31 struct clk_mux *mux = to_clk_mux(hw);
32 int num_parents = clk_hw_get_num_parents(hw); 32 int num_parents = clk_hw_get_num_parents(hw);
33 u32 val;
34 33
35 /* 34 if (table) {
36 * FIXME need a mux-specific flag to determine if val is bitwise or numeric
37 * e.g. sys_clkin_ck's clksel field is 3 bits wide, but ranges from 0x1
38 * to 0x7 (index starts at one)
39 * OTOH, pmd_trace_clk_mux_ck uses a separate bit for each clock, so
40 * val = 0x4 really means "bit 2, index starts at bit 0"
41 */
42 val = clk_readl(mux->reg) >> mux->shift;
43 val &= mux->mask;
44
45 if (mux->table) {
46 int i; 35 int i;
47 36
48 for (i = 0; i < num_parents; i++) 37 for (i = 0; i < num_parents; i++)
49 if (mux->table[i] == val) 38 if (table[i] == val)
50 return i; 39 return i;
51 return -EINVAL; 40 return -EINVAL;
52 } 41 }
53 42
54 if (val && (mux->flags & CLK_MUX_INDEX_BIT)) 43 if (val && (flags & CLK_MUX_INDEX_BIT))
55 val = ffs(val) - 1; 44 val = ffs(val) - 1;
56 45
57 if (val && (mux->flags & CLK_MUX_INDEX_ONE)) 46 if (val && (flags & CLK_MUX_INDEX_ONE))
58 val--; 47 val--;
59 48
60 if (val >= num_parents) 49 if (val >= num_parents)
@@ -62,36 +51,58 @@ static u8 clk_mux_get_parent(struct clk_hw *hw)
62 51
63 return val; 52 return val;
64} 53}
54EXPORT_SYMBOL_GPL(clk_mux_val_to_index);
65 55
66static int clk_mux_set_parent(struct clk_hw *hw, u8 index) 56unsigned int clk_mux_index_to_val(u32 *table, unsigned int flags, u8 index)
67{ 57{
68 struct clk_mux *mux = to_clk_mux(hw); 58 unsigned int val = index;
69 u32 val;
70 unsigned long flags = 0;
71 59
72 if (mux->table) { 60 if (table) {
73 index = mux->table[index]; 61 val = table[index];
74 } else { 62 } else {
75 if (mux->flags & CLK_MUX_INDEX_BIT) 63 if (flags & CLK_MUX_INDEX_BIT)
76 index = 1 << index; 64 val = 1 << index;
77 65
78 if (mux->flags & CLK_MUX_INDEX_ONE) 66 if (flags & CLK_MUX_INDEX_ONE)
79 index++; 67 val++;
80 } 68 }
81 69
70 return val;
71}
72EXPORT_SYMBOL_GPL(clk_mux_index_to_val);
73
74static u8 clk_mux_get_parent(struct clk_hw *hw)
75{
76 struct clk_mux *mux = to_clk_mux(hw);
77 u32 val;
78
79 val = clk_readl(mux->reg) >> mux->shift;
80 val &= mux->mask;
81
82 return clk_mux_val_to_index(hw, mux->table, mux->flags, val);
83}
84
85static int clk_mux_set_parent(struct clk_hw *hw, u8 index)
86{
87 struct clk_mux *mux = to_clk_mux(hw);
88 u32 val = clk_mux_index_to_val(mux->table, mux->flags, index);
89 unsigned long flags = 0;
90 u32 reg;
91
82 if (mux->lock) 92 if (mux->lock)
83 spin_lock_irqsave(mux->lock, flags); 93 spin_lock_irqsave(mux->lock, flags);
84 else 94 else
85 __acquire(mux->lock); 95 __acquire(mux->lock);
86 96
87 if (mux->flags & CLK_MUX_HIWORD_MASK) { 97 if (mux->flags & CLK_MUX_HIWORD_MASK) {
88 val = mux->mask << (mux->shift + 16); 98 reg = mux->mask << (mux->shift + 16);
89 } else { 99 } else {
90 val = clk_readl(mux->reg); 100 reg = clk_readl(mux->reg);
91 val &= ~(mux->mask << mux->shift); 101 reg &= ~(mux->mask << mux->shift);
92 } 102 }
93 val |= index << mux->shift; 103 val = val << mux->shift;
94 clk_writel(val, mux->reg); 104 reg |= val;
105 clk_writel(reg, mux->reg);
95 106
96 if (mux->lock) 107 if (mux->lock)
97 spin_unlock_irqrestore(mux->lock, flags); 108 spin_unlock_irqrestore(mux->lock, flags);
diff --git a/drivers/clk/clk-stm32f4.c b/drivers/clk/clk-stm32f4.c
index da44f8dc1d29..294850bdc195 100644
--- a/drivers/clk/clk-stm32f4.c
+++ b/drivers/clk/clk-stm32f4.c
@@ -282,6 +282,7 @@ static const struct stm32f4_gate_data stm32f746_gates[] __initconst = {
282 282
283 { STM32F4_RCC_APB2ENR, 0, "tim1", "apb2_mul" }, 283 { STM32F4_RCC_APB2ENR, 0, "tim1", "apb2_mul" },
284 { STM32F4_RCC_APB2ENR, 1, "tim8", "apb2_mul" }, 284 { STM32F4_RCC_APB2ENR, 1, "tim8", "apb2_mul" },
285 { STM32F4_RCC_APB2ENR, 7, "sdmmc2", "sdmux" },
285 { STM32F4_RCC_APB2ENR, 8, "adc1", "apb2_div" }, 286 { STM32F4_RCC_APB2ENR, 8, "adc1", "apb2_div" },
286 { STM32F4_RCC_APB2ENR, 9, "adc2", "apb2_div" }, 287 { STM32F4_RCC_APB2ENR, 9, "adc2", "apb2_div" },
287 { STM32F4_RCC_APB2ENR, 10, "adc3", "apb2_div" }, 288 { STM32F4_RCC_APB2ENR, 10, "adc3", "apb2_div" },
@@ -315,7 +316,7 @@ static const u64 stm32f46xx_gate_map[MAX_GATE_MAP] = { 0x000000f17ef417ffull,
315 316
316static const u64 stm32f746_gate_map[MAX_GATE_MAP] = { 0x000000f17ef417ffull, 317static const u64 stm32f746_gate_map[MAX_GATE_MAP] = { 0x000000f17ef417ffull,
317 0x0000000000000003ull, 318 0x0000000000000003ull,
318 0x04f77f033e01c9ffull }; 319 0x04f77f833e01c9ffull };
319 320
320static const u64 *stm32f4_gate_map; 321static const u64 *stm32f4_gate_map;
321 322
@@ -521,7 +522,7 @@ static const struct stm32f4_pll_data stm32f429_pll[MAX_PLL_DIV] = {
521}; 522};
522 523
523static const struct stm32f4_pll_data stm32f469_pll[MAX_PLL_DIV] = { 524static const struct stm32f4_pll_data stm32f469_pll[MAX_PLL_DIV] = {
524 { PLL, 50, { "pll", "pll-q", NULL } }, 525 { PLL, 50, { "pll", "pll-q", "pll-r" } },
525 { PLL_I2S, 50, { "plli2s-p", "plli2s-q", "plli2s-r" } }, 526 { PLL_I2S, 50, { "plli2s-p", "plli2s-q", "plli2s-r" } },
526 { PLL_SAI, 50, { "pllsai-p", "pllsai-q", "pllsai-r" } }, 527 { PLL_SAI, 50, { "pllsai-p", "pllsai-q", "pllsai-r" } },
527}; 528};
@@ -1047,6 +1048,8 @@ static const char *rtc_parents[4] = {
1047 "no-clock", "lse", "lsi", "hse-rtc" 1048 "no-clock", "lse", "lsi", "hse-rtc"
1048}; 1049};
1049 1050
1051static const char *dsi_parent[2] = { NULL, "pll-r" };
1052
1050static const char *lcd_parent[1] = { "pllsai-r-div" }; 1053static const char *lcd_parent[1] = { "pllsai-r-div" };
1051 1054
1052static const char *i2s_parents[2] = { "plli2s-r", NULL }; 1055static const char *i2s_parents[2] = { "plli2s-r", NULL };
@@ -1156,6 +1159,12 @@ static const struct stm32_aux_clk stm32f469_aux_clk[] = {
1156 NO_GATE, 0, 1159 NO_GATE, 0,
1157 0 1160 0
1158 }, 1161 },
1162 {
1163 CLK_F469_DSI, "dsi", dsi_parent, ARRAY_SIZE(dsi_parent),
1164 STM32F4_RCC_DCKCFGR, 29, 1,
1165 STM32F4_RCC_APB2ENR, 27,
1166 CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT
1167 },
1159}; 1168};
1160 1169
1161static const struct stm32_aux_clk stm32f746_aux_clk[] = { 1170static const struct stm32_aux_clk stm32f746_aux_clk[] = {
@@ -1450,6 +1459,7 @@ static void __init stm32f4_rcc_init(struct device_node *np)
1450 stm32f4_gate_map = data->gates_map; 1459 stm32f4_gate_map = data->gates_map;
1451 1460
1452 hse_clk = of_clk_get_parent_name(np, 0); 1461 hse_clk = of_clk_get_parent_name(np, 0);
1462 dsi_parent[0] = hse_clk;
1453 1463
1454 i2s_in_clk = of_clk_get_parent_name(np, 1); 1464 i2s_in_clk = of_clk_get_parent_name(np, 1);
1455 1465
diff --git a/drivers/clk/clk-stm32mp1.c b/drivers/clk/clk-stm32mp1.c
new file mode 100644
index 000000000000..f1d5967b4b39
--- /dev/null
+++ b/drivers/clk/clk-stm32mp1.c
@@ -0,0 +1,2117 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (C) STMicroelectronics 2018 - All Rights Reserved
4 * Author: Olivier Bideau <olivier.bideau@st.com> for STMicroelectronics.
5 * Author: Gabriel Fernandez <gabriel.fernandez@st.com> for STMicroelectronics.
6 */
7
8#include <linux/clk.h>
9#include <linux/clk-provider.h>
10#include <linux/delay.h>
11#include <linux/err.h>
12#include <linux/io.h>
13#include <linux/of.h>
14#include <linux/of_address.h>
15#include <linux/slab.h>
16#include <linux/spinlock.h>
17
18#include <dt-bindings/clock/stm32mp1-clks.h>
19
20static DEFINE_SPINLOCK(rlock);
21
22#define RCC_OCENSETR 0x0C
23#define RCC_HSICFGR 0x18
24#define RCC_RDLSICR 0x144
25#define RCC_PLL1CR 0x80
26#define RCC_PLL1CFGR1 0x84
27#define RCC_PLL1CFGR2 0x88
28#define RCC_PLL2CR 0x94
29#define RCC_PLL2CFGR1 0x98
30#define RCC_PLL2CFGR2 0x9C
31#define RCC_PLL3CR 0x880
32#define RCC_PLL3CFGR1 0x884
33#define RCC_PLL3CFGR2 0x888
34#define RCC_PLL4CR 0x894
35#define RCC_PLL4CFGR1 0x898
36#define RCC_PLL4CFGR2 0x89C
37#define RCC_APB1ENSETR 0xA00
38#define RCC_APB2ENSETR 0xA08
39#define RCC_APB3ENSETR 0xA10
40#define RCC_APB4ENSETR 0x200
41#define RCC_APB5ENSETR 0x208
42#define RCC_AHB2ENSETR 0xA18
43#define RCC_AHB3ENSETR 0xA20
44#define RCC_AHB4ENSETR 0xA28
45#define RCC_AHB5ENSETR 0x210
46#define RCC_AHB6ENSETR 0x218
47#define RCC_AHB6LPENSETR 0x318
48#define RCC_RCK12SELR 0x28
49#define RCC_RCK3SELR 0x820
50#define RCC_RCK4SELR 0x824
51#define RCC_MPCKSELR 0x20
52#define RCC_ASSCKSELR 0x24
53#define RCC_MSSCKSELR 0x48
54#define RCC_SPI6CKSELR 0xC4
55#define RCC_SDMMC12CKSELR 0x8F4
56#define RCC_SDMMC3CKSELR 0x8F8
57#define RCC_FMCCKSELR 0x904
58#define RCC_I2C46CKSELR 0xC0
59#define RCC_I2C12CKSELR 0x8C0
60#define RCC_I2C35CKSELR 0x8C4
61#define RCC_UART1CKSELR 0xC8
62#define RCC_QSPICKSELR 0x900
63#define RCC_ETHCKSELR 0x8FC
64#define RCC_RNG1CKSELR 0xCC
65#define RCC_RNG2CKSELR 0x920
66#define RCC_GPUCKSELR 0x938
67#define RCC_USBCKSELR 0x91C
68#define RCC_STGENCKSELR 0xD4
69#define RCC_SPDIFCKSELR 0x914
70#define RCC_SPI2S1CKSELR 0x8D8
71#define RCC_SPI2S23CKSELR 0x8DC
72#define RCC_SPI2S45CKSELR 0x8E0
73#define RCC_CECCKSELR 0x918
74#define RCC_LPTIM1CKSELR 0x934
75#define RCC_LPTIM23CKSELR 0x930
76#define RCC_LPTIM45CKSELR 0x92C
77#define RCC_UART24CKSELR 0x8E8
78#define RCC_UART35CKSELR 0x8EC
79#define RCC_UART6CKSELR 0x8E4
80#define RCC_UART78CKSELR 0x8F0
81#define RCC_FDCANCKSELR 0x90C
82#define RCC_SAI1CKSELR 0x8C8
83#define RCC_SAI2CKSELR 0x8CC
84#define RCC_SAI3CKSELR 0x8D0
85#define RCC_SAI4CKSELR 0x8D4
86#define RCC_ADCCKSELR 0x928
87#define RCC_MPCKDIVR 0x2C
88#define RCC_DSICKSELR 0x924
89#define RCC_CPERCKSELR 0xD0
90#define RCC_MCO1CFGR 0x800
91#define RCC_MCO2CFGR 0x804
92#define RCC_BDCR 0x140
93#define RCC_AXIDIVR 0x30
94#define RCC_MCUDIVR 0x830
95#define RCC_APB1DIVR 0x834
96#define RCC_APB2DIVR 0x838
97#define RCC_APB3DIVR 0x83C
98#define RCC_APB4DIVR 0x3C
99#define RCC_APB5DIVR 0x40
100#define RCC_TIMG1PRER 0x828
101#define RCC_TIMG2PRER 0x82C
102#define RCC_RTCDIVR 0x44
103#define RCC_DBGCFGR 0x80C
104
105#define RCC_CLR 0x4
106
107static const char * const ref12_parents[] = {
108 "ck_hsi", "ck_hse"
109};
110
111static const char * const ref3_parents[] = {
112 "ck_hsi", "ck_hse", "ck_csi"
113};
114
115static const char * const ref4_parents[] = {
116 "ck_hsi", "ck_hse", "ck_csi"
117};
118
119static const char * const cpu_src[] = {
120 "ck_hsi", "ck_hse", "pll1_p"
121};
122
123static const char * const axi_src[] = {
124 "ck_hsi", "ck_hse", "pll2_p", "pll3_p"
125};
126
127static const char * const per_src[] = {
128 "ck_hsi", "ck_csi", "ck_hse"
129};
130
131static const char * const mcu_src[] = {
132 "ck_hsi", "ck_hse", "ck_csi", "pll3_p"
133};
134
135static const char * const sdmmc12_src[] = {
136 "ck_axi", "pll3_r", "pll4_p", "ck_hsi"
137};
138
139static const char * const sdmmc3_src[] = {
140 "ck_mcu", "pll3_r", "pll4_p", "ck_hsi"
141};
142
143static const char * const fmc_src[] = {
144 "ck_axi", "pll3_r", "pll4_p", "ck_per"
145};
146
147static const char * const qspi_src[] = {
148 "ck_axi", "pll3_r", "pll4_p", "ck_per"
149};
150
151static const char * const eth_src[] = {
152 "pll4_p", "pll3_q"
153};
154
155static const char * const rng_src[] = {
156 "ck_csi", "pll4_r", "ck_lse", "ck_lsi"
157};
158
159static const char * const usbphy_src[] = {
160 "ck_hse", "pll4_r", "clk-hse-div2"
161};
162
163static const char * const usbo_src[] = {
164 "pll4_r", "ck_usbo_48m"
165};
166
167static const char * const stgen_src[] = {
168 "ck_hsi", "ck_hse"
169};
170
171static const char * const spdif_src[] = {
172 "pll4_p", "pll3_q", "ck_hsi"
173};
174
175static const char * const spi123_src[] = {
176 "pll4_p", "pll3_q", "i2s_ckin", "ck_per", "pll3_r"
177};
178
179static const char * const spi45_src[] = {
180 "pclk2", "pll4_q", "ck_hsi", "ck_csi", "ck_hse"
181};
182
183static const char * const spi6_src[] = {
184 "pclk5", "pll4_q", "ck_hsi", "ck_csi", "ck_hse", "pll3_q"
185};
186
187static const char * const cec_src[] = {
188 "ck_lse", "ck_lsi", "ck_csi"
189};
190
191static const char * const i2c12_src[] = {
192 "pclk1", "pll4_r", "ck_hsi", "ck_csi"
193};
194
195static const char * const i2c35_src[] = {
196 "pclk1", "pll4_r", "ck_hsi", "ck_csi"
197};
198
199static const char * const i2c46_src[] = {
200 "pclk5", "pll3_q", "ck_hsi", "ck_csi"
201};
202
203static const char * const lptim1_src[] = {
204 "pclk1", "pll4_p", "pll3_q", "ck_lse", "ck_lsi", "ck_per"
205};
206
207static const char * const lptim23_src[] = {
208 "pclk3", "pll4_q", "ck_per", "ck_lse", "ck_lsi"
209};
210
211static const char * const lptim45_src[] = {
212 "pclk3", "pll4_p", "pll3_q", "ck_lse", "ck_lsi", "ck_per"
213};
214
215static const char * const usart1_src[] = {
216 "pclk5", "pll3_q", "ck_hsi", "ck_csi", "pll4_q", "ck_hse"
217};
218
219const char * const usart234578_src[] = {
220 "pclk1", "pll4_q", "ck_hsi", "ck_csi", "ck_hse"
221};
222
223static const char * const usart6_src[] = {
224 "pclk2", "pll4_q", "ck_hsi", "ck_csi", "ck_hse"
225};
226
227static const char * const dfsdm_src[] = {
228 "pclk2", "ck_mcu"
229};
230
231static const char * const fdcan_src[] = {
232 "ck_hse", "pll3_q", "pll4_q"
233};
234
235static const char * const sai_src[] = {
236 "pll4_q", "pll3_q", "i2s_ckin", "ck_per"
237};
238
239static const char * const sai2_src[] = {
240 "pll4_q", "pll3_q", "i2s_ckin", "ck_per", "spdif_ck_symb"
241};
242
243static const char * const adc12_src[] = {
244 "pll4_q", "ck_per"
245};
246
247static const char * const dsi_src[] = {
248 "ck_dsi_phy", "pll4_p"
249};
250
251static const char * const rtc_src[] = {
252 "off", "ck_lse", "ck_lsi", "ck_hse_rtc"
253};
254
255static const char * const mco1_src[] = {
256 "ck_hsi", "ck_hse", "ck_csi", "ck_lsi", "ck_lse"
257};
258
259static const char * const mco2_src[] = {
260 "ck_mpu", "ck_axi", "ck_mcu", "pll4_p", "ck_hse", "ck_hsi"
261};
262
263static const char * const ck_trace_src[] = {
264 "ck_axi"
265};
266
267static const struct clk_div_table axi_div_table[] = {
268 { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 },
269 { 4, 4 }, { 5, 4 }, { 6, 4 }, { 7, 4 },
270 { 0 },
271};
272
273static const struct clk_div_table mcu_div_table[] = {
274 { 0, 1 }, { 1, 2 }, { 2, 4 }, { 3, 8 },
275 { 4, 16 }, { 5, 32 }, { 6, 64 }, { 7, 128 },
276 { 8, 512 }, { 9, 512 }, { 10, 512}, { 11, 512 },
277 { 12, 512 }, { 13, 512 }, { 14, 512}, { 15, 512 },
278 { 0 },
279};
280
281static const struct clk_div_table apb_div_table[] = {
282 { 0, 1 }, { 1, 2 }, { 2, 4 }, { 3, 8 },
283 { 4, 16 }, { 5, 16 }, { 6, 16 }, { 7, 16 },
284 { 0 },
285};
286
287static const struct clk_div_table ck_trace_div_table[] = {
288 { 0, 1 }, { 1, 2 }, { 2, 4 }, { 3, 8 },
289 { 4, 16 }, { 5, 16 }, { 6, 16 }, { 7, 16 },
290 { 0 },
291};
292
293#define MAX_MUX_CLK 2
294
295struct stm32_mmux {
296 u8 nbr_clk;
297 struct clk_hw *hws[MAX_MUX_CLK];
298};
299
300struct stm32_clk_mmux {
301 struct clk_mux mux;
302 struct stm32_mmux *mmux;
303};
304
305struct stm32_mgate {
306 u8 nbr_clk;
307 u32 flag;
308};
309
310struct stm32_clk_mgate {
311 struct clk_gate gate;
312 struct stm32_mgate *mgate;
313 u32 mask;
314};
315
316struct clock_config {
317 u32 id;
318 const char *name;
319 union {
320 const char *parent_name;
321 const char * const *parent_names;
322 };
323 int num_parents;
324 unsigned long flags;
325 void *cfg;
326 struct clk_hw * (*func)(struct device *dev,
327 struct clk_hw_onecell_data *clk_data,
328 void __iomem *base, spinlock_t *lock,
329 const struct clock_config *cfg);
330};
331
332#define NO_ID ~0
333
334struct gate_cfg {
335 u32 reg_off;
336 u8 bit_idx;
337 u8 gate_flags;
338};
339
340struct fixed_factor_cfg {
341 unsigned int mult;
342 unsigned int div;
343};
344
345struct div_cfg {
346 u32 reg_off;
347 u8 shift;
348 u8 width;
349 u8 div_flags;
350 const struct clk_div_table *table;
351};
352
353struct mux_cfg {
354 u32 reg_off;
355 u8 shift;
356 u8 width;
357 u8 mux_flags;
358 u32 *table;
359};
360
361struct stm32_gate_cfg {
362 struct gate_cfg *gate;
363 struct stm32_mgate *mgate;
364 const struct clk_ops *ops;
365};
366
367struct stm32_div_cfg {
368 struct div_cfg *div;
369 const struct clk_ops *ops;
370};
371
372struct stm32_mux_cfg {
373 struct mux_cfg *mux;
374 struct stm32_mmux *mmux;
375 const struct clk_ops *ops;
376};
377
378/* STM32 Composite clock */
379struct stm32_composite_cfg {
380 const struct stm32_gate_cfg *gate;
381 const struct stm32_div_cfg *div;
382 const struct stm32_mux_cfg *mux;
383};
384
385static struct clk_hw *
386_clk_hw_register_gate(struct device *dev,
387 struct clk_hw_onecell_data *clk_data,
388 void __iomem *base, spinlock_t *lock,
389 const struct clock_config *cfg)
390{
391 struct gate_cfg *gate_cfg = cfg->cfg;
392
393 return clk_hw_register_gate(dev,
394 cfg->name,
395 cfg->parent_name,
396 cfg->flags,
397 gate_cfg->reg_off + base,
398 gate_cfg->bit_idx,
399 gate_cfg->gate_flags,
400 lock);
401}
402
403static struct clk_hw *
404_clk_hw_register_fixed_factor(struct device *dev,
405 struct clk_hw_onecell_data *clk_data,
406 void __iomem *base, spinlock_t *lock,
407 const struct clock_config *cfg)
408{
409 struct fixed_factor_cfg *ff_cfg = cfg->cfg;
410
411 return clk_hw_register_fixed_factor(dev, cfg->name, cfg->parent_name,
412 cfg->flags, ff_cfg->mult,
413 ff_cfg->div);
414}
415
416static struct clk_hw *
417_clk_hw_register_divider_table(struct device *dev,
418 struct clk_hw_onecell_data *clk_data,
419 void __iomem *base, spinlock_t *lock,
420 const struct clock_config *cfg)
421{
422 struct div_cfg *div_cfg = cfg->cfg;
423
424 return clk_hw_register_divider_table(dev,
425 cfg->name,
426 cfg->parent_name,
427 cfg->flags,
428 div_cfg->reg_off + base,
429 div_cfg->shift,
430 div_cfg->width,
431 div_cfg->div_flags,
432 div_cfg->table,
433 lock);
434}
435
436static struct clk_hw *
437_clk_hw_register_mux(struct device *dev,
438 struct clk_hw_onecell_data *clk_data,
439 void __iomem *base, spinlock_t *lock,
440 const struct clock_config *cfg)
441{
442 struct mux_cfg *mux_cfg = cfg->cfg;
443
444 return clk_hw_register_mux(dev, cfg->name, cfg->parent_names,
445 cfg->num_parents, cfg->flags,
446 mux_cfg->reg_off + base, mux_cfg->shift,
447 mux_cfg->width, mux_cfg->mux_flags, lock);
448}
449
450/* MP1 Gate clock with set & clear registers */
451
452static int mp1_gate_clk_enable(struct clk_hw *hw)
453{
454 if (!clk_gate_ops.is_enabled(hw))
455 clk_gate_ops.enable(hw);
456
457 return 0;
458}
459
460static void mp1_gate_clk_disable(struct clk_hw *hw)
461{
462 struct clk_gate *gate = to_clk_gate(hw);
463 unsigned long flags = 0;
464
465 if (clk_gate_ops.is_enabled(hw)) {
466 spin_lock_irqsave(gate->lock, flags);
467 writel_relaxed(BIT(gate->bit_idx), gate->reg + RCC_CLR);
468 spin_unlock_irqrestore(gate->lock, flags);
469 }
470}
471
472const struct clk_ops mp1_gate_clk_ops = {
473 .enable = mp1_gate_clk_enable,
474 .disable = mp1_gate_clk_disable,
475 .is_enabled = clk_gate_is_enabled,
476};
477
478static struct clk_hw *_get_stm32_mux(void __iomem *base,
479 const struct stm32_mux_cfg *cfg,
480 spinlock_t *lock)
481{
482 struct stm32_clk_mmux *mmux;
483 struct clk_mux *mux;
484 struct clk_hw *mux_hw;
485
486 if (cfg->mmux) {
487 mmux = kzalloc(sizeof(*mmux), GFP_KERNEL);
488 if (!mmux)
489 return ERR_PTR(-ENOMEM);
490
491 mmux->mux.reg = cfg->mux->reg_off + base;
492 mmux->mux.shift = cfg->mux->shift;
493 mmux->mux.mask = (1 << cfg->mux->width) - 1;
494 mmux->mux.flags = cfg->mux->mux_flags;
495 mmux->mux.table = cfg->mux->table;
496 mmux->mux.lock = lock;
497 mmux->mmux = cfg->mmux;
498 mux_hw = &mmux->mux.hw;
499 cfg->mmux->hws[cfg->mmux->nbr_clk++] = mux_hw;
500
501 } else {
502 mux = kzalloc(sizeof(*mux), GFP_KERNEL);
503 if (!mux)
504 return ERR_PTR(-ENOMEM);
505
506 mux->reg = cfg->mux->reg_off + base;
507 mux->shift = cfg->mux->shift;
508 mux->mask = (1 << cfg->mux->width) - 1;
509 mux->flags = cfg->mux->mux_flags;
510 mux->table = cfg->mux->table;
511 mux->lock = lock;
512 mux_hw = &mux->hw;
513 }
514
515 return mux_hw;
516}
517
518static struct clk_hw *_get_stm32_div(void __iomem *base,
519 const struct stm32_div_cfg *cfg,
520 spinlock_t *lock)
521{
522 struct clk_divider *div;
523
524 div = kzalloc(sizeof(*div), GFP_KERNEL);
525
526 if (!div)
527 return ERR_PTR(-ENOMEM);
528
529 div->reg = cfg->div->reg_off + base;
530 div->shift = cfg->div->shift;
531 div->width = cfg->div->width;
532 div->flags = cfg->div->div_flags;
533 div->table = cfg->div->table;
534 div->lock = lock;
535
536 return &div->hw;
537}
538
539static struct clk_hw *
540_get_stm32_gate(void __iomem *base,
541 const struct stm32_gate_cfg *cfg, spinlock_t *lock)
542{
543 struct stm32_clk_mgate *mgate;
544 struct clk_gate *gate;
545 struct clk_hw *gate_hw;
546
547 if (cfg->mgate) {
548 mgate = kzalloc(sizeof(*mgate), GFP_KERNEL);
549 if (!mgate)
550 return ERR_PTR(-ENOMEM);
551
552 mgate->gate.reg = cfg->gate->reg_off + base;
553 mgate->gate.bit_idx = cfg->gate->bit_idx;
554 mgate->gate.flags = cfg->gate->gate_flags;
555 mgate->gate.lock = lock;
556 mgate->mask = BIT(cfg->mgate->nbr_clk++);
557
558 mgate->mgate = cfg->mgate;
559
560 gate_hw = &mgate->gate.hw;
561
562 } else {
563 gate = kzalloc(sizeof(*gate), GFP_KERNEL);
564 if (!gate)
565 return ERR_PTR(-ENOMEM);
566
567 gate->reg = cfg->gate->reg_off + base;
568 gate->bit_idx = cfg->gate->bit_idx;
569 gate->flags = cfg->gate->gate_flags;
570 gate->lock = lock;
571
572 gate_hw = &gate->hw;
573 }
574
575 return gate_hw;
576}
577
578static struct clk_hw *
579clk_stm32_register_gate_ops(struct device *dev,
580 const char *name,
581 const char *parent_name,
582 unsigned long flags,
583 void __iomem *base,
584 const struct stm32_gate_cfg *cfg,
585 spinlock_t *lock)
586{
587 struct clk_init_data init = { NULL };
588 struct clk_gate *gate;
589 struct clk_hw *hw;
590 int ret;
591
592 gate = kzalloc(sizeof(*gate), GFP_KERNEL);
593 if (!gate)
594 return ERR_PTR(-ENOMEM);
595
596 init.name = name;
597 init.parent_names = &parent_name;
598 init.num_parents = 1;
599 init.flags = flags;
600
601 init.ops = &clk_gate_ops;
602
603 if (cfg->ops)
604 init.ops = cfg->ops;
605
606 hw = _get_stm32_gate(base, cfg, lock);
607 if (IS_ERR(hw))
608 return ERR_PTR(-ENOMEM);
609
610 hw->init = &init;
611
612 ret = clk_hw_register(dev, hw);
613 if (ret) {
614 kfree(gate);
615 hw = ERR_PTR(ret);
616 }
617
618 return hw;
619}
620
621static struct clk_hw *
622clk_stm32_register_composite(struct device *dev,
623 const char *name, const char * const *parent_names,
624 int num_parents, void __iomem *base,
625 const struct stm32_composite_cfg *cfg,
626 unsigned long flags, spinlock_t *lock)
627{
628 const struct clk_ops *mux_ops, *div_ops, *gate_ops;
629 struct clk_hw *mux_hw, *div_hw, *gate_hw;
630
631 mux_hw = NULL;
632 div_hw = NULL;
633 gate_hw = NULL;
634 mux_ops = NULL;
635 div_ops = NULL;
636 gate_ops = NULL;
637
638 if (cfg->mux) {
639 mux_hw = _get_stm32_mux(base, cfg->mux, lock);
640
641 if (!IS_ERR(mux_hw)) {
642 mux_ops = &clk_mux_ops;
643
644 if (cfg->mux->ops)
645 mux_ops = cfg->mux->ops;
646 }
647 }
648
649 if (cfg->div) {
650 div_hw = _get_stm32_div(base, cfg->div, lock);
651
652 if (!IS_ERR(div_hw)) {
653 div_ops = &clk_divider_ops;
654
655 if (cfg->div->ops)
656 div_ops = cfg->div->ops;
657 }
658 }
659
660 if (cfg->gate) {
661 gate_hw = _get_stm32_gate(base, cfg->gate, lock);
662
663 if (!IS_ERR(gate_hw)) {
664 gate_ops = &clk_gate_ops;
665
666 if (cfg->gate->ops)
667 gate_ops = cfg->gate->ops;
668 }
669 }
670
671 return clk_hw_register_composite(dev, name, parent_names, num_parents,
672 mux_hw, mux_ops, div_hw, div_ops,
673 gate_hw, gate_ops, flags);
674}
675
676#define to_clk_mgate(_gate) container_of(_gate, struct stm32_clk_mgate, gate)
677
678static int mp1_mgate_clk_enable(struct clk_hw *hw)
679{
680 struct clk_gate *gate = to_clk_gate(hw);
681 struct stm32_clk_mgate *clk_mgate = to_clk_mgate(gate);
682
683 clk_mgate->mgate->flag |= clk_mgate->mask;
684
685 mp1_gate_clk_enable(hw);
686
687 return 0;
688}
689
690static void mp1_mgate_clk_disable(struct clk_hw *hw)
691{
692 struct clk_gate *gate = to_clk_gate(hw);
693 struct stm32_clk_mgate *clk_mgate = to_clk_mgate(gate);
694
695 clk_mgate->mgate->flag &= ~clk_mgate->mask;
696
697 if (clk_mgate->mgate->flag == 0)
698 mp1_gate_clk_disable(hw);
699}
700
701const struct clk_ops mp1_mgate_clk_ops = {
702 .enable = mp1_mgate_clk_enable,
703 .disable = mp1_mgate_clk_disable,
704 .is_enabled = clk_gate_is_enabled,
705
706};
707
708#define to_clk_mmux(_mux) container_of(_mux, struct stm32_clk_mmux, mux)
709
710static u8 clk_mmux_get_parent(struct clk_hw *hw)
711{
712 return clk_mux_ops.get_parent(hw);
713}
714
715static int clk_mmux_set_parent(struct clk_hw *hw, u8 index)
716{
717 struct clk_mux *mux = to_clk_mux(hw);
718 struct stm32_clk_mmux *clk_mmux = to_clk_mmux(mux);
719 struct clk_hw *hwp;
720 int ret, n;
721
722 ret = clk_mux_ops.set_parent(hw, index);
723 if (ret)
724 return ret;
725
726 hwp = clk_hw_get_parent(hw);
727
728 for (n = 0; n < clk_mmux->mmux->nbr_clk; n++)
729 if (clk_mmux->mmux->hws[n] != hw)
730 clk_hw_reparent(clk_mmux->mmux->hws[n], hwp);
731
732 return 0;
733}
734
735const struct clk_ops clk_mmux_ops = {
736 .get_parent = clk_mmux_get_parent,
737 .set_parent = clk_mmux_set_parent,
738 .determine_rate = __clk_mux_determine_rate,
739};
740
741/* STM32 PLL */
742struct stm32_pll_obj {
743 /* lock pll enable/disable registers */
744 spinlock_t *lock;
745 void __iomem *reg;
746 struct clk_hw hw;
747};
748
749#define to_pll(_hw) container_of(_hw, struct stm32_pll_obj, hw)
750
751#define PLL_ON BIT(0)
752#define PLL_RDY BIT(1)
753#define DIVN_MASK 0x1FF
754#define DIVM_MASK 0x3F
755#define DIVM_SHIFT 16
756#define DIVN_SHIFT 0
757#define FRAC_OFFSET 0xC
758#define FRAC_MASK 0x1FFF
759#define FRAC_SHIFT 3
760#define FRACLE BIT(16)
761
762static int __pll_is_enabled(struct clk_hw *hw)
763{
764 struct stm32_pll_obj *clk_elem = to_pll(hw);
765
766 return readl_relaxed(clk_elem->reg) & PLL_ON;
767}
768
769#define TIMEOUT 5
770
771static int pll_enable(struct clk_hw *hw)
772{
773 struct stm32_pll_obj *clk_elem = to_pll(hw);
774 u32 reg;
775 unsigned long flags = 0;
776 unsigned int timeout = TIMEOUT;
777 int bit_status = 0;
778
779 spin_lock_irqsave(clk_elem->lock, flags);
780
781 if (__pll_is_enabled(hw))
782 goto unlock;
783
784 reg = readl_relaxed(clk_elem->reg);
785 reg |= PLL_ON;
786 writel_relaxed(reg, clk_elem->reg);
787
788 /* We can't use readl_poll_timeout() because we can be blocked if
789 * someone enables this clock before clocksource changes.
790 * Only jiffies counter is available. Jiffies are incremented by
791 * interruptions and enable op does not allow to be interrupted.
792 */
793 do {
794 bit_status = !(readl_relaxed(clk_elem->reg) & PLL_RDY);
795
796 if (bit_status)
797 udelay(120);
798
799 } while (bit_status && --timeout);
800
801unlock:
802 spin_unlock_irqrestore(clk_elem->lock, flags);
803
804 return bit_status;
805}
806
807static void pll_disable(struct clk_hw *hw)
808{
809 struct stm32_pll_obj *clk_elem = to_pll(hw);
810 u32 reg;
811 unsigned long flags = 0;
812
813 spin_lock_irqsave(clk_elem->lock, flags);
814
815 reg = readl_relaxed(clk_elem->reg);
816 reg &= ~PLL_ON;
817 writel_relaxed(reg, clk_elem->reg);
818
819 spin_unlock_irqrestore(clk_elem->lock, flags);
820}
821
822static u32 pll_frac_val(struct clk_hw *hw)
823{
824 struct stm32_pll_obj *clk_elem = to_pll(hw);
825 u32 reg, frac = 0;
826
827 reg = readl_relaxed(clk_elem->reg + FRAC_OFFSET);
828 if (reg & FRACLE)
829 frac = (reg >> FRAC_SHIFT) & FRAC_MASK;
830
831 return frac;
832}
833
834static unsigned long pll_recalc_rate(struct clk_hw *hw,
835 unsigned long parent_rate)
836{
837 struct stm32_pll_obj *clk_elem = to_pll(hw);
838 u32 reg;
839 u32 frac, divm, divn;
840 u64 rate, rate_frac = 0;
841
842 reg = readl_relaxed(clk_elem->reg + 4);
843
844 divm = ((reg >> DIVM_SHIFT) & DIVM_MASK) + 1;
845 divn = ((reg >> DIVN_SHIFT) & DIVN_MASK) + 1;
846 rate = (u64)parent_rate * divn;
847
848 do_div(rate, divm);
849
850 frac = pll_frac_val(hw);
851 if (frac) {
852 rate_frac = (u64)parent_rate * (u64)frac;
853 do_div(rate_frac, (divm * 8192));
854 }
855
856 return rate + rate_frac;
857}
858
859static int pll_is_enabled(struct clk_hw *hw)
860{
861 struct stm32_pll_obj *clk_elem = to_pll(hw);
862 unsigned long flags = 0;
863 int ret;
864
865 spin_lock_irqsave(clk_elem->lock, flags);
866 ret = __pll_is_enabled(hw);
867 spin_unlock_irqrestore(clk_elem->lock, flags);
868
869 return ret;
870}
871
872static const struct clk_ops pll_ops = {
873 .enable = pll_enable,
874 .disable = pll_disable,
875 .recalc_rate = pll_recalc_rate,
876 .is_enabled = pll_is_enabled,
877};
878
879static struct clk_hw *clk_register_pll(struct device *dev, const char *name,
880 const char *parent_name,
881 void __iomem *reg,
882 unsigned long flags,
883 spinlock_t *lock)
884{
885 struct stm32_pll_obj *element;
886 struct clk_init_data init;
887 struct clk_hw *hw;
888 int err;
889
890 element = kzalloc(sizeof(*element), GFP_KERNEL);
891 if (!element)
892 return ERR_PTR(-ENOMEM);
893
894 init.name = name;
895 init.ops = &pll_ops;
896 init.flags = flags;
897 init.parent_names = &parent_name;
898 init.num_parents = 1;
899
900 element->hw.init = &init;
901 element->reg = reg;
902 element->lock = lock;
903
904 hw = &element->hw;
905 err = clk_hw_register(dev, hw);
906
907 if (err) {
908 kfree(element);
909 return ERR_PTR(err);
910 }
911
912 return hw;
913}
914
915/* Kernel Timer */
916struct timer_cker {
917 /* lock the kernel output divider register */
918 spinlock_t *lock;
919 void __iomem *apbdiv;
920 void __iomem *timpre;
921 struct clk_hw hw;
922};
923
924#define to_timer_cker(_hw) container_of(_hw, struct timer_cker, hw)
925
926#define APB_DIV_MASK 0x07
927#define TIM_PRE_MASK 0x01
928
929static unsigned long __bestmult(struct clk_hw *hw, unsigned long rate,
930 unsigned long parent_rate)
931{
932 struct timer_cker *tim_ker = to_timer_cker(hw);
933 u32 prescaler;
934 unsigned int mult = 0;
935
936 prescaler = readl_relaxed(tim_ker->apbdiv) & APB_DIV_MASK;
937 if (prescaler < 2)
938 return 1;
939
940 mult = 2;
941
942 if (rate / parent_rate >= 4)
943 mult = 4;
944
945 return mult;
946}
947
948static long timer_ker_round_rate(struct clk_hw *hw, unsigned long rate,
949 unsigned long *parent_rate)
950{
951 unsigned long factor = __bestmult(hw, rate, *parent_rate);
952
953 return *parent_rate * factor;
954}
955
956static int timer_ker_set_rate(struct clk_hw *hw, unsigned long rate,
957 unsigned long parent_rate)
958{
959 struct timer_cker *tim_ker = to_timer_cker(hw);
960 unsigned long flags = 0;
961 unsigned long factor = __bestmult(hw, rate, parent_rate);
962 int ret = 0;
963
964 spin_lock_irqsave(tim_ker->lock, flags);
965
966 switch (factor) {
967 case 1:
968 break;
969 case 2:
970 writel_relaxed(0, tim_ker->timpre);
971 break;
972 case 4:
973 writel_relaxed(1, tim_ker->timpre);
974 break;
975 default:
976 ret = -EINVAL;
977 }
978 spin_unlock_irqrestore(tim_ker->lock, flags);
979
980 return ret;
981}
982
983static unsigned long timer_ker_recalc_rate(struct clk_hw *hw,
984 unsigned long parent_rate)
985{
986 struct timer_cker *tim_ker = to_timer_cker(hw);
987 u32 prescaler, timpre;
988 u32 mul;
989
990 prescaler = readl_relaxed(tim_ker->apbdiv) & APB_DIV_MASK;
991
992 timpre = readl_relaxed(tim_ker->timpre) & TIM_PRE_MASK;
993
994 if (!prescaler)
995 return parent_rate;
996
997 mul = (timpre + 1) * 2;
998
999 return parent_rate * mul;
1000}
1001
1002static const struct clk_ops timer_ker_ops = {
1003 .recalc_rate = timer_ker_recalc_rate,
1004 .round_rate = timer_ker_round_rate,
1005 .set_rate = timer_ker_set_rate,
1006
1007};
1008
1009static struct clk_hw *clk_register_cktim(struct device *dev, const char *name,
1010 const char *parent_name,
1011 unsigned long flags,
1012 void __iomem *apbdiv,
1013 void __iomem *timpre,
1014 spinlock_t *lock)
1015{
1016 struct timer_cker *tim_ker;
1017 struct clk_init_data init;
1018 struct clk_hw *hw;
1019 int err;
1020
1021 tim_ker = kzalloc(sizeof(*tim_ker), GFP_KERNEL);
1022 if (!tim_ker)
1023 return ERR_PTR(-ENOMEM);
1024
1025 init.name = name;
1026 init.ops = &timer_ker_ops;
1027 init.flags = flags;
1028 init.parent_names = &parent_name;
1029 init.num_parents = 1;
1030
1031 tim_ker->hw.init = &init;
1032 tim_ker->lock = lock;
1033 tim_ker->apbdiv = apbdiv;
1034 tim_ker->timpre = timpre;
1035
1036 hw = &tim_ker->hw;
1037 err = clk_hw_register(dev, hw);
1038
1039 if (err) {
1040 kfree(tim_ker);
1041 return ERR_PTR(err);
1042 }
1043
1044 return hw;
1045}
1046
1047struct stm32_pll_cfg {
1048 u32 offset;
1049};
1050
1051struct clk_hw *_clk_register_pll(struct device *dev,
1052 struct clk_hw_onecell_data *clk_data,
1053 void __iomem *base, spinlock_t *lock,
1054 const struct clock_config *cfg)
1055{
1056 struct stm32_pll_cfg *stm_pll_cfg = cfg->cfg;
1057
1058 return clk_register_pll(dev, cfg->name, cfg->parent_name,
1059 base + stm_pll_cfg->offset, cfg->flags, lock);
1060}
1061
1062struct stm32_cktim_cfg {
1063 u32 offset_apbdiv;
1064 u32 offset_timpre;
1065};
1066
1067static struct clk_hw *_clk_register_cktim(struct device *dev,
1068 struct clk_hw_onecell_data *clk_data,
1069 void __iomem *base, spinlock_t *lock,
1070 const struct clock_config *cfg)
1071{
1072 struct stm32_cktim_cfg *cktim_cfg = cfg->cfg;
1073
1074 return clk_register_cktim(dev, cfg->name, cfg->parent_name, cfg->flags,
1075 cktim_cfg->offset_apbdiv + base,
1076 cktim_cfg->offset_timpre + base, lock);
1077}
1078
1079static struct clk_hw *
1080_clk_stm32_register_gate(struct device *dev,
1081 struct clk_hw_onecell_data *clk_data,
1082 void __iomem *base, spinlock_t *lock,
1083 const struct clock_config *cfg)
1084{
1085 return clk_stm32_register_gate_ops(dev,
1086 cfg->name,
1087 cfg->parent_name,
1088 cfg->flags,
1089 base,
1090 cfg->cfg,
1091 lock);
1092}
1093
1094static struct clk_hw *
1095_clk_stm32_register_composite(struct device *dev,
1096 struct clk_hw_onecell_data *clk_data,
1097 void __iomem *base, spinlock_t *lock,
1098 const struct clock_config *cfg)
1099{
1100 return clk_stm32_register_composite(dev, cfg->name, cfg->parent_names,
1101 cfg->num_parents, base, cfg->cfg,
1102 cfg->flags, lock);
1103}
1104
1105#define GATE(_id, _name, _parent, _flags, _offset, _bit_idx, _gate_flags)\
1106{\
1107 .id = _id,\
1108 .name = _name,\
1109 .parent_name = _parent,\
1110 .flags = _flags,\
1111 .cfg = &(struct gate_cfg) {\
1112 .reg_off = _offset,\
1113 .bit_idx = _bit_idx,\
1114 .gate_flags = _gate_flags,\
1115 },\
1116 .func = _clk_hw_register_gate,\
1117}
1118
1119#define FIXED_FACTOR(_id, _name, _parent, _flags, _mult, _div)\
1120{\
1121 .id = _id,\
1122 .name = _name,\
1123 .parent_name = _parent,\
1124 .flags = _flags,\
1125 .cfg = &(struct fixed_factor_cfg) {\
1126 .mult = _mult,\
1127 .div = _div,\
1128 },\
1129 .func = _clk_hw_register_fixed_factor,\
1130}
1131
1132#define DIV_TABLE(_id, _name, _parent, _flags, _offset, _shift, _width,\
1133 _div_flags, _div_table)\
1134{\
1135 .id = _id,\
1136 .name = _name,\
1137 .parent_name = _parent,\
1138 .flags = _flags,\
1139 .cfg = &(struct div_cfg) {\
1140 .reg_off = _offset,\
1141 .shift = _shift,\
1142 .width = _width,\
1143 .div_flags = _div_flags,\
1144 .table = _div_table,\
1145 },\
1146 .func = _clk_hw_register_divider_table,\
1147}
1148
1149#define DIV(_id, _name, _parent, _flags, _offset, _shift, _width, _div_flags)\
1150 DIV_TABLE(_id, _name, _parent, _flags, _offset, _shift, _width,\
1151 _div_flags, NULL)
1152
1153#define MUX(_id, _name, _parents, _flags, _offset, _shift, _width, _mux_flags)\
1154{\
1155 .id = _id,\
1156 .name = _name,\
1157 .parent_names = _parents,\
1158 .num_parents = ARRAY_SIZE(_parents),\
1159 .flags = _flags,\
1160 .cfg = &(struct mux_cfg) {\
1161 .reg_off = _offset,\
1162 .shift = _shift,\
1163 .width = _width,\
1164 .mux_flags = _mux_flags,\
1165 },\
1166 .func = _clk_hw_register_mux,\
1167}
1168
1169#define PLL(_id, _name, _parent, _flags, _offset)\
1170{\
1171 .id = _id,\
1172 .name = _name,\
1173 .parent_name = _parent,\
1174 .flags = _flags,\
1175 .cfg = &(struct stm32_pll_cfg) {\
1176 .offset = _offset,\
1177 },\
1178 .func = _clk_register_pll,\
1179}
1180
1181#define STM32_CKTIM(_name, _parent, _flags, _offset_apbdiv, _offset_timpre)\
1182{\
1183 .id = NO_ID,\
1184 .name = _name,\
1185 .parent_name = _parent,\
1186 .flags = _flags,\
1187 .cfg = &(struct stm32_cktim_cfg) {\
1188 .offset_apbdiv = _offset_apbdiv,\
1189 .offset_timpre = _offset_timpre,\
1190 },\
1191 .func = _clk_register_cktim,\
1192}
1193
1194#define STM32_TIM(_id, _name, _parent, _offset_set, _bit_idx)\
1195 GATE_MP1(_id, _name, _parent, CLK_SET_RATE_PARENT,\
1196 _offset_set, _bit_idx, 0)
1197
1198/* STM32 GATE */
1199#define STM32_GATE(_id, _name, _parent, _flags, _gate)\
1200{\
1201 .id = _id,\
1202 .name = _name,\
1203 .parent_name = _parent,\
1204 .flags = _flags,\
1205 .cfg = (struct stm32_gate_cfg *) {_gate},\
1206 .func = _clk_stm32_register_gate,\
1207}
1208
1209#define _STM32_GATE(_gate_offset, _gate_bit_idx, _gate_flags, _mgate, _ops)\
1210 (&(struct stm32_gate_cfg) {\
1211 &(struct gate_cfg) {\
1212 .reg_off = _gate_offset,\
1213 .bit_idx = _gate_bit_idx,\
1214 .gate_flags = _gate_flags,\
1215 },\
1216 .mgate = _mgate,\
1217 .ops = _ops,\
1218 })
1219
1220#define _STM32_MGATE(_mgate)\
1221 (&per_gate_cfg[_mgate])
1222
1223#define _GATE(_gate_offset, _gate_bit_idx, _gate_flags)\
1224 _STM32_GATE(_gate_offset, _gate_bit_idx, _gate_flags,\
1225 NULL, NULL)\
1226
1227#define _GATE_MP1(_gate_offset, _gate_bit_idx, _gate_flags)\
1228 _STM32_GATE(_gate_offset, _gate_bit_idx, _gate_flags,\
1229 NULL, &mp1_gate_clk_ops)\
1230
1231#define _MGATE_MP1(_mgate)\
1232 .gate = &per_gate_cfg[_mgate]
1233
1234#define GATE_MP1(_id, _name, _parent, _flags, _offset, _bit_idx, _gate_flags)\
1235 STM32_GATE(_id, _name, _parent, _flags,\
1236 _GATE_MP1(_offset, _bit_idx, _gate_flags))
1237
1238#define MGATE_MP1(_id, _name, _parent, _flags, _mgate)\
1239 STM32_GATE(_id, _name, _parent, _flags,\
1240 _STM32_MGATE(_mgate))
1241
1242#define _STM32_DIV(_div_offset, _div_shift, _div_width,\
1243 _div_flags, _div_table, _ops)\
1244 .div = &(struct stm32_div_cfg) {\
1245 &(struct div_cfg) {\
1246 .reg_off = _div_offset,\
1247 .shift = _div_shift,\
1248 .width = _div_width,\
1249 .div_flags = _div_flags,\
1250 .table = _div_table,\
1251 },\
1252 .ops = _ops,\
1253 }
1254
1255#define _DIV(_div_offset, _div_shift, _div_width, _div_flags, _div_table)\
1256 _STM32_DIV(_div_offset, _div_shift, _div_width,\
1257 _div_flags, _div_table, NULL)\
1258
1259#define _STM32_MUX(_offset, _shift, _width, _mux_flags, _mmux, _ops)\
1260 .mux = &(struct stm32_mux_cfg) {\
1261 &(struct mux_cfg) {\
1262 .reg_off = _offset,\
1263 .shift = _shift,\
1264 .width = _width,\
1265 .mux_flags = _mux_flags,\
1266 .table = NULL,\
1267 },\
1268 .mmux = _mmux,\
1269 .ops = _ops,\
1270 }
1271
1272#define _MUX(_offset, _shift, _width, _mux_flags)\
1273 _STM32_MUX(_offset, _shift, _width, _mux_flags, NULL, NULL)\
1274
1275#define _MMUX(_mmux) .mux = &ker_mux_cfg[_mmux]
1276
1277#define PARENT(_parent) ((const char *[]) { _parent})
1278
1279#define _NO_MUX .mux = NULL
1280#define _NO_DIV .div = NULL
1281#define _NO_GATE .gate = NULL
1282
1283#define COMPOSITE(_id, _name, _parents, _flags, _gate, _mux, _div)\
1284{\
1285 .id = _id,\
1286 .name = _name,\
1287 .parent_names = _parents,\
1288 .num_parents = ARRAY_SIZE(_parents),\
1289 .flags = _flags,\
1290 .cfg = &(struct stm32_composite_cfg) {\
1291 _gate,\
1292 _mux,\
1293 _div,\
1294 },\
1295 .func = _clk_stm32_register_composite,\
1296}
1297
1298#define PCLK(_id, _name, _parent, _flags, _mgate)\
1299 MGATE_MP1(_id, _name, _parent, _flags, _mgate)
1300
1301#define KCLK(_id, _name, _parents, _flags, _mgate, _mmux)\
1302 COMPOSITE(_id, _name, _parents, CLK_OPS_PARENT_ENABLE | _flags,\
1303 _MGATE_MP1(_mgate),\
1304 _MMUX(_mmux),\
1305 _NO_DIV)
1306
1307enum {
1308 G_SAI1,
1309 G_SAI2,
1310 G_SAI3,
1311 G_SAI4,
1312 G_SPI1,
1313 G_SPI2,
1314 G_SPI3,
1315 G_SPI4,
1316 G_SPI5,
1317 G_SPI6,
1318 G_SPDIF,
1319 G_I2C1,
1320 G_I2C2,
1321 G_I2C3,
1322 G_I2C4,
1323 G_I2C5,
1324 G_I2C6,
1325 G_USART2,
1326 G_UART4,
1327 G_USART3,
1328 G_UART5,
1329 G_USART1,
1330 G_USART6,
1331 G_UART7,
1332 G_UART8,
1333 G_LPTIM1,
1334 G_LPTIM2,
1335 G_LPTIM3,
1336 G_LPTIM4,
1337 G_LPTIM5,
1338 G_LTDC,
1339 G_DSI,
1340 G_QSPI,
1341 G_FMC,
1342 G_SDMMC1,
1343 G_SDMMC2,
1344 G_SDMMC3,
1345 G_USBO,
1346 G_USBPHY,
1347 G_RNG1,
1348 G_RNG2,
1349 G_FDCAN,
1350 G_DAC12,
1351 G_CEC,
1352 G_ADC12,
1353 G_GPU,
1354 G_STGEN,
1355 G_DFSDM,
1356 G_ADFSDM,
1357 G_TIM2,
1358 G_TIM3,
1359 G_TIM4,
1360 G_TIM5,
1361 G_TIM6,
1362 G_TIM7,
1363 G_TIM12,
1364 G_TIM13,
1365 G_TIM14,
1366 G_MDIO,
1367 G_TIM1,
1368 G_TIM8,
1369 G_TIM15,
1370 G_TIM16,
1371 G_TIM17,
1372 G_SYSCFG,
1373 G_VREF,
1374 G_TMPSENS,
1375 G_PMBCTRL,
1376 G_HDP,
1377 G_IWDG2,
1378 G_STGENRO,
1379 G_DMA1,
1380 G_DMA2,
1381 G_DMAMUX,
1382 G_DCMI,
1383 G_CRYP2,
1384 G_HASH2,
1385 G_CRC2,
1386 G_HSEM,
1387 G_IPCC,
1388 G_GPIOA,
1389 G_GPIOB,
1390 G_GPIOC,
1391 G_GPIOD,
1392 G_GPIOE,
1393 G_GPIOF,
1394 G_GPIOG,
1395 G_GPIOH,
1396 G_GPIOI,
1397 G_GPIOJ,
1398 G_GPIOK,
1399 G_MDMA,
1400 G_ETHCK,
1401 G_ETHTX,
1402 G_ETHRX,
1403 G_ETHMAC,
1404 G_CRC1,
1405 G_USBH,
1406 G_ETHSTP,
1407 G_RTCAPB,
1408 G_TZC,
1409 G_TZPC,
1410 G_IWDG1,
1411 G_BSEC,
1412 G_GPIOZ,
1413 G_CRYP1,
1414 G_HASH1,
1415 G_BKPSRAM,
1416
1417 G_LAST
1418};
1419
1420struct stm32_mgate mp1_mgate[G_LAST];
1421
1422#define _K_GATE(_id, _gate_offset, _gate_bit_idx, _gate_flags,\
1423 _mgate, _ops)\
1424 [_id] = {\
1425 &(struct gate_cfg) {\
1426 .reg_off = _gate_offset,\
1427 .bit_idx = _gate_bit_idx,\
1428 .gate_flags = _gate_flags,\
1429 },\
1430 .mgate = _mgate,\
1431 .ops = _ops,\
1432 }
1433
1434#define K_GATE(_id, _gate_offset, _gate_bit_idx, _gate_flags)\
1435 _K_GATE(_id, _gate_offset, _gate_bit_idx, _gate_flags,\
1436 NULL, &mp1_gate_clk_ops)
1437
1438#define K_MGATE(_id, _gate_offset, _gate_bit_idx, _gate_flags)\
1439 _K_GATE(_id, _gate_offset, _gate_bit_idx, _gate_flags,\
1440 &mp1_mgate[_id], &mp1_mgate_clk_ops)
1441
1442/* Peripheral gates */
1443struct stm32_gate_cfg per_gate_cfg[G_LAST] = {
1444 /* Multi gates */
1445 K_GATE(G_MDIO, RCC_APB1ENSETR, 31, 0),
1446 K_MGATE(G_DAC12, RCC_APB1ENSETR, 29, 0),
1447 K_MGATE(G_CEC, RCC_APB1ENSETR, 27, 0),
1448 K_MGATE(G_SPDIF, RCC_APB1ENSETR, 26, 0),
1449 K_MGATE(G_I2C5, RCC_APB1ENSETR, 24, 0),
1450 K_MGATE(G_I2C3, RCC_APB1ENSETR, 23, 0),
1451 K_MGATE(G_I2C2, RCC_APB1ENSETR, 22, 0),
1452 K_MGATE(G_I2C1, RCC_APB1ENSETR, 21, 0),
1453 K_MGATE(G_UART8, RCC_APB1ENSETR, 19, 0),
1454 K_MGATE(G_UART7, RCC_APB1ENSETR, 18, 0),
1455 K_MGATE(G_UART5, RCC_APB1ENSETR, 17, 0),
1456 K_MGATE(G_UART4, RCC_APB1ENSETR, 16, 0),
1457 K_MGATE(G_USART3, RCC_APB1ENSETR, 15, 0),
1458 K_MGATE(G_USART2, RCC_APB1ENSETR, 14, 0),
1459 K_MGATE(G_SPI3, RCC_APB1ENSETR, 12, 0),
1460 K_MGATE(G_SPI2, RCC_APB1ENSETR, 11, 0),
1461 K_MGATE(G_LPTIM1, RCC_APB1ENSETR, 9, 0),
1462 K_GATE(G_TIM14, RCC_APB1ENSETR, 8, 0),
1463 K_GATE(G_TIM13, RCC_APB1ENSETR, 7, 0),
1464 K_GATE(G_TIM12, RCC_APB1ENSETR, 6, 0),
1465 K_GATE(G_TIM7, RCC_APB1ENSETR, 5, 0),
1466 K_GATE(G_TIM6, RCC_APB1ENSETR, 4, 0),
1467 K_GATE(G_TIM5, RCC_APB1ENSETR, 3, 0),
1468 K_GATE(G_TIM4, RCC_APB1ENSETR, 2, 0),
1469 K_GATE(G_TIM3, RCC_APB1ENSETR, 1, 0),
1470 K_GATE(G_TIM2, RCC_APB1ENSETR, 0, 0),
1471
1472 K_MGATE(G_FDCAN, RCC_APB2ENSETR, 24, 0),
1473 K_GATE(G_ADFSDM, RCC_APB2ENSETR, 21, 0),
1474 K_GATE(G_DFSDM, RCC_APB2ENSETR, 20, 0),
1475 K_MGATE(G_SAI3, RCC_APB2ENSETR, 18, 0),
1476 K_MGATE(G_SAI2, RCC_APB2ENSETR, 17, 0),
1477 K_MGATE(G_SAI1, RCC_APB2ENSETR, 16, 0),
1478 K_MGATE(G_USART6, RCC_APB2ENSETR, 13, 0),
1479 K_MGATE(G_SPI5, RCC_APB2ENSETR, 10, 0),
1480 K_MGATE(G_SPI4, RCC_APB2ENSETR, 9, 0),
1481 K_MGATE(G_SPI1, RCC_APB2ENSETR, 8, 0),
1482 K_GATE(G_TIM17, RCC_APB2ENSETR, 4, 0),
1483 K_GATE(G_TIM16, RCC_APB2ENSETR, 3, 0),
1484 K_GATE(G_TIM15, RCC_APB2ENSETR, 2, 0),
1485 K_GATE(G_TIM8, RCC_APB2ENSETR, 1, 0),
1486 K_GATE(G_TIM1, RCC_APB2ENSETR, 0, 0),
1487
1488 K_GATE(G_HDP, RCC_APB3ENSETR, 20, 0),
1489 K_GATE(G_PMBCTRL, RCC_APB3ENSETR, 17, 0),
1490 K_GATE(G_TMPSENS, RCC_APB3ENSETR, 16, 0),
1491 K_GATE(G_VREF, RCC_APB3ENSETR, 13, 0),
1492 K_GATE(G_SYSCFG, RCC_APB3ENSETR, 11, 0),
1493 K_MGATE(G_SAI4, RCC_APB3ENSETR, 8, 0),
1494 K_MGATE(G_LPTIM5, RCC_APB3ENSETR, 3, 0),
1495 K_MGATE(G_LPTIM4, RCC_APB3ENSETR, 2, 0),
1496 K_MGATE(G_LPTIM3, RCC_APB3ENSETR, 1, 0),
1497 K_MGATE(G_LPTIM2, RCC_APB3ENSETR, 0, 0),
1498
1499 K_GATE(G_STGENRO, RCC_APB4ENSETR, 20, 0),
1500 K_MGATE(G_USBPHY, RCC_APB4ENSETR, 16, 0),
1501 K_GATE(G_IWDG2, RCC_APB4ENSETR, 15, 0),
1502 K_MGATE(G_DSI, RCC_APB4ENSETR, 4, 0),
1503 K_MGATE(G_LTDC, RCC_APB4ENSETR, 0, 0),
1504
1505 K_GATE(G_STGEN, RCC_APB5ENSETR, 20, 0),
1506 K_GATE(G_BSEC, RCC_APB5ENSETR, 16, 0),
1507 K_GATE(G_IWDG1, RCC_APB5ENSETR, 15, 0),
1508 K_GATE(G_TZPC, RCC_APB5ENSETR, 13, 0),
1509 K_GATE(G_TZC, RCC_APB5ENSETR, 12, 0),
1510 K_GATE(G_RTCAPB, RCC_APB5ENSETR, 8, 0),
1511 K_MGATE(G_USART1, RCC_APB5ENSETR, 4, 0),
1512 K_MGATE(G_I2C6, RCC_APB5ENSETR, 3, 0),
1513 K_MGATE(G_I2C4, RCC_APB5ENSETR, 2, 0),
1514 K_MGATE(G_SPI6, RCC_APB5ENSETR, 0, 0),
1515
1516 K_MGATE(G_SDMMC3, RCC_AHB2ENSETR, 16, 0),
1517 K_MGATE(G_USBO, RCC_AHB2ENSETR, 8, 0),
1518 K_MGATE(G_ADC12, RCC_AHB2ENSETR, 5, 0),
1519 K_GATE(G_DMAMUX, RCC_AHB2ENSETR, 2, 0),
1520 K_GATE(G_DMA2, RCC_AHB2ENSETR, 1, 0),
1521 K_GATE(G_DMA1, RCC_AHB2ENSETR, 0, 0),
1522
1523 K_GATE(G_IPCC, RCC_AHB3ENSETR, 12, 0),
1524 K_GATE(G_HSEM, RCC_AHB3ENSETR, 11, 0),
1525 K_GATE(G_CRC2, RCC_AHB3ENSETR, 7, 0),
1526 K_MGATE(G_RNG2, RCC_AHB3ENSETR, 6, 0),
1527 K_GATE(G_HASH2, RCC_AHB3ENSETR, 5, 0),
1528 K_GATE(G_CRYP2, RCC_AHB3ENSETR, 4, 0),
1529 K_GATE(G_DCMI, RCC_AHB3ENSETR, 0, 0),
1530
1531 K_GATE(G_GPIOK, RCC_AHB4ENSETR, 10, 0),
1532 K_GATE(G_GPIOJ, RCC_AHB4ENSETR, 9, 0),
1533 K_GATE(G_GPIOI, RCC_AHB4ENSETR, 8, 0),
1534 K_GATE(G_GPIOH, RCC_AHB4ENSETR, 7, 0),
1535 K_GATE(G_GPIOG, RCC_AHB4ENSETR, 6, 0),
1536 K_GATE(G_GPIOF, RCC_AHB4ENSETR, 5, 0),
1537 K_GATE(G_GPIOE, RCC_AHB4ENSETR, 4, 0),
1538 K_GATE(G_GPIOD, RCC_AHB4ENSETR, 3, 0),
1539 K_GATE(G_GPIOC, RCC_AHB4ENSETR, 2, 0),
1540 K_GATE(G_GPIOB, RCC_AHB4ENSETR, 1, 0),
1541 K_GATE(G_GPIOA, RCC_AHB4ENSETR, 0, 0),
1542
1543 K_GATE(G_BKPSRAM, RCC_AHB5ENSETR, 8, 0),
1544 K_MGATE(G_RNG1, RCC_AHB5ENSETR, 6, 0),
1545 K_GATE(G_HASH1, RCC_AHB5ENSETR, 5, 0),
1546 K_GATE(G_CRYP1, RCC_AHB5ENSETR, 4, 0),
1547 K_GATE(G_GPIOZ, RCC_AHB5ENSETR, 0, 0),
1548
1549 K_GATE(G_USBH, RCC_AHB6ENSETR, 24, 0),
1550 K_GATE(G_CRC1, RCC_AHB6ENSETR, 20, 0),
1551 K_MGATE(G_SDMMC2, RCC_AHB6ENSETR, 17, 0),
1552 K_MGATE(G_SDMMC1, RCC_AHB6ENSETR, 16, 0),
1553 K_MGATE(G_QSPI, RCC_AHB6ENSETR, 14, 0),
1554 K_MGATE(G_FMC, RCC_AHB6ENSETR, 12, 0),
1555 K_GATE(G_ETHMAC, RCC_AHB6ENSETR, 10, 0),
1556 K_GATE(G_ETHRX, RCC_AHB6ENSETR, 9, 0),
1557 K_GATE(G_ETHTX, RCC_AHB6ENSETR, 8, 0),
1558 K_GATE(G_ETHCK, RCC_AHB6ENSETR, 7, 0),
1559 K_MGATE(G_GPU, RCC_AHB6ENSETR, 5, 0),
1560 K_GATE(G_MDMA, RCC_AHB6ENSETR, 0, 0),
1561 K_GATE(G_ETHSTP, RCC_AHB6LPENSETR, 11, 0),
1562};
1563
1564enum {
1565 M_SDMMC12,
1566 M_SDMMC3,
1567 M_FMC,
1568 M_QSPI,
1569 M_RNG1,
1570 M_RNG2,
1571 M_USBPHY,
1572 M_USBO,
1573 M_STGEN,
1574 M_SPDIF,
1575 M_SPI1,
1576 M_SPI23,
1577 M_SPI45,
1578 M_SPI6,
1579 M_CEC,
1580 M_I2C12,
1581 M_I2C35,
1582 M_I2C46,
1583 M_LPTIM1,
1584 M_LPTIM23,
1585 M_LPTIM45,
1586 M_USART1,
1587 M_UART24,
1588 M_UART35,
1589 M_USART6,
1590 M_UART78,
1591 M_SAI1,
1592 M_SAI2,
1593 M_SAI3,
1594 M_SAI4,
1595 M_DSI,
1596 M_FDCAN,
1597 M_ADC12,
1598 M_ETHCK,
1599 M_CKPER,
1600 M_LAST
1601};
1602
1603struct stm32_mmux ker_mux[M_LAST];
1604
1605#define _K_MUX(_id, _offset, _shift, _width, _mux_flags, _mmux, _ops)\
1606 [_id] = {\
1607 &(struct mux_cfg) {\
1608 .reg_off = _offset,\
1609 .shift = _shift,\
1610 .width = _width,\
1611 .mux_flags = _mux_flags,\
1612 .table = NULL,\
1613 },\
1614 .mmux = _mmux,\
1615 .ops = _ops,\
1616 }
1617
1618#define K_MUX(_id, _offset, _shift, _width, _mux_flags)\
1619 _K_MUX(_id, _offset, _shift, _width, _mux_flags,\
1620 NULL, NULL)
1621
1622#define K_MMUX(_id, _offset, _shift, _width, _mux_flags)\
1623 _K_MUX(_id, _offset, _shift, _width, _mux_flags,\
1624 &ker_mux[_id], &clk_mmux_ops)
1625
1626const struct stm32_mux_cfg ker_mux_cfg[M_LAST] = {
1627 /* Kernel multi mux */
1628 K_MMUX(M_SDMMC12, RCC_SDMMC12CKSELR, 0, 3, 0),
1629 K_MMUX(M_SPI23, RCC_SPI2S23CKSELR, 0, 3, 0),
1630 K_MMUX(M_SPI45, RCC_SPI2S45CKSELR, 0, 3, 0),
1631 K_MMUX(M_I2C12, RCC_I2C12CKSELR, 0, 3, 0),
1632 K_MMUX(M_I2C35, RCC_I2C35CKSELR, 0, 3, 0),
1633 K_MMUX(M_LPTIM23, RCC_LPTIM23CKSELR, 0, 3, 0),
1634 K_MMUX(M_LPTIM45, RCC_LPTIM45CKSELR, 0, 3, 0),
1635 K_MMUX(M_UART24, RCC_UART24CKSELR, 0, 3, 0),
1636 K_MMUX(M_UART35, RCC_UART35CKSELR, 0, 3, 0),
1637 K_MMUX(M_UART78, RCC_UART78CKSELR, 0, 3, 0),
1638 K_MMUX(M_SAI1, RCC_SAI1CKSELR, 0, 3, 0),
1639 K_MMUX(M_ETHCK, RCC_ETHCKSELR, 0, 2, 0),
1640 K_MMUX(M_I2C46, RCC_I2C46CKSELR, 0, 3, 0),
1641
1642 /* Kernel simple mux */
1643 K_MUX(M_RNG2, RCC_RNG2CKSELR, 0, 2, 0),
1644 K_MUX(M_SDMMC3, RCC_SDMMC3CKSELR, 0, 3, 0),
1645 K_MUX(M_FMC, RCC_FMCCKSELR, 0, 2, 0),
1646 K_MUX(M_QSPI, RCC_QSPICKSELR, 0, 2, 0),
1647 K_MUX(M_USBPHY, RCC_USBCKSELR, 0, 2, 0),
1648 K_MUX(M_USBO, RCC_USBCKSELR, 4, 1, 0),
1649 K_MUX(M_SPDIF, RCC_SPDIFCKSELR, 0, 2, 0),
1650 K_MUX(M_SPI1, RCC_SPI2S1CKSELR, 0, 3, 0),
1651 K_MUX(M_CEC, RCC_CECCKSELR, 0, 2, 0),
1652 K_MUX(M_LPTIM1, RCC_LPTIM1CKSELR, 0, 3, 0),
1653 K_MUX(M_USART6, RCC_UART6CKSELR, 0, 3, 0),
1654 K_MUX(M_FDCAN, RCC_FDCANCKSELR, 0, 2, 0),
1655 K_MUX(M_SAI2, RCC_SAI2CKSELR, 0, 3, 0),
1656 K_MUX(M_SAI3, RCC_SAI3CKSELR, 0, 3, 0),
1657 K_MUX(M_SAI4, RCC_SAI4CKSELR, 0, 3, 0),
1658 K_MUX(M_ADC12, RCC_ADCCKSELR, 0, 2, 0),
1659 K_MUX(M_DSI, RCC_DSICKSELR, 0, 1, 0),
1660 K_MUX(M_CKPER, RCC_CPERCKSELR, 0, 2, 0),
1661 K_MUX(M_RNG1, RCC_RNG1CKSELR, 0, 2, 0),
1662 K_MUX(M_STGEN, RCC_STGENCKSELR, 0, 2, 0),
1663 K_MUX(M_USART1, RCC_UART1CKSELR, 0, 3, 0),
1664 K_MUX(M_SPI6, RCC_SPI6CKSELR, 0, 3, 0),
1665};
1666
1667static const struct clock_config stm32mp1_clock_cfg[] = {
1668 /* Oscillator divider */
1669 DIV(NO_ID, "clk-hsi-div", "clk-hsi", 0, RCC_HSICFGR, 0, 2,
1670 CLK_DIVIDER_READ_ONLY),
1671
1672 /* External / Internal Oscillators */
1673 GATE_MP1(CK_HSE, "ck_hse", "clk-hse", 0, RCC_OCENSETR, 8, 0),
1674 GATE_MP1(CK_CSI, "ck_csi", "clk-csi", 0, RCC_OCENSETR, 4, 0),
1675 GATE_MP1(CK_HSI, "ck_hsi", "clk-hsi-div", 0, RCC_OCENSETR, 0, 0),
1676 GATE(CK_LSI, "ck_lsi", "clk-lsi", 0, RCC_RDLSICR, 0, 0),
1677 GATE(CK_LSE, "ck_lse", "clk-lse", 0, RCC_BDCR, 0, 0),
1678
1679 FIXED_FACTOR(CK_HSE_DIV2, "clk-hse-div2", "ck_hse", 0, 1, 2),
1680
1681 /* ref clock pll */
1682 MUX(NO_ID, "ref1", ref12_parents, CLK_OPS_PARENT_ENABLE, RCC_RCK12SELR,
1683 0, 2, CLK_MUX_READ_ONLY),
1684
1685 MUX(NO_ID, "ref3", ref3_parents, CLK_OPS_PARENT_ENABLE, RCC_RCK3SELR,
1686 0, 2, CLK_MUX_READ_ONLY),
1687
1688 MUX(NO_ID, "ref4", ref4_parents, CLK_OPS_PARENT_ENABLE, RCC_RCK4SELR,
1689 0, 2, CLK_MUX_READ_ONLY),
1690
1691 /* PLLs */
1692 PLL(PLL1, "pll1", "ref1", CLK_IGNORE_UNUSED, RCC_PLL1CR),
1693 PLL(PLL2, "pll2", "ref1", CLK_IGNORE_UNUSED, RCC_PLL2CR),
1694 PLL(PLL3, "pll3", "ref3", CLK_IGNORE_UNUSED, RCC_PLL3CR),
1695 PLL(PLL4, "pll4", "ref4", CLK_IGNORE_UNUSED, RCC_PLL4CR),
1696
1697 /* ODF */
1698 COMPOSITE(PLL1_P, "pll1_p", PARENT("pll1"), 0,
1699 _GATE(RCC_PLL1CR, 4, 0),
1700 _NO_MUX,
1701 _DIV(RCC_PLL1CFGR2, 0, 7, 0, NULL)),
1702
1703 COMPOSITE(PLL2_P, "pll2_p", PARENT("pll2"), 0,
1704 _GATE(RCC_PLL2CR, 4, 0),
1705 _NO_MUX,
1706 _DIV(RCC_PLL2CFGR2, 0, 7, 0, NULL)),
1707
1708 COMPOSITE(PLL2_Q, "pll2_q", PARENT("pll2"), 0,
1709 _GATE(RCC_PLL2CR, 5, 0),
1710 _NO_MUX,
1711 _DIV(RCC_PLL2CFGR2, 8, 7, 0, NULL)),
1712
1713 COMPOSITE(PLL2_R, "pll2_r", PARENT("pll2"), CLK_IS_CRITICAL,
1714 _GATE(RCC_PLL2CR, 6, 0),
1715 _NO_MUX,
1716 _DIV(RCC_PLL2CFGR2, 16, 7, 0, NULL)),
1717
1718 COMPOSITE(PLL3_P, "pll3_p", PARENT("pll3"), 0,
1719 _GATE(RCC_PLL3CR, 4, 0),
1720 _NO_MUX,
1721 _DIV(RCC_PLL3CFGR2, 0, 7, 0, NULL)),
1722
1723 COMPOSITE(PLL3_Q, "pll3_q", PARENT("pll3"), 0,
1724 _GATE(RCC_PLL3CR, 5, 0),
1725 _NO_MUX,
1726 _DIV(RCC_PLL3CFGR2, 8, 7, 0, NULL)),
1727
1728 COMPOSITE(PLL3_R, "pll3_r", PARENT("pll3"), 0,
1729 _GATE(RCC_PLL3CR, 6, 0),
1730 _NO_MUX,
1731 _DIV(RCC_PLL3CFGR2, 16, 7, 0, NULL)),
1732
1733 COMPOSITE(PLL4_P, "pll4_p", PARENT("pll4"), 0,
1734 _GATE(RCC_PLL4CR, 4, 0),
1735 _NO_MUX,
1736 _DIV(RCC_PLL4CFGR2, 0, 7, 0, NULL)),
1737
1738 COMPOSITE(PLL4_Q, "pll4_q", PARENT("pll4"), 0,
1739 _GATE(RCC_PLL4CR, 5, 0),
1740 _NO_MUX,
1741 _DIV(RCC_PLL4CFGR2, 8, 7, 0, NULL)),
1742
1743 COMPOSITE(PLL4_R, "pll4_r", PARENT("pll4"), 0,
1744 _GATE(RCC_PLL4CR, 6, 0),
1745 _NO_MUX,
1746 _DIV(RCC_PLL4CFGR2, 16, 7, 0, NULL)),
1747
1748 /* MUX system clocks */
1749 MUX(CK_PER, "ck_per", per_src, CLK_OPS_PARENT_ENABLE,
1750 RCC_CPERCKSELR, 0, 2, 0),
1751
1752 MUX(CK_MPU, "ck_mpu", cpu_src, CLK_OPS_PARENT_ENABLE |
1753 CLK_IS_CRITICAL, RCC_MPCKSELR, 0, 2, 0),
1754
1755 COMPOSITE(CK_AXI, "ck_axi", axi_src, CLK_IS_CRITICAL |
1756 CLK_OPS_PARENT_ENABLE,
1757 _NO_GATE,
1758 _MUX(RCC_ASSCKSELR, 0, 2, 0),
1759 _DIV(RCC_AXIDIVR, 0, 3, 0, axi_div_table)),
1760
1761 COMPOSITE(CK_MCU, "ck_mcu", mcu_src, CLK_IS_CRITICAL |
1762 CLK_OPS_PARENT_ENABLE,
1763 _NO_GATE,
1764 _MUX(RCC_MSSCKSELR, 0, 2, 0),
1765 _DIV(RCC_MCUDIVR, 0, 4, 0, mcu_div_table)),
1766
1767 DIV_TABLE(NO_ID, "pclk1", "ck_mcu", CLK_IGNORE_UNUSED, RCC_APB1DIVR, 0,
1768 3, CLK_DIVIDER_READ_ONLY, apb_div_table),
1769
1770 DIV_TABLE(NO_ID, "pclk2", "ck_mcu", CLK_IGNORE_UNUSED, RCC_APB2DIVR, 0,
1771 3, CLK_DIVIDER_READ_ONLY, apb_div_table),
1772
1773 DIV_TABLE(NO_ID, "pclk3", "ck_mcu", CLK_IGNORE_UNUSED, RCC_APB3DIVR, 0,
1774 3, CLK_DIVIDER_READ_ONLY, apb_div_table),
1775
1776 DIV_TABLE(NO_ID, "pclk4", "ck_axi", CLK_IGNORE_UNUSED, RCC_APB4DIVR, 0,
1777 3, CLK_DIVIDER_READ_ONLY, apb_div_table),
1778
1779 DIV_TABLE(NO_ID, "pclk5", "ck_axi", CLK_IGNORE_UNUSED, RCC_APB5DIVR, 0,
1780 3, CLK_DIVIDER_READ_ONLY, apb_div_table),
1781
1782 /* Kernel Timers */
1783 STM32_CKTIM("ck1_tim", "pclk1", 0, RCC_APB1DIVR, RCC_TIMG1PRER),
1784 STM32_CKTIM("ck2_tim", "pclk2", 0, RCC_APB2DIVR, RCC_TIMG2PRER),
1785
1786 STM32_TIM(TIM2_K, "tim2_k", "ck1_tim", RCC_APB1ENSETR, 0),
1787 STM32_TIM(TIM3_K, "tim3_k", "ck1_tim", RCC_APB1ENSETR, 1),
1788 STM32_TIM(TIM4_K, "tim4_k", "ck1_tim", RCC_APB1ENSETR, 2),
1789 STM32_TIM(TIM5_K, "tim5_k", "ck1_tim", RCC_APB1ENSETR, 3),
1790 STM32_TIM(TIM6_K, "tim6_k", "ck1_tim", RCC_APB1ENSETR, 4),
1791 STM32_TIM(TIM7_K, "tim7_k", "ck1_tim", RCC_APB1ENSETR, 5),
1792 STM32_TIM(TIM12_K, "tim12_k", "ck1_tim", RCC_APB1ENSETR, 6),
1793 STM32_TIM(TIM13_K, "tim13_k", "ck1_tim", RCC_APB1ENSETR, 7),
1794 STM32_TIM(TIM14_K, "tim14_k", "ck1_tim", RCC_APB1ENSETR, 8),
1795 STM32_TIM(TIM1_K, "tim1_k", "ck2_tim", RCC_APB2ENSETR, 0),
1796 STM32_TIM(TIM8_K, "tim8_k", "ck2_tim", RCC_APB2ENSETR, 1),
1797 STM32_TIM(TIM15_K, "tim15_k", "ck2_tim", RCC_APB2ENSETR, 2),
1798 STM32_TIM(TIM16_K, "tim16_k", "ck2_tim", RCC_APB2ENSETR, 3),
1799 STM32_TIM(TIM17_K, "tim17_k", "ck2_tim", RCC_APB2ENSETR, 4),
1800
1801 /* Peripheral clocks */
1802 PCLK(TIM2, "tim2", "pclk1", CLK_IGNORE_UNUSED, G_TIM2),
1803 PCLK(TIM3, "tim3", "pclk1", CLK_IGNORE_UNUSED, G_TIM3),
1804 PCLK(TIM4, "tim4", "pclk1", CLK_IGNORE_UNUSED, G_TIM4),
1805 PCLK(TIM5, "tim5", "pclk1", CLK_IGNORE_UNUSED, G_TIM5),
1806 PCLK(TIM6, "tim6", "pclk1", CLK_IGNORE_UNUSED, G_TIM6),
1807 PCLK(TIM7, "tim7", "pclk1", CLK_IGNORE_UNUSED, G_TIM7),
1808 PCLK(TIM12, "tim12", "pclk1", CLK_IGNORE_UNUSED, G_TIM12),
1809 PCLK(TIM13, "tim13", "pclk1", CLK_IGNORE_UNUSED, G_TIM13),
1810 PCLK(TIM14, "tim14", "pclk1", CLK_IGNORE_UNUSED, G_TIM14),
1811 PCLK(LPTIM1, "lptim1", "pclk1", 0, G_LPTIM1),
1812 PCLK(SPI2, "spi2", "pclk1", 0, G_SPI2),
1813 PCLK(SPI3, "spi3", "pclk1", 0, G_SPI3),
1814 PCLK(USART2, "usart2", "pclk1", 0, G_USART2),
1815 PCLK(USART3, "usart3", "pclk1", 0, G_USART3),
1816 PCLK(UART4, "uart4", "pclk1", 0, G_UART4),
1817 PCLK(UART5, "uart5", "pclk1", 0, G_UART5),
1818 PCLK(UART7, "uart7", "pclk1", 0, G_UART7),
1819 PCLK(UART8, "uart8", "pclk1", 0, G_UART8),
1820 PCLK(I2C1, "i2c1", "pclk1", 0, G_I2C1),
1821 PCLK(I2C2, "i2c2", "pclk1", 0, G_I2C2),
1822 PCLK(I2C3, "i2c3", "pclk1", 0, G_I2C3),
1823 PCLK(I2C5, "i2c5", "pclk1", 0, G_I2C5),
1824 PCLK(SPDIF, "spdif", "pclk1", 0, G_SPDIF),
1825 PCLK(CEC, "cec", "pclk1", 0, G_CEC),
1826 PCLK(DAC12, "dac12", "pclk1", 0, G_DAC12),
1827 PCLK(MDIO, "mdio", "pclk1", 0, G_MDIO),
1828 PCLK(TIM1, "tim1", "pclk2", CLK_IGNORE_UNUSED, G_TIM1),
1829 PCLK(TIM8, "tim8", "pclk2", CLK_IGNORE_UNUSED, G_TIM8),
1830 PCLK(TIM15, "tim15", "pclk2", CLK_IGNORE_UNUSED, G_TIM15),
1831 PCLK(TIM16, "tim16", "pclk2", CLK_IGNORE_UNUSED, G_TIM16),
1832 PCLK(TIM17, "tim17", "pclk2", CLK_IGNORE_UNUSED, G_TIM17),
1833 PCLK(SPI1, "spi1", "pclk2", 0, G_SPI1),
1834 PCLK(SPI4, "spi4", "pclk2", 0, G_SPI4),
1835 PCLK(SPI5, "spi5", "pclk2", 0, G_SPI5),
1836 PCLK(USART6, "usart6", "pclk2", 0, G_USART6),
1837 PCLK(SAI1, "sai1", "pclk2", 0, G_SAI1),
1838 PCLK(SAI2, "sai2", "pclk2", 0, G_SAI2),
1839 PCLK(SAI3, "sai3", "pclk2", 0, G_SAI3),
1840 PCLK(DFSDM, "dfsdm", "pclk2", 0, G_DFSDM),
1841 PCLK(FDCAN, "fdcan", "pclk2", 0, G_FDCAN),
1842 PCLK(LPTIM2, "lptim2", "pclk3", 0, G_LPTIM2),
1843 PCLK(LPTIM3, "lptim3", "pclk3", 0, G_LPTIM3),
1844 PCLK(LPTIM4, "lptim4", "pclk3", 0, G_LPTIM4),
1845 PCLK(LPTIM5, "lptim5", "pclk3", 0, G_LPTIM5),
1846 PCLK(SAI4, "sai4", "pclk3", 0, G_SAI4),
1847 PCLK(SYSCFG, "syscfg", "pclk3", 0, G_SYSCFG),
1848 PCLK(VREF, "vref", "pclk3", 13, G_VREF),
1849 PCLK(TMPSENS, "tmpsens", "pclk3", 0, G_TMPSENS),
1850 PCLK(PMBCTRL, "pmbctrl", "pclk3", 0, G_PMBCTRL),
1851 PCLK(HDP, "hdp", "pclk3", 0, G_HDP),
1852 PCLK(LTDC, "ltdc", "pclk4", 0, G_LTDC),
1853 PCLK(DSI, "dsi", "pclk4", 0, G_DSI),
1854 PCLK(IWDG2, "iwdg2", "pclk4", 0, G_IWDG2),
1855 PCLK(USBPHY, "usbphy", "pclk4", 0, G_USBPHY),
1856 PCLK(STGENRO, "stgenro", "pclk4", 0, G_STGENRO),
1857 PCLK(SPI6, "spi6", "pclk5", 0, G_SPI6),
1858 PCLK(I2C4, "i2c4", "pclk5", 0, G_I2C4),
1859 PCLK(I2C6, "i2c6", "pclk5", 0, G_I2C6),
1860 PCLK(USART1, "usart1", "pclk5", 0, G_USART1),
1861 PCLK(RTCAPB, "rtcapb", "pclk5", CLK_IGNORE_UNUSED |
1862 CLK_IS_CRITICAL, G_RTCAPB),
1863 PCLK(TZC, "tzc", "pclk5", CLK_IGNORE_UNUSED, G_TZC),
1864 PCLK(TZPC, "tzpc", "pclk5", CLK_IGNORE_UNUSED, G_TZPC),
1865 PCLK(IWDG1, "iwdg1", "pclk5", 0, G_IWDG1),
1866 PCLK(BSEC, "bsec", "pclk5", CLK_IGNORE_UNUSED, G_BSEC),
1867 PCLK(STGEN, "stgen", "pclk5", CLK_IGNORE_UNUSED, G_STGEN),
1868 PCLK(DMA1, "dma1", "ck_mcu", 0, G_DMA1),
1869 PCLK(DMA2, "dma2", "ck_mcu", 0, G_DMA2),
1870 PCLK(DMAMUX, "dmamux", "ck_mcu", 0, G_DMAMUX),
1871 PCLK(ADC12, "adc12", "ck_mcu", 0, G_ADC12),
1872 PCLK(USBO, "usbo", "ck_mcu", 0, G_USBO),
1873 PCLK(SDMMC3, "sdmmc3", "ck_mcu", 0, G_SDMMC3),
1874 PCLK(DCMI, "dcmi", "ck_mcu", 0, G_DCMI),
1875 PCLK(CRYP2, "cryp2", "ck_mcu", 0, G_CRYP2),
1876 PCLK(HASH2, "hash2", "ck_mcu", 0, G_HASH2),
1877 PCLK(RNG2, "rng2", "ck_mcu", 0, G_RNG2),
1878 PCLK(CRC2, "crc2", "ck_mcu", 0, G_CRC2),
1879 PCLK(HSEM, "hsem", "ck_mcu", 0, G_HSEM),
1880 PCLK(IPCC, "ipcc", "ck_mcu", 0, G_IPCC),
1881 PCLK(GPIOA, "gpioa", "ck_mcu", 0, G_GPIOA),
1882 PCLK(GPIOB, "gpiob", "ck_mcu", 0, G_GPIOB),
1883 PCLK(GPIOC, "gpioc", "ck_mcu", 0, G_GPIOC),
1884 PCLK(GPIOD, "gpiod", "ck_mcu", 0, G_GPIOD),
1885 PCLK(GPIOE, "gpioe", "ck_mcu", 0, G_GPIOE),
1886 PCLK(GPIOF, "gpiof", "ck_mcu", 0, G_GPIOF),
1887 PCLK(GPIOG, "gpiog", "ck_mcu", 0, G_GPIOG),
1888 PCLK(GPIOH, "gpioh", "ck_mcu", 0, G_GPIOH),
1889 PCLK(GPIOI, "gpioi", "ck_mcu", 0, G_GPIOI),
1890 PCLK(GPIOJ, "gpioj", "ck_mcu", 0, G_GPIOJ),
1891 PCLK(GPIOK, "gpiok", "ck_mcu", 0, G_GPIOK),
1892 PCLK(GPIOZ, "gpioz", "ck_axi", CLK_IGNORE_UNUSED, G_GPIOZ),
1893 PCLK(CRYP1, "cryp1", "ck_axi", CLK_IGNORE_UNUSED, G_CRYP1),
1894 PCLK(HASH1, "hash1", "ck_axi", CLK_IGNORE_UNUSED, G_HASH1),
1895 PCLK(RNG1, "rng1", "ck_axi", 0, G_RNG1),
1896 PCLK(BKPSRAM, "bkpsram", "ck_axi", CLK_IGNORE_UNUSED, G_BKPSRAM),
1897 PCLK(MDMA, "mdma", "ck_axi", 0, G_MDMA),
1898 PCLK(GPU, "gpu", "ck_axi", 0, G_GPU),
1899 PCLK(ETHTX, "ethtx", "ck_axi", 0, G_ETHTX),
1900 PCLK(ETHRX, "ethrx", "ck_axi", 0, G_ETHRX),
1901 PCLK(ETHMAC, "ethmac", "ck_axi", 0, G_ETHMAC),
1902 PCLK(FMC, "fmc", "ck_axi", CLK_IGNORE_UNUSED, G_FMC),
1903 PCLK(QSPI, "qspi", "ck_axi", CLK_IGNORE_UNUSED, G_QSPI),
1904 PCLK(SDMMC1, "sdmmc1", "ck_axi", 0, G_SDMMC1),
1905 PCLK(SDMMC2, "sdmmc2", "ck_axi", 0, G_SDMMC2),
1906 PCLK(CRC1, "crc1", "ck_axi", 0, G_CRC1),
1907 PCLK(USBH, "usbh", "ck_axi", 0, G_USBH),
1908 PCLK(ETHSTP, "ethstp", "ck_axi", 0, G_ETHSTP),
1909
1910 /* Kernel clocks */
1911 KCLK(SDMMC1_K, "sdmmc1_k", sdmmc12_src, 0, G_SDMMC1, M_SDMMC12),
1912 KCLK(SDMMC2_K, "sdmmc2_k", sdmmc12_src, 0, G_SDMMC2, M_SDMMC12),
1913 KCLK(SDMMC3_K, "sdmmc3_k", sdmmc3_src, 0, G_SDMMC3, M_SDMMC3),
1914 KCLK(FMC_K, "fmc_k", fmc_src, 0, G_FMC, M_FMC),
1915 KCLK(QSPI_K, "qspi_k", qspi_src, 0, G_QSPI, M_QSPI),
1916 KCLK(RNG1_K, "rng1_k", rng_src, 0, G_RNG1, M_RNG1),
1917 KCLK(RNG2_K, "rng2_k", rng_src, 0, G_RNG2, M_RNG2),
1918 KCLK(USBPHY_K, "usbphy_k", usbphy_src, 0, G_USBPHY, M_USBPHY),
1919 KCLK(STGEN_K, "stgen_k", stgen_src, CLK_IGNORE_UNUSED,
1920 G_STGEN, M_STGEN),
1921 KCLK(SPDIF_K, "spdif_k", spdif_src, 0, G_SPDIF, M_SPDIF),
1922 KCLK(SPI1_K, "spi1_k", spi123_src, 0, G_SPI1, M_SPI1),
1923 KCLK(SPI2_K, "spi2_k", spi123_src, 0, G_SPI2, M_SPI23),
1924 KCLK(SPI3_K, "spi3_k", spi123_src, 0, G_SPI3, M_SPI23),
1925 KCLK(SPI4_K, "spi4_k", spi45_src, 0, G_SPI4, M_SPI45),
1926 KCLK(SPI5_K, "spi5_k", spi45_src, 0, G_SPI5, M_SPI45),
1927 KCLK(SPI6_K, "spi6_k", spi6_src, 0, G_SPI6, M_SPI6),
1928 KCLK(CEC_K, "cec_k", cec_src, 0, G_CEC, M_CEC),
1929 KCLK(I2C1_K, "i2c1_k", i2c12_src, 0, G_I2C1, M_I2C12),
1930 KCLK(I2C2_K, "i2c2_k", i2c12_src, 0, G_I2C2, M_I2C12),
1931 KCLK(I2C3_K, "i2c3_k", i2c35_src, 0, G_I2C3, M_I2C35),
1932 KCLK(I2C5_K, "i2c5_k", i2c35_src, 0, G_I2C5, M_I2C35),
1933 KCLK(I2C4_K, "i2c4_k", i2c46_src, 0, G_I2C4, M_I2C46),
1934 KCLK(I2C6_K, "i2c6_k", i2c46_src, 0, G_I2C6, M_I2C46),
1935 KCLK(LPTIM1_K, "lptim1_k", lptim1_src, 0, G_LPTIM1, M_LPTIM1),
1936 KCLK(LPTIM2_K, "lptim2_k", lptim23_src, 0, G_LPTIM2, M_LPTIM23),
1937 KCLK(LPTIM3_K, "lptim3_k", lptim23_src, 0, G_LPTIM3, M_LPTIM23),
1938 KCLK(LPTIM4_K, "lptim4_k", lptim45_src, 0, G_LPTIM4, M_LPTIM45),
1939 KCLK(LPTIM5_K, "lptim5_k", lptim45_src, 0, G_LPTIM5, M_LPTIM45),
1940 KCLK(USART1_K, "usart1_k", usart1_src, 0, G_USART1, M_USART1),
1941 KCLK(USART2_K, "usart2_k", usart234578_src, 0, G_USART2, M_UART24),
1942 KCLK(USART3_K, "usart3_k", usart234578_src, 0, G_USART3, M_UART35),
1943 KCLK(UART4_K, "uart4_k", usart234578_src, 0, G_UART4, M_UART24),
1944 KCLK(UART5_K, "uart5_k", usart234578_src, 0, G_UART5, M_UART35),
1945 KCLK(USART6_K, "uart6_k", usart6_src, 0, G_USART6, M_USART6),
1946 KCLK(UART7_K, "uart7_k", usart234578_src, 0, G_UART7, M_UART78),
1947 KCLK(UART8_K, "uart8_k", usart234578_src, 0, G_UART8, M_UART78),
1948 KCLK(FDCAN_K, "fdcan_k", fdcan_src, 0, G_FDCAN, M_FDCAN),
1949 KCLK(SAI1_K, "sai1_k", sai_src, 0, G_SAI1, M_SAI1),
1950 KCLK(SAI2_K, "sai2_k", sai2_src, 0, G_SAI2, M_SAI2),
1951 KCLK(SAI3_K, "sai3_k", sai_src, 0, G_SAI2, M_SAI3),
1952 KCLK(SAI4_K, "sai4_k", sai_src, 0, G_SAI2, M_SAI4),
1953 KCLK(ADC12_K, "adc12_k", adc12_src, 0, G_ADC12, M_ADC12),
1954 KCLK(DSI_K, "dsi_k", dsi_src, 0, G_DSI, M_DSI),
1955 KCLK(ADFSDM_K, "adfsdm_k", sai_src, 0, G_ADFSDM, M_SAI1),
1956 KCLK(USBO_K, "usbo_k", usbo_src, 0, G_USBO, M_USBO),
1957 KCLK(ETHCK_K, "ethck_k", eth_src, 0, G_ETHCK, M_ETHCK),
1958
1959 /* Particulary Kernel Clocks (no mux or no gate) */
1960 MGATE_MP1(DFSDM_K, "dfsdm_k", "ck_mcu", 0, G_DFSDM),
1961 MGATE_MP1(DSI_PX, "dsi_px", "pll4_q", CLK_SET_RATE_PARENT, G_DSI),
1962 MGATE_MP1(LTDC_PX, "ltdc_px", "pll4_q", CLK_SET_RATE_PARENT, G_LTDC),
1963 MGATE_MP1(GPU_K, "gpu_k", "pll2_q", 0, G_GPU),
1964 MGATE_MP1(DAC12_K, "dac12_k", "ck_lsi", 0, G_DAC12),
1965
1966 COMPOSITE(ETHPTP_K, "ethptp_k", eth_src, CLK_OPS_PARENT_ENABLE,
1967 _NO_GATE,
1968 _MMUX(M_ETHCK),
1969 _DIV(RCC_ETHCKSELR, 4, 4, CLK_DIVIDER_ALLOW_ZERO, NULL)),
1970
1971 /* RTC clock */
1972 DIV(NO_ID, "ck_hse_rtc", "ck_hse", 0, RCC_RTCDIVR, 0, 7,
1973 CLK_DIVIDER_ALLOW_ZERO),
1974
1975 COMPOSITE(RTC, "ck_rtc", rtc_src, CLK_OPS_PARENT_ENABLE |
1976 CLK_SET_RATE_PARENT,
1977 _GATE(RCC_BDCR, 20, 0),
1978 _MUX(RCC_BDCR, 16, 2, 0),
1979 _NO_DIV),
1980
1981 /* MCO clocks */
1982 COMPOSITE(CK_MCO1, "ck_mco1", mco1_src, CLK_OPS_PARENT_ENABLE |
1983 CLK_SET_RATE_NO_REPARENT,
1984 _GATE(RCC_MCO1CFGR, 12, 0),
1985 _MUX(RCC_MCO1CFGR, 0, 3, 0),
1986 _DIV(RCC_MCO1CFGR, 4, 4, 0, NULL)),
1987
1988 COMPOSITE(CK_MCO2, "ck_mco2", mco2_src, CLK_OPS_PARENT_ENABLE |
1989 CLK_SET_RATE_NO_REPARENT,
1990 _GATE(RCC_MCO2CFGR, 12, 0),
1991 _MUX(RCC_MCO2CFGR, 0, 3, 0),
1992 _DIV(RCC_MCO2CFGR, 4, 4, 0, NULL)),
1993
1994 /* Debug clocks */
1995 FIXED_FACTOR(NO_ID, "ck_axi_div2", "ck_axi", 0, 1, 2),
1996
1997 GATE(DBG, "ck_apb_dbg", "ck_axi_div2", 0, RCC_DBGCFGR, 8, 0),
1998
1999 GATE(CK_DBG, "ck_sys_dbg", "ck_axi", 0, RCC_DBGCFGR, 8, 0),
2000
2001 COMPOSITE(CK_TRACE, "ck_trace", ck_trace_src, CLK_OPS_PARENT_ENABLE,
2002 _GATE(RCC_DBGCFGR, 9, 0),
2003 _NO_MUX,
2004 _DIV(RCC_DBGCFGR, 0, 3, 0, ck_trace_div_table)),
2005};
2006
2007struct stm32_clock_match_data {
2008 const struct clock_config *cfg;
2009 unsigned int num;
2010 unsigned int maxbinding;
2011};
2012
2013static struct stm32_clock_match_data stm32mp1_data = {
2014 .cfg = stm32mp1_clock_cfg,
2015 .num = ARRAY_SIZE(stm32mp1_clock_cfg),
2016 .maxbinding = STM32MP1_LAST_CLK,
2017};
2018
2019static const struct of_device_id stm32mp1_match_data[] = {
2020 {
2021 .compatible = "st,stm32mp1-rcc",
2022 .data = &stm32mp1_data,
2023 },
2024 { }
2025};
2026
2027static int stm32_register_hw_clk(struct device *dev,
2028 struct clk_hw_onecell_data *clk_data,
2029 void __iomem *base, spinlock_t *lock,
2030 const struct clock_config *cfg)
2031{
2032 static struct clk_hw **hws;
2033 struct clk_hw *hw = ERR_PTR(-ENOENT);
2034
2035 hws = clk_data->hws;
2036
2037 if (cfg->func)
2038 hw = (*cfg->func)(dev, clk_data, base, lock, cfg);
2039
2040 if (IS_ERR(hw)) {
2041 pr_err("Unable to register %s\n", cfg->name);
2042 return PTR_ERR(hw);
2043 }
2044
2045 if (cfg->id != NO_ID)
2046 hws[cfg->id] = hw;
2047
2048 return 0;
2049}
2050
2051static int stm32_rcc_init(struct device_node *np,
2052 void __iomem *base,
2053 const struct of_device_id *match_data)
2054{
2055 struct clk_hw_onecell_data *clk_data;
2056 struct clk_hw **hws;
2057 const struct of_device_id *match;
2058 const struct stm32_clock_match_data *data;
2059 int err, n, max_binding;
2060
2061 match = of_match_node(match_data, np);
2062 if (!match) {
2063 pr_err("%s: match data not found\n", __func__);
2064 return -ENODEV;
2065 }
2066
2067 data = match->data;
2068
2069 max_binding = data->maxbinding;
2070
2071 clk_data = kzalloc(sizeof(*clk_data) +
2072 sizeof(*clk_data->hws) * max_binding,
2073 GFP_KERNEL);
2074 if (!clk_data)
2075 return -ENOMEM;
2076
2077 clk_data->num = max_binding;
2078
2079 hws = clk_data->hws;
2080
2081 for (n = 0; n < max_binding; n++)
2082 hws[n] = ERR_PTR(-ENOENT);
2083
2084 for (n = 0; n < data->num; n++) {
2085 err = stm32_register_hw_clk(NULL, clk_data, base, &rlock,
2086 &data->cfg[n]);
2087 if (err) {
2088 pr_err("%s: can't register %s\n", __func__,
2089 data->cfg[n].name);
2090
2091 kfree(clk_data);
2092
2093 return err;
2094 }
2095 }
2096
2097 return of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data);
2098}
2099
2100static void stm32mp1_rcc_init(struct device_node *np)
2101{
2102 void __iomem *base;
2103
2104 base = of_iomap(np, 0);
2105 if (!base) {
2106 pr_err("%s: unable to map resource", np->name);
2107 of_node_put(np);
2108 return;
2109 }
2110
2111 if (stm32_rcc_init(np, base, stm32mp1_match_data)) {
2112 iounmap(base);
2113 of_node_put(np);
2114 }
2115}
2116
2117CLK_OF_DECLARE_DRIVER(stm32mp1_rcc, "st,stm32mp1-rcc", stm32mp1_rcc_init);
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 0f686a9dac3e..ea67ac81c6f9 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -1125,8 +1125,10 @@ static int clk_core_round_rate_nolock(struct clk_core *core,
1125{ 1125{
1126 lockdep_assert_held(&prepare_lock); 1126 lockdep_assert_held(&prepare_lock);
1127 1127
1128 if (!core) 1128 if (!core) {
1129 req->rate = 0;
1129 return 0; 1130 return 0;
1131 }
1130 1132
1131 clk_core_init_rate_req(core, req); 1133 clk_core_init_rate_req(core, req);
1132 1134
@@ -2309,8 +2311,11 @@ static int clk_core_set_phase_nolock(struct clk_core *core, int degrees)
2309 2311
2310 trace_clk_set_phase(core, degrees); 2312 trace_clk_set_phase(core, degrees);
2311 2313
2312 if (core->ops->set_phase) 2314 if (core->ops->set_phase) {
2313 ret = core->ops->set_phase(core->hw, degrees); 2315 ret = core->ops->set_phase(core->hw, degrees);
2316 if (!ret)
2317 core->phase = degrees;
2318 }
2314 2319
2315 trace_clk_set_phase_complete(core, degrees); 2320 trace_clk_set_phase_complete(core, degrees);
2316 2321
@@ -2370,6 +2375,9 @@ static int clk_core_get_phase(struct clk_core *core)
2370 int ret; 2375 int ret;
2371 2376
2372 clk_prepare_lock(); 2377 clk_prepare_lock();
2378 /* Always try to update cached phase if possible */
2379 if (core->ops->get_phase)
2380 core->phase = core->ops->get_phase(core->hw);
2373 ret = core->phase; 2381 ret = core->phase;
2374 clk_prepare_unlock(); 2382 clk_prepare_unlock();
2375 2383
@@ -2486,19 +2494,7 @@ static int clk_summary_show(struct seq_file *s, void *data)
2486 2494
2487 return 0; 2495 return 0;
2488} 2496}
2489 2497DEFINE_SHOW_ATTRIBUTE(clk_summary);
2490
2491static int clk_summary_open(struct inode *inode, struct file *file)
2492{
2493 return single_open(file, clk_summary_show, inode->i_private);
2494}
2495
2496static const struct file_operations clk_summary_fops = {
2497 .open = clk_summary_open,
2498 .read = seq_read,
2499 .llseek = seq_lseek,
2500 .release = single_release,
2501};
2502 2498
2503static void clk_dump_one(struct seq_file *s, struct clk_core *c, int level) 2499static void clk_dump_one(struct seq_file *s, struct clk_core *c, int level)
2504{ 2500{
@@ -2532,7 +2528,7 @@ static void clk_dump_subtree(struct seq_file *s, struct clk_core *c, int level)
2532 seq_putc(s, '}'); 2528 seq_putc(s, '}');
2533} 2529}
2534 2530
2535static int clk_dump(struct seq_file *s, void *data) 2531static int clk_dump_show(struct seq_file *s, void *data)
2536{ 2532{
2537 struct clk_core *c; 2533 struct clk_core *c;
2538 bool first_node = true; 2534 bool first_node = true;
@@ -2555,19 +2551,7 @@ static int clk_dump(struct seq_file *s, void *data)
2555 seq_puts(s, "}\n"); 2551 seq_puts(s, "}\n");
2556 return 0; 2552 return 0;
2557} 2553}
2558 2554DEFINE_SHOW_ATTRIBUTE(clk_dump);
2559
2560static int clk_dump_open(struct inode *inode, struct file *file)
2561{
2562 return single_open(file, clk_dump, inode->i_private);
2563}
2564
2565static const struct file_operations clk_dump_fops = {
2566 .open = clk_dump_open,
2567 .read = seq_read,
2568 .llseek = seq_lseek,
2569 .release = single_release,
2570};
2571 2555
2572static const struct { 2556static const struct {
2573 unsigned long flag; 2557 unsigned long flag;
@@ -2589,7 +2573,7 @@ static const struct {
2589#undef ENTRY 2573#undef ENTRY
2590}; 2574};
2591 2575
2592static int clk_flags_dump(struct seq_file *s, void *data) 2576static int clk_flags_show(struct seq_file *s, void *data)
2593{ 2577{
2594 struct clk_core *core = s->private; 2578 struct clk_core *core = s->private;
2595 unsigned long flags = core->flags; 2579 unsigned long flags = core->flags;
@@ -2608,20 +2592,9 @@ static int clk_flags_dump(struct seq_file *s, void *data)
2608 2592
2609 return 0; 2593 return 0;
2610} 2594}
2595DEFINE_SHOW_ATTRIBUTE(clk_flags);
2611 2596
2612static int clk_flags_open(struct inode *inode, struct file *file) 2597static int possible_parents_show(struct seq_file *s, void *data)
2613{
2614 return single_open(file, clk_flags_dump, inode->i_private);
2615}
2616
2617static const struct file_operations clk_flags_fops = {
2618 .open = clk_flags_open,
2619 .read = seq_read,
2620 .llseek = seq_lseek,
2621 .release = single_release,
2622};
2623
2624static int possible_parents_dump(struct seq_file *s, void *data)
2625{ 2598{
2626 struct clk_core *core = s->private; 2599 struct clk_core *core = s->private;
2627 int i; 2600 int i;
@@ -2633,18 +2606,7 @@ static int possible_parents_dump(struct seq_file *s, void *data)
2633 2606
2634 return 0; 2607 return 0;
2635} 2608}
2636 2609DEFINE_SHOW_ATTRIBUTE(possible_parents);
2637static int possible_parents_open(struct inode *inode, struct file *file)
2638{
2639 return single_open(file, possible_parents_dump, inode->i_private);
2640}
2641
2642static const struct file_operations possible_parents_fops = {
2643 .open = possible_parents_open,
2644 .read = seq_read,
2645 .llseek = seq_lseek,
2646 .release = single_release,
2647};
2648 2610
2649static int clk_debug_create_one(struct clk_core *core, struct dentry *pdentry) 2611static int clk_debug_create_one(struct clk_core *core, struct dentry *pdentry)
2650{ 2612{
@@ -2928,6 +2890,17 @@ static int __clk_core_init(struct clk_core *core)
2928 } 2890 }
2929 2891
2930 /* 2892 /*
2893 * optional platform-specific magic
2894 *
2895 * The .init callback is not used by any of the basic clock types, but
2896 * exists for weird hardware that must perform initialization magic.
2897 * Please consider other ways of solving initialization problems before
2898 * using this callback, as its use is discouraged.
2899 */
2900 if (core->ops->init)
2901 core->ops->init(core->hw);
2902
2903 /*
2931 * Set clk's accuracy. The preferred method is to use 2904 * Set clk's accuracy. The preferred method is to use
2932 * .recalc_accuracy. For simple clocks and lazy developers the default 2905 * .recalc_accuracy. For simple clocks and lazy developers the default
2933 * fallback is to use the parent's accuracy. If a clock doesn't have a 2906 * fallback is to use the parent's accuracy. If a clock doesn't have a
@@ -2968,48 +2941,42 @@ static int __clk_core_init(struct clk_core *core)
2968 core->rate = core->req_rate = rate; 2941 core->rate = core->req_rate = rate;
2969 2942
2970 /* 2943 /*
2944 * Enable CLK_IS_CRITICAL clocks so newly added critical clocks
2945 * don't get accidentally disabled when walking the orphan tree and
2946 * reparenting clocks
2947 */
2948 if (core->flags & CLK_IS_CRITICAL) {
2949 unsigned long flags;
2950
2951 clk_core_prepare(core);
2952
2953 flags = clk_enable_lock();
2954 clk_core_enable(core);
2955 clk_enable_unlock(flags);
2956 }
2957
2958 /*
2971 * walk the list of orphan clocks and reparent any that newly finds a 2959 * walk the list of orphan clocks and reparent any that newly finds a
2972 * parent. 2960 * parent.
2973 */ 2961 */
2974 hlist_for_each_entry_safe(orphan, tmp2, &clk_orphan_list, child_node) { 2962 hlist_for_each_entry_safe(orphan, tmp2, &clk_orphan_list, child_node) {
2975 struct clk_core *parent = __clk_init_parent(orphan); 2963 struct clk_core *parent = __clk_init_parent(orphan);
2976 unsigned long flags;
2977 2964
2978 /* 2965 /*
2979 * we could call __clk_set_parent, but that would result in a 2966 * We need to use __clk_set_parent_before() and _after() to
2980 * redundant call to the .set_rate op, if it exists 2967 * to properly migrate any prepare/enable count of the orphan
2968 * clock. This is important for CLK_IS_CRITICAL clocks, which
2969 * are enabled during init but might not have a parent yet.
2981 */ 2970 */
2982 if (parent) { 2971 if (parent) {
2983 /* update the clk tree topology */ 2972 /* update the clk tree topology */
2984 flags = clk_enable_lock(); 2973 __clk_set_parent_before(orphan, parent);
2985 clk_reparent(orphan, parent); 2974 __clk_set_parent_after(orphan, parent, NULL);
2986 clk_enable_unlock(flags);
2987 __clk_recalc_accuracies(orphan); 2975 __clk_recalc_accuracies(orphan);
2988 __clk_recalc_rates(orphan, 0); 2976 __clk_recalc_rates(orphan, 0);
2989 } 2977 }
2990 } 2978 }
2991 2979
2992 /*
2993 * optional platform-specific magic
2994 *
2995 * The .init callback is not used by any of the basic clock types, but
2996 * exists for weird hardware that must perform initialization magic.
2997 * Please consider other ways of solving initialization problems before
2998 * using this callback, as its use is discouraged.
2999 */
3000 if (core->ops->init)
3001 core->ops->init(core->hw);
3002
3003 if (core->flags & CLK_IS_CRITICAL) {
3004 unsigned long flags;
3005
3006 clk_core_prepare(core);
3007
3008 flags = clk_enable_lock();
3009 clk_core_enable(core);
3010 clk_enable_unlock(flags);
3011 }
3012
3013 kref_init(&core->ref); 2980 kref_init(&core->ref);
3014out: 2981out:
3015 clk_pm_runtime_put(core); 2982 clk_pm_runtime_put(core);
diff --git a/drivers/clk/keystone/sci-clk.c b/drivers/clk/keystone/sci-clk.c
index 9cdf9d5050ac..4cb70bed89a9 100644
--- a/drivers/clk/keystone/sci-clk.c
+++ b/drivers/clk/keystone/sci-clk.c
@@ -29,21 +29,10 @@
29#define SCI_CLK_INPUT_TERMINATION BIT(2) 29#define SCI_CLK_INPUT_TERMINATION BIT(2)
30 30
31/** 31/**
32 * struct sci_clk_data - TI SCI clock data
33 * @dev: device index
34 * @num_clks: number of clocks for this device
35 */
36struct sci_clk_data {
37 u16 dev;
38 u16 num_clks;
39};
40
41/**
42 * struct sci_clk_provider - TI SCI clock provider representation 32 * struct sci_clk_provider - TI SCI clock provider representation
43 * @sci: Handle to the System Control Interface protocol handler 33 * @sci: Handle to the System Control Interface protocol handler
44 * @ops: Pointer to the SCI ops to be used by the clocks 34 * @ops: Pointer to the SCI ops to be used by the clocks
45 * @dev: Device pointer for the clock provider 35 * @dev: Device pointer for the clock provider
46 * @clk_data: Clock data
47 * @clocks: Clocks array for this device 36 * @clocks: Clocks array for this device
48 * @num_clocks: Total number of clocks for this provider 37 * @num_clocks: Total number of clocks for this provider
49 */ 38 */
@@ -51,8 +40,7 @@ struct sci_clk_provider {
51 const struct ti_sci_handle *sci; 40 const struct ti_sci_handle *sci;
52 const struct ti_sci_clk_ops *ops; 41 const struct ti_sci_clk_ops *ops;
53 struct device *dev; 42 struct device *dev;
54 const struct sci_clk_data *clk_data; 43 struct sci_clk **clocks;
55 struct clk_hw **clocks;
56 int num_clocks; 44 int num_clocks;
57}; 45};
58 46
@@ -61,6 +49,7 @@ struct sci_clk_provider {
61 * @hw: Hardware clock cookie for common clock framework 49 * @hw: Hardware clock cookie for common clock framework
62 * @dev_id: Device index 50 * @dev_id: Device index
63 * @clk_id: Clock index 51 * @clk_id: Clock index
52 * @num_parents: Number of parents for this clock
64 * @provider: Master clock provider 53 * @provider: Master clock provider
65 * @flags: Flags for the clock 54 * @flags: Flags for the clock
66 */ 55 */
@@ -68,6 +57,7 @@ struct sci_clk {
68 struct clk_hw hw; 57 struct clk_hw hw;
69 u16 dev_id; 58 u16 dev_id;
70 u8 clk_id; 59 u8 clk_id;
60 u8 num_parents;
71 struct sci_clk_provider *provider; 61 struct sci_clk_provider *provider;
72 u8 flags; 62 u8 flags;
73}; 63};
@@ -273,38 +263,22 @@ static const struct clk_ops sci_clk_ops = {
273/** 263/**
274 * _sci_clk_get - Gets a handle for an SCI clock 264 * _sci_clk_get - Gets a handle for an SCI clock
275 * @provider: Handle to SCI clock provider 265 * @provider: Handle to SCI clock provider
276 * @dev_id: device ID for the clock to register 266 * @sci_clk: Handle to the SCI clock to populate
277 * @clk_id: clock ID for the clock to register
278 * 267 *
279 * Gets a handle to an existing TI SCI hw clock, or builds a new clock 268 * Gets a handle to an existing TI SCI hw clock, or builds a new clock
280 * entry and registers it with the common clock framework. Called from 269 * entry and registers it with the common clock framework. Called from
281 * the common clock framework, when a corresponding of_clk_get call is 270 * the common clock framework, when a corresponding of_clk_get call is
282 * executed, or recursively from itself when parsing parent clocks. 271 * executed, or recursively from itself when parsing parent clocks.
283 * Returns a pointer to the hw clock struct, or ERR_PTR value in failure. 272 * Returns 0 on success, negative error code on failure.
284 */ 273 */
285static struct clk_hw *_sci_clk_build(struct sci_clk_provider *provider, 274static int _sci_clk_build(struct sci_clk_provider *provider,
286 u16 dev_id, u8 clk_id) 275 struct sci_clk *sci_clk)
287{ 276{
288 struct clk_init_data init = { NULL }; 277 struct clk_init_data init = { NULL };
289 struct sci_clk *sci_clk = NULL;
290 char *name = NULL; 278 char *name = NULL;
291 char **parent_names = NULL; 279 char **parent_names = NULL;
292 int i; 280 int i;
293 int ret; 281 int ret = 0;
294
295 sci_clk = devm_kzalloc(provider->dev, sizeof(*sci_clk), GFP_KERNEL);
296 if (!sci_clk)
297 return ERR_PTR(-ENOMEM);
298
299 sci_clk->dev_id = dev_id;
300 sci_clk->clk_id = clk_id;
301 sci_clk->provider = provider;
302
303 ret = provider->ops->get_num_parents(provider->sci, dev_id,
304 clk_id,
305 &init.num_parents);
306 if (ret)
307 goto err;
308 282
309 name = kasprintf(GFP_KERNEL, "%s:%d:%d", dev_name(provider->dev), 283 name = kasprintf(GFP_KERNEL, "%s:%d:%d", dev_name(provider->dev),
310 sci_clk->dev_id, sci_clk->clk_id); 284 sci_clk->dev_id, sci_clk->clk_id);
@@ -317,11 +291,11 @@ static struct clk_hw *_sci_clk_build(struct sci_clk_provider *provider,
317 * to have mux functionality. Otherwise it is going to act as a root 291 * to have mux functionality. Otherwise it is going to act as a root
318 * clock. 292 * clock.
319 */ 293 */
320 if (init.num_parents < 2) 294 if (sci_clk->num_parents < 2)
321 init.num_parents = 0; 295 sci_clk->num_parents = 0;
322 296
323 if (init.num_parents) { 297 if (sci_clk->num_parents) {
324 parent_names = kcalloc(init.num_parents, sizeof(char *), 298 parent_names = kcalloc(sci_clk->num_parents, sizeof(char *),
325 GFP_KERNEL); 299 GFP_KERNEL);
326 300
327 if (!parent_names) { 301 if (!parent_names) {
@@ -329,7 +303,7 @@ static struct clk_hw *_sci_clk_build(struct sci_clk_provider *provider,
329 goto err; 303 goto err;
330 } 304 }
331 305
332 for (i = 0; i < init.num_parents; i++) { 306 for (i = 0; i < sci_clk->num_parents; i++) {
333 char *parent_name; 307 char *parent_name;
334 308
335 parent_name = kasprintf(GFP_KERNEL, "%s:%d:%d", 309 parent_name = kasprintf(GFP_KERNEL, "%s:%d:%d",
@@ -346,6 +320,7 @@ static struct clk_hw *_sci_clk_build(struct sci_clk_provider *provider,
346 } 320 }
347 321
348 init.ops = &sci_clk_ops; 322 init.ops = &sci_clk_ops;
323 init.num_parents = sci_clk->num_parents;
349 sci_clk->hw.init = &init; 324 sci_clk->hw.init = &init;
350 325
351 ret = devm_clk_hw_register(provider->dev, &sci_clk->hw); 326 ret = devm_clk_hw_register(provider->dev, &sci_clk->hw);
@@ -354,7 +329,7 @@ static struct clk_hw *_sci_clk_build(struct sci_clk_provider *provider,
354 329
355err: 330err:
356 if (parent_names) { 331 if (parent_names) {
357 for (i = 0; i < init.num_parents; i++) 332 for (i = 0; i < sci_clk->num_parents; i++)
358 kfree(parent_names[i]); 333 kfree(parent_names[i]);
359 334
360 kfree(parent_names); 335 kfree(parent_names);
@@ -362,10 +337,7 @@ err:
362 337
363 kfree(name); 338 kfree(name);
364 339
365 if (ret) 340 return ret;
366 return ERR_PTR(ret);
367
368 return &sci_clk->hw;
369} 341}
370 342
371static int _cmp_sci_clk(const void *a, const void *b) 343static int _cmp_sci_clk(const void *a, const void *b)
@@ -414,253 +386,20 @@ static struct clk_hw *sci_clk_get(struct of_phandle_args *clkspec, void *data)
414 386
415static int ti_sci_init_clocks(struct sci_clk_provider *p) 387static int ti_sci_init_clocks(struct sci_clk_provider *p)
416{ 388{
417 const struct sci_clk_data *data = p->clk_data;
418 struct clk_hw *hw;
419 int i; 389 int i;
420 int num_clks = 0; 390 int ret;
421
422 while (data->num_clks) {
423 num_clks += data->num_clks;
424 data++;
425 }
426
427 p->num_clocks = num_clks;
428
429 p->clocks = devm_kcalloc(p->dev, num_clks, sizeof(struct sci_clk),
430 GFP_KERNEL);
431 if (!p->clocks)
432 return -ENOMEM;
433
434 num_clks = 0;
435
436 data = p->clk_data;
437
438 while (data->num_clks) {
439 for (i = 0; i < data->num_clks; i++) {
440 hw = _sci_clk_build(p, data->dev, i);
441 if (!IS_ERR(hw)) {
442 p->clocks[num_clks++] = hw;
443 continue;
444 }
445
446 /* Skip any holes in the clock lists */
447 if (PTR_ERR(hw) == -ENODEV)
448 continue;
449 391
450 return PTR_ERR(hw); 392 for (i = 0; i < p->num_clocks; i++) {
451 } 393 ret = _sci_clk_build(p, p->clocks[i]);
452 data++; 394 if (ret)
395 return ret;
453 } 396 }
454 397
455 return 0; 398 return 0;
456} 399}
457 400
458static const struct sci_clk_data k2g_clk_data[] = {
459 /* pmmc */
460 { .dev = 0x0, .num_clks = 4 },
461
462 /* mlb0 */
463 { .dev = 0x1, .num_clks = 5 },
464
465 /* dss0 */
466 { .dev = 0x2, .num_clks = 2 },
467
468 /* mcbsp0 */
469 { .dev = 0x3, .num_clks = 8 },
470
471 /* mcasp0 */
472 { .dev = 0x4, .num_clks = 8 },
473
474 /* mcasp1 */
475 { .dev = 0x5, .num_clks = 8 },
476
477 /* mcasp2 */
478 { .dev = 0x6, .num_clks = 8 },
479
480 /* dcan0 */
481 { .dev = 0x8, .num_clks = 2 },
482
483 /* dcan1 */
484 { .dev = 0x9, .num_clks = 2 },
485
486 /* emif0 */
487 { .dev = 0xa, .num_clks = 6 },
488
489 /* mmchs0 */
490 { .dev = 0xb, .num_clks = 3 },
491
492 /* mmchs1 */
493 { .dev = 0xc, .num_clks = 3 },
494
495 /* gpmc0 */
496 { .dev = 0xd, .num_clks = 1 },
497
498 /* elm0 */
499 { .dev = 0xe, .num_clks = 1 },
500
501 /* spi0 */
502 { .dev = 0x10, .num_clks = 1 },
503
504 /* spi1 */
505 { .dev = 0x11, .num_clks = 1 },
506
507 /* spi2 */
508 { .dev = 0x12, .num_clks = 1 },
509
510 /* spi3 */
511 { .dev = 0x13, .num_clks = 1 },
512
513 /* icss0 */
514 { .dev = 0x14, .num_clks = 6 },
515
516 /* icss1 */
517 { .dev = 0x15, .num_clks = 6 },
518
519 /* usb0 */
520 { .dev = 0x16, .num_clks = 7 },
521
522 /* usb1 */
523 { .dev = 0x17, .num_clks = 7 },
524
525 /* nss0 */
526 { .dev = 0x18, .num_clks = 14 },
527
528 /* pcie0 */
529 { .dev = 0x19, .num_clks = 1 },
530
531 /* gpio0 */
532 { .dev = 0x1b, .num_clks = 1 },
533
534 /* gpio1 */
535 { .dev = 0x1c, .num_clks = 1 },
536
537 /* timer64_0 */
538 { .dev = 0x1d, .num_clks = 9 },
539
540 /* timer64_1 */
541 { .dev = 0x1e, .num_clks = 9 },
542
543 /* timer64_2 */
544 { .dev = 0x1f, .num_clks = 9 },
545
546 /* timer64_3 */
547 { .dev = 0x20, .num_clks = 9 },
548
549 /* timer64_4 */
550 { .dev = 0x21, .num_clks = 9 },
551
552 /* timer64_5 */
553 { .dev = 0x22, .num_clks = 9 },
554
555 /* timer64_6 */
556 { .dev = 0x23, .num_clks = 9 },
557
558 /* msgmgr0 */
559 { .dev = 0x25, .num_clks = 1 },
560
561 /* bootcfg0 */
562 { .dev = 0x26, .num_clks = 1 },
563
564 /* arm_bootrom0 */
565 { .dev = 0x27, .num_clks = 1 },
566
567 /* dsp_bootrom0 */
568 { .dev = 0x29, .num_clks = 1 },
569
570 /* debugss0 */
571 { .dev = 0x2b, .num_clks = 8 },
572
573 /* uart0 */
574 { .dev = 0x2c, .num_clks = 1 },
575
576 /* uart1 */
577 { .dev = 0x2d, .num_clks = 1 },
578
579 /* uart2 */
580 { .dev = 0x2e, .num_clks = 1 },
581
582 /* ehrpwm0 */
583 { .dev = 0x2f, .num_clks = 1 },
584
585 /* ehrpwm1 */
586 { .dev = 0x30, .num_clks = 1 },
587
588 /* ehrpwm2 */
589 { .dev = 0x31, .num_clks = 1 },
590
591 /* ehrpwm3 */
592 { .dev = 0x32, .num_clks = 1 },
593
594 /* ehrpwm4 */
595 { .dev = 0x33, .num_clks = 1 },
596
597 /* ehrpwm5 */
598 { .dev = 0x34, .num_clks = 1 },
599
600 /* eqep0 */
601 { .dev = 0x35, .num_clks = 1 },
602
603 /* eqep1 */
604 { .dev = 0x36, .num_clks = 1 },
605
606 /* eqep2 */
607 { .dev = 0x37, .num_clks = 1 },
608
609 /* ecap0 */
610 { .dev = 0x38, .num_clks = 1 },
611
612 /* ecap1 */
613 { .dev = 0x39, .num_clks = 1 },
614
615 /* i2c0 */
616 { .dev = 0x3a, .num_clks = 1 },
617
618 /* i2c1 */
619 { .dev = 0x3b, .num_clks = 1 },
620
621 /* i2c2 */
622 { .dev = 0x3c, .num_clks = 1 },
623
624 /* edma0 */
625 { .dev = 0x3f, .num_clks = 2 },
626
627 /* semaphore0 */
628 { .dev = 0x40, .num_clks = 1 },
629
630 /* intc0 */
631 { .dev = 0x41, .num_clks = 1 },
632
633 /* gic0 */
634 { .dev = 0x42, .num_clks = 1 },
635
636 /* qspi0 */
637 { .dev = 0x43, .num_clks = 5 },
638
639 /* arm_64b_counter0 */
640 { .dev = 0x44, .num_clks = 2 },
641
642 /* tetris0 */
643 { .dev = 0x45, .num_clks = 2 },
644
645 /* cgem0 */
646 { .dev = 0x46, .num_clks = 2 },
647
648 /* msmc0 */
649 { .dev = 0x47, .num_clks = 1 },
650
651 /* cbass0 */
652 { .dev = 0x49, .num_clks = 1 },
653
654 /* board0 */
655 { .dev = 0x4c, .num_clks = 36 },
656
657 /* edma1 */
658 { .dev = 0x4f, .num_clks = 2 },
659 { .num_clks = 0 },
660};
661
662static const struct of_device_id ti_sci_clk_of_match[] = { 401static const struct of_device_id ti_sci_clk_of_match[] = {
663 { .compatible = "ti,k2g-sci-clk", .data = &k2g_clk_data }, 402 { .compatible = "ti,k2g-sci-clk" },
664 { /* Sentinel */ }, 403 { /* Sentinel */ },
665}; 404};
666MODULE_DEVICE_TABLE(of, ti_sci_clk_of_match); 405MODULE_DEVICE_TABLE(of, ti_sci_clk_of_match);
@@ -681,12 +420,16 @@ static int ti_sci_clk_probe(struct platform_device *pdev)
681 struct device_node *np = dev->of_node; 420 struct device_node *np = dev->of_node;
682 struct sci_clk_provider *provider; 421 struct sci_clk_provider *provider;
683 const struct ti_sci_handle *handle; 422 const struct ti_sci_handle *handle;
684 const struct sci_clk_data *data;
685 int ret; 423 int ret;
686 424 int num_clks = 0;
687 data = of_device_get_match_data(dev); 425 struct sci_clk **clks = NULL;
688 if (!data) 426 struct sci_clk **tmp_clks;
689 return -EINVAL; 427 struct sci_clk *sci_clk;
428 int max_clks = 0;
429 int clk_id = 0;
430 int dev_id = 0;
431 u8 num_parents;
432 int gap_size = 0;
690 433
691 handle = devm_ti_sci_get_handle(dev); 434 handle = devm_ti_sci_get_handle(dev);
692 if (IS_ERR(handle)) 435 if (IS_ERR(handle))
@@ -696,12 +439,69 @@ static int ti_sci_clk_probe(struct platform_device *pdev)
696 if (!provider) 439 if (!provider)
697 return -ENOMEM; 440 return -ENOMEM;
698 441
699 provider->clk_data = data;
700
701 provider->sci = handle; 442 provider->sci = handle;
702 provider->ops = &handle->ops.clk_ops; 443 provider->ops = &handle->ops.clk_ops;
703 provider->dev = dev; 444 provider->dev = dev;
704 445
446 while (1) {
447 ret = provider->ops->get_num_parents(provider->sci, dev_id,
448 clk_id, &num_parents);
449 if (ret) {
450 gap_size++;
451 if (!clk_id) {
452 if (gap_size >= 5)
453 break;
454 dev_id++;
455 } else {
456 if (gap_size >= 2) {
457 dev_id++;
458 clk_id = 0;
459 gap_size = 0;
460 } else {
461 clk_id++;
462 }
463 }
464 continue;
465 }
466
467 gap_size = 0;
468
469 if (num_clks == max_clks) {
470 tmp_clks = devm_kmalloc_array(dev, max_clks + 64,
471 sizeof(sci_clk),
472 GFP_KERNEL);
473 memcpy(tmp_clks, clks, max_clks * sizeof(sci_clk));
474 if (max_clks)
475 devm_kfree(dev, clks);
476 max_clks += 64;
477 clks = tmp_clks;
478 }
479
480 sci_clk = devm_kzalloc(dev, sizeof(*sci_clk), GFP_KERNEL);
481 if (!sci_clk)
482 return -ENOMEM;
483 sci_clk->dev_id = dev_id;
484 sci_clk->clk_id = clk_id;
485 sci_clk->provider = provider;
486 sci_clk->num_parents = num_parents;
487
488 clks[num_clks] = sci_clk;
489
490 clk_id++;
491 num_clks++;
492 }
493
494 provider->clocks = devm_kmalloc_array(dev, num_clks, sizeof(sci_clk),
495 GFP_KERNEL);
496 if (!provider->clocks)
497 return -ENOMEM;
498
499 memcpy(provider->clocks, clks, num_clks * sizeof(sci_clk));
500
501 provider->num_clocks = num_clks;
502
503 devm_kfree(dev, clks);
504
705 ret = ti_sci_init_clocks(provider); 505 ret = ti_sci_init_clocks(provider);
706 if (ret) { 506 if (ret) {
707 pr_err("ti-sci-init-clocks failed.\n"); 507 pr_err("ti-sci-init-clocks failed.\n");
diff --git a/drivers/clk/mediatek/clk-mt2712.c b/drivers/clk/mediatek/clk-mt2712.c
index 498d13799388..991d4093726e 100644
--- a/drivers/clk/mediatek/clk-mt2712.c
+++ b/drivers/clk/mediatek/clk-mt2712.c
@@ -221,6 +221,8 @@ static const struct mtk_fixed_factor top_divs[] = {
221 4), 221 4),
222 FACTOR(CLK_TOP_D2A_ULCLK_6P5M, "d2a_ulclk_6p5m", "clk26m", 1, 222 FACTOR(CLK_TOP_D2A_ULCLK_6P5M, "d2a_ulclk_6p5m", "clk26m", 1,
223 4), 223 4),
224 FACTOR(CLK_TOP_APLL1_D3, "apll1_d3", "apll1_ck", 1,
225 3),
224}; 226};
225 227
226static const char * const axi_parents[] = { 228static const char * const axi_parents[] = {
@@ -625,7 +627,7 @@ static const char * const ether_125m_parents[] = {
625static const char * const ether_50m_parents[] = { 627static const char * const ether_50m_parents[] = {
626 "clk26m", 628 "clk26m",
627 "etherpll_50m", 629 "etherpll_50m",
628 "univpll_d26", 630 "apll1_d3",
629 "univpll3_d4" 631 "univpll3_d4"
630}; 632};
631 633
@@ -686,7 +688,7 @@ static const char * const i2c_parents[] = {
686 688
687static const char * const msdc0p_aes_parents[] = { 689static const char * const msdc0p_aes_parents[] = {
688 "clk26m", 690 "clk26m",
689 "msdcpll_ck", 691 "syspll_d2",
690 "univpll_d3", 692 "univpll_d3",
691 "vcodecpll_ck" 693 "vcodecpll_ck"
692}; 694};
@@ -719,6 +721,17 @@ static const char * const aud_apll2_parents[] = {
719 "clkaud_ext_i_2" 721 "clkaud_ext_i_2"
720}; 722};
721 723
724static const char * const apll1_ref_parents[] = {
725 "clkaud_ext_i_2",
726 "clkaud_ext_i_1",
727 "clki2si0_mck_i",
728 "clki2si1_mck_i",
729 "clki2si2_mck_i",
730 "clktdmin_mclk_i",
731 "clki2si2_mck_i",
732 "clktdmin_mclk_i"
733};
734
722static const char * const audull_vtx_parents[] = { 735static const char * const audull_vtx_parents[] = {
723 "d2a_ulclk_6p5m", 736 "d2a_ulclk_6p5m",
724 "clkaud_ext_i_0" 737 "clkaud_ext_i_0"
@@ -886,6 +899,10 @@ static struct mtk_composite top_muxes[] = {
886 aud_apll2_parents, 0x134, 1, 1), 899 aud_apll2_parents, 0x134, 1, 1),
887 MUX(CLK_TOP_DA_AUDULL_VTX_6P5M_SEL, "audull_vtx_sel", 900 MUX(CLK_TOP_DA_AUDULL_VTX_6P5M_SEL, "audull_vtx_sel",
888 audull_vtx_parents, 0x134, 31, 1), 901 audull_vtx_parents, 0x134, 31, 1),
902 MUX(CLK_TOP_APLL1_REF_SEL, "apll1_ref_sel",
903 apll1_ref_parents, 0x134, 4, 3),
904 MUX(CLK_TOP_APLL2_REF_SEL, "apll2_ref_sel",
905 apll1_ref_parents, 0x134, 7, 3),
889}; 906};
890 907
891static const char * const mcu_mp0_parents[] = { 908static const char * const mcu_mp0_parents[] = {
@@ -932,36 +949,56 @@ static const struct mtk_clk_divider top_adj_divs[] = {
932 DIV_ADJ(CLK_TOP_APLL_DIV7, "apll_div7", "i2si3_sel", 0x128, 24, 8), 949 DIV_ADJ(CLK_TOP_APLL_DIV7, "apll_div7", "i2si3_sel", 0x128, 24, 8),
933}; 950};
934 951
935static const struct mtk_gate_regs top_cg_regs = { 952static const struct mtk_gate_regs top0_cg_regs = {
936 .set_ofs = 0x120, 953 .set_ofs = 0x120,
937 .clr_ofs = 0x120, 954 .clr_ofs = 0x120,
938 .sta_ofs = 0x120, 955 .sta_ofs = 0x120,
939}; 956};
940 957
941#define GATE_TOP(_id, _name, _parent, _shift) { \ 958static const struct mtk_gate_regs top1_cg_regs = {
959 .set_ofs = 0x424,
960 .clr_ofs = 0x424,
961 .sta_ofs = 0x424,
962};
963
964#define GATE_TOP0(_id, _name, _parent, _shift) { \
942 .id = _id, \ 965 .id = _id, \
943 .name = _name, \ 966 .name = _name, \
944 .parent_name = _parent, \ 967 .parent_name = _parent, \
945 .regs = &top_cg_regs, \ 968 .regs = &top0_cg_regs, \
946 .shift = _shift, \ 969 .shift = _shift, \
947 .ops = &mtk_clk_gate_ops_no_setclr, \ 970 .ops = &mtk_clk_gate_ops_no_setclr, \
948 } 971 }
949 972
973#define GATE_TOP1(_id, _name, _parent, _shift) { \
974 .id = _id, \
975 .name = _name, \
976 .parent_name = _parent, \
977 .regs = &top1_cg_regs, \
978 .shift = _shift, \
979 .ops = &mtk_clk_gate_ops_no_setclr_inv, \
980 }
981
950static const struct mtk_gate top_clks[] = { 982static const struct mtk_gate top_clks[] = {
951 GATE_TOP(CLK_TOP_APLL_DIV_PDN0, "apll_div_pdn0", "i2so1_sel", 0), 983 /* TOP0 */
952 GATE_TOP(CLK_TOP_APLL_DIV_PDN1, "apll_div_pdn1", "i2so2_sel", 1), 984 GATE_TOP0(CLK_TOP_APLL_DIV_PDN0, "apll_div_pdn0", "i2so1_sel", 0),
953 GATE_TOP(CLK_TOP_APLL_DIV_PDN2, "apll_div_pdn2", "i2so3_sel", 2), 985 GATE_TOP0(CLK_TOP_APLL_DIV_PDN1, "apll_div_pdn1", "i2so2_sel", 1),
954 GATE_TOP(CLK_TOP_APLL_DIV_PDN3, "apll_div_pdn3", "tdmo0_sel", 3), 986 GATE_TOP0(CLK_TOP_APLL_DIV_PDN2, "apll_div_pdn2", "i2so3_sel", 2),
955 GATE_TOP(CLK_TOP_APLL_DIV_PDN4, "apll_div_pdn4", "tdmo1_sel", 4), 987 GATE_TOP0(CLK_TOP_APLL_DIV_PDN3, "apll_div_pdn3", "tdmo0_sel", 3),
956 GATE_TOP(CLK_TOP_APLL_DIV_PDN5, "apll_div_pdn5", "i2si1_sel", 5), 988 GATE_TOP0(CLK_TOP_APLL_DIV_PDN4, "apll_div_pdn4", "tdmo1_sel", 4),
957 GATE_TOP(CLK_TOP_APLL_DIV_PDN6, "apll_div_pdn6", "i2si2_sel", 6), 989 GATE_TOP0(CLK_TOP_APLL_DIV_PDN5, "apll_div_pdn5", "i2si1_sel", 5),
958 GATE_TOP(CLK_TOP_APLL_DIV_PDN7, "apll_div_pdn7", "i2si3_sel", 7), 990 GATE_TOP0(CLK_TOP_APLL_DIV_PDN6, "apll_div_pdn6", "i2si2_sel", 6),
991 GATE_TOP0(CLK_TOP_APLL_DIV_PDN7, "apll_div_pdn7", "i2si3_sel", 7),
992 /* TOP1 */
993 GATE_TOP1(CLK_TOP_NFI2X_EN, "nfi2x_en", "nfi2x_sel", 0),
994 GATE_TOP1(CLK_TOP_NFIECC_EN, "nfiecc_en", "nfiecc_sel", 1),
995 GATE_TOP1(CLK_TOP_NFI1X_CK_EN, "nfi1x_ck_en", "nfi2x_sel", 2),
959}; 996};
960 997
961static const struct mtk_gate_regs infra_cg_regs = { 998static const struct mtk_gate_regs infra_cg_regs = {
962 .set_ofs = 0x40, 999 .set_ofs = 0x40,
963 .clr_ofs = 0x44, 1000 .clr_ofs = 0x44,
964 .sta_ofs = 0x40, 1001 .sta_ofs = 0x48,
965}; 1002};
966 1003
967#define GATE_INFRA(_id, _name, _parent, _shift) { \ 1004#define GATE_INFRA(_id, _name, _parent, _shift) { \
@@ -1120,6 +1157,10 @@ static const struct mtk_gate peri_clks[] = {
1120 "msdc50_0_h_sel", 4), 1157 "msdc50_0_h_sel", 4),
1121 GATE_PERI2(CLK_PERI_MSDC50_3_HCLK_EN, "per_msdc50_3_h", 1158 GATE_PERI2(CLK_PERI_MSDC50_3_HCLK_EN, "per_msdc50_3_h",
1122 "msdc50_3_h_sel", 5), 1159 "msdc50_3_h_sel", 5),
1160 GATE_PERI2(CLK_PERI_MSDC30_0_QTR_EN, "per_msdc30_0_q",
1161 "axi_sel", 6),
1162 GATE_PERI2(CLK_PERI_MSDC30_3_QTR_EN, "per_msdc30_3_q",
1163 "mem_sel", 7),
1123}; 1164};
1124 1165
1125#define MT2712_PLL_FMAX (3000UL * MHZ) 1166#define MT2712_PLL_FMAX (3000UL * MHZ)
diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
index 7694302c70a4..d5cbec522aec 100644
--- a/drivers/clk/meson/Kconfig
+++ b/drivers/clk/meson/Kconfig
@@ -3,10 +3,15 @@ config COMMON_CLK_AMLOGIC
3 depends on OF 3 depends on OF
4 depends on ARCH_MESON || COMPILE_TEST 4 depends on ARCH_MESON || COMPILE_TEST
5 5
6config COMMON_CLK_REGMAP_MESON
7 bool
8 select REGMAP
9
6config COMMON_CLK_MESON8B 10config COMMON_CLK_MESON8B
7 bool 11 bool
8 depends on COMMON_CLK_AMLOGIC 12 depends on COMMON_CLK_AMLOGIC
9 select RESET_CONTROLLER 13 select RESET_CONTROLLER
14 select COMMON_CLK_REGMAP_MESON
10 help 15 help
11 Support for the clock controller on AmLogic S802 (Meson8), 16 Support for the clock controller on AmLogic S802 (Meson8),
12 S805 (Meson8b) and S812 (Meson8m2) devices. Say Y if you 17 S805 (Meson8b) and S812 (Meson8m2) devices. Say Y if you
@@ -16,6 +21,8 @@ config COMMON_CLK_GXBB
16 bool 21 bool
17 depends on COMMON_CLK_AMLOGIC 22 depends on COMMON_CLK_AMLOGIC
18 select RESET_CONTROLLER 23 select RESET_CONTROLLER
24 select COMMON_CLK_REGMAP_MESON
25 select MFD_SYSCON
19 help 26 help
20 Support for the clock controller on AmLogic S905 devices, aka gxbb. 27 Support for the clock controller on AmLogic S905 devices, aka gxbb.
21 Say Y if you want peripherals and CPU frequency scaling to work. 28 Say Y if you want peripherals and CPU frequency scaling to work.
@@ -24,6 +31,8 @@ config COMMON_CLK_AXG
24 bool 31 bool
25 depends on COMMON_CLK_AMLOGIC 32 depends on COMMON_CLK_AMLOGIC
26 select RESET_CONTROLLER 33 select RESET_CONTROLLER
34 select COMMON_CLK_REGMAP_MESON
35 select MFD_SYSCON
27 help 36 help
28 Support for the clock controller on AmLogic A113D devices, aka axg. 37 Support for the clock controller on AmLogic A113D devices, aka axg.
29 Say Y if you want peripherals and CPU frequency scaling to work. 38 Say Y if you want peripherals and CPU frequency scaling to work.
diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
index 3c03ce583798..ffee82e60b7a 100644
--- a/drivers/clk/meson/Makefile
+++ b/drivers/clk/meson/Makefile
@@ -2,7 +2,8 @@
2# Makefile for Meson specific clk 2# Makefile for Meson specific clk
3# 3#
4 4
5obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-cpu.o clk-mpll.o clk-audio-divider.o 5obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-mpll.o clk-audio-divider.o
6obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o 6obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o
7obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o gxbb-aoclk-regmap.o gxbb-aoclk-32k.o 7obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o gxbb-aoclk-32k.o
8obj-$(CONFIG_COMMON_CLK_AXG) += axg.o 8obj-$(CONFIG_COMMON_CLK_AXG) += axg.o
9obj-$(CONFIG_COMMON_CLK_REGMAP_MESON) += clk-regmap.o
diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c
index 1294f3ad7cd5..5f5d468c1efe 100644
--- a/drivers/clk/meson/axg.c
+++ b/drivers/clk/meson/axg.c
@@ -11,125 +11,51 @@
11 11
12#include <linux/clk.h> 12#include <linux/clk.h>
13#include <linux/clk-provider.h> 13#include <linux/clk-provider.h>
14#include <linux/init.h>
14#include <linux/of_address.h> 15#include <linux/of_address.h>
15#include <linux/of_device.h> 16#include <linux/of_device.h>
17#include <linux/mfd/syscon.h>
16#include <linux/platform_device.h> 18#include <linux/platform_device.h>
17#include <linux/init.h> 19#include <linux/regmap.h>
18 20
19#include "clkc.h" 21#include "clkc.h"
20#include "axg.h" 22#include "axg.h"
21 23
22static DEFINE_SPINLOCK(meson_clk_lock); 24static DEFINE_SPINLOCK(meson_clk_lock);
23 25
24static const struct pll_rate_table sys_pll_rate_table[] = { 26static struct clk_regmap axg_fixed_pll = {
25 PLL_RATE(24000000, 56, 1, 2), 27 .data = &(struct meson_clk_pll_data){
26 PLL_RATE(48000000, 64, 1, 2), 28 .m = {
27 PLL_RATE(72000000, 72, 1, 2), 29 .reg_off = HHI_MPLL_CNTL,
28 PLL_RATE(96000000, 64, 1, 2), 30 .shift = 0,
29 PLL_RATE(120000000, 80, 1, 2), 31 .width = 9,
30 PLL_RATE(144000000, 96, 1, 2), 32 },
31 PLL_RATE(168000000, 56, 1, 1), 33 .n = {
32 PLL_RATE(192000000, 64, 1, 1), 34 .reg_off = HHI_MPLL_CNTL,
33 PLL_RATE(216000000, 72, 1, 1), 35 .shift = 9,
34 PLL_RATE(240000000, 80, 1, 1), 36 .width = 5,
35 PLL_RATE(264000000, 88, 1, 1), 37 },
36 PLL_RATE(288000000, 96, 1, 1), 38 .od = {
37 PLL_RATE(312000000, 52, 1, 2), 39 .reg_off = HHI_MPLL_CNTL,
38 PLL_RATE(336000000, 56, 1, 2), 40 .shift = 16,
39 PLL_RATE(360000000, 60, 1, 2), 41 .width = 2,
40 PLL_RATE(384000000, 64, 1, 2), 42 },
41 PLL_RATE(408000000, 68, 1, 2), 43 .frac = {
42 PLL_RATE(432000000, 72, 1, 2), 44 .reg_off = HHI_MPLL_CNTL2,
43 PLL_RATE(456000000, 76, 1, 2), 45 .shift = 0,
44 PLL_RATE(480000000, 80, 1, 2), 46 .width = 12,
45 PLL_RATE(504000000, 84, 1, 2), 47 },
46 PLL_RATE(528000000, 88, 1, 2), 48 .l = {
47 PLL_RATE(552000000, 92, 1, 2), 49 .reg_off = HHI_MPLL_CNTL,
48 PLL_RATE(576000000, 96, 1, 2), 50 .shift = 31,
49 PLL_RATE(600000000, 50, 1, 1), 51 .width = 1,
50 PLL_RATE(624000000, 52, 1, 1), 52 },
51 PLL_RATE(648000000, 54, 1, 1), 53 .rst = {
52 PLL_RATE(672000000, 56, 1, 1), 54 .reg_off = HHI_MPLL_CNTL,
53 PLL_RATE(696000000, 58, 1, 1), 55 .shift = 29,
54 PLL_RATE(720000000, 60, 1, 1), 56 .width = 1,
55 PLL_RATE(744000000, 62, 1, 1), 57 },
56 PLL_RATE(768000000, 64, 1, 1),
57 PLL_RATE(792000000, 66, 1, 1),
58 PLL_RATE(816000000, 68, 1, 1),
59 PLL_RATE(840000000, 70, 1, 1),
60 PLL_RATE(864000000, 72, 1, 1),
61 PLL_RATE(888000000, 74, 1, 1),
62 PLL_RATE(912000000, 76, 1, 1),
63 PLL_RATE(936000000, 78, 1, 1),
64 PLL_RATE(960000000, 80, 1, 1),
65 PLL_RATE(984000000, 82, 1, 1),
66 PLL_RATE(1008000000, 84, 1, 1),
67 PLL_RATE(1032000000, 86, 1, 1),
68 PLL_RATE(1056000000, 88, 1, 1),
69 PLL_RATE(1080000000, 90, 1, 1),
70 PLL_RATE(1104000000, 92, 1, 1),
71 PLL_RATE(1128000000, 94, 1, 1),
72 PLL_RATE(1152000000, 96, 1, 1),
73 PLL_RATE(1176000000, 98, 1, 1),
74 PLL_RATE(1200000000, 50, 1, 0),
75 PLL_RATE(1224000000, 51, 1, 0),
76 PLL_RATE(1248000000, 52, 1, 0),
77 PLL_RATE(1272000000, 53, 1, 0),
78 PLL_RATE(1296000000, 54, 1, 0),
79 PLL_RATE(1320000000, 55, 1, 0),
80 PLL_RATE(1344000000, 56, 1, 0),
81 PLL_RATE(1368000000, 57, 1, 0),
82 PLL_RATE(1392000000, 58, 1, 0),
83 PLL_RATE(1416000000, 59, 1, 0),
84 PLL_RATE(1440000000, 60, 1, 0),
85 PLL_RATE(1464000000, 61, 1, 0),
86 PLL_RATE(1488000000, 62, 1, 0),
87 PLL_RATE(1512000000, 63, 1, 0),
88 PLL_RATE(1536000000, 64, 1, 0),
89 PLL_RATE(1560000000, 65, 1, 0),
90 PLL_RATE(1584000000, 66, 1, 0),
91 PLL_RATE(1608000000, 67, 1, 0),
92 PLL_RATE(1632000000, 68, 1, 0),
93 PLL_RATE(1656000000, 68, 1, 0),
94 PLL_RATE(1680000000, 68, 1, 0),
95 PLL_RATE(1704000000, 68, 1, 0),
96 PLL_RATE(1728000000, 69, 1, 0),
97 PLL_RATE(1752000000, 69, 1, 0),
98 PLL_RATE(1776000000, 69, 1, 0),
99 PLL_RATE(1800000000, 69, 1, 0),
100 PLL_RATE(1824000000, 70, 1, 0),
101 PLL_RATE(1848000000, 70, 1, 0),
102 PLL_RATE(1872000000, 70, 1, 0),
103 PLL_RATE(1896000000, 70, 1, 0),
104 PLL_RATE(1920000000, 71, 1, 0),
105 PLL_RATE(1944000000, 71, 1, 0),
106 PLL_RATE(1968000000, 71, 1, 0),
107 PLL_RATE(1992000000, 71, 1, 0),
108 PLL_RATE(2016000000, 72, 1, 0),
109 PLL_RATE(2040000000, 72, 1, 0),
110 PLL_RATE(2064000000, 72, 1, 0),
111 PLL_RATE(2088000000, 72, 1, 0),
112 PLL_RATE(2112000000, 73, 1, 0),
113 { /* sentinel */ },
114};
115
116static struct meson_clk_pll axg_fixed_pll = {
117 .m = {
118 .reg_off = HHI_MPLL_CNTL,
119 .shift = 0,
120 .width = 9,
121 },
122 .n = {
123 .reg_off = HHI_MPLL_CNTL,
124 .shift = 9,
125 .width = 5,
126 },
127 .od = {
128 .reg_off = HHI_MPLL_CNTL,
129 .shift = 16,
130 .width = 2,
131 }, 58 },
132 .lock = &meson_clk_lock,
133 .hw.init = &(struct clk_init_data){ 59 .hw.init = &(struct clk_init_data){
134 .name = "fixed_pll", 60 .name = "fixed_pll",
135 .ops = &meson_clk_pll_ro_ops, 61 .ops = &meson_clk_pll_ro_ops,
@@ -138,25 +64,34 @@ static struct meson_clk_pll axg_fixed_pll = {
138 }, 64 },
139}; 65};
140 66
141static struct meson_clk_pll axg_sys_pll = { 67static struct clk_regmap axg_sys_pll = {
142 .m = { 68 .data = &(struct meson_clk_pll_data){
143 .reg_off = HHI_SYS_PLL_CNTL, 69 .m = {
144 .shift = 0, 70 .reg_off = HHI_SYS_PLL_CNTL,
145 .width = 9, 71 .shift = 0,
72 .width = 9,
73 },
74 .n = {
75 .reg_off = HHI_SYS_PLL_CNTL,
76 .shift = 9,
77 .width = 5,
78 },
79 .od = {
80 .reg_off = HHI_SYS_PLL_CNTL,
81 .shift = 16,
82 .width = 2,
83 },
84 .l = {
85 .reg_off = HHI_SYS_PLL_CNTL,
86 .shift = 31,
87 .width = 1,
88 },
89 .rst = {
90 .reg_off = HHI_SYS_PLL_CNTL,
91 .shift = 29,
92 .width = 1,
93 },
146 }, 94 },
147 .n = {
148 .reg_off = HHI_SYS_PLL_CNTL,
149 .shift = 9,
150 .width = 5,
151 },
152 .od = {
153 .reg_off = HHI_SYS_PLL_CNTL,
154 .shift = 10,
155 .width = 2,
156 },
157 .rate_table = sys_pll_rate_table,
158 .rate_count = ARRAY_SIZE(sys_pll_rate_table),
159 .lock = &meson_clk_lock,
160 .hw.init = &(struct clk_init_data){ 95 .hw.init = &(struct clk_init_data){
161 .name = "sys_pll", 96 .name = "sys_pll",
162 .ops = &meson_clk_pll_ro_ops, 97 .ops = &meson_clk_pll_ro_ops,
@@ -257,40 +192,51 @@ static const struct pll_rate_table axg_gp0_pll_rate_table[] = {
257 { /* sentinel */ }, 192 { /* sentinel */ },
258}; 193};
259 194
260static struct pll_params_table axg_gp0_params_table[] = { 195static const struct reg_sequence axg_gp0_init_regs[] = {
261 PLL_PARAM(HHI_GP0_PLL_CNTL, 0x40010250), 196 { .reg = HHI_GP0_PLL_CNTL1, .def = 0xc084b000 },
262 PLL_PARAM(HHI_GP0_PLL_CNTL1, 0xc084a000), 197 { .reg = HHI_GP0_PLL_CNTL2, .def = 0xb75020be },
263 PLL_PARAM(HHI_GP0_PLL_CNTL2, 0xb75020be), 198 { .reg = HHI_GP0_PLL_CNTL3, .def = 0x0a59a288 },
264 PLL_PARAM(HHI_GP0_PLL_CNTL3, 0x0a59a288), 199 { .reg = HHI_GP0_PLL_CNTL4, .def = 0xc000004d },
265 PLL_PARAM(HHI_GP0_PLL_CNTL4, 0xc000004d), 200 { .reg = HHI_GP0_PLL_CNTL5, .def = 0x00078000 },
266 PLL_PARAM(HHI_GP0_PLL_CNTL5, 0x00078000), 201 { .reg = HHI_GP0_PLL_CNTL, .def = 0x40010250 },
267}; 202};
268 203
269static struct meson_clk_pll axg_gp0_pll = { 204static struct clk_regmap axg_gp0_pll = {
270 .m = { 205 .data = &(struct meson_clk_pll_data){
271 .reg_off = HHI_GP0_PLL_CNTL, 206 .m = {
272 .shift = 0, 207 .reg_off = HHI_GP0_PLL_CNTL,
273 .width = 9, 208 .shift = 0,
274 }, 209 .width = 9,
275 .n = { 210 },
276 .reg_off = HHI_GP0_PLL_CNTL, 211 .n = {
277 .shift = 9, 212 .reg_off = HHI_GP0_PLL_CNTL,
278 .width = 5, 213 .shift = 9,
279 }, 214 .width = 5,
280 .od = { 215 },
281 .reg_off = HHI_GP0_PLL_CNTL, 216 .od = {
282 .shift = 16, 217 .reg_off = HHI_GP0_PLL_CNTL,
283 .width = 2, 218 .shift = 16,
284 }, 219 .width = 2,
285 .params = { 220 },
286 .params_table = axg_gp0_params_table, 221 .frac = {
287 .params_count = ARRAY_SIZE(axg_gp0_params_table), 222 .reg_off = HHI_GP0_PLL_CNTL1,
288 .no_init_reset = true, 223 .shift = 0,
289 .reset_lock_loop = true, 224 .width = 10,
290 }, 225 },
291 .rate_table = axg_gp0_pll_rate_table, 226 .l = {
292 .rate_count = ARRAY_SIZE(axg_gp0_pll_rate_table), 227 .reg_off = HHI_GP0_PLL_CNTL,
293 .lock = &meson_clk_lock, 228 .shift = 31,
229 .width = 1,
230 },
231 .rst = {
232 .reg_off = HHI_GP0_PLL_CNTL,
233 .shift = 29,
234 .width = 1,
235 },
236 .table = axg_gp0_pll_rate_table,
237 .init_regs = axg_gp0_init_regs,
238 .init_count = ARRAY_SIZE(axg_gp0_init_regs),
239 },
294 .hw.init = &(struct clk_init_data){ 240 .hw.init = &(struct clk_init_data){
295 .name = "gp0_pll", 241 .name = "gp0_pll",
296 .ops = &meson_clk_pll_ops, 242 .ops = &meson_clk_pll_ops,
@@ -299,234 +245,427 @@ static struct meson_clk_pll axg_gp0_pll = {
299 }, 245 },
300}; 246};
301 247
248static const struct reg_sequence axg_hifi_init_regs[] = {
249 { .reg = HHI_HIFI_PLL_CNTL1, .def = 0xc084b000 },
250 { .reg = HHI_HIFI_PLL_CNTL2, .def = 0xb75020be },
251 { .reg = HHI_HIFI_PLL_CNTL3, .def = 0x0a6a3a88 },
252 { .reg = HHI_HIFI_PLL_CNTL4, .def = 0xc000004d },
253 { .reg = HHI_HIFI_PLL_CNTL5, .def = 0x00058000 },
254 { .reg = HHI_HIFI_PLL_CNTL, .def = 0x40010250 },
255};
256
257static struct clk_regmap axg_hifi_pll = {
258 .data = &(struct meson_clk_pll_data){
259 .m = {
260 .reg_off = HHI_HIFI_PLL_CNTL,
261 .shift = 0,
262 .width = 9,
263 },
264 .n = {
265 .reg_off = HHI_HIFI_PLL_CNTL,
266 .shift = 9,
267 .width = 5,
268 },
269 .od = {
270 .reg_off = HHI_HIFI_PLL_CNTL,
271 .shift = 16,
272 .width = 2,
273 },
274 .frac = {
275 .reg_off = HHI_HIFI_PLL_CNTL5,
276 .shift = 0,
277 .width = 13,
278 },
279 .l = {
280 .reg_off = HHI_HIFI_PLL_CNTL,
281 .shift = 31,
282 .width = 1,
283 },
284 .rst = {
285 .reg_off = HHI_HIFI_PLL_CNTL,
286 .shift = 29,
287 .width = 1,
288 },
289 .table = axg_gp0_pll_rate_table,
290 .init_regs = axg_hifi_init_regs,
291 .init_count = ARRAY_SIZE(axg_hifi_init_regs),
292 .flags = CLK_MESON_PLL_ROUND_CLOSEST,
293 },
294 .hw.init = &(struct clk_init_data){
295 .name = "hifi_pll",
296 .ops = &meson_clk_pll_ops,
297 .parent_names = (const char *[]){ "xtal" },
298 .num_parents = 1,
299 },
300};
302 301
303static struct clk_fixed_factor axg_fclk_div2 = { 302static struct clk_fixed_factor axg_fclk_div2_div = {
304 .mult = 1, 303 .mult = 1,
305 .div = 2, 304 .div = 2,
306 .hw.init = &(struct clk_init_data){ 305 .hw.init = &(struct clk_init_data){
307 .name = "fclk_div2", 306 .name = "fclk_div2_div",
308 .ops = &clk_fixed_factor_ops, 307 .ops = &clk_fixed_factor_ops,
309 .parent_names = (const char *[]){ "fixed_pll" }, 308 .parent_names = (const char *[]){ "fixed_pll" },
310 .num_parents = 1, 309 .num_parents = 1,
311 }, 310 },
312}; 311};
313 312
314static struct clk_fixed_factor axg_fclk_div3 = { 313static struct clk_regmap axg_fclk_div2 = {
314 .data = &(struct clk_regmap_gate_data){
315 .offset = HHI_MPLL_CNTL6,
316 .bit_idx = 27,
317 },
318 .hw.init = &(struct clk_init_data){
319 .name = "fclk_div2",
320 .ops = &clk_regmap_gate_ops,
321 .parent_names = (const char *[]){ "fclk_div2_div" },
322 .num_parents = 1,
323 },
324};
325
326static struct clk_fixed_factor axg_fclk_div3_div = {
315 .mult = 1, 327 .mult = 1,
316 .div = 3, 328 .div = 3,
317 .hw.init = &(struct clk_init_data){ 329 .hw.init = &(struct clk_init_data){
318 .name = "fclk_div3", 330 .name = "fclk_div3_div",
319 .ops = &clk_fixed_factor_ops, 331 .ops = &clk_fixed_factor_ops,
320 .parent_names = (const char *[]){ "fixed_pll" }, 332 .parent_names = (const char *[]){ "fixed_pll" },
321 .num_parents = 1, 333 .num_parents = 1,
322 }, 334 },
323}; 335};
324 336
325static struct clk_fixed_factor axg_fclk_div4 = { 337static struct clk_regmap axg_fclk_div3 = {
338 .data = &(struct clk_regmap_gate_data){
339 .offset = HHI_MPLL_CNTL6,
340 .bit_idx = 28,
341 },
342 .hw.init = &(struct clk_init_data){
343 .name = "fclk_div3",
344 .ops = &clk_regmap_gate_ops,
345 .parent_names = (const char *[]){ "fclk_div3_div" },
346 .num_parents = 1,
347 },
348};
349
350static struct clk_fixed_factor axg_fclk_div4_div = {
326 .mult = 1, 351 .mult = 1,
327 .div = 4, 352 .div = 4,
328 .hw.init = &(struct clk_init_data){ 353 .hw.init = &(struct clk_init_data){
329 .name = "fclk_div4", 354 .name = "fclk_div4_div",
330 .ops = &clk_fixed_factor_ops, 355 .ops = &clk_fixed_factor_ops,
331 .parent_names = (const char *[]){ "fixed_pll" }, 356 .parent_names = (const char *[]){ "fixed_pll" },
332 .num_parents = 1, 357 .num_parents = 1,
333 }, 358 },
334}; 359};
335 360
336static struct clk_fixed_factor axg_fclk_div5 = { 361static struct clk_regmap axg_fclk_div4 = {
362 .data = &(struct clk_regmap_gate_data){
363 .offset = HHI_MPLL_CNTL6,
364 .bit_idx = 29,
365 },
366 .hw.init = &(struct clk_init_data){
367 .name = "fclk_div4",
368 .ops = &clk_regmap_gate_ops,
369 .parent_names = (const char *[]){ "fclk_div4_div" },
370 .num_parents = 1,
371 },
372};
373
374static struct clk_fixed_factor axg_fclk_div5_div = {
337 .mult = 1, 375 .mult = 1,
338 .div = 5, 376 .div = 5,
339 .hw.init = &(struct clk_init_data){ 377 .hw.init = &(struct clk_init_data){
340 .name = "fclk_div5", 378 .name = "fclk_div5_div",
341 .ops = &clk_fixed_factor_ops, 379 .ops = &clk_fixed_factor_ops,
342 .parent_names = (const char *[]){ "fixed_pll" }, 380 .parent_names = (const char *[]){ "fixed_pll" },
343 .num_parents = 1, 381 .num_parents = 1,
344 }, 382 },
345}; 383};
346 384
347static struct clk_fixed_factor axg_fclk_div7 = { 385static struct clk_regmap axg_fclk_div5 = {
386 .data = &(struct clk_regmap_gate_data){
387 .offset = HHI_MPLL_CNTL6,
388 .bit_idx = 30,
389 },
390 .hw.init = &(struct clk_init_data){
391 .name = "fclk_div5",
392 .ops = &clk_regmap_gate_ops,
393 .parent_names = (const char *[]){ "fclk_div5_div" },
394 .num_parents = 1,
395 },
396};
397
398static struct clk_fixed_factor axg_fclk_div7_div = {
348 .mult = 1, 399 .mult = 1,
349 .div = 7, 400 .div = 7,
350 .hw.init = &(struct clk_init_data){ 401 .hw.init = &(struct clk_init_data){
351 .name = "fclk_div7", 402 .name = "fclk_div7_div",
352 .ops = &clk_fixed_factor_ops, 403 .ops = &clk_fixed_factor_ops,
353 .parent_names = (const char *[]){ "fixed_pll" }, 404 .parent_names = (const char *[]){ "fixed_pll" },
354 .num_parents = 1, 405 .num_parents = 1,
355 }, 406 },
356}; 407};
357 408
358static struct meson_clk_mpll axg_mpll0 = { 409static struct clk_regmap axg_fclk_div7 = {
359 .sdm = { 410 .data = &(struct clk_regmap_gate_data){
360 .reg_off = HHI_MPLL_CNTL7, 411 .offset = HHI_MPLL_CNTL6,
361 .shift = 0, 412 .bit_idx = 31,
362 .width = 14,
363 }, 413 },
364 .sdm_en = { 414 .hw.init = &(struct clk_init_data){
365 .reg_off = HHI_MPLL_CNTL7, 415 .name = "fclk_div7",
366 .shift = 15, 416 .ops = &clk_regmap_gate_ops,
367 .width = 1, 417 .parent_names = (const char *[]){ "fclk_div7_div" },
418 .num_parents = 1,
368 }, 419 },
369 .n2 = { 420};
370 .reg_off = HHI_MPLL_CNTL7, 421
371 .shift = 16, 422static struct clk_regmap axg_mpll_prediv = {
372 .width = 9, 423 .data = &(struct clk_regmap_div_data){
424 .offset = HHI_MPLL_CNTL5,
425 .shift = 12,
426 .width = 1,
373 }, 427 },
374 .en = { 428 .hw.init = &(struct clk_init_data){
375 .reg_off = HHI_MPLL_CNTL7, 429 .name = "mpll_prediv",
376 .shift = 14, 430 .ops = &clk_regmap_divider_ro_ops,
377 .width = 1, 431 .parent_names = (const char *[]){ "fixed_pll" },
432 .num_parents = 1,
378 }, 433 },
379 .ssen = { 434};
380 .reg_off = HHI_MPLL_CNTL, 435
381 .shift = 25, 436static struct clk_regmap axg_mpll0_div = {
382 .width = 1, 437 .data = &(struct meson_clk_mpll_data){
438 .sdm = {
439 .reg_off = HHI_MPLL_CNTL7,
440 .shift = 0,
441 .width = 14,
442 },
443 .sdm_en = {
444 .reg_off = HHI_MPLL_CNTL7,
445 .shift = 15,
446 .width = 1,
447 },
448 .n2 = {
449 .reg_off = HHI_MPLL_CNTL7,
450 .shift = 16,
451 .width = 9,
452 },
453 .ssen = {
454 .reg_off = HHI_MPLL_CNTL,
455 .shift = 25,
456 .width = 1,
457 },
458 .misc = {
459 .reg_off = HHI_PLL_TOP_MISC,
460 .shift = 0,
461 .width = 1,
462 },
463 .lock = &meson_clk_lock,
383 }, 464 },
384 .lock = &meson_clk_lock,
385 .hw.init = &(struct clk_init_data){ 465 .hw.init = &(struct clk_init_data){
386 .name = "mpll0", 466 .name = "mpll0_div",
387 .ops = &meson_clk_mpll_ops, 467 .ops = &meson_clk_mpll_ops,
388 .parent_names = (const char *[]){ "fixed_pll" }, 468 .parent_names = (const char *[]){ "mpll_prediv" },
389 .num_parents = 1, 469 .num_parents = 1,
390 }, 470 },
391}; 471};
392 472
393static struct meson_clk_mpll axg_mpll1 = { 473static struct clk_regmap axg_mpll0 = {
394 .sdm = { 474 .data = &(struct clk_regmap_gate_data){
395 .reg_off = HHI_MPLL_CNTL8, 475 .offset = HHI_MPLL_CNTL7,
396 .shift = 0, 476 .bit_idx = 14,
397 .width = 14,
398 }, 477 },
399 .sdm_en = { 478 .hw.init = &(struct clk_init_data){
400 .reg_off = HHI_MPLL_CNTL8, 479 .name = "mpll0",
401 .shift = 15, 480 .ops = &clk_regmap_gate_ops,
402 .width = 1, 481 .parent_names = (const char *[]){ "mpll0_div" },
403 }, 482 .num_parents = 1,
404 .n2 = { 483 .flags = CLK_SET_RATE_PARENT,
405 .reg_off = HHI_MPLL_CNTL8,
406 .shift = 16,
407 .width = 9,
408 }, 484 },
409 .en = { 485};
410 .reg_off = HHI_MPLL_CNTL8, 486
411 .shift = 14, 487static struct clk_regmap axg_mpll1_div = {
412 .width = 1, 488 .data = &(struct meson_clk_mpll_data){
489 .sdm = {
490 .reg_off = HHI_MPLL_CNTL8,
491 .shift = 0,
492 .width = 14,
493 },
494 .sdm_en = {
495 .reg_off = HHI_MPLL_CNTL8,
496 .shift = 15,
497 .width = 1,
498 },
499 .n2 = {
500 .reg_off = HHI_MPLL_CNTL8,
501 .shift = 16,
502 .width = 9,
503 },
504 .misc = {
505 .reg_off = HHI_PLL_TOP_MISC,
506 .shift = 1,
507 .width = 1,
508 },
509 .lock = &meson_clk_lock,
413 }, 510 },
414 .lock = &meson_clk_lock,
415 .hw.init = &(struct clk_init_data){ 511 .hw.init = &(struct clk_init_data){
416 .name = "mpll1", 512 .name = "mpll1_div",
417 .ops = &meson_clk_mpll_ops, 513 .ops = &meson_clk_mpll_ops,
418 .parent_names = (const char *[]){ "fixed_pll" }, 514 .parent_names = (const char *[]){ "mpll_prediv" },
419 .num_parents = 1, 515 .num_parents = 1,
420 }, 516 },
421}; 517};
422 518
423static struct meson_clk_mpll axg_mpll2 = { 519static struct clk_regmap axg_mpll1 = {
424 .sdm = { 520 .data = &(struct clk_regmap_gate_data){
425 .reg_off = HHI_MPLL_CNTL9, 521 .offset = HHI_MPLL_CNTL8,
426 .shift = 0, 522 .bit_idx = 14,
427 .width = 14,
428 }, 523 },
429 .sdm_en = { 524 .hw.init = &(struct clk_init_data){
430 .reg_off = HHI_MPLL_CNTL9, 525 .name = "mpll1",
431 .shift = 15, 526 .ops = &clk_regmap_gate_ops,
432 .width = 1, 527 .parent_names = (const char *[]){ "mpll1_div" },
433 }, 528 .num_parents = 1,
434 .n2 = { 529 .flags = CLK_SET_RATE_PARENT,
435 .reg_off = HHI_MPLL_CNTL9,
436 .shift = 16,
437 .width = 9,
438 }, 530 },
439 .en = { 531};
440 .reg_off = HHI_MPLL_CNTL9, 532
441 .shift = 14, 533static struct clk_regmap axg_mpll2_div = {
442 .width = 1, 534 .data = &(struct meson_clk_mpll_data){
535 .sdm = {
536 .reg_off = HHI_MPLL_CNTL9,
537 .shift = 0,
538 .width = 14,
539 },
540 .sdm_en = {
541 .reg_off = HHI_MPLL_CNTL9,
542 .shift = 15,
543 .width = 1,
544 },
545 .n2 = {
546 .reg_off = HHI_MPLL_CNTL9,
547 .shift = 16,
548 .width = 9,
549 },
550 .misc = {
551 .reg_off = HHI_PLL_TOP_MISC,
552 .shift = 2,
553 .width = 1,
554 },
555 .lock = &meson_clk_lock,
443 }, 556 },
444 .lock = &meson_clk_lock,
445 .hw.init = &(struct clk_init_data){ 557 .hw.init = &(struct clk_init_data){
446 .name = "mpll2", 558 .name = "mpll2_div",
447 .ops = &meson_clk_mpll_ops, 559 .ops = &meson_clk_mpll_ops,
448 .parent_names = (const char *[]){ "fixed_pll" }, 560 .parent_names = (const char *[]){ "mpll_prediv" },
449 .num_parents = 1, 561 .num_parents = 1,
450 }, 562 },
451}; 563};
452 564
453static struct meson_clk_mpll axg_mpll3 = { 565static struct clk_regmap axg_mpll2 = {
454 .sdm = { 566 .data = &(struct clk_regmap_gate_data){
455 .reg_off = HHI_MPLL3_CNTL0, 567 .offset = HHI_MPLL_CNTL9,
456 .shift = 12, 568 .bit_idx = 14,
457 .width = 14,
458 }, 569 },
459 .sdm_en = { 570 .hw.init = &(struct clk_init_data){
460 .reg_off = HHI_MPLL3_CNTL0, 571 .name = "mpll2",
461 .shift = 11, 572 .ops = &clk_regmap_gate_ops,
462 .width = 1, 573 .parent_names = (const char *[]){ "mpll2_div" },
574 .num_parents = 1,
575 .flags = CLK_SET_RATE_PARENT,
576 },
577};
578
579static struct clk_regmap axg_mpll3_div = {
580 .data = &(struct meson_clk_mpll_data){
581 .sdm = {
582 .reg_off = HHI_MPLL3_CNTL0,
583 .shift = 12,
584 .width = 14,
585 },
586 .sdm_en = {
587 .reg_off = HHI_MPLL3_CNTL0,
588 .shift = 11,
589 .width = 1,
590 },
591 .n2 = {
592 .reg_off = HHI_MPLL3_CNTL0,
593 .shift = 2,
594 .width = 9,
595 },
596 .misc = {
597 .reg_off = HHI_PLL_TOP_MISC,
598 .shift = 3,
599 .width = 1,
600 },
601 .lock = &meson_clk_lock,
463 }, 602 },
464 .n2 = { 603 .hw.init = &(struct clk_init_data){
465 .reg_off = HHI_MPLL3_CNTL0, 604 .name = "mpll3_div",
466 .shift = 2, 605 .ops = &meson_clk_mpll_ops,
467 .width = 9, 606 .parent_names = (const char *[]){ "mpll_prediv" },
607 .num_parents = 1,
468 }, 608 },
469 .en = { 609};
470 .reg_off = HHI_MPLL3_CNTL0, 610
471 .shift = 0, 611static struct clk_regmap axg_mpll3 = {
472 .width = 1, 612 .data = &(struct clk_regmap_gate_data){
613 .offset = HHI_MPLL3_CNTL0,
614 .bit_idx = 0,
473 }, 615 },
474 .lock = &meson_clk_lock,
475 .hw.init = &(struct clk_init_data){ 616 .hw.init = &(struct clk_init_data){
476 .name = "mpll3", 617 .name = "mpll3",
477 .ops = &meson_clk_mpll_ops, 618 .ops = &clk_regmap_gate_ops,
478 .parent_names = (const char *[]){ "fixed_pll" }, 619 .parent_names = (const char *[]){ "mpll3_div" },
479 .num_parents = 1, 620 .num_parents = 1,
621 .flags = CLK_SET_RATE_PARENT,
480 }, 622 },
481}; 623};
482 624
483/*
484 * FIXME The legacy composite clocks (e.g. clk81) are both PLL post-dividers
485 * and should be modeled with their respective PLLs via the forthcoming
486 * coordinated clock rates feature
487 */
488static u32 mux_table_clk81[] = { 0, 2, 3, 4, 5, 6, 7 }; 625static u32 mux_table_clk81[] = { 0, 2, 3, 4, 5, 6, 7 };
489static const char * const clk81_parent_names[] = { 626static const char * const clk81_parent_names[] = {
490 "xtal", "fclk_div7", "mpll1", "mpll2", "fclk_div4", 627 "xtal", "fclk_div7", "mpll1", "mpll2", "fclk_div4",
491 "fclk_div3", "fclk_div5" 628 "fclk_div3", "fclk_div5"
492}; 629};
493 630
494static struct clk_mux axg_mpeg_clk_sel = { 631static struct clk_regmap axg_mpeg_clk_sel = {
495 .reg = (void *)HHI_MPEG_CLK_CNTL, 632 .data = &(struct clk_regmap_mux_data){
496 .mask = 0x7, 633 .offset = HHI_MPEG_CLK_CNTL,
497 .shift = 12, 634 .mask = 0x7,
498 .flags = CLK_MUX_READ_ONLY, 635 .shift = 12,
499 .table = mux_table_clk81, 636 .table = mux_table_clk81,
500 .lock = &meson_clk_lock, 637 },
501 .hw.init = &(struct clk_init_data){ 638 .hw.init = &(struct clk_init_data){
502 .name = "mpeg_clk_sel", 639 .name = "mpeg_clk_sel",
503 .ops = &clk_mux_ro_ops, 640 .ops = &clk_regmap_mux_ro_ops,
504 .parent_names = clk81_parent_names, 641 .parent_names = clk81_parent_names,
505 .num_parents = ARRAY_SIZE(clk81_parent_names), 642 .num_parents = ARRAY_SIZE(clk81_parent_names),
506 }, 643 },
507}; 644};
508 645
509static struct clk_divider axg_mpeg_clk_div = { 646static struct clk_regmap axg_mpeg_clk_div = {
510 .reg = (void *)HHI_MPEG_CLK_CNTL, 647 .data = &(struct clk_regmap_div_data){
511 .shift = 0, 648 .offset = HHI_MPEG_CLK_CNTL,
512 .width = 7, 649 .shift = 0,
513 .lock = &meson_clk_lock, 650 .width = 7,
651 },
514 .hw.init = &(struct clk_init_data){ 652 .hw.init = &(struct clk_init_data){
515 .name = "mpeg_clk_div", 653 .name = "mpeg_clk_div",
516 .ops = &clk_divider_ops, 654 .ops = &clk_regmap_divider_ops,
517 .parent_names = (const char *[]){ "mpeg_clk_sel" }, 655 .parent_names = (const char *[]){ "mpeg_clk_sel" },
518 .num_parents = 1, 656 .num_parents = 1,
519 .flags = CLK_SET_RATE_PARENT, 657 .flags = CLK_SET_RATE_PARENT,
520 }, 658 },
521}; 659};
522 660
523static struct clk_gate axg_clk81 = { 661static struct clk_regmap axg_clk81 = {
524 .reg = (void *)HHI_MPEG_CLK_CNTL, 662 .data = &(struct clk_regmap_gate_data){
525 .bit_idx = 7, 663 .offset = HHI_MPEG_CLK_CNTL,
526 .lock = &meson_clk_lock, 664 .bit_idx = 7,
665 },
527 .hw.init = &(struct clk_init_data){ 666 .hw.init = &(struct clk_init_data){
528 .name = "clk81", 667 .name = "clk81",
529 .ops = &clk_gate_ops, 668 .ops = &clk_regmap_gate_ops,
530 .parent_names = (const char *[]){ "mpeg_clk_div" }, 669 .parent_names = (const char *[]){ "mpeg_clk_div" },
531 .num_parents = 1, 670 .num_parents = 1,
532 .flags = (CLK_SET_RATE_PARENT | CLK_IS_CRITICAL), 671 .flags = (CLK_SET_RATE_PARENT | CLK_IS_CRITICAL),
@@ -545,42 +684,45 @@ static const char * const axg_sd_emmc_clk0_parent_names[] = {
545}; 684};
546 685
547/* SDcard clock */ 686/* SDcard clock */
548static struct clk_mux axg_sd_emmc_b_clk0_sel = { 687static struct clk_regmap axg_sd_emmc_b_clk0_sel = {
549 .reg = (void *)HHI_SD_EMMC_CLK_CNTL, 688 .data = &(struct clk_regmap_mux_data){
550 .mask = 0x7, 689 .offset = HHI_SD_EMMC_CLK_CNTL,
551 .shift = 25, 690 .mask = 0x7,
552 .lock = &meson_clk_lock, 691 .shift = 25,
692 },
553 .hw.init = &(struct clk_init_data) { 693 .hw.init = &(struct clk_init_data) {
554 .name = "sd_emmc_b_clk0_sel", 694 .name = "sd_emmc_b_clk0_sel",
555 .ops = &clk_mux_ops, 695 .ops = &clk_regmap_mux_ops,
556 .parent_names = axg_sd_emmc_clk0_parent_names, 696 .parent_names = axg_sd_emmc_clk0_parent_names,
557 .num_parents = ARRAY_SIZE(axg_sd_emmc_clk0_parent_names), 697 .num_parents = ARRAY_SIZE(axg_sd_emmc_clk0_parent_names),
558 .flags = CLK_SET_RATE_PARENT, 698 .flags = CLK_SET_RATE_PARENT,
559 }, 699 },
560}; 700};
561 701
562static struct clk_divider axg_sd_emmc_b_clk0_div = { 702static struct clk_regmap axg_sd_emmc_b_clk0_div = {
563 .reg = (void *)HHI_SD_EMMC_CLK_CNTL, 703 .data = &(struct clk_regmap_div_data){
564 .shift = 16, 704 .offset = HHI_SD_EMMC_CLK_CNTL,
565 .width = 7, 705 .shift = 16,
566 .lock = &meson_clk_lock, 706 .width = 7,
567 .flags = CLK_DIVIDER_ROUND_CLOSEST, 707 .flags = CLK_DIVIDER_ROUND_CLOSEST,
708 },
568 .hw.init = &(struct clk_init_data) { 709 .hw.init = &(struct clk_init_data) {
569 .name = "sd_emmc_b_clk0_div", 710 .name = "sd_emmc_b_clk0_div",
570 .ops = &clk_divider_ops, 711 .ops = &clk_regmap_divider_ops,
571 .parent_names = (const char *[]){ "sd_emmc_b_clk0_sel" }, 712 .parent_names = (const char *[]){ "sd_emmc_b_clk0_sel" },
572 .num_parents = 1, 713 .num_parents = 1,
573 .flags = CLK_SET_RATE_PARENT, 714 .flags = CLK_SET_RATE_PARENT,
574 }, 715 },
575}; 716};
576 717
577static struct clk_gate axg_sd_emmc_b_clk0 = { 718static struct clk_regmap axg_sd_emmc_b_clk0 = {
578 .reg = (void *)HHI_SD_EMMC_CLK_CNTL, 719 .data = &(struct clk_regmap_gate_data){
579 .bit_idx = 23, 720 .offset = HHI_SD_EMMC_CLK_CNTL,
580 .lock = &meson_clk_lock, 721 .bit_idx = 23,
722 },
581 .hw.init = &(struct clk_init_data){ 723 .hw.init = &(struct clk_init_data){
582 .name = "sd_emmc_b_clk0", 724 .name = "sd_emmc_b_clk0",
583 .ops = &clk_gate_ops, 725 .ops = &clk_regmap_gate_ops,
584 .parent_names = (const char *[]){ "sd_emmc_b_clk0_div" }, 726 .parent_names = (const char *[]){ "sd_emmc_b_clk0_div" },
585 .num_parents = 1, 727 .num_parents = 1,
586 .flags = CLK_SET_RATE_PARENT, 728 .flags = CLK_SET_RATE_PARENT,
@@ -588,42 +730,45 @@ static struct clk_gate axg_sd_emmc_b_clk0 = {
588}; 730};
589 731
590/* EMMC/NAND clock */ 732/* EMMC/NAND clock */
591static struct clk_mux axg_sd_emmc_c_clk0_sel = { 733static struct clk_regmap axg_sd_emmc_c_clk0_sel = {
592 .reg = (void *)HHI_NAND_CLK_CNTL, 734 .data = &(struct clk_regmap_mux_data){
593 .mask = 0x7, 735 .offset = HHI_NAND_CLK_CNTL,
594 .shift = 9, 736 .mask = 0x7,
595 .lock = &meson_clk_lock, 737 .shift = 9,
738 },
596 .hw.init = &(struct clk_init_data) { 739 .hw.init = &(struct clk_init_data) {
597 .name = "sd_emmc_c_clk0_sel", 740 .name = "sd_emmc_c_clk0_sel",
598 .ops = &clk_mux_ops, 741 .ops = &clk_regmap_mux_ops,
599 .parent_names = axg_sd_emmc_clk0_parent_names, 742 .parent_names = axg_sd_emmc_clk0_parent_names,
600 .num_parents = ARRAY_SIZE(axg_sd_emmc_clk0_parent_names), 743 .num_parents = ARRAY_SIZE(axg_sd_emmc_clk0_parent_names),
601 .flags = CLK_SET_RATE_PARENT, 744 .flags = CLK_SET_RATE_PARENT,
602 }, 745 },
603}; 746};
604 747
605static struct clk_divider axg_sd_emmc_c_clk0_div = { 748static struct clk_regmap axg_sd_emmc_c_clk0_div = {
606 .reg = (void *)HHI_NAND_CLK_CNTL, 749 .data = &(struct clk_regmap_div_data){
607 .shift = 0, 750 .offset = HHI_NAND_CLK_CNTL,
608 .width = 7, 751 .shift = 0,
609 .lock = &meson_clk_lock, 752 .width = 7,
610 .flags = CLK_DIVIDER_ROUND_CLOSEST, 753 .flags = CLK_DIVIDER_ROUND_CLOSEST,
754 },
611 .hw.init = &(struct clk_init_data) { 755 .hw.init = &(struct clk_init_data) {
612 .name = "sd_emmc_c_clk0_div", 756 .name = "sd_emmc_c_clk0_div",
613 .ops = &clk_divider_ops, 757 .ops = &clk_regmap_divider_ops,
614 .parent_names = (const char *[]){ "sd_emmc_c_clk0_sel" }, 758 .parent_names = (const char *[]){ "sd_emmc_c_clk0_sel" },
615 .num_parents = 1, 759 .num_parents = 1,
616 .flags = CLK_SET_RATE_PARENT, 760 .flags = CLK_SET_RATE_PARENT,
617 }, 761 },
618}; 762};
619 763
620static struct clk_gate axg_sd_emmc_c_clk0 = { 764static struct clk_regmap axg_sd_emmc_c_clk0 = {
621 .reg = (void *)HHI_NAND_CLK_CNTL, 765 .data = &(struct clk_regmap_gate_data){
622 .bit_idx = 7, 766 .offset = HHI_NAND_CLK_CNTL,
623 .lock = &meson_clk_lock, 767 .bit_idx = 7,
768 },
624 .hw.init = &(struct clk_init_data){ 769 .hw.init = &(struct clk_init_data){
625 .name = "sd_emmc_c_clk0", 770 .name = "sd_emmc_c_clk0",
626 .ops = &clk_gate_ops, 771 .ops = &clk_regmap_gate_ops,
627 .parent_names = (const char *[]){ "sd_emmc_c_clk0_div" }, 772 .parent_names = (const char *[]){ "sd_emmc_c_clk0_div" },
628 .num_parents = 1, 773 .num_parents = 1,
629 .flags = CLK_SET_RATE_PARENT, 774 .flags = CLK_SET_RATE_PARENT,
@@ -750,27 +895,24 @@ static struct clk_hw_onecell_data axg_hw_onecell_data = {
750 [CLKID_SD_EMMC_C_CLK0_SEL] = &axg_sd_emmc_c_clk0_sel.hw, 895 [CLKID_SD_EMMC_C_CLK0_SEL] = &axg_sd_emmc_c_clk0_sel.hw,
751 [CLKID_SD_EMMC_C_CLK0_DIV] = &axg_sd_emmc_c_clk0_div.hw, 896 [CLKID_SD_EMMC_C_CLK0_DIV] = &axg_sd_emmc_c_clk0_div.hw,
752 [CLKID_SD_EMMC_C_CLK0] = &axg_sd_emmc_c_clk0.hw, 897 [CLKID_SD_EMMC_C_CLK0] = &axg_sd_emmc_c_clk0.hw,
898 [CLKID_MPLL0_DIV] = &axg_mpll0_div.hw,
899 [CLKID_MPLL1_DIV] = &axg_mpll1_div.hw,
900 [CLKID_MPLL2_DIV] = &axg_mpll2_div.hw,
901 [CLKID_MPLL3_DIV] = &axg_mpll3_div.hw,
902 [CLKID_HIFI_PLL] = &axg_hifi_pll.hw,
903 [CLKID_MPLL_PREDIV] = &axg_mpll_prediv.hw,
904 [CLKID_FCLK_DIV2_DIV] = &axg_fclk_div2_div.hw,
905 [CLKID_FCLK_DIV3_DIV] = &axg_fclk_div3_div.hw,
906 [CLKID_FCLK_DIV4_DIV] = &axg_fclk_div4_div.hw,
907 [CLKID_FCLK_DIV5_DIV] = &axg_fclk_div5_div.hw,
908 [CLKID_FCLK_DIV7_DIV] = &axg_fclk_div7_div.hw,
753 [NR_CLKS] = NULL, 909 [NR_CLKS] = NULL,
754 }, 910 },
755 .num = NR_CLKS, 911 .num = NR_CLKS,
756}; 912};
757 913
758/* Convenience tables to populate base addresses in .probe */ 914/* Convenience table to populate regmap in .probe */
759 915static struct clk_regmap *const axg_clk_regmaps[] = {
760static struct meson_clk_pll *const axg_clk_plls[] = {
761 &axg_fixed_pll,
762 &axg_sys_pll,
763 &axg_gp0_pll,
764};
765
766static struct meson_clk_mpll *const axg_clk_mplls[] = {
767 &axg_mpll0,
768 &axg_mpll1,
769 &axg_mpll2,
770 &axg_mpll3,
771};
772
773static struct clk_gate *const axg_clk_gates[] = {
774 &axg_clk81, 916 &axg_clk81,
775 &axg_ddr, 917 &axg_ddr,
776 &axg_audio_locker, 918 &axg_audio_locker,
@@ -818,113 +960,100 @@ static struct clk_gate *const axg_clk_gates[] = {
818 &axg_ao_i2c, 960 &axg_ao_i2c,
819 &axg_sd_emmc_b_clk0, 961 &axg_sd_emmc_b_clk0,
820 &axg_sd_emmc_c_clk0, 962 &axg_sd_emmc_c_clk0,
821};
822
823static struct clk_mux *const axg_clk_muxes[] = {
824 &axg_mpeg_clk_sel,
825 &axg_sd_emmc_b_clk0_sel,
826 &axg_sd_emmc_c_clk0_sel,
827};
828
829static struct clk_divider *const axg_clk_dividers[] = {
830 &axg_mpeg_clk_div, 963 &axg_mpeg_clk_div,
831 &axg_sd_emmc_b_clk0_div, 964 &axg_sd_emmc_b_clk0_div,
832 &axg_sd_emmc_c_clk0_div, 965 &axg_sd_emmc_c_clk0_div,
833}; 966 &axg_mpeg_clk_sel,
834 967 &axg_sd_emmc_b_clk0_sel,
835struct clkc_data { 968 &axg_sd_emmc_c_clk0_sel,
836 struct clk_gate *const *clk_gates; 969 &axg_mpll0,
837 unsigned int clk_gates_count; 970 &axg_mpll1,
838 struct meson_clk_mpll *const *clk_mplls; 971 &axg_mpll2,
839 unsigned int clk_mplls_count; 972 &axg_mpll3,
840 struct meson_clk_pll *const *clk_plls; 973 &axg_mpll0_div,
841 unsigned int clk_plls_count; 974 &axg_mpll1_div,
842 struct clk_mux *const *clk_muxes; 975 &axg_mpll2_div,
843 unsigned int clk_muxes_count; 976 &axg_mpll3_div,
844 struct clk_divider *const *clk_dividers; 977 &axg_fixed_pll,
845 unsigned int clk_dividers_count; 978 &axg_sys_pll,
846 struct clk_hw_onecell_data *hw_onecell_data; 979 &axg_gp0_pll,
847}; 980 &axg_hifi_pll,
848 981 &axg_mpll_prediv,
849static const struct clkc_data axg_clkc_data = { 982 &axg_fclk_div2,
850 .clk_gates = axg_clk_gates, 983 &axg_fclk_div3,
851 .clk_gates_count = ARRAY_SIZE(axg_clk_gates), 984 &axg_fclk_div4,
852 .clk_mplls = axg_clk_mplls, 985 &axg_fclk_div5,
853 .clk_mplls_count = ARRAY_SIZE(axg_clk_mplls), 986 &axg_fclk_div7,
854 .clk_plls = axg_clk_plls,
855 .clk_plls_count = ARRAY_SIZE(axg_clk_plls),
856 .clk_muxes = axg_clk_muxes,
857 .clk_muxes_count = ARRAY_SIZE(axg_clk_muxes),
858 .clk_dividers = axg_clk_dividers,
859 .clk_dividers_count = ARRAY_SIZE(axg_clk_dividers),
860 .hw_onecell_data = &axg_hw_onecell_data,
861}; 987};
862 988
863static const struct of_device_id clkc_match_table[] = { 989static const struct of_device_id clkc_match_table[] = {
864 { .compatible = "amlogic,axg-clkc", .data = &axg_clkc_data }, 990 { .compatible = "amlogic,axg-clkc" },
865 {} 991 {}
866}; 992};
867 993
994static const struct regmap_config clkc_regmap_config = {
995 .reg_bits = 32,
996 .val_bits = 32,
997 .reg_stride = 4,
998};
999
868static int axg_clkc_probe(struct platform_device *pdev) 1000static int axg_clkc_probe(struct platform_device *pdev)
869{ 1001{
870 struct device *dev = &pdev->dev; 1002 struct device *dev = &pdev->dev;
871 const struct clkc_data *clkc_data;
872 struct resource *res; 1003 struct resource *res;
873 void __iomem *clk_base; 1004 void __iomem *clk_base = NULL;
874 int ret, clkid, i; 1005 struct regmap *map;
875 1006 int ret, i;
876 clkc_data = of_device_get_match_data(&pdev->dev);
877 if (!clkc_data)
878 return -EINVAL;
879
880 /* Generic clocks and PLLs */
881 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
882 if (!res)
883 return -EINVAL;
884 clk_base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
885 if (!clk_base) {
886 dev_err(&pdev->dev, "Unable to map clk base\n");
887 return -ENXIO;
888 }
889 1007
890 /* Populate base address for PLLs */ 1008 /* Get the hhi system controller node if available */
891 for (i = 0; i < clkc_data->clk_plls_count; i++) 1009 map = syscon_node_to_regmap(of_get_parent(dev->of_node));
892 clkc_data->clk_plls[i]->base = clk_base; 1010 if (IS_ERR(map)) {
1011 dev_err(dev,
1012 "failed to get HHI regmap - Trying obsolete regs\n");
893 1013
894 /* Populate base address for MPLLs */ 1014 /*
895 for (i = 0; i < clkc_data->clk_mplls_count; i++) 1015 * FIXME: HHI registers should be accessed through
896 clkc_data->clk_mplls[i]->base = clk_base; 1016 * the appropriate system controller. This is required because
1017 * there is more than just clocks in this register space
1018 *
1019 * This fallback method is only provided temporarily until
1020 * all the platform DTs are properly using the syscon node
1021 */
1022 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1023 if (!res)
1024 return -EINVAL;
897 1025
898 /* Populate base address for gates */
899 for (i = 0; i < clkc_data->clk_gates_count; i++)
900 clkc_data->clk_gates[i]->reg = clk_base +
901 (u64)clkc_data->clk_gates[i]->reg;
902 1026
903 /* Populate base address for muxes */ 1027 clk_base = devm_ioremap(dev, res->start, resource_size(res));
904 for (i = 0; i < clkc_data->clk_muxes_count; i++) 1028 if (!clk_base) {
905 clkc_data->clk_muxes[i]->reg = clk_base + 1029 dev_err(dev, "Unable to map clk base\n");
906 (u64)clkc_data->clk_muxes[i]->reg; 1030 return -ENXIO;
1031 }
1032
1033 map = devm_regmap_init_mmio(dev, clk_base,
1034 &clkc_regmap_config);
1035 if (IS_ERR(map))
1036 return PTR_ERR(map);
1037 }
907 1038
908 /* Populate base address for dividers */ 1039 /* Populate regmap for the regmap backed clocks */
909 for (i = 0; i < clkc_data->clk_dividers_count; i++) 1040 for (i = 0; i < ARRAY_SIZE(axg_clk_regmaps); i++)
910 clkc_data->clk_dividers[i]->reg = clk_base + 1041 axg_clk_regmaps[i]->map = map;
911 (u64)clkc_data->clk_dividers[i]->reg;
912 1042
913 for (clkid = 0; clkid < clkc_data->hw_onecell_data->num; clkid++) { 1043 for (i = 0; i < axg_hw_onecell_data.num; i++) {
914 /* array might be sparse */ 1044 /* array might be sparse */
915 if (!clkc_data->hw_onecell_data->hws[clkid]) 1045 if (!axg_hw_onecell_data.hws[i])
916 continue; 1046 continue;
917 1047
918 ret = devm_clk_hw_register(dev, 1048 ret = devm_clk_hw_register(dev, axg_hw_onecell_data.hws[i]);
919 clkc_data->hw_onecell_data->hws[clkid]);
920 if (ret) { 1049 if (ret) {
921 dev_err(&pdev->dev, "Clock registration failed\n"); 1050 dev_err(dev, "Clock registration failed\n");
922 return ret; 1051 return ret;
923 } 1052 }
924 } 1053 }
925 1054
926 return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, 1055 return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
927 clkc_data->hw_onecell_data); 1056 &axg_hw_onecell_data);
928} 1057}
929 1058
930static struct platform_driver axg_driver = { 1059static struct platform_driver axg_driver = {
diff --git a/drivers/clk/meson/axg.h b/drivers/clk/meson/axg.h
index ce0bafdb6b28..b421df6a7ea0 100644
--- a/drivers/clk/meson/axg.h
+++ b/drivers/clk/meson/axg.h
@@ -117,8 +117,18 @@
117#define CLKID_SD_EMMC_B_CLK0_DIV 62 117#define CLKID_SD_EMMC_B_CLK0_DIV 62
118#define CLKID_SD_EMMC_C_CLK0_SEL 63 118#define CLKID_SD_EMMC_C_CLK0_SEL 63
119#define CLKID_SD_EMMC_C_CLK0_DIV 64 119#define CLKID_SD_EMMC_C_CLK0_DIV 64
120#define CLKID_MPLL0_DIV 65
121#define CLKID_MPLL1_DIV 66
122#define CLKID_MPLL2_DIV 67
123#define CLKID_MPLL3_DIV 68
124#define CLKID_MPLL_PREDIV 70
125#define CLKID_FCLK_DIV2_DIV 71
126#define CLKID_FCLK_DIV3_DIV 72
127#define CLKID_FCLK_DIV4_DIV 73
128#define CLKID_FCLK_DIV5_DIV 74
129#define CLKID_FCLK_DIV7_DIV 75
120 130
121#define NR_CLKS 65 131#define NR_CLKS 76
122 132
123/* include the CLKIDs that have been made part of the DT binding */ 133/* include the CLKIDs that have been made part of the DT binding */
124#include <dt-bindings/clock/axg-clkc.h> 134#include <dt-bindings/clock/axg-clkc.h>
diff --git a/drivers/clk/meson/clk-audio-divider.c b/drivers/clk/meson/clk-audio-divider.c
index 6c07db06642d..f7ab5b1db342 100644
--- a/drivers/clk/meson/clk-audio-divider.c
+++ b/drivers/clk/meson/clk-audio-divider.c
@@ -28,8 +28,11 @@
28#include <linux/clk-provider.h> 28#include <linux/clk-provider.h>
29#include "clkc.h" 29#include "clkc.h"
30 30
31#define to_meson_clk_audio_divider(_hw) container_of(_hw, \ 31static inline struct meson_clk_audio_div_data *
32 struct meson_clk_audio_divider, hw) 32meson_clk_audio_div_data(struct clk_regmap *clk)
33{
34 return (struct meson_clk_audio_div_data *)clk->data;
35}
33 36
34static int _div_round(unsigned long parent_rate, unsigned long rate, 37static int _div_round(unsigned long parent_rate, unsigned long rate,
35 unsigned long flags) 38 unsigned long flags)
@@ -45,15 +48,9 @@ static int _get_val(unsigned long parent_rate, unsigned long rate)
45 return DIV_ROUND_UP_ULL((u64)parent_rate, rate) - 1; 48 return DIV_ROUND_UP_ULL((u64)parent_rate, rate) - 1;
46} 49}
47 50
48static int _valid_divider(struct clk_hw *hw, int divider) 51static int _valid_divider(unsigned int width, int divider)
49{ 52{
50 struct meson_clk_audio_divider *adiv = 53 int max_divider = 1 << width;
51 to_meson_clk_audio_divider(hw);
52 int max_divider;
53 u8 width;
54
55 width = adiv->div.width;
56 max_divider = 1 << width;
57 54
58 return clamp(divider, 1, max_divider); 55 return clamp(divider, 1, max_divider);
59} 56}
@@ -61,14 +58,11 @@ static int _valid_divider(struct clk_hw *hw, int divider)
61static unsigned long audio_divider_recalc_rate(struct clk_hw *hw, 58static unsigned long audio_divider_recalc_rate(struct clk_hw *hw,
62 unsigned long parent_rate) 59 unsigned long parent_rate)
63{ 60{
64 struct meson_clk_audio_divider *adiv = 61 struct clk_regmap *clk = to_clk_regmap(hw);
65 to_meson_clk_audio_divider(hw); 62 struct meson_clk_audio_div_data *adiv = meson_clk_audio_div_data(clk);
66 struct parm *p; 63 unsigned long divider;
67 unsigned long reg, divider;
68 64
69 p = &adiv->div; 65 divider = meson_parm_read(clk->map, &adiv->div);
70 reg = readl(adiv->base + p->reg_off);
71 divider = PARM_GET(p->width, p->shift, reg) + 1;
72 66
73 return DIV_ROUND_UP_ULL((u64)parent_rate, divider); 67 return DIV_ROUND_UP_ULL((u64)parent_rate, divider);
74} 68}
@@ -77,14 +71,14 @@ static long audio_divider_round_rate(struct clk_hw *hw,
77 unsigned long rate, 71 unsigned long rate,
78 unsigned long *parent_rate) 72 unsigned long *parent_rate)
79{ 73{
80 struct meson_clk_audio_divider *adiv = 74 struct clk_regmap *clk = to_clk_regmap(hw);
81 to_meson_clk_audio_divider(hw); 75 struct meson_clk_audio_div_data *adiv = meson_clk_audio_div_data(clk);
82 unsigned long max_prate; 76 unsigned long max_prate;
83 int divider; 77 int divider;
84 78
85 if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) { 79 if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) {
86 divider = _div_round(*parent_rate, rate, adiv->flags); 80 divider = _div_round(*parent_rate, rate, adiv->flags);
87 divider = _valid_divider(hw, divider); 81 divider = _valid_divider(adiv->div.width, divider);
88 return DIV_ROUND_UP_ULL((u64)*parent_rate, divider); 82 return DIV_ROUND_UP_ULL((u64)*parent_rate, divider);
89 } 83 }
90 84
@@ -93,7 +87,7 @@ static long audio_divider_round_rate(struct clk_hw *hw,
93 87
94 /* Get the corresponding rounded down divider */ 88 /* Get the corresponding rounded down divider */
95 divider = max_prate / rate; 89 divider = max_prate / rate;
96 divider = _valid_divider(hw, divider); 90 divider = _valid_divider(adiv->div.width, divider);
97 91
98 /* Get actual rate of the parent */ 92 /* Get actual rate of the parent */
99 *parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw), 93 *parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw),
@@ -106,28 +100,11 @@ static int audio_divider_set_rate(struct clk_hw *hw,
106 unsigned long rate, 100 unsigned long rate,
107 unsigned long parent_rate) 101 unsigned long parent_rate)
108{ 102{
109 struct meson_clk_audio_divider *adiv = 103 struct clk_regmap *clk = to_clk_regmap(hw);
110 to_meson_clk_audio_divider(hw); 104 struct meson_clk_audio_div_data *adiv = meson_clk_audio_div_data(clk);
111 struct parm *p; 105 int val = _get_val(parent_rate, rate);
112 unsigned long reg, flags = 0; 106
113 int val; 107 meson_parm_write(clk->map, &adiv->div, val);
114
115 val = _get_val(parent_rate, rate);
116
117 if (adiv->lock)
118 spin_lock_irqsave(adiv->lock, flags);
119 else
120 __acquire(adiv->lock);
121
122 p = &adiv->div;
123 reg = readl(adiv->base + p->reg_off);
124 reg = PARM_SET(p->width, p->shift, reg, val);
125 writel(reg, adiv->base + p->reg_off);
126
127 if (adiv->lock)
128 spin_unlock_irqrestore(adiv->lock, flags);
129 else
130 __release(adiv->lock);
131 108
132 return 0; 109 return 0;
133} 110}
diff --git a/drivers/clk/meson/clk-cpu.c b/drivers/clk/meson/clk-cpu.c
deleted file mode 100644
index f8b2b7efd016..000000000000
--- a/drivers/clk/meson/clk-cpu.c
+++ /dev/null
@@ -1,178 +0,0 @@
1/*
2 * Copyright (c) 2015 Endless Mobile, Inc.
3 * Author: Carlo Caione <carlo@endlessm.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18/*
19 * CPU clock path:
20 *
21 * +-[/N]-----|3|
22 * MUX2 +--[/3]-+----------|2| MUX1
23 * [sys_pll]---|1| |--[/2]------------|1|-|1|
24 * | |---+------------------|0| | |----- [a5_clk]
25 * +--|0| | |
26 * [xtal]---+-------------------------------|0|
27 *
28 *
29 *
30 */
31
32#include <linux/delay.h>
33#include <linux/err.h>
34#include <linux/io.h>
35#include <linux/module.h>
36#include <linux/of_address.h>
37#include <linux/slab.h>
38#include <linux/clk.h>
39#include <linux/clk-provider.h>
40
41#define MESON_CPU_CLK_CNTL1 0x00
42#define MESON_CPU_CLK_CNTL 0x40
43
44#define MESON_CPU_CLK_MUX1 BIT(7)
45#define MESON_CPU_CLK_MUX2 BIT(0)
46
47#define MESON_N_WIDTH 9
48#define MESON_N_SHIFT 20
49#define MESON_SEL_WIDTH 2
50#define MESON_SEL_SHIFT 2
51
52#include "clkc.h"
53
54#define to_meson_clk_cpu_hw(_hw) container_of(_hw, struct meson_clk_cpu, hw)
55#define to_meson_clk_cpu_nb(_nb) container_of(_nb, struct meson_clk_cpu, clk_nb)
56
57static long meson_clk_cpu_round_rate(struct clk_hw *hw, unsigned long rate,
58 unsigned long *prate)
59{
60 struct meson_clk_cpu *clk_cpu = to_meson_clk_cpu_hw(hw);
61
62 return divider_round_rate(hw, rate, prate, clk_cpu->div_table,
63 MESON_N_WIDTH, CLK_DIVIDER_ROUND_CLOSEST);
64}
65
66static int meson_clk_cpu_set_rate(struct clk_hw *hw, unsigned long rate,
67 unsigned long parent_rate)
68{
69 struct meson_clk_cpu *clk_cpu = to_meson_clk_cpu_hw(hw);
70 unsigned int div, sel, N = 0;
71 u32 reg;
72
73 div = DIV_ROUND_UP(parent_rate, rate);
74
75 if (div <= 3) {
76 sel = div - 1;
77 } else {
78 sel = 3;
79 N = div / 2;
80 }
81
82 reg = readl(clk_cpu->base + clk_cpu->reg_off + MESON_CPU_CLK_CNTL1);
83 reg = PARM_SET(MESON_N_WIDTH, MESON_N_SHIFT, reg, N);
84 writel(reg, clk_cpu->base + clk_cpu->reg_off + MESON_CPU_CLK_CNTL1);
85
86 reg = readl(clk_cpu->base + clk_cpu->reg_off + MESON_CPU_CLK_CNTL);
87 reg = PARM_SET(MESON_SEL_WIDTH, MESON_SEL_SHIFT, reg, sel);
88 writel(reg, clk_cpu->base + clk_cpu->reg_off + MESON_CPU_CLK_CNTL);
89
90 return 0;
91}
92
93static unsigned long meson_clk_cpu_recalc_rate(struct clk_hw *hw,
94 unsigned long parent_rate)
95{
96 struct meson_clk_cpu *clk_cpu = to_meson_clk_cpu_hw(hw);
97 unsigned int N, sel;
98 unsigned int div = 1;
99 u32 reg;
100
101 reg = readl(clk_cpu->base + clk_cpu->reg_off + MESON_CPU_CLK_CNTL1);
102 N = PARM_GET(MESON_N_WIDTH, MESON_N_SHIFT, reg);
103
104 reg = readl(clk_cpu->base + clk_cpu->reg_off + MESON_CPU_CLK_CNTL);
105 sel = PARM_GET(MESON_SEL_WIDTH, MESON_SEL_SHIFT, reg);
106
107 if (sel < 3)
108 div = sel + 1;
109 else
110 div = 2 * N;
111
112 return parent_rate / div;
113}
114
115/* FIXME MUX1 & MUX2 should be struct clk_hw objects */
116static int meson_clk_cpu_pre_rate_change(struct meson_clk_cpu *clk_cpu,
117 struct clk_notifier_data *ndata)
118{
119 u32 cpu_clk_cntl;
120
121 /* switch MUX1 to xtal */
122 cpu_clk_cntl = readl(clk_cpu->base + clk_cpu->reg_off
123 + MESON_CPU_CLK_CNTL);
124 cpu_clk_cntl &= ~MESON_CPU_CLK_MUX1;
125 writel(cpu_clk_cntl, clk_cpu->base + clk_cpu->reg_off
126 + MESON_CPU_CLK_CNTL);
127 udelay(100);
128
129 /* switch MUX2 to sys-pll */
130 cpu_clk_cntl |= MESON_CPU_CLK_MUX2;
131 writel(cpu_clk_cntl, clk_cpu->base + clk_cpu->reg_off
132 + MESON_CPU_CLK_CNTL);
133
134 return 0;
135}
136
137/* FIXME MUX1 & MUX2 should be struct clk_hw objects */
138static int meson_clk_cpu_post_rate_change(struct meson_clk_cpu *clk_cpu,
139 struct clk_notifier_data *ndata)
140{
141 u32 cpu_clk_cntl;
142
143 /* switch MUX1 to divisors' output */
144 cpu_clk_cntl = readl(clk_cpu->base + clk_cpu->reg_off
145 + MESON_CPU_CLK_CNTL);
146 cpu_clk_cntl |= MESON_CPU_CLK_MUX1;
147 writel(cpu_clk_cntl, clk_cpu->base + clk_cpu->reg_off
148 + MESON_CPU_CLK_CNTL);
149 udelay(100);
150
151 return 0;
152}
153
154/*
155 * This clock notifier is called when the frequency of the of the parent
156 * PLL clock is to be changed. We use the xtal input as temporary parent
157 * while the PLL frequency is stabilized.
158 */
159int meson_clk_cpu_notifier_cb(struct notifier_block *nb,
160 unsigned long event, void *data)
161{
162 struct clk_notifier_data *ndata = data;
163 struct meson_clk_cpu *clk_cpu = to_meson_clk_cpu_nb(nb);
164 int ret = 0;
165
166 if (event == PRE_RATE_CHANGE)
167 ret = meson_clk_cpu_pre_rate_change(clk_cpu, ndata);
168 else if (event == POST_RATE_CHANGE)
169 ret = meson_clk_cpu_post_rate_change(clk_cpu, ndata);
170
171 return notifier_from_errno(ret);
172}
173
174const struct clk_ops meson_clk_cpu_ops = {
175 .recalc_rate = meson_clk_cpu_recalc_rate,
176 .round_rate = meson_clk_cpu_round_rate,
177 .set_rate = meson_clk_cpu_set_rate,
178};
diff --git a/drivers/clk/meson/clk-mpll.c b/drivers/clk/meson/clk-mpll.c
index 5144360e2c80..0df1227b65b3 100644
--- a/drivers/clk/meson/clk-mpll.c
+++ b/drivers/clk/meson/clk-mpll.c
@@ -68,11 +68,15 @@
68#define N2_MIN 4 68#define N2_MIN 4
69#define N2_MAX 511 69#define N2_MAX 511
70 70
71#define to_meson_clk_mpll(_hw) container_of(_hw, struct meson_clk_mpll, hw) 71static inline struct meson_clk_mpll_data *
72meson_clk_mpll_data(struct clk_regmap *clk)
73{
74 return (struct meson_clk_mpll_data *)clk->data;
75}
72 76
73static long rate_from_params(unsigned long parent_rate, 77static long rate_from_params(unsigned long parent_rate,
74 unsigned long sdm, 78 unsigned int sdm,
75 unsigned long n2) 79 unsigned int n2)
76{ 80{
77 unsigned long divisor = (SDM_DEN * n2) + sdm; 81 unsigned long divisor = (SDM_DEN * n2) + sdm;
78 82
@@ -84,8 +88,8 @@ static long rate_from_params(unsigned long parent_rate,
84 88
85static void params_from_rate(unsigned long requested_rate, 89static void params_from_rate(unsigned long requested_rate,
86 unsigned long parent_rate, 90 unsigned long parent_rate,
87 unsigned long *sdm, 91 unsigned int *sdm,
88 unsigned long *n2) 92 unsigned int *n2)
89{ 93{
90 uint64_t div = parent_rate; 94 uint64_t div = parent_rate;
91 unsigned long rem = do_div(div, requested_rate); 95 unsigned long rem = do_div(div, requested_rate);
@@ -105,31 +109,23 @@ static void params_from_rate(unsigned long requested_rate,
105static unsigned long mpll_recalc_rate(struct clk_hw *hw, 109static unsigned long mpll_recalc_rate(struct clk_hw *hw,
106 unsigned long parent_rate) 110 unsigned long parent_rate)
107{ 111{
108 struct meson_clk_mpll *mpll = to_meson_clk_mpll(hw); 112 struct clk_regmap *clk = to_clk_regmap(hw);
109 struct parm *p; 113 struct meson_clk_mpll_data *mpll = meson_clk_mpll_data(clk);
110 unsigned long reg, sdm, n2; 114 unsigned int sdm, n2;
111 long rate; 115 long rate;
112 116
113 p = &mpll->sdm; 117 sdm = meson_parm_read(clk->map, &mpll->sdm);
114 reg = readl(mpll->base + p->reg_off); 118 n2 = meson_parm_read(clk->map, &mpll->n2);
115 sdm = PARM_GET(p->width, p->shift, reg);
116
117 p = &mpll->n2;
118 reg = readl(mpll->base + p->reg_off);
119 n2 = PARM_GET(p->width, p->shift, reg);
120 119
121 rate = rate_from_params(parent_rate, sdm, n2); 120 rate = rate_from_params(parent_rate, sdm, n2);
122 if (rate < 0) 121 return rate < 0 ? 0 : rate;
123 return 0;
124
125 return rate;
126} 122}
127 123
128static long mpll_round_rate(struct clk_hw *hw, 124static long mpll_round_rate(struct clk_hw *hw,
129 unsigned long rate, 125 unsigned long rate,
130 unsigned long *parent_rate) 126 unsigned long *parent_rate)
131{ 127{
132 unsigned long sdm, n2; 128 unsigned int sdm, n2;
133 129
134 params_from_rate(rate, *parent_rate, &sdm, &n2); 130 params_from_rate(rate, *parent_rate, &sdm, &n2);
135 return rate_from_params(*parent_rate, sdm, n2); 131 return rate_from_params(*parent_rate, sdm, n2);
@@ -139,9 +135,9 @@ static int mpll_set_rate(struct clk_hw *hw,
139 unsigned long rate, 135 unsigned long rate,
140 unsigned long parent_rate) 136 unsigned long parent_rate)
141{ 137{
142 struct meson_clk_mpll *mpll = to_meson_clk_mpll(hw); 138 struct clk_regmap *clk = to_clk_regmap(hw);
143 struct parm *p; 139 struct meson_clk_mpll_data *mpll = meson_clk_mpll_data(clk);
144 unsigned long reg, sdm, n2; 140 unsigned int sdm, n2;
145 unsigned long flags = 0; 141 unsigned long flags = 0;
146 142
147 params_from_rate(rate, parent_rate, &sdm, &n2); 143 params_from_rate(rate, parent_rate, &sdm, &n2);
@@ -151,97 +147,36 @@ static int mpll_set_rate(struct clk_hw *hw,
151 else 147 else
152 __acquire(mpll->lock); 148 __acquire(mpll->lock);
153 149
154 p = &mpll->sdm; 150 /* Enable and set the fractional part */
155 reg = readl(mpll->base + p->reg_off); 151 meson_parm_write(clk->map, &mpll->sdm, sdm);
156 reg = PARM_SET(p->width, p->shift, reg, sdm); 152 meson_parm_write(clk->map, &mpll->sdm_en, 1);
157 writel(reg, mpll->base + p->reg_off);
158
159 p = &mpll->sdm_en;
160 reg = readl(mpll->base + p->reg_off);
161 reg = PARM_SET(p->width, p->shift, reg, 1);
162 writel(reg, mpll->base + p->reg_off);
163
164 p = &mpll->ssen;
165 if (p->width != 0) {
166 reg = readl(mpll->base + p->reg_off);
167 reg = PARM_SET(p->width, p->shift, reg, 1);
168 writel(reg, mpll->base + p->reg_off);
169 }
170
171 p = &mpll->n2;
172 reg = readl(mpll->base + p->reg_off);
173 reg = PARM_SET(p->width, p->shift, reg, n2);
174 writel(reg, mpll->base + p->reg_off);
175
176 if (mpll->lock)
177 spin_unlock_irqrestore(mpll->lock, flags);
178 else
179 __release(mpll->lock);
180
181 return 0;
182}
183 153
184static void mpll_enable_core(struct clk_hw *hw, int enable) 154 /* Set additional fractional part enable if required */
185{ 155 if (MESON_PARM_APPLICABLE(&mpll->ssen))
186 struct meson_clk_mpll *mpll = to_meson_clk_mpll(hw); 156 meson_parm_write(clk->map, &mpll->ssen, 1);
187 struct parm *p;
188 unsigned long reg;
189 unsigned long flags = 0;
190 157
191 if (mpll->lock) 158 /* Set the integer divider part */
192 spin_lock_irqsave(mpll->lock, flags); 159 meson_parm_write(clk->map, &mpll->n2, n2);
193 else
194 __acquire(mpll->lock);
195 160
196 p = &mpll->en; 161 /* Set the magic misc bit if required */
197 reg = readl(mpll->base + p->reg_off); 162 if (MESON_PARM_APPLICABLE(&mpll->misc))
198 reg = PARM_SET(p->width, p->shift, reg, enable ? 1 : 0); 163 meson_parm_write(clk->map, &mpll->misc, 1);
199 writel(reg, mpll->base + p->reg_off);
200 164
201 if (mpll->lock) 165 if (mpll->lock)
202 spin_unlock_irqrestore(mpll->lock, flags); 166 spin_unlock_irqrestore(mpll->lock, flags);
203 else 167 else
204 __release(mpll->lock); 168 __release(mpll->lock);
205}
206
207
208static int mpll_enable(struct clk_hw *hw)
209{
210 mpll_enable_core(hw, 1);
211 169
212 return 0; 170 return 0;
213} 171}
214 172
215static void mpll_disable(struct clk_hw *hw)
216{
217 mpll_enable_core(hw, 0);
218}
219
220static int mpll_is_enabled(struct clk_hw *hw)
221{
222 struct meson_clk_mpll *mpll = to_meson_clk_mpll(hw);
223 struct parm *p;
224 unsigned long reg;
225 int en;
226
227 p = &mpll->en;
228 reg = readl(mpll->base + p->reg_off);
229 en = PARM_GET(p->width, p->shift, reg);
230
231 return en;
232}
233
234const struct clk_ops meson_clk_mpll_ro_ops = { 173const struct clk_ops meson_clk_mpll_ro_ops = {
235 .recalc_rate = mpll_recalc_rate, 174 .recalc_rate = mpll_recalc_rate,
236 .round_rate = mpll_round_rate, 175 .round_rate = mpll_round_rate,
237 .is_enabled = mpll_is_enabled,
238}; 176};
239 177
240const struct clk_ops meson_clk_mpll_ops = { 178const struct clk_ops meson_clk_mpll_ops = {
241 .recalc_rate = mpll_recalc_rate, 179 .recalc_rate = mpll_recalc_rate,
242 .round_rate = mpll_round_rate, 180 .round_rate = mpll_round_rate,
243 .set_rate = mpll_set_rate, 181 .set_rate = mpll_set_rate,
244 .enable = mpll_enable,
245 .disable = mpll_disable,
246 .is_enabled = mpll_is_enabled,
247}; 182};
diff --git a/drivers/clk/meson/clk-pll.c b/drivers/clk/meson/clk-pll.c
index 01341553f50b..65a7bd903551 100644
--- a/drivers/clk/meson/clk-pll.c
+++ b/drivers/clk/meson/clk-pll.c
@@ -2,6 +2,9 @@
2 * Copyright (c) 2015 Endless Mobile, Inc. 2 * Copyright (c) 2015 Endless Mobile, Inc.
3 * Author: Carlo Caione <carlo@endlessm.com> 3 * Author: Carlo Caione <carlo@endlessm.com>
4 * 4 *
5 * Copyright (c) 2018 Baylibre, SAS.
6 * Author: Jerome Brunet <jbrunet@baylibre.com>
7 *
5 * This program is free software; you can redistribute it and/or modify it 8 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License, 9 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation. 10 * version 2, as published by the Free Software Foundation.
@@ -27,13 +30,14 @@
27 * | | 30 * | |
28 * FREF VCO 31 * FREF VCO
29 * 32 *
30 * out = (in * M / N) >> OD 33 * out = in * (m + frac / frac_max) / (n << sum(ods))
31 */ 34 */
32 35
33#include <linux/clk-provider.h> 36#include <linux/clk-provider.h>
34#include <linux/delay.h> 37#include <linux/delay.h>
35#include <linux/err.h> 38#include <linux/err.h>
36#include <linux/io.h> 39#include <linux/io.h>
40#include <linux/math64.h>
37#include <linux/module.h> 41#include <linux/module.h>
38#include <linux/of_address.h> 42#include <linux/of_address.h>
39#include <linux/slab.h> 43#include <linux/slab.h>
@@ -41,209 +45,213 @@
41 45
42#include "clkc.h" 46#include "clkc.h"
43 47
44#define MESON_PLL_RESET BIT(29) 48static inline struct meson_clk_pll_data *
45#define MESON_PLL_LOCK BIT(31) 49meson_clk_pll_data(struct clk_regmap *clk)
46
47#define to_meson_clk_pll(_hw) container_of(_hw, struct meson_clk_pll, hw)
48
49static unsigned long meson_clk_pll_recalc_rate(struct clk_hw *hw,
50 unsigned long parent_rate)
51{ 50{
52 struct meson_clk_pll *pll = to_meson_clk_pll(hw); 51 return (struct meson_clk_pll_data *)clk->data;
53 struct parm *p;
54 unsigned long parent_rate_mhz = parent_rate / 1000000;
55 unsigned long rate_mhz;
56 u16 n, m, frac = 0, od, od2 = 0;
57 u32 reg;
58
59 p = &pll->n;
60 reg = readl(pll->base + p->reg_off);
61 n = PARM_GET(p->width, p->shift, reg);
62
63 p = &pll->m;
64 reg = readl(pll->base + p->reg_off);
65 m = PARM_GET(p->width, p->shift, reg);
66
67 p = &pll->od;
68 reg = readl(pll->base + p->reg_off);
69 od = PARM_GET(p->width, p->shift, reg);
70
71 p = &pll->od2;
72 if (p->width) {
73 reg = readl(pll->base + p->reg_off);
74 od2 = PARM_GET(p->width, p->shift, reg);
75 }
76
77 p = &pll->frac;
78 if (p->width) {
79 reg = readl(pll->base + p->reg_off);
80 frac = PARM_GET(p->width, p->shift, reg);
81 rate_mhz = (parent_rate_mhz * m + \
82 (parent_rate_mhz * frac >> 12)) * 2 / n;
83 rate_mhz = rate_mhz >> od >> od2;
84 } else
85 rate_mhz = (parent_rate_mhz * m / n) >> od >> od2;
86
87 return rate_mhz * 1000000;
88} 52}
89 53
90static long meson_clk_pll_round_rate(struct clk_hw *hw, unsigned long rate, 54static unsigned long __pll_params_to_rate(unsigned long parent_rate,
91 unsigned long *parent_rate) 55 const struct pll_rate_table *pllt,
56 u16 frac,
57 struct meson_clk_pll_data *pll)
92{ 58{
93 struct meson_clk_pll *pll = to_meson_clk_pll(hw); 59 u64 rate = (u64)parent_rate * pllt->m;
94 const struct pll_rate_table *rate_table = pll->rate_table; 60 unsigned int od = pllt->od + pllt->od2 + pllt->od3;
95 int i;
96 61
97 for (i = 0; i < pll->rate_count; i++) { 62 if (frac && MESON_PARM_APPLICABLE(&pll->frac)) {
98 if (rate <= rate_table[i].rate) 63 u64 frac_rate = (u64)parent_rate * frac;
99 return rate_table[i].rate; 64
65 rate += DIV_ROUND_UP_ULL(frac_rate,
66 (1 << pll->frac.width));
100 } 67 }
101 68
102 /* else return the smallest value */ 69 return DIV_ROUND_UP_ULL(rate, pllt->n << od);
103 return rate_table[0].rate;
104} 70}
105 71
106static const struct pll_rate_table *meson_clk_get_pll_settings(struct meson_clk_pll *pll, 72static unsigned long meson_clk_pll_recalc_rate(struct clk_hw *hw,
107 unsigned long rate) 73 unsigned long parent_rate)
108{ 74{
109 const struct pll_rate_table *rate_table = pll->rate_table; 75 struct clk_regmap *clk = to_clk_regmap(hw);
110 int i; 76 struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
77 struct pll_rate_table pllt;
78 u16 frac;
111 79
112 for (i = 0; i < pll->rate_count; i++) { 80 pllt.n = meson_parm_read(clk->map, &pll->n);
113 if (rate == rate_table[i].rate) 81 pllt.m = meson_parm_read(clk->map, &pll->m);
114 return &rate_table[i]; 82 pllt.od = meson_parm_read(clk->map, &pll->od);
115 } 83
116 return NULL; 84 pllt.od2 = MESON_PARM_APPLICABLE(&pll->od2) ?
85 meson_parm_read(clk->map, &pll->od2) :
86 0;
87
88 pllt.od3 = MESON_PARM_APPLICABLE(&pll->od3) ?
89 meson_parm_read(clk->map, &pll->od3) :
90 0;
91
92 frac = MESON_PARM_APPLICABLE(&pll->frac) ?
93 meson_parm_read(clk->map, &pll->frac) :
94 0;
95
96 return __pll_params_to_rate(parent_rate, &pllt, frac, pll);
117} 97}
118 98
119/* Specific wait loop for GXL/GXM GP0 PLL */ 99static u16 __pll_params_with_frac(unsigned long rate,
120static int meson_clk_pll_wait_lock_reset(struct meson_clk_pll *pll, 100 unsigned long parent_rate,
121 struct parm *p_n) 101 const struct pll_rate_table *pllt,
102 struct meson_clk_pll_data *pll)
122{ 103{
123 int delay = 100; 104 u16 frac_max = (1 << pll->frac.width);
124 u32 reg; 105 u64 val = (u64)rate * pllt->n;
125 106
126 while (delay > 0) { 107 val <<= pllt->od + pllt->od2 + pllt->od3;
127 reg = readl(pll->base + p_n->reg_off);
128 writel(reg | MESON_PLL_RESET, pll->base + p_n->reg_off);
129 udelay(10);
130 writel(reg & ~MESON_PLL_RESET, pll->base + p_n->reg_off);
131 108
132 /* This delay comes from AMLogic tree clk-gp0-gxl driver */ 109 if (pll->flags & CLK_MESON_PLL_ROUND_CLOSEST)
133 mdelay(1); 110 val = DIV_ROUND_CLOSEST_ULL(val * frac_max, parent_rate);
111 else
112 val = div_u64(val * frac_max, parent_rate);
134 113
135 reg = readl(pll->base + p_n->reg_off); 114 val -= pllt->m * frac_max;
136 if (reg & MESON_PLL_LOCK) 115
137 return 0; 116 return min((u16)val, (u16)(frac_max - 1));
138 delay--; 117}
118
119static const struct pll_rate_table *
120meson_clk_get_pll_settings(unsigned long rate,
121 struct meson_clk_pll_data *pll)
122{
123 const struct pll_rate_table *table = pll->table;
124 unsigned int i = 0;
125
126 if (!table)
127 return NULL;
128
129 /* Find the first table element exceeding rate */
130 while (table[i].rate && table[i].rate <= rate)
131 i++;
132
133 if (i != 0) {
134 if (MESON_PARM_APPLICABLE(&pll->frac) ||
135 !(pll->flags & CLK_MESON_PLL_ROUND_CLOSEST) ||
136 (abs(rate - table[i - 1].rate) <
137 abs(rate - table[i].rate)))
138 i--;
139 } 139 }
140 return -ETIMEDOUT; 140
141 return (struct pll_rate_table *)&table[i];
141} 142}
142 143
143static int meson_clk_pll_wait_lock(struct meson_clk_pll *pll, 144static long meson_clk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
144 struct parm *p_n) 145 unsigned long *parent_rate)
145{ 146{
146 int delay = 24000000; 147 struct clk_regmap *clk = to_clk_regmap(hw);
147 u32 reg; 148 struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
149 const struct pll_rate_table *pllt =
150 meson_clk_get_pll_settings(rate, pll);
151 u16 frac;
152
153 if (!pllt)
154 return meson_clk_pll_recalc_rate(hw, *parent_rate);
155
156 if (!MESON_PARM_APPLICABLE(&pll->frac)
157 || rate == pllt->rate)
158 return pllt->rate;
159
160 /*
161 * The rate provided by the setting is not an exact match, let's
162 * try to improve the result using the fractional parameter
163 */
164 frac = __pll_params_with_frac(rate, *parent_rate, pllt, pll);
165
166 return __pll_params_to_rate(*parent_rate, pllt, frac, pll);
167}
148 168
149 while (delay > 0) { 169static int meson_clk_pll_wait_lock(struct clk_hw *hw)
150 reg = readl(pll->base + p_n->reg_off); 170{
171 struct clk_regmap *clk = to_clk_regmap(hw);
172 struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
173 int delay = 24000000;
151 174
152 if (reg & MESON_PLL_LOCK) 175 do {
176 /* Is the clock locked now ? */
177 if (meson_parm_read(clk->map, &pll->l))
153 return 0; 178 return 0;
179
154 delay--; 180 delay--;
155 } 181 } while (delay > 0);
182
156 return -ETIMEDOUT; 183 return -ETIMEDOUT;
157} 184}
158 185
159static void meson_clk_pll_init_params(struct meson_clk_pll *pll) 186static void meson_clk_pll_init(struct clk_hw *hw)
160{ 187{
161 int i; 188 struct clk_regmap *clk = to_clk_regmap(hw);
162 189 struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
163 for (i = 0 ; i < pll->params.params_count ; ++i) 190
164 writel(pll->params.params_table[i].value, 191 if (pll->init_count) {
165 pll->base + pll->params.params_table[i].reg_off); 192 meson_parm_write(clk->map, &pll->rst, 1);
193 regmap_multi_reg_write(clk->map, pll->init_regs,
194 pll->init_count);
195 meson_parm_write(clk->map, &pll->rst, 0);
196 }
166} 197}
167 198
168static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, 199static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
169 unsigned long parent_rate) 200 unsigned long parent_rate)
170{ 201{
171 struct meson_clk_pll *pll = to_meson_clk_pll(hw); 202 struct clk_regmap *clk = to_clk_regmap(hw);
172 struct parm *p; 203 struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
173 const struct pll_rate_table *rate_set; 204 const struct pll_rate_table *pllt;
174 unsigned long old_rate; 205 unsigned long old_rate;
175 int ret = 0; 206 u16 frac = 0;
176 u32 reg;
177 207
178 if (parent_rate == 0 || rate == 0) 208 if (parent_rate == 0 || rate == 0)
179 return -EINVAL; 209 return -EINVAL;
180 210
181 old_rate = rate; 211 old_rate = rate;
182 212
183 rate_set = meson_clk_get_pll_settings(pll, rate); 213 pllt = meson_clk_get_pll_settings(rate, pll);
184 if (!rate_set) 214 if (!pllt)
185 return -EINVAL; 215 return -EINVAL;
186 216
187 /* Initialize the PLL in a clean state if specified */ 217 /* Put the pll in reset to write the params */
188 if (pll->params.params_count) 218 meson_parm_write(clk->map, &pll->rst, 1);
189 meson_clk_pll_init_params(pll);
190
191 /* PLL reset */
192 p = &pll->n;
193 reg = readl(pll->base + p->reg_off);
194 /* If no_init_reset is provided, avoid resetting at this point */
195 if (!pll->params.no_init_reset)
196 writel(reg | MESON_PLL_RESET, pll->base + p->reg_off);
197
198 reg = PARM_SET(p->width, p->shift, reg, rate_set->n);
199 writel(reg, pll->base + p->reg_off);
200
201 p = &pll->m;
202 reg = readl(pll->base + p->reg_off);
203 reg = PARM_SET(p->width, p->shift, reg, rate_set->m);
204 writel(reg, pll->base + p->reg_off);
205
206 p = &pll->od;
207 reg = readl(pll->base + p->reg_off);
208 reg = PARM_SET(p->width, p->shift, reg, rate_set->od);
209 writel(reg, pll->base + p->reg_off);
210
211 p = &pll->od2;
212 if (p->width) {
213 reg = readl(pll->base + p->reg_off);
214 reg = PARM_SET(p->width, p->shift, reg, rate_set->od2);
215 writel(reg, pll->base + p->reg_off);
216 }
217 219
218 p = &pll->frac; 220 meson_parm_write(clk->map, &pll->n, pllt->n);
219 if (p->width) { 221 meson_parm_write(clk->map, &pll->m, pllt->m);
220 reg = readl(pll->base + p->reg_off); 222 meson_parm_write(clk->map, &pll->od, pllt->od);
221 reg = PARM_SET(p->width, p->shift, reg, rate_set->frac); 223
222 writel(reg, pll->base + p->reg_off); 224 if (MESON_PARM_APPLICABLE(&pll->od2))
223 } 225 meson_parm_write(clk->map, &pll->od2, pllt->od2);
226
227 if (MESON_PARM_APPLICABLE(&pll->od3))
228 meson_parm_write(clk->map, &pll->od3, pllt->od3);
224 229
225 p = &pll->n; 230 if (MESON_PARM_APPLICABLE(&pll->frac)) {
226 /* If clear_reset_for_lock is provided, remove the reset bit here */ 231 frac = __pll_params_with_frac(rate, parent_rate, pllt, pll);
227 if (pll->params.clear_reset_for_lock) { 232 meson_parm_write(clk->map, &pll->frac, frac);
228 reg = readl(pll->base + p->reg_off);
229 writel(reg & ~MESON_PLL_RESET, pll->base + p->reg_off);
230 } 233 }
231 234
232 /* If reset_lock_loop, use a special loop including resetting */ 235 /* make sure the reset is cleared at this point */
233 if (pll->params.reset_lock_loop) 236 meson_parm_write(clk->map, &pll->rst, 0);
234 ret = meson_clk_pll_wait_lock_reset(pll, p); 237
235 else 238 if (meson_clk_pll_wait_lock(hw)) {
236 ret = meson_clk_pll_wait_lock(pll, p);
237 if (ret) {
238 pr_warn("%s: pll did not lock, trying to restore old rate %lu\n", 239 pr_warn("%s: pll did not lock, trying to restore old rate %lu\n",
239 __func__, old_rate); 240 __func__, old_rate);
241 /*
242 * FIXME: Do we really need/want this HACK ?
243 * It looks unsafe. what happens if the clock gets into a
244 * broken state and we can't lock back on the old_rate ? Looks
245 * like an infinite recursion is possible
246 */
240 meson_clk_pll_set_rate(hw, old_rate, parent_rate); 247 meson_clk_pll_set_rate(hw, old_rate, parent_rate);
241 } 248 }
242 249
243 return ret; 250 return 0;
244} 251}
245 252
246const struct clk_ops meson_clk_pll_ops = { 253const struct clk_ops meson_clk_pll_ops = {
254 .init = meson_clk_pll_init,
247 .recalc_rate = meson_clk_pll_recalc_rate, 255 .recalc_rate = meson_clk_pll_recalc_rate,
248 .round_rate = meson_clk_pll_round_rate, 256 .round_rate = meson_clk_pll_round_rate,
249 .set_rate = meson_clk_pll_set_rate, 257 .set_rate = meson_clk_pll_set_rate,
diff --git a/drivers/clk/meson/clk-regmap.c b/drivers/clk/meson/clk-regmap.c
new file mode 100644
index 000000000000..3645fdb62343
--- /dev/null
+++ b/drivers/clk/meson/clk-regmap.c
@@ -0,0 +1,166 @@
1// SPDX-License-Identifier: GPL-2.0
2// Copyright (c) 2018 BayLibre, SAS.
3// Author: Jerome Brunet <jbrunet@baylibre.com>
4
5#include "clk-regmap.h"
6
7static int clk_regmap_gate_endisable(struct clk_hw *hw, int enable)
8{
9 struct clk_regmap *clk = to_clk_regmap(hw);
10 struct clk_regmap_gate_data *gate = clk_get_regmap_gate_data(clk);
11 int set = gate->flags & CLK_GATE_SET_TO_DISABLE ? 1 : 0;
12
13 set ^= enable;
14
15 return regmap_update_bits(clk->map, gate->offset, BIT(gate->bit_idx),
16 set ? BIT(gate->bit_idx) : 0);
17}
18
19static int clk_regmap_gate_enable(struct clk_hw *hw)
20{
21 return clk_regmap_gate_endisable(hw, 1);
22}
23
24static void clk_regmap_gate_disable(struct clk_hw *hw)
25{
26 clk_regmap_gate_endisable(hw, 0);
27}
28
29static int clk_regmap_gate_is_enabled(struct clk_hw *hw)
30{
31 struct clk_regmap *clk = to_clk_regmap(hw);
32 struct clk_regmap_gate_data *gate = clk_get_regmap_gate_data(clk);
33 unsigned int val;
34
35 regmap_read(clk->map, gate->offset, &val);
36 if (gate->flags & CLK_GATE_SET_TO_DISABLE)
37 val ^= BIT(gate->bit_idx);
38
39 val &= BIT(gate->bit_idx);
40
41 return val ? 1 : 0;
42}
43
44const struct clk_ops clk_regmap_gate_ops = {
45 .enable = clk_regmap_gate_enable,
46 .disable = clk_regmap_gate_disable,
47 .is_enabled = clk_regmap_gate_is_enabled,
48};
49EXPORT_SYMBOL_GPL(clk_regmap_gate_ops);
50
51static unsigned long clk_regmap_div_recalc_rate(struct clk_hw *hw,
52 unsigned long prate)
53{
54 struct clk_regmap *clk = to_clk_regmap(hw);
55 struct clk_regmap_div_data *div = clk_get_regmap_div_data(clk);
56 unsigned int val;
57 int ret;
58
59 ret = regmap_read(clk->map, div->offset, &val);
60 if (ret)
61 /* Gives a hint that something is wrong */
62 return 0;
63
64 val >>= div->shift;
65 val &= clk_div_mask(div->width);
66 return divider_recalc_rate(hw, prate, val, div->table, div->flags,
67 div->width);
68}
69
70static long clk_regmap_div_round_rate(struct clk_hw *hw, unsigned long rate,
71 unsigned long *prate)
72{
73 struct clk_regmap *clk = to_clk_regmap(hw);
74 struct clk_regmap_div_data *div = clk_get_regmap_div_data(clk);
75 unsigned int val;
76 int ret;
77
78 /* if read only, just return current value */
79 if (div->flags & CLK_DIVIDER_READ_ONLY) {
80 ret = regmap_read(clk->map, div->offset, &val);
81 if (ret)
82 /* Gives a hint that something is wrong */
83 return 0;
84
85 val >>= div->shift;
86 val &= clk_div_mask(div->width);
87
88 return divider_ro_round_rate(hw, rate, prate, div->table,
89 div->width, div->flags, val);
90 }
91
92 return divider_round_rate(hw, rate, prate, div->table, div->width,
93 div->flags);
94}
95
96static int clk_regmap_div_set_rate(struct clk_hw *hw, unsigned long rate,
97 unsigned long parent_rate)
98{
99 struct clk_regmap *clk = to_clk_regmap(hw);
100 struct clk_regmap_div_data *div = clk_get_regmap_div_data(clk);
101 unsigned int val;
102 int ret;
103
104 ret = divider_get_val(rate, parent_rate, div->table, div->width,
105 div->flags);
106 if (ret < 0)
107 return ret;
108
109 val = (unsigned int)ret << div->shift;
110 return regmap_update_bits(clk->map, div->offset,
111 clk_div_mask(div->width) << div->shift, val);
112};
113
114/* Would prefer clk_regmap_div_ro_ops but clashes with qcom */
115
116const struct clk_ops clk_regmap_divider_ops = {
117 .recalc_rate = clk_regmap_div_recalc_rate,
118 .round_rate = clk_regmap_div_round_rate,
119 .set_rate = clk_regmap_div_set_rate,
120};
121EXPORT_SYMBOL_GPL(clk_regmap_divider_ops);
122
123const struct clk_ops clk_regmap_divider_ro_ops = {
124 .recalc_rate = clk_regmap_div_recalc_rate,
125 .round_rate = clk_regmap_div_round_rate,
126};
127EXPORT_SYMBOL_GPL(clk_regmap_divider_ro_ops);
128
129static u8 clk_regmap_mux_get_parent(struct clk_hw *hw)
130{
131 struct clk_regmap *clk = to_clk_regmap(hw);
132 struct clk_regmap_mux_data *mux = clk_get_regmap_mux_data(clk);
133 unsigned int val;
134 int ret;
135
136 ret = regmap_read(clk->map, mux->offset, &val);
137 if (ret)
138 return ret;
139
140 val >>= mux->shift;
141 val &= mux->mask;
142 return clk_mux_val_to_index(hw, mux->table, mux->flags, val);
143}
144
145static int clk_regmap_mux_set_parent(struct clk_hw *hw, u8 index)
146{
147 struct clk_regmap *clk = to_clk_regmap(hw);
148 struct clk_regmap_mux_data *mux = clk_get_regmap_mux_data(clk);
149 unsigned int val = clk_mux_index_to_val(mux->table, mux->flags, index);
150
151 return regmap_update_bits(clk->map, mux->offset,
152 mux->mask << mux->shift,
153 val << mux->shift);
154}
155
156const struct clk_ops clk_regmap_mux_ops = {
157 .get_parent = clk_regmap_mux_get_parent,
158 .set_parent = clk_regmap_mux_set_parent,
159 .determine_rate = __clk_mux_determine_rate,
160};
161EXPORT_SYMBOL_GPL(clk_regmap_mux_ops);
162
163const struct clk_ops clk_regmap_mux_ro_ops = {
164 .get_parent = clk_regmap_mux_get_parent,
165};
166EXPORT_SYMBOL_GPL(clk_regmap_mux_ro_ops);
diff --git a/drivers/clk/meson/clk-regmap.h b/drivers/clk/meson/clk-regmap.h
new file mode 100644
index 000000000000..627c888026d7
--- /dev/null
+++ b/drivers/clk/meson/clk-regmap.h
@@ -0,0 +1,111 @@
1// SPDX-License-Identifier: GPL-2.0
2// Copyright (c) 2018 BayLibre, SAS.
3// Author: Jerome Brunet <jbrunet@baylibre.com>
4
5#ifndef __CLK_REGMAP_H
6#define __CLK_REGMAP_H
7
8#include <linux/clk-provider.h>
9#include <linux/regmap.h>
10
11/**
12 * struct clk_regmap - regmap backed clock
13 *
14 * @hw: handle between common and hardware-specific interfaces
15 * @map: pointer to the regmap structure controlling the clock
16 * @data: data specific to the clock type
17 *
18 * Clock which is controlled by regmap backed registers. The actual type of
19 * of the clock is controlled by the clock_ops and data.
20 */
21struct clk_regmap {
22 struct clk_hw hw;
23 struct regmap *map;
24 void *data;
25};
26
27#define to_clk_regmap(_hw) container_of(_hw, struct clk_regmap, hw)
28
29/**
30 * struct clk_regmap_gate_data - regmap backed gate specific data
31 *
32 * @offset: offset of the register controlling gate
33 * @bit_idx: single bit controlling gate
34 * @flags: hardware-specific flags
35 *
36 * Flags:
37 * Same as clk_gate except CLK_GATE_HIWORD_MASK which is ignored
38 */
39struct clk_regmap_gate_data {
40 unsigned int offset;
41 u8 bit_idx;
42 u8 flags;
43};
44
45static inline struct clk_regmap_gate_data *
46clk_get_regmap_gate_data(struct clk_regmap *clk)
47{
48 return (struct clk_regmap_gate_data *)clk->data;
49}
50
51extern const struct clk_ops clk_regmap_gate_ops;
52
53/**
54 * struct clk_regmap_div_data - regmap backed adjustable divider specific data
55 *
56 * @offset: offset of the register controlling the divider
57 * @shift: shift to the divider bit field
58 * @width: width of the divider bit field
59 * @table: array of value/divider pairs, last entry should have div = 0
60 *
61 * Flags:
62 * Same as clk_divider except CLK_DIVIDER_HIWORD_MASK which is ignored
63 */
64struct clk_regmap_div_data {
65 unsigned int offset;
66 u8 shift;
67 u8 width;
68 u8 flags;
69 const struct clk_div_table *table;
70};
71
72static inline struct clk_regmap_div_data *
73clk_get_regmap_div_data(struct clk_regmap *clk)
74{
75 return (struct clk_regmap_div_data *)clk->data;
76}
77
78extern const struct clk_ops clk_regmap_divider_ops;
79extern const struct clk_ops clk_regmap_divider_ro_ops;
80
81/**
82 * struct clk_regmap_mux_data - regmap backed multiplexer clock specific data
83 *
84 * @hw: handle between common and hardware-specific interfaces
85 * @offset: offset of theregister controlling multiplexer
86 * @table: array of parent indexed register values
87 * @shift: shift to multiplexer bit field
88 * @mask: mask of mutliplexer bit field
89 * @flags: hardware-specific flags
90 *
91 * Flags:
92 * Same as clk_divider except CLK_MUX_HIWORD_MASK which is ignored
93 */
94struct clk_regmap_mux_data {
95 unsigned int offset;
96 u32 *table;
97 u32 mask;
98 u8 shift;
99 u8 flags;
100};
101
102static inline struct clk_regmap_mux_data *
103clk_get_regmap_mux_data(struct clk_regmap *clk)
104{
105 return (struct clk_regmap_mux_data *)clk->data;
106}
107
108extern const struct clk_ops clk_regmap_mux_ops;
109extern const struct clk_ops clk_regmap_mux_ro_ops;
110
111#endif /* __CLK_REGMAP_H */
diff --git a/drivers/clk/meson/clkc.h b/drivers/clk/meson/clkc.h
index c2ff0520ce53..8fe73c4edca8 100644
--- a/drivers/clk/meson/clkc.h
+++ b/drivers/clk/meson/clkc.h
@@ -18,6 +18,9 @@
18#ifndef __CLKC_H 18#ifndef __CLKC_H
19#define __CLKC_H 19#define __CLKC_H
20 20
21#include <linux/clk-provider.h>
22#include "clk-regmap.h"
23
21#define PMASK(width) GENMASK(width - 1, 0) 24#define PMASK(width) GENMASK(width - 1, 0)
22#define SETPMASK(width, shift) GENMASK(shift + width - 1, shift) 25#define SETPMASK(width, shift) GENMASK(shift + width - 1, shift)
23#define CLRPMASK(width, shift) (~SETPMASK(width, shift)) 26#define CLRPMASK(width, shift) (~SETPMASK(width, shift))
@@ -35,13 +38,29 @@ struct parm {
35 u8 width; 38 u8 width;
36}; 39};
37 40
41static inline unsigned int meson_parm_read(struct regmap *map, struct parm *p)
42{
43 unsigned int val;
44
45 regmap_read(map, p->reg_off, &val);
46 return PARM_GET(p->width, p->shift, val);
47}
48
49static inline void meson_parm_write(struct regmap *map, struct parm *p,
50 unsigned int val)
51{
52 regmap_update_bits(map, p->reg_off, SETPMASK(p->width, p->shift),
53 val << p->shift);
54}
55
56
38struct pll_rate_table { 57struct pll_rate_table {
39 unsigned long rate; 58 unsigned long rate;
40 u16 m; 59 u16 m;
41 u16 n; 60 u16 n;
42 u16 od; 61 u16 od;
43 u16 od2; 62 u16 od2;
44 u16 frac; 63 u16 od3;
45}; 64};
46 65
47#define PLL_RATE(_r, _m, _n, _od) \ 66#define PLL_RATE(_r, _m, _n, _od) \
@@ -50,97 +69,53 @@ struct pll_rate_table {
50 .m = (_m), \ 69 .m = (_m), \
51 .n = (_n), \ 70 .n = (_n), \
52 .od = (_od), \ 71 .od = (_od), \
53 } \
54
55#define PLL_FRAC_RATE(_r, _m, _n, _od, _od2, _frac) \
56 { \
57 .rate = (_r), \
58 .m = (_m), \
59 .n = (_n), \
60 .od = (_od), \
61 .od2 = (_od2), \
62 .frac = (_frac), \
63 } \
64
65struct pll_params_table {
66 unsigned int reg_off;
67 unsigned int value;
68};
69
70#define PLL_PARAM(_reg, _val) \
71 { \
72 .reg_off = (_reg), \
73 .value = (_val), \
74 } 72 }
75 73
76struct pll_setup_params { 74#define CLK_MESON_PLL_ROUND_CLOSEST BIT(0)
77 struct pll_params_table *params_table;
78 unsigned int params_count;
79 /* Workaround for GP0, do not reset before configuring */
80 bool no_init_reset;
81 /* Workaround for GP0, unreset right before checking for lock */
82 bool clear_reset_for_lock;
83 /* Workaround for GXL GP0, reset in the lock checking loop */
84 bool reset_lock_loop;
85};
86 75
87struct meson_clk_pll { 76struct meson_clk_pll_data {
88 struct clk_hw hw;
89 void __iomem *base;
90 struct parm m; 77 struct parm m;
91 struct parm n; 78 struct parm n;
92 struct parm frac; 79 struct parm frac;
93 struct parm od; 80 struct parm od;
94 struct parm od2; 81 struct parm od2;
95 const struct pll_setup_params params; 82 struct parm od3;
96 const struct pll_rate_table *rate_table; 83 struct parm l;
97 unsigned int rate_count; 84 struct parm rst;
98 spinlock_t *lock; 85 const struct reg_sequence *init_regs;
86 unsigned int init_count;
87 const struct pll_rate_table *table;
88 u8 flags;
99}; 89};
100 90
101#define to_meson_clk_pll(_hw) container_of(_hw, struct meson_clk_pll, hw) 91#define to_meson_clk_pll(_hw) container_of(_hw, struct meson_clk_pll, hw)
102 92
103struct meson_clk_cpu { 93struct meson_clk_mpll_data {
104 struct clk_hw hw;
105 void __iomem *base;
106 u16 reg_off;
107 struct notifier_block clk_nb;
108 const struct clk_div_table *div_table;
109};
110
111int meson_clk_cpu_notifier_cb(struct notifier_block *nb, unsigned long event,
112 void *data);
113
114struct meson_clk_mpll {
115 struct clk_hw hw;
116 void __iomem *base;
117 struct parm sdm; 94 struct parm sdm;
118 struct parm sdm_en; 95 struct parm sdm_en;
119 struct parm n2; 96 struct parm n2;
120 struct parm en;
121 struct parm ssen; 97 struct parm ssen;
98 struct parm misc;
122 spinlock_t *lock; 99 spinlock_t *lock;
123}; 100};
124 101
125struct meson_clk_audio_divider { 102struct meson_clk_audio_div_data {
126 struct clk_hw hw;
127 void __iomem *base;
128 struct parm div; 103 struct parm div;
129 u8 flags; 104 u8 flags;
130 spinlock_t *lock;
131}; 105};
132 106
133#define MESON_GATE(_name, _reg, _bit) \ 107#define MESON_GATE(_name, _reg, _bit) \
134struct clk_gate _name = { \ 108struct clk_regmap _name = { \
135 .reg = (void __iomem *) _reg, \ 109 .data = &(struct clk_regmap_gate_data){ \
136 .bit_idx = (_bit), \ 110 .offset = (_reg), \
137 .lock = &meson_clk_lock, \ 111 .bit_idx = (_bit), \
138 .hw.init = &(struct clk_init_data) { \ 112 }, \
139 .name = #_name, \ 113 .hw.init = &(struct clk_init_data) { \
140 .ops = &clk_gate_ops, \ 114 .name = #_name, \
115 .ops = &clk_regmap_gate_ops, \
141 .parent_names = (const char *[]){ "clk81" }, \ 116 .parent_names = (const char *[]){ "clk81" }, \
142 .num_parents = 1, \ 117 .num_parents = 1, \
143 .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED), \ 118 .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED), \
144 }, \ 119 }, \
145}; 120};
146 121
diff --git a/drivers/clk/meson/gxbb-aoclk-regmap.c b/drivers/clk/meson/gxbb-aoclk-regmap.c
deleted file mode 100644
index 2515fbfa0467..000000000000
--- a/drivers/clk/meson/gxbb-aoclk-regmap.c
+++ /dev/null
@@ -1,46 +0,0 @@
1/*
2 * Copyright (c) 2017 BayLibre, SAS.
3 * Author: Neil Armstrong <narmstrong@baylibre.com>
4 *
5 * SPDX-License-Identifier: GPL-2.0+
6 */
7
8#include <linux/clk-provider.h>
9#include <linux/bitfield.h>
10#include <linux/regmap.h>
11#include "gxbb-aoclk.h"
12
13static int aoclk_gate_regmap_enable(struct clk_hw *hw)
14{
15 struct aoclk_gate_regmap *gate = to_aoclk_gate_regmap(hw);
16
17 return regmap_update_bits(gate->regmap, AO_RTI_GEN_CNTL_REG0,
18 BIT(gate->bit_idx), BIT(gate->bit_idx));
19}
20
21static void aoclk_gate_regmap_disable(struct clk_hw *hw)
22{
23 struct aoclk_gate_regmap *gate = to_aoclk_gate_regmap(hw);
24
25 regmap_update_bits(gate->regmap, AO_RTI_GEN_CNTL_REG0,
26 BIT(gate->bit_idx), 0);
27}
28
29static int aoclk_gate_regmap_is_enabled(struct clk_hw *hw)
30{
31 struct aoclk_gate_regmap *gate = to_aoclk_gate_regmap(hw);
32 unsigned int val;
33 int ret;
34
35 ret = regmap_read(gate->regmap, AO_RTI_GEN_CNTL_REG0, &val);
36 if (ret)
37 return ret;
38
39 return (val & BIT(gate->bit_idx)) != 0;
40}
41
42const struct clk_ops meson_aoclk_gate_regmap_ops = {
43 .enable = aoclk_gate_regmap_enable,
44 .disable = aoclk_gate_regmap_disable,
45 .is_enabled = aoclk_gate_regmap_is_enabled,
46};
diff --git a/drivers/clk/meson/gxbb-aoclk.c b/drivers/clk/meson/gxbb-aoclk.c
index 6c161e0a8e59..9ec23ae9a219 100644
--- a/drivers/clk/meson/gxbb-aoclk.c
+++ b/drivers/clk/meson/gxbb-aoclk.c
@@ -62,10 +62,9 @@
62#include <linux/delay.h> 62#include <linux/delay.h>
63#include <dt-bindings/clock/gxbb-aoclkc.h> 63#include <dt-bindings/clock/gxbb-aoclkc.h>
64#include <dt-bindings/reset/gxbb-aoclkc.h> 64#include <dt-bindings/reset/gxbb-aoclkc.h>
65#include "clk-regmap.h"
65#include "gxbb-aoclk.h" 66#include "gxbb-aoclk.h"
66 67
67static DEFINE_SPINLOCK(gxbb_aoclk_lock);
68
69struct gxbb_aoclk_reset_controller { 68struct gxbb_aoclk_reset_controller {
70 struct reset_controller_dev reset; 69 struct reset_controller_dev reset;
71 unsigned int *data; 70 unsigned int *data;
@@ -87,12 +86,14 @@ static const struct reset_control_ops gxbb_aoclk_reset_ops = {
87}; 86};
88 87
89#define GXBB_AO_GATE(_name, _bit) \ 88#define GXBB_AO_GATE(_name, _bit) \
90static struct aoclk_gate_regmap _name##_ao = { \ 89static struct clk_regmap _name##_ao = { \
91 .bit_idx = (_bit), \ 90 .data = &(struct clk_regmap_gate_data) { \
92 .lock = &gxbb_aoclk_lock, \ 91 .offset = AO_RTI_GEN_CNTL_REG0, \
92 .bit_idx = (_bit), \
93 }, \
93 .hw.init = &(struct clk_init_data) { \ 94 .hw.init = &(struct clk_init_data) { \
94 .name = #_name "_ao", \ 95 .name = #_name "_ao", \
95 .ops = &meson_aoclk_gate_regmap_ops, \ 96 .ops = &clk_regmap_gate_ops, \
96 .parent_names = (const char *[]){ "clk81" }, \ 97 .parent_names = (const char *[]){ "clk81" }, \
97 .num_parents = 1, \ 98 .num_parents = 1, \
98 .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED), \ 99 .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED), \
@@ -107,7 +108,6 @@ GXBB_AO_GATE(uart2, 5);
107GXBB_AO_GATE(ir_blaster, 6); 108GXBB_AO_GATE(ir_blaster, 6);
108 109
109static struct aoclk_cec_32k cec_32k_ao = { 110static struct aoclk_cec_32k cec_32k_ao = {
110 .lock = &gxbb_aoclk_lock,
111 .hw.init = &(struct clk_init_data) { 111 .hw.init = &(struct clk_init_data) {
112 .name = "cec_32k_ao", 112 .name = "cec_32k_ao",
113 .ops = &meson_aoclk_cec_32k_ops, 113 .ops = &meson_aoclk_cec_32k_ops,
@@ -126,7 +126,7 @@ static unsigned int gxbb_aoclk_reset[] = {
126 [RESET_AO_IR_BLASTER] = 23, 126 [RESET_AO_IR_BLASTER] = 23,
127}; 127};
128 128
129static struct aoclk_gate_regmap *gxbb_aoclk_gate[] = { 129static struct clk_regmap *gxbb_aoclk_gate[] = {
130 [CLKID_AO_REMOTE] = &remote_ao, 130 [CLKID_AO_REMOTE] = &remote_ao,
131 [CLKID_AO_I2C_MASTER] = &i2c_master_ao, 131 [CLKID_AO_I2C_MASTER] = &i2c_master_ao,
132 [CLKID_AO_I2C_SLAVE] = &i2c_slave_ao, 132 [CLKID_AO_I2C_SLAVE] = &i2c_slave_ao,
@@ -177,10 +177,10 @@ static int gxbb_aoclkc_probe(struct platform_device *pdev)
177 * Populate regmap and register all clks 177 * Populate regmap and register all clks
178 */ 178 */
179 for (clkid = 0; clkid < ARRAY_SIZE(gxbb_aoclk_gate); clkid++) { 179 for (clkid = 0; clkid < ARRAY_SIZE(gxbb_aoclk_gate); clkid++) {
180 gxbb_aoclk_gate[clkid]->regmap = regmap; 180 gxbb_aoclk_gate[clkid]->map = regmap;
181 181
182 ret = devm_clk_hw_register(dev, 182 ret = devm_clk_hw_register(dev,
183 gxbb_aoclk_onecell_data.hws[clkid]); 183 gxbb_aoclk_onecell_data.hws[clkid]);
184 if (ret) 184 if (ret)
185 return ret; 185 return ret;
186 } 186 }
diff --git a/drivers/clk/meson/gxbb-aoclk.h b/drivers/clk/meson/gxbb-aoclk.h
index e8604c8f7eee..0be78383f257 100644
--- a/drivers/clk/meson/gxbb-aoclk.h
+++ b/drivers/clk/meson/gxbb-aoclk.h
@@ -17,22 +17,11 @@
17#define AO_RTC_ALT_CLK_CNTL0 0x94 17#define AO_RTC_ALT_CLK_CNTL0 0x94
18#define AO_RTC_ALT_CLK_CNTL1 0x98 18#define AO_RTC_ALT_CLK_CNTL1 0x98
19 19
20struct aoclk_gate_regmap {
21 struct clk_hw hw;
22 unsigned bit_idx;
23 struct regmap *regmap;
24 spinlock_t *lock;
25};
26
27#define to_aoclk_gate_regmap(_hw) \
28 container_of(_hw, struct aoclk_gate_regmap, hw)
29
30extern const struct clk_ops meson_aoclk_gate_regmap_ops; 20extern const struct clk_ops meson_aoclk_gate_regmap_ops;
31 21
32struct aoclk_cec_32k { 22struct aoclk_cec_32k {
33 struct clk_hw hw; 23 struct clk_hw hw;
34 struct regmap *regmap; 24 struct regmap *regmap;
35 spinlock_t *lock;
36}; 25};
37 26
38#define to_aoclk_cec_32k(_hw) container_of(_hw, struct aoclk_cec_32k, hw) 27#define to_aoclk_cec_32k(_hw) container_of(_hw, struct aoclk_cec_32k, hw)
diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c
index af24455af5b4..b1e4d9557610 100644
--- a/drivers/clk/meson/gxbb.c
+++ b/drivers/clk/meson/gxbb.c
@@ -19,108 +19,19 @@
19 19
20#include <linux/clk.h> 20#include <linux/clk.h>
21#include <linux/clk-provider.h> 21#include <linux/clk-provider.h>
22#include <linux/init.h>
22#include <linux/of_address.h> 23#include <linux/of_address.h>
23#include <linux/of_device.h> 24#include <linux/of_device.h>
25#include <linux/mfd/syscon.h>
24#include <linux/platform_device.h> 26#include <linux/platform_device.h>
25#include <linux/init.h> 27#include <linux/regmap.h>
26 28
27#include "clkc.h" 29#include "clkc.h"
28#include "gxbb.h" 30#include "gxbb.h"
31#include "clk-regmap.h"
29 32
30static DEFINE_SPINLOCK(meson_clk_lock); 33static DEFINE_SPINLOCK(meson_clk_lock);
31 34
32static const struct pll_rate_table sys_pll_rate_table[] = {
33 PLL_RATE(24000000, 56, 1, 2),
34 PLL_RATE(48000000, 64, 1, 2),
35 PLL_RATE(72000000, 72, 1, 2),
36 PLL_RATE(96000000, 64, 1, 2),
37 PLL_RATE(120000000, 80, 1, 2),
38 PLL_RATE(144000000, 96, 1, 2),
39 PLL_RATE(168000000, 56, 1, 1),
40 PLL_RATE(192000000, 64, 1, 1),
41 PLL_RATE(216000000, 72, 1, 1),
42 PLL_RATE(240000000, 80, 1, 1),
43 PLL_RATE(264000000, 88, 1, 1),
44 PLL_RATE(288000000, 96, 1, 1),
45 PLL_RATE(312000000, 52, 1, 2),
46 PLL_RATE(336000000, 56, 1, 2),
47 PLL_RATE(360000000, 60, 1, 2),
48 PLL_RATE(384000000, 64, 1, 2),
49 PLL_RATE(408000000, 68, 1, 2),
50 PLL_RATE(432000000, 72, 1, 2),
51 PLL_RATE(456000000, 76, 1, 2),
52 PLL_RATE(480000000, 80, 1, 2),
53 PLL_RATE(504000000, 84, 1, 2),
54 PLL_RATE(528000000, 88, 1, 2),
55 PLL_RATE(552000000, 92, 1, 2),
56 PLL_RATE(576000000, 96, 1, 2),
57 PLL_RATE(600000000, 50, 1, 1),
58 PLL_RATE(624000000, 52, 1, 1),
59 PLL_RATE(648000000, 54, 1, 1),
60 PLL_RATE(672000000, 56, 1, 1),
61 PLL_RATE(696000000, 58, 1, 1),
62 PLL_RATE(720000000, 60, 1, 1),
63 PLL_RATE(744000000, 62, 1, 1),
64 PLL_RATE(768000000, 64, 1, 1),
65 PLL_RATE(792000000, 66, 1, 1),
66 PLL_RATE(816000000, 68, 1, 1),
67 PLL_RATE(840000000, 70, 1, 1),
68 PLL_RATE(864000000, 72, 1, 1),
69 PLL_RATE(888000000, 74, 1, 1),
70 PLL_RATE(912000000, 76, 1, 1),
71 PLL_RATE(936000000, 78, 1, 1),
72 PLL_RATE(960000000, 80, 1, 1),
73 PLL_RATE(984000000, 82, 1, 1),
74 PLL_RATE(1008000000, 84, 1, 1),
75 PLL_RATE(1032000000, 86, 1, 1),
76 PLL_RATE(1056000000, 88, 1, 1),
77 PLL_RATE(1080000000, 90, 1, 1),
78 PLL_RATE(1104000000, 92, 1, 1),
79 PLL_RATE(1128000000, 94, 1, 1),
80 PLL_RATE(1152000000, 96, 1, 1),
81 PLL_RATE(1176000000, 98, 1, 1),
82 PLL_RATE(1200000000, 50, 1, 0),
83 PLL_RATE(1224000000, 51, 1, 0),
84 PLL_RATE(1248000000, 52, 1, 0),
85 PLL_RATE(1272000000, 53, 1, 0),
86 PLL_RATE(1296000000, 54, 1, 0),
87 PLL_RATE(1320000000, 55, 1, 0),
88 PLL_RATE(1344000000, 56, 1, 0),
89 PLL_RATE(1368000000, 57, 1, 0),
90 PLL_RATE(1392000000, 58, 1, 0),
91 PLL_RATE(1416000000, 59, 1, 0),
92 PLL_RATE(1440000000, 60, 1, 0),
93 PLL_RATE(1464000000, 61, 1, 0),
94 PLL_RATE(1488000000, 62, 1, 0),
95 PLL_RATE(1512000000, 63, 1, 0),
96 PLL_RATE(1536000000, 64, 1, 0),
97 PLL_RATE(1560000000, 65, 1, 0),
98 PLL_RATE(1584000000, 66, 1, 0),
99 PLL_RATE(1608000000, 67, 1, 0),
100 PLL_RATE(1632000000, 68, 1, 0),
101 PLL_RATE(1656000000, 68, 1, 0),
102 PLL_RATE(1680000000, 68, 1, 0),
103 PLL_RATE(1704000000, 68, 1, 0),
104 PLL_RATE(1728000000, 69, 1, 0),
105 PLL_RATE(1752000000, 69, 1, 0),
106 PLL_RATE(1776000000, 69, 1, 0),
107 PLL_RATE(1800000000, 69, 1, 0),
108 PLL_RATE(1824000000, 70, 1, 0),
109 PLL_RATE(1848000000, 70, 1, 0),
110 PLL_RATE(1872000000, 70, 1, 0),
111 PLL_RATE(1896000000, 70, 1, 0),
112 PLL_RATE(1920000000, 71, 1, 0),
113 PLL_RATE(1944000000, 71, 1, 0),
114 PLL_RATE(1968000000, 71, 1, 0),
115 PLL_RATE(1992000000, 71, 1, 0),
116 PLL_RATE(2016000000, 72, 1, 0),
117 PLL_RATE(2040000000, 72, 1, 0),
118 PLL_RATE(2064000000, 72, 1, 0),
119 PLL_RATE(2088000000, 72, 1, 0),
120 PLL_RATE(2112000000, 73, 1, 0),
121 { /* sentinel */ },
122};
123
124static const struct pll_rate_table gxbb_gp0_pll_rate_table[] = { 35static const struct pll_rate_table gxbb_gp0_pll_rate_table[] = {
125 PLL_RATE(96000000, 32, 1, 3), 36 PLL_RATE(96000000, 32, 1, 3),
126 PLL_RATE(99000000, 33, 1, 3), 37 PLL_RATE(99000000, 33, 1, 3),
@@ -278,23 +189,39 @@ static const struct pll_rate_table gxl_gp0_pll_rate_table[] = {
278 { /* sentinel */ }, 189 { /* sentinel */ },
279}; 190};
280 191
281static struct meson_clk_pll gxbb_fixed_pll = { 192static struct clk_regmap gxbb_fixed_pll = {
282 .m = { 193 .data = &(struct meson_clk_pll_data){
283 .reg_off = HHI_MPLL_CNTL, 194 .m = {
284 .shift = 0, 195 .reg_off = HHI_MPLL_CNTL,
285 .width = 9, 196 .shift = 0,
197 .width = 9,
198 },
199 .n = {
200 .reg_off = HHI_MPLL_CNTL,
201 .shift = 9,
202 .width = 5,
203 },
204 .od = {
205 .reg_off = HHI_MPLL_CNTL,
206 .shift = 16,
207 .width = 2,
208 },
209 .frac = {
210 .reg_off = HHI_MPLL_CNTL2,
211 .shift = 0,
212 .width = 12,
213 },
214 .l = {
215 .reg_off = HHI_MPLL_CNTL,
216 .shift = 31,
217 .width = 1,
218 },
219 .rst = {
220 .reg_off = HHI_MPLL_CNTL,
221 .shift = 29,
222 .width = 1,
223 },
286 }, 224 },
287 .n = {
288 .reg_off = HHI_MPLL_CNTL,
289 .shift = 9,
290 .width = 5,
291 },
292 .od = {
293 .reg_off = HHI_MPLL_CNTL,
294 .shift = 16,
295 .width = 2,
296 },
297 .lock = &meson_clk_lock,
298 .hw.init = &(struct clk_init_data){ 225 .hw.init = &(struct clk_init_data){
299 .name = "fixed_pll", 226 .name = "fixed_pll",
300 .ops = &meson_clk_pll_ro_ops, 227 .ops = &meson_clk_pll_ro_ops,
@@ -304,33 +231,118 @@ static struct meson_clk_pll gxbb_fixed_pll = {
304 }, 231 },
305}; 232};
306 233
307static struct meson_clk_pll gxbb_hdmi_pll = { 234static struct clk_fixed_factor gxbb_hdmi_pll_pre_mult = {
308 .m = { 235 .mult = 2,
309 .reg_off = HHI_HDMI_PLL_CNTL, 236 .div = 1,
310 .shift = 0, 237 .hw.init = &(struct clk_init_data){
311 .width = 9, 238 .name = "hdmi_pll_pre_mult",
312 }, 239 .ops = &clk_fixed_factor_ops,
313 .n = { 240 .parent_names = (const char *[]){ "xtal" },
314 .reg_off = HHI_HDMI_PLL_CNTL, 241 .num_parents = 1,
315 .shift = 9,
316 .width = 5,
317 }, 242 },
318 .frac = { 243};
319 .reg_off = HHI_HDMI_PLL_CNTL2, 244
320 .shift = 0, 245static struct clk_regmap gxbb_hdmi_pll = {
321 .width = 12, 246 .data = &(struct meson_clk_pll_data){
247 .m = {
248 .reg_off = HHI_HDMI_PLL_CNTL,
249 .shift = 0,
250 .width = 9,
251 },
252 .n = {
253 .reg_off = HHI_HDMI_PLL_CNTL,
254 .shift = 9,
255 .width = 5,
256 },
257 .frac = {
258 .reg_off = HHI_HDMI_PLL_CNTL2,
259 .shift = 0,
260 .width = 12,
261 },
262 .od = {
263 .reg_off = HHI_HDMI_PLL_CNTL2,
264 .shift = 16,
265 .width = 2,
266 },
267 .od2 = {
268 .reg_off = HHI_HDMI_PLL_CNTL2,
269 .shift = 22,
270 .width = 2,
271 },
272 .od3 = {
273 .reg_off = HHI_HDMI_PLL_CNTL2,
274 .shift = 18,
275 .width = 2,
276 },
277 .l = {
278 .reg_off = HHI_HDMI_PLL_CNTL,
279 .shift = 31,
280 .width = 1,
281 },
282 .rst = {
283 .reg_off = HHI_HDMI_PLL_CNTL,
284 .shift = 28,
285 .width = 1,
286 },
322 }, 287 },
323 .od = { 288 .hw.init = &(struct clk_init_data){
324 .reg_off = HHI_HDMI_PLL_CNTL2, 289 .name = "hdmi_pll",
325 .shift = 16, 290 .ops = &meson_clk_pll_ro_ops,
326 .width = 2, 291 .parent_names = (const char *[]){ "hdmi_pll_pre_mult" },
292 .num_parents = 1,
293 .flags = CLK_GET_RATE_NOCACHE,
327 }, 294 },
328 .od2 = { 295};
329 .reg_off = HHI_HDMI_PLL_CNTL2, 296
330 .shift = 22, 297static struct clk_regmap gxl_hdmi_pll = {
331 .width = 2, 298 .data = &(struct meson_clk_pll_data){
299 .m = {
300 .reg_off = HHI_HDMI_PLL_CNTL,
301 .shift = 0,
302 .width = 9,
303 },
304 .n = {
305 .reg_off = HHI_HDMI_PLL_CNTL,
306 .shift = 9,
307 .width = 5,
308 },
309 .frac = {
310 /*
311 * On gxl, there is a register shift due to
312 * HHI_HDMI_PLL_CNTL1 which does not exist on gxbb,
313 * so we compute the register offset based on the PLL
314 * base to get it right
315 */
316 .reg_off = HHI_HDMI_PLL_CNTL + 4,
317 .shift = 0,
318 .width = 12,
319 },
320 .od = {
321 .reg_off = HHI_HDMI_PLL_CNTL + 8,
322 .shift = 21,
323 .width = 2,
324 },
325 .od2 = {
326 .reg_off = HHI_HDMI_PLL_CNTL + 8,
327 .shift = 23,
328 .width = 2,
329 },
330 .od3 = {
331 .reg_off = HHI_HDMI_PLL_CNTL + 8,
332 .shift = 19,
333 .width = 2,
334 },
335 .l = {
336 .reg_off = HHI_HDMI_PLL_CNTL,
337 .shift = 31,
338 .width = 1,
339 },
340 .rst = {
341 .reg_off = HHI_HDMI_PLL_CNTL,
342 .shift = 29,
343 .width = 1,
344 },
332 }, 345 },
333 .lock = &meson_clk_lock,
334 .hw.init = &(struct clk_init_data){ 346 .hw.init = &(struct clk_init_data){
335 .name = "hdmi_pll", 347 .name = "hdmi_pll",
336 .ops = &meson_clk_pll_ro_ops, 348 .ops = &meson_clk_pll_ro_ops,
@@ -340,25 +352,34 @@ static struct meson_clk_pll gxbb_hdmi_pll = {
340 }, 352 },
341}; 353};
342 354
343static struct meson_clk_pll gxbb_sys_pll = { 355static struct clk_regmap gxbb_sys_pll = {
344 .m = { 356 .data = &(struct meson_clk_pll_data){
345 .reg_off = HHI_SYS_PLL_CNTL, 357 .m = {
346 .shift = 0, 358 .reg_off = HHI_SYS_PLL_CNTL,
347 .width = 9, 359 .shift = 0,
348 }, 360 .width = 9,
349 .n = { 361 },
350 .reg_off = HHI_SYS_PLL_CNTL, 362 .n = {
351 .shift = 9, 363 .reg_off = HHI_SYS_PLL_CNTL,
352 .width = 5, 364 .shift = 9,
365 .width = 5,
366 },
367 .od = {
368 .reg_off = HHI_SYS_PLL_CNTL,
369 .shift = 10,
370 .width = 2,
371 },
372 .l = {
373 .reg_off = HHI_SYS_PLL_CNTL,
374 .shift = 31,
375 .width = 1,
376 },
377 .rst = {
378 .reg_off = HHI_SYS_PLL_CNTL,
379 .shift = 29,
380 .width = 1,
381 },
353 }, 382 },
354 .od = {
355 .reg_off = HHI_SYS_PLL_CNTL,
356 .shift = 10,
357 .width = 2,
358 },
359 .rate_table = sys_pll_rate_table,
360 .rate_count = ARRAY_SIZE(sys_pll_rate_table),
361 .lock = &meson_clk_lock,
362 .hw.init = &(struct clk_init_data){ 383 .hw.init = &(struct clk_init_data){
363 .name = "sys_pll", 384 .name = "sys_pll",
364 .ops = &meson_clk_pll_ro_ops, 385 .ops = &meson_clk_pll_ro_ops,
@@ -368,38 +389,44 @@ static struct meson_clk_pll gxbb_sys_pll = {
368 }, 389 },
369}; 390};
370 391
371struct pll_params_table gxbb_gp0_params_table[] = { 392static const struct reg_sequence gxbb_gp0_init_regs[] = {
372 PLL_PARAM(HHI_GP0_PLL_CNTL, 0x6a000228), 393 { .reg = HHI_GP0_PLL_CNTL2, .def = 0x69c80000 },
373 PLL_PARAM(HHI_GP0_PLL_CNTL2, 0x69c80000), 394 { .reg = HHI_GP0_PLL_CNTL3, .def = 0x0a5590c4 },
374 PLL_PARAM(HHI_GP0_PLL_CNTL3, 0x0a5590c4), 395 { .reg = HHI_GP0_PLL_CNTL4, .def = 0x0000500d },
375 PLL_PARAM(HHI_GP0_PLL_CNTL4, 0x0000500d), 396 { .reg = HHI_GP0_PLL_CNTL, .def = 0x4a000228 },
376}; 397};
377 398
378static struct meson_clk_pll gxbb_gp0_pll = { 399static struct clk_regmap gxbb_gp0_pll = {
379 .m = { 400 .data = &(struct meson_clk_pll_data){
380 .reg_off = HHI_GP0_PLL_CNTL, 401 .m = {
381 .shift = 0, 402 .reg_off = HHI_GP0_PLL_CNTL,
382 .width = 9, 403 .shift = 0,
383 }, 404 .width = 9,
384 .n = { 405 },
385 .reg_off = HHI_GP0_PLL_CNTL, 406 .n = {
386 .shift = 9, 407 .reg_off = HHI_GP0_PLL_CNTL,
387 .width = 5, 408 .shift = 9,
388 }, 409 .width = 5,
389 .od = { 410 },
390 .reg_off = HHI_GP0_PLL_CNTL, 411 .od = {
391 .shift = 16, 412 .reg_off = HHI_GP0_PLL_CNTL,
392 .width = 2, 413 .shift = 16,
393 }, 414 .width = 2,
394 .params = { 415 },
395 .params_table = gxbb_gp0_params_table, 416 .l = {
396 .params_count = ARRAY_SIZE(gxbb_gp0_params_table), 417 .reg_off = HHI_GP0_PLL_CNTL,
397 .no_init_reset = true, 418 .shift = 31,
398 .clear_reset_for_lock = true, 419 .width = 1,
420 },
421 .rst = {
422 .reg_off = HHI_GP0_PLL_CNTL,
423 .shift = 29,
424 .width = 1,
425 },
426 .table = gxbb_gp0_pll_rate_table,
427 .init_regs = gxbb_gp0_init_regs,
428 .init_count = ARRAY_SIZE(gxbb_gp0_init_regs),
399 }, 429 },
400 .rate_table = gxbb_gp0_pll_rate_table,
401 .rate_count = ARRAY_SIZE(gxbb_gp0_pll_rate_table),
402 .lock = &meson_clk_lock,
403 .hw.init = &(struct clk_init_data){ 430 .hw.init = &(struct clk_init_data){
404 .name = "gp0_pll", 431 .name = "gp0_pll",
405 .ops = &meson_clk_pll_ops, 432 .ops = &meson_clk_pll_ops,
@@ -409,40 +436,51 @@ static struct meson_clk_pll gxbb_gp0_pll = {
409 }, 436 },
410}; 437};
411 438
412struct pll_params_table gxl_gp0_params_table[] = { 439static const struct reg_sequence gxl_gp0_init_regs[] = {
413 PLL_PARAM(HHI_GP0_PLL_CNTL, 0x40010250), 440 { .reg = HHI_GP0_PLL_CNTL1, .def = 0xc084b000 },
414 PLL_PARAM(HHI_GP0_PLL_CNTL1, 0xc084a000), 441 { .reg = HHI_GP0_PLL_CNTL2, .def = 0xb75020be },
415 PLL_PARAM(HHI_GP0_PLL_CNTL2, 0xb75020be), 442 { .reg = HHI_GP0_PLL_CNTL3, .def = 0x0a59a288 },
416 PLL_PARAM(HHI_GP0_PLL_CNTL3, 0x0a59a288), 443 { .reg = HHI_GP0_PLL_CNTL4, .def = 0xc000004d },
417 PLL_PARAM(HHI_GP0_PLL_CNTL4, 0xc000004d), 444 { .reg = HHI_GP0_PLL_CNTL5, .def = 0x00078000 },
418 PLL_PARAM(HHI_GP0_PLL_CNTL5, 0x00078000), 445 { .reg = HHI_GP0_PLL_CNTL, .def = 0x40010250 },
419}; 446};
420 447
421static struct meson_clk_pll gxl_gp0_pll = { 448static struct clk_regmap gxl_gp0_pll = {
422 .m = { 449 .data = &(struct meson_clk_pll_data){
423 .reg_off = HHI_GP0_PLL_CNTL, 450 .m = {
424 .shift = 0, 451 .reg_off = HHI_GP0_PLL_CNTL,
425 .width = 9, 452 .shift = 0,
426 }, 453 .width = 9,
427 .n = { 454 },
428 .reg_off = HHI_GP0_PLL_CNTL, 455 .n = {
429 .shift = 9, 456 .reg_off = HHI_GP0_PLL_CNTL,
430 .width = 5, 457 .shift = 9,
431 }, 458 .width = 5,
432 .od = { 459 },
433 .reg_off = HHI_GP0_PLL_CNTL, 460 .od = {
434 .shift = 16, 461 .reg_off = HHI_GP0_PLL_CNTL,
435 .width = 2, 462 .shift = 16,
463 .width = 2,
464 },
465 .frac = {
466 .reg_off = HHI_GP0_PLL_CNTL1,
467 .shift = 0,
468 .width = 10,
469 },
470 .l = {
471 .reg_off = HHI_GP0_PLL_CNTL,
472 .shift = 31,
473 .width = 1,
474 },
475 .rst = {
476 .reg_off = HHI_GP0_PLL_CNTL,
477 .shift = 29,
478 .width = 1,
479 },
480 .table = gxl_gp0_pll_rate_table,
481 .init_regs = gxl_gp0_init_regs,
482 .init_count = ARRAY_SIZE(gxl_gp0_init_regs),
436 }, 483 },
437 .params = {
438 .params_table = gxl_gp0_params_table,
439 .params_count = ARRAY_SIZE(gxl_gp0_params_table),
440 .no_init_reset = true,
441 .reset_lock_loop = true,
442 },
443 .rate_table = gxl_gp0_pll_rate_table,
444 .rate_count = ARRAY_SIZE(gxl_gp0_pll_rate_table),
445 .lock = &meson_clk_lock,
446 .hw.init = &(struct clk_init_data){ 484 .hw.init = &(struct clk_init_data){
447 .name = "gp0_pll", 485 .name = "gp0_pll",
448 .ops = &meson_clk_pll_ops, 486 .ops = &meson_clk_pll_ops,
@@ -452,161 +490,267 @@ static struct meson_clk_pll gxl_gp0_pll = {
452 }, 490 },
453}; 491};
454 492
455static struct clk_fixed_factor gxbb_fclk_div2 = { 493static struct clk_fixed_factor gxbb_fclk_div2_div = {
456 .mult = 1, 494 .mult = 1,
457 .div = 2, 495 .div = 2,
458 .hw.init = &(struct clk_init_data){ 496 .hw.init = &(struct clk_init_data){
459 .name = "fclk_div2", 497 .name = "fclk_div2_div",
460 .ops = &clk_fixed_factor_ops, 498 .ops = &clk_fixed_factor_ops,
461 .parent_names = (const char *[]){ "fixed_pll" }, 499 .parent_names = (const char *[]){ "fixed_pll" },
462 .num_parents = 1, 500 .num_parents = 1,
463 }, 501 },
464}; 502};
465 503
466static struct clk_fixed_factor gxbb_fclk_div3 = { 504static struct clk_regmap gxbb_fclk_div2 = {
505 .data = &(struct clk_regmap_gate_data){
506 .offset = HHI_MPLL_CNTL6,
507 .bit_idx = 27,
508 },
509 .hw.init = &(struct clk_init_data){
510 .name = "fclk_div2",
511 .ops = &clk_regmap_gate_ops,
512 .parent_names = (const char *[]){ "fclk_div2_div" },
513 .num_parents = 1,
514 },
515};
516
517static struct clk_fixed_factor gxbb_fclk_div3_div = {
467 .mult = 1, 518 .mult = 1,
468 .div = 3, 519 .div = 3,
469 .hw.init = &(struct clk_init_data){ 520 .hw.init = &(struct clk_init_data){
470 .name = "fclk_div3", 521 .name = "fclk_div3_div",
471 .ops = &clk_fixed_factor_ops, 522 .ops = &clk_fixed_factor_ops,
472 .parent_names = (const char *[]){ "fixed_pll" }, 523 .parent_names = (const char *[]){ "fixed_pll" },
473 .num_parents = 1, 524 .num_parents = 1,
474 }, 525 },
475}; 526};
476 527
477static struct clk_fixed_factor gxbb_fclk_div4 = { 528static struct clk_regmap gxbb_fclk_div3 = {
529 .data = &(struct clk_regmap_gate_data){
530 .offset = HHI_MPLL_CNTL6,
531 .bit_idx = 28,
532 },
533 .hw.init = &(struct clk_init_data){
534 .name = "fclk_div3",
535 .ops = &clk_regmap_gate_ops,
536 .parent_names = (const char *[]){ "fclk_div3_div" },
537 .num_parents = 1,
538 },
539};
540
541static struct clk_fixed_factor gxbb_fclk_div4_div = {
478 .mult = 1, 542 .mult = 1,
479 .div = 4, 543 .div = 4,
480 .hw.init = &(struct clk_init_data){ 544 .hw.init = &(struct clk_init_data){
481 .name = "fclk_div4", 545 .name = "fclk_div4_div",
482 .ops = &clk_fixed_factor_ops, 546 .ops = &clk_fixed_factor_ops,
483 .parent_names = (const char *[]){ "fixed_pll" }, 547 .parent_names = (const char *[]){ "fixed_pll" },
484 .num_parents = 1, 548 .num_parents = 1,
485 }, 549 },
486}; 550};
487 551
488static struct clk_fixed_factor gxbb_fclk_div5 = { 552static struct clk_regmap gxbb_fclk_div4 = {
553 .data = &(struct clk_regmap_gate_data){
554 .offset = HHI_MPLL_CNTL6,
555 .bit_idx = 29,
556 },
557 .hw.init = &(struct clk_init_data){
558 .name = "fclk_div4",
559 .ops = &clk_regmap_gate_ops,
560 .parent_names = (const char *[]){ "fclk_div4_div" },
561 .num_parents = 1,
562 },
563};
564
565static struct clk_fixed_factor gxbb_fclk_div5_div = {
489 .mult = 1, 566 .mult = 1,
490 .div = 5, 567 .div = 5,
491 .hw.init = &(struct clk_init_data){ 568 .hw.init = &(struct clk_init_data){
492 .name = "fclk_div5", 569 .name = "fclk_div5_div",
493 .ops = &clk_fixed_factor_ops, 570 .ops = &clk_fixed_factor_ops,
494 .parent_names = (const char *[]){ "fixed_pll" }, 571 .parent_names = (const char *[]){ "fixed_pll" },
495 .num_parents = 1, 572 .num_parents = 1,
496 }, 573 },
497}; 574};
498 575
499static struct clk_fixed_factor gxbb_fclk_div7 = { 576static struct clk_regmap gxbb_fclk_div5 = {
577 .data = &(struct clk_regmap_gate_data){
578 .offset = HHI_MPLL_CNTL6,
579 .bit_idx = 30,
580 },
581 .hw.init = &(struct clk_init_data){
582 .name = "fclk_div5",
583 .ops = &clk_regmap_gate_ops,
584 .parent_names = (const char *[]){ "fclk_div5_div" },
585 .num_parents = 1,
586 },
587};
588
589static struct clk_fixed_factor gxbb_fclk_div7_div = {
500 .mult = 1, 590 .mult = 1,
501 .div = 7, 591 .div = 7,
502 .hw.init = &(struct clk_init_data){ 592 .hw.init = &(struct clk_init_data){
503 .name = "fclk_div7", 593 .name = "fclk_div7_div",
504 .ops = &clk_fixed_factor_ops, 594 .ops = &clk_fixed_factor_ops,
505 .parent_names = (const char *[]){ "fixed_pll" }, 595 .parent_names = (const char *[]){ "fixed_pll" },
506 .num_parents = 1, 596 .num_parents = 1,
507 }, 597 },
508}; 598};
509 599
510static struct meson_clk_mpll gxbb_mpll0 = { 600static struct clk_regmap gxbb_fclk_div7 = {
511 .sdm = { 601 .data = &(struct clk_regmap_gate_data){
512 .reg_off = HHI_MPLL_CNTL7, 602 .offset = HHI_MPLL_CNTL6,
513 .shift = 0, 603 .bit_idx = 31,
514 .width = 14,
515 }, 604 },
516 .sdm_en = { 605 .hw.init = &(struct clk_init_data){
517 .reg_off = HHI_MPLL_CNTL7, 606 .name = "fclk_div7",
518 .shift = 15, 607 .ops = &clk_regmap_gate_ops,
519 .width = 1, 608 .parent_names = (const char *[]){ "fclk_div7_div" },
609 .num_parents = 1,
520 }, 610 },
521 .n2 = { 611};
522 .reg_off = HHI_MPLL_CNTL7, 612
523 .shift = 16, 613static struct clk_regmap gxbb_mpll_prediv = {
524 .width = 9, 614 .data = &(struct clk_regmap_div_data){
615 .offset = HHI_MPLL_CNTL5,
616 .shift = 12,
617 .width = 1,
525 }, 618 },
526 .en = { 619 .hw.init = &(struct clk_init_data){
527 .reg_off = HHI_MPLL_CNTL7, 620 .name = "mpll_prediv",
528 .shift = 14, 621 .ops = &clk_regmap_divider_ro_ops,
529 .width = 1, 622 .parent_names = (const char *[]){ "fixed_pll" },
623 .num_parents = 1,
530 }, 624 },
531 .ssen = { 625};
532 .reg_off = HHI_MPLL_CNTL, 626
533 .shift = 25, 627static struct clk_regmap gxbb_mpll0_div = {
534 .width = 1, 628 .data = &(struct meson_clk_mpll_data){
629 .sdm = {
630 .reg_off = HHI_MPLL_CNTL7,
631 .shift = 0,
632 .width = 14,
633 },
634 .sdm_en = {
635 .reg_off = HHI_MPLL_CNTL7,
636 .shift = 15,
637 .width = 1,
638 },
639 .n2 = {
640 .reg_off = HHI_MPLL_CNTL7,
641 .shift = 16,
642 .width = 9,
643 },
644 .ssen = {
645 .reg_off = HHI_MPLL_CNTL,
646 .shift = 25,
647 .width = 1,
648 },
649 .lock = &meson_clk_lock,
535 }, 650 },
536 .lock = &meson_clk_lock,
537 .hw.init = &(struct clk_init_data){ 651 .hw.init = &(struct clk_init_data){
538 .name = "mpll0", 652 .name = "mpll0_div",
539 .ops = &meson_clk_mpll_ops, 653 .ops = &meson_clk_mpll_ops,
540 .parent_names = (const char *[]){ "fixed_pll" }, 654 .parent_names = (const char *[]){ "mpll_prediv" },
541 .num_parents = 1, 655 .num_parents = 1,
542 }, 656 },
543}; 657};
544 658
545static struct meson_clk_mpll gxbb_mpll1 = { 659static struct clk_regmap gxbb_mpll0 = {
546 .sdm = { 660 .data = &(struct clk_regmap_gate_data){
547 .reg_off = HHI_MPLL_CNTL8, 661 .offset = HHI_MPLL_CNTL7,
548 .shift = 0, 662 .bit_idx = 14,
549 .width = 14,
550 },
551 .sdm_en = {
552 .reg_off = HHI_MPLL_CNTL8,
553 .shift = 15,
554 .width = 1,
555 }, 663 },
556 .n2 = { 664 .hw.init = &(struct clk_init_data){
557 .reg_off = HHI_MPLL_CNTL8, 665 .name = "mpll0",
558 .shift = 16, 666 .ops = &clk_regmap_gate_ops,
559 .width = 9, 667 .parent_names = (const char *[]){ "mpll0_div" },
668 .num_parents = 1,
669 .flags = CLK_SET_RATE_PARENT,
560 }, 670 },
561 .en = { 671};
562 .reg_off = HHI_MPLL_CNTL8, 672
563 .shift = 14, 673static struct clk_regmap gxbb_mpll1_div = {
564 .width = 1, 674 .data = &(struct meson_clk_mpll_data){
675 .sdm = {
676 .reg_off = HHI_MPLL_CNTL8,
677 .shift = 0,
678 .width = 14,
679 },
680 .sdm_en = {
681 .reg_off = HHI_MPLL_CNTL8,
682 .shift = 15,
683 .width = 1,
684 },
685 .n2 = {
686 .reg_off = HHI_MPLL_CNTL8,
687 .shift = 16,
688 .width = 9,
689 },
690 .lock = &meson_clk_lock,
565 }, 691 },
566 .lock = &meson_clk_lock,
567 .hw.init = &(struct clk_init_data){ 692 .hw.init = &(struct clk_init_data){
568 .name = "mpll1", 693 .name = "mpll1_div",
569 .ops = &meson_clk_mpll_ops, 694 .ops = &meson_clk_mpll_ops,
570 .parent_names = (const char *[]){ "fixed_pll" }, 695 .parent_names = (const char *[]){ "mpll_prediv" },
571 .num_parents = 1, 696 .num_parents = 1,
572 }, 697 },
573}; 698};
574 699
575static struct meson_clk_mpll gxbb_mpll2 = { 700static struct clk_regmap gxbb_mpll1 = {
576 .sdm = { 701 .data = &(struct clk_regmap_gate_data){
577 .reg_off = HHI_MPLL_CNTL9, 702 .offset = HHI_MPLL_CNTL8,
578 .shift = 0, 703 .bit_idx = 14,
579 .width = 14,
580 },
581 .sdm_en = {
582 .reg_off = HHI_MPLL_CNTL9,
583 .shift = 15,
584 .width = 1,
585 }, 704 },
586 .n2 = { 705 .hw.init = &(struct clk_init_data){
587 .reg_off = HHI_MPLL_CNTL9, 706 .name = "mpll1",
588 .shift = 16, 707 .ops = &clk_regmap_gate_ops,
589 .width = 9, 708 .parent_names = (const char *[]){ "mpll1_div" },
709 .num_parents = 1,
710 .flags = CLK_SET_RATE_PARENT,
590 }, 711 },
591 .en = { 712};
592 .reg_off = HHI_MPLL_CNTL9, 713
593 .shift = 14, 714static struct clk_regmap gxbb_mpll2_div = {
594 .width = 1, 715 .data = &(struct meson_clk_mpll_data){
716 .sdm = {
717 .reg_off = HHI_MPLL_CNTL9,
718 .shift = 0,
719 .width = 14,
720 },
721 .sdm_en = {
722 .reg_off = HHI_MPLL_CNTL9,
723 .shift = 15,
724 .width = 1,
725 },
726 .n2 = {
727 .reg_off = HHI_MPLL_CNTL9,
728 .shift = 16,
729 .width = 9,
730 },
731 .lock = &meson_clk_lock,
595 }, 732 },
596 .lock = &meson_clk_lock,
597 .hw.init = &(struct clk_init_data){ 733 .hw.init = &(struct clk_init_data){
598 .name = "mpll2", 734 .name = "mpll2_div",
599 .ops = &meson_clk_mpll_ops, 735 .ops = &meson_clk_mpll_ops,
600 .parent_names = (const char *[]){ "fixed_pll" }, 736 .parent_names = (const char *[]){ "mpll_prediv" },
601 .num_parents = 1, 737 .num_parents = 1,
602 }, 738 },
603}; 739};
604 740
605/* 741static struct clk_regmap gxbb_mpll2 = {
606 * FIXME The legacy composite clocks (e.g. clk81) are both PLL post-dividers 742 .data = &(struct clk_regmap_gate_data){
607 * and should be modeled with their respective PLLs via the forthcoming 743 .offset = HHI_MPLL_CNTL9,
608 * coordinated clock rates feature 744 .bit_idx = 14,
609 */ 745 },
746 .hw.init = &(struct clk_init_data){
747 .name = "mpll2",
748 .ops = &clk_regmap_gate_ops,
749 .parent_names = (const char *[]){ "mpll2_div" },
750 .num_parents = 1,
751 .flags = CLK_SET_RATE_PARENT,
752 },
753};
610 754
611static u32 mux_table_clk81[] = { 0, 2, 3, 4, 5, 6, 7 }; 755static u32 mux_table_clk81[] = { 0, 2, 3, 4, 5, 6, 7 };
612static const char * const clk81_parent_names[] = { 756static const char * const clk81_parent_names[] = {
@@ -614,16 +758,16 @@ static const char * const clk81_parent_names[] = {
614 "fclk_div3", "fclk_div5" 758 "fclk_div3", "fclk_div5"
615}; 759};
616 760
617static struct clk_mux gxbb_mpeg_clk_sel = { 761static struct clk_regmap gxbb_mpeg_clk_sel = {
618 .reg = (void *)HHI_MPEG_CLK_CNTL, 762 .data = &(struct clk_regmap_mux_data){
619 .mask = 0x7, 763 .offset = HHI_MPEG_CLK_CNTL,
620 .shift = 12, 764 .mask = 0x7,
621 .flags = CLK_MUX_READ_ONLY, 765 .shift = 12,
622 .table = mux_table_clk81, 766 .table = mux_table_clk81,
623 .lock = &meson_clk_lock, 767 },
624 .hw.init = &(struct clk_init_data){ 768 .hw.init = &(struct clk_init_data){
625 .name = "mpeg_clk_sel", 769 .name = "mpeg_clk_sel",
626 .ops = &clk_mux_ro_ops, 770 .ops = &clk_regmap_mux_ro_ops,
627 /* 771 /*
628 * bits 14:12 selects from 8 possible parents: 772 * bits 14:12 selects from 8 possible parents:
629 * xtal, 1'b0 (wtf), fclk_div7, mpll_clkout1, mpll_clkout2, 773 * xtal, 1'b0 (wtf), fclk_div7, mpll_clkout1, mpll_clkout2,
@@ -631,72 +775,75 @@ static struct clk_mux gxbb_mpeg_clk_sel = {
631 */ 775 */
632 .parent_names = clk81_parent_names, 776 .parent_names = clk81_parent_names,
633 .num_parents = ARRAY_SIZE(clk81_parent_names), 777 .num_parents = ARRAY_SIZE(clk81_parent_names),
634 .flags = (CLK_SET_RATE_NO_REPARENT | CLK_IGNORE_UNUSED),
635 }, 778 },
636}; 779};
637 780
638static struct clk_divider gxbb_mpeg_clk_div = { 781static struct clk_regmap gxbb_mpeg_clk_div = {
639 .reg = (void *)HHI_MPEG_CLK_CNTL, 782 .data = &(struct clk_regmap_div_data){
640 .shift = 0, 783 .offset = HHI_MPEG_CLK_CNTL,
641 .width = 7, 784 .shift = 0,
642 .lock = &meson_clk_lock, 785 .width = 7,
786 },
643 .hw.init = &(struct clk_init_data){ 787 .hw.init = &(struct clk_init_data){
644 .name = "mpeg_clk_div", 788 .name = "mpeg_clk_div",
645 .ops = &clk_divider_ops, 789 .ops = &clk_regmap_divider_ro_ops,
646 .parent_names = (const char *[]){ "mpeg_clk_sel" }, 790 .parent_names = (const char *[]){ "mpeg_clk_sel" },
647 .num_parents = 1, 791 .num_parents = 1,
648 .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED),
649 }, 792 },
650}; 793};
651 794
652/* the mother of dragons^W gates */ 795/* the mother of dragons gates */
653static struct clk_gate gxbb_clk81 = { 796static struct clk_regmap gxbb_clk81 = {
654 .reg = (void *)HHI_MPEG_CLK_CNTL, 797 .data = &(struct clk_regmap_gate_data){
655 .bit_idx = 7, 798 .offset = HHI_MPEG_CLK_CNTL,
656 .lock = &meson_clk_lock, 799 .bit_idx = 7,
800 },
657 .hw.init = &(struct clk_init_data){ 801 .hw.init = &(struct clk_init_data){
658 .name = "clk81", 802 .name = "clk81",
659 .ops = &clk_gate_ops, 803 .ops = &clk_regmap_gate_ops,
660 .parent_names = (const char *[]){ "mpeg_clk_div" }, 804 .parent_names = (const char *[]){ "mpeg_clk_div" },
661 .num_parents = 1, 805 .num_parents = 1,
662 .flags = (CLK_SET_RATE_PARENT | CLK_IS_CRITICAL), 806 .flags = CLK_IS_CRITICAL,
663 }, 807 },
664}; 808};
665 809
666static struct clk_mux gxbb_sar_adc_clk_sel = { 810static struct clk_regmap gxbb_sar_adc_clk_sel = {
667 .reg = (void *)HHI_SAR_CLK_CNTL, 811 .data = &(struct clk_regmap_mux_data){
668 .mask = 0x3, 812 .offset = HHI_SAR_CLK_CNTL,
669 .shift = 9, 813 .mask = 0x3,
670 .lock = &meson_clk_lock, 814 .shift = 9,
815 },
671 .hw.init = &(struct clk_init_data){ 816 .hw.init = &(struct clk_init_data){
672 .name = "sar_adc_clk_sel", 817 .name = "sar_adc_clk_sel",
673 .ops = &clk_mux_ops, 818 .ops = &clk_regmap_mux_ops,
674 /* NOTE: The datasheet doesn't list the parents for bit 10 */ 819 /* NOTE: The datasheet doesn't list the parents for bit 10 */
675 .parent_names = (const char *[]){ "xtal", "clk81", }, 820 .parent_names = (const char *[]){ "xtal", "clk81", },
676 .num_parents = 2, 821 .num_parents = 2,
677 }, 822 },
678}; 823};
679 824
680static struct clk_divider gxbb_sar_adc_clk_div = { 825static struct clk_regmap gxbb_sar_adc_clk_div = {
681 .reg = (void *)HHI_SAR_CLK_CNTL, 826 .data = &(struct clk_regmap_div_data){
682 .shift = 0, 827 .offset = HHI_SAR_CLK_CNTL,
683 .width = 8, 828 .shift = 0,
684 .lock = &meson_clk_lock, 829 .width = 8,
830 },
685 .hw.init = &(struct clk_init_data){ 831 .hw.init = &(struct clk_init_data){
686 .name = "sar_adc_clk_div", 832 .name = "sar_adc_clk_div",
687 .ops = &clk_divider_ops, 833 .ops = &clk_regmap_divider_ops,
688 .parent_names = (const char *[]){ "sar_adc_clk_sel" }, 834 .parent_names = (const char *[]){ "sar_adc_clk_sel" },
689 .num_parents = 1, 835 .num_parents = 1,
690 }, 836 },
691}; 837};
692 838
693static struct clk_gate gxbb_sar_adc_clk = { 839static struct clk_regmap gxbb_sar_adc_clk = {
694 .reg = (void *)HHI_SAR_CLK_CNTL, 840 .data = &(struct clk_regmap_gate_data){
695 .bit_idx = 8, 841 .offset = HHI_SAR_CLK_CNTL,
696 .lock = &meson_clk_lock, 842 .bit_idx = 8,
843 },
697 .hw.init = &(struct clk_init_data){ 844 .hw.init = &(struct clk_init_data){
698 .name = "sar_adc_clk", 845 .name = "sar_adc_clk",
699 .ops = &clk_gate_ops, 846 .ops = &clk_regmap_gate_ops,
700 .parent_names = (const char *[]){ "sar_adc_clk_div" }, 847 .parent_names = (const char *[]){ "sar_adc_clk_div" },
701 .num_parents = 1, 848 .num_parents = 1,
702 .flags = CLK_SET_RATE_PARENT, 849 .flags = CLK_SET_RATE_PARENT,
@@ -708,21 +855,20 @@ static struct clk_gate gxbb_sar_adc_clk = {
708 * muxed by a glitch-free switch. 855 * muxed by a glitch-free switch.
709 */ 856 */
710 857
711static u32 mux_table_mali_0_1[] = {0, 1, 2, 3, 4, 5, 6, 7};
712static const char * const gxbb_mali_0_1_parent_names[] = { 858static const char * const gxbb_mali_0_1_parent_names[] = {
713 "xtal", "gp0_pll", "mpll2", "mpll1", "fclk_div7", 859 "xtal", "gp0_pll", "mpll2", "mpll1", "fclk_div7",
714 "fclk_div4", "fclk_div3", "fclk_div5" 860 "fclk_div4", "fclk_div3", "fclk_div5"
715}; 861};
716 862
717static struct clk_mux gxbb_mali_0_sel = { 863static struct clk_regmap gxbb_mali_0_sel = {
718 .reg = (void *)HHI_MALI_CLK_CNTL, 864 .data = &(struct clk_regmap_mux_data){
719 .mask = 0x7, 865 .offset = HHI_MALI_CLK_CNTL,
720 .shift = 9, 866 .mask = 0x7,
721 .table = mux_table_mali_0_1, 867 .shift = 9,
722 .lock = &meson_clk_lock, 868 },
723 .hw.init = &(struct clk_init_data){ 869 .hw.init = &(struct clk_init_data){
724 .name = "mali_0_sel", 870 .name = "mali_0_sel",
725 .ops = &clk_mux_ops, 871 .ops = &clk_regmap_mux_ops,
726 /* 872 /*
727 * bits 10:9 selects from 8 possible parents: 873 * bits 10:9 selects from 8 possible parents:
728 * xtal, gp0_pll, mpll2, mpll1, fclk_div7, 874 * xtal, gp0_pll, mpll2, mpll1, fclk_div7,
@@ -734,42 +880,44 @@ static struct clk_mux gxbb_mali_0_sel = {
734 }, 880 },
735}; 881};
736 882
737static struct clk_divider gxbb_mali_0_div = { 883static struct clk_regmap gxbb_mali_0_div = {
738 .reg = (void *)HHI_MALI_CLK_CNTL, 884 .data = &(struct clk_regmap_div_data){
739 .shift = 0, 885 .offset = HHI_MALI_CLK_CNTL,
740 .width = 7, 886 .shift = 0,
741 .lock = &meson_clk_lock, 887 .width = 7,
888 },
742 .hw.init = &(struct clk_init_data){ 889 .hw.init = &(struct clk_init_data){
743 .name = "mali_0_div", 890 .name = "mali_0_div",
744 .ops = &clk_divider_ops, 891 .ops = &clk_regmap_divider_ops,
745 .parent_names = (const char *[]){ "mali_0_sel" }, 892 .parent_names = (const char *[]){ "mali_0_sel" },
746 .num_parents = 1, 893 .num_parents = 1,
747 .flags = CLK_SET_RATE_NO_REPARENT, 894 .flags = CLK_SET_RATE_NO_REPARENT,
748 }, 895 },
749}; 896};
750 897
751static struct clk_gate gxbb_mali_0 = { 898static struct clk_regmap gxbb_mali_0 = {
752 .reg = (void *)HHI_MALI_CLK_CNTL, 899 .data = &(struct clk_regmap_gate_data){
753 .bit_idx = 8, 900 .offset = HHI_MALI_CLK_CNTL,
754 .lock = &meson_clk_lock, 901 .bit_idx = 8,
902 },
755 .hw.init = &(struct clk_init_data){ 903 .hw.init = &(struct clk_init_data){
756 .name = "mali_0", 904 .name = "mali_0",
757 .ops = &clk_gate_ops, 905 .ops = &clk_regmap_gate_ops,
758 .parent_names = (const char *[]){ "mali_0_div" }, 906 .parent_names = (const char *[]){ "mali_0_div" },
759 .num_parents = 1, 907 .num_parents = 1,
760 .flags = CLK_SET_RATE_PARENT, 908 .flags = CLK_SET_RATE_PARENT,
761 }, 909 },
762}; 910};
763 911
764static struct clk_mux gxbb_mali_1_sel = { 912static struct clk_regmap gxbb_mali_1_sel = {
765 .reg = (void *)HHI_MALI_CLK_CNTL, 913 .data = &(struct clk_regmap_mux_data){
766 .mask = 0x7, 914 .offset = HHI_MALI_CLK_CNTL,
767 .shift = 25, 915 .mask = 0x7,
768 .table = mux_table_mali_0_1, 916 .shift = 25,
769 .lock = &meson_clk_lock, 917 },
770 .hw.init = &(struct clk_init_data){ 918 .hw.init = &(struct clk_init_data){
771 .name = "mali_1_sel", 919 .name = "mali_1_sel",
772 .ops = &clk_mux_ops, 920 .ops = &clk_regmap_mux_ops,
773 /* 921 /*
774 * bits 10:9 selects from 8 possible parents: 922 * bits 10:9 selects from 8 possible parents:
775 * xtal, gp0_pll, mpll2, mpll1, fclk_div7, 923 * xtal, gp0_pll, mpll2, mpll1, fclk_div7,
@@ -781,77 +929,79 @@ static struct clk_mux gxbb_mali_1_sel = {
781 }, 929 },
782}; 930};
783 931
784static struct clk_divider gxbb_mali_1_div = { 932static struct clk_regmap gxbb_mali_1_div = {
785 .reg = (void *)HHI_MALI_CLK_CNTL, 933 .data = &(struct clk_regmap_div_data){
786 .shift = 16, 934 .offset = HHI_MALI_CLK_CNTL,
787 .width = 7, 935 .shift = 16,
788 .lock = &meson_clk_lock, 936 .width = 7,
937 },
789 .hw.init = &(struct clk_init_data){ 938 .hw.init = &(struct clk_init_data){
790 .name = "mali_1_div", 939 .name = "mali_1_div",
791 .ops = &clk_divider_ops, 940 .ops = &clk_regmap_divider_ops,
792 .parent_names = (const char *[]){ "mali_1_sel" }, 941 .parent_names = (const char *[]){ "mali_1_sel" },
793 .num_parents = 1, 942 .num_parents = 1,
794 .flags = CLK_SET_RATE_NO_REPARENT, 943 .flags = CLK_SET_RATE_NO_REPARENT,
795 }, 944 },
796}; 945};
797 946
798static struct clk_gate gxbb_mali_1 = { 947static struct clk_regmap gxbb_mali_1 = {
799 .reg = (void *)HHI_MALI_CLK_CNTL, 948 .data = &(struct clk_regmap_gate_data){
800 .bit_idx = 24, 949 .offset = HHI_MALI_CLK_CNTL,
801 .lock = &meson_clk_lock, 950 .bit_idx = 24,
951 },
802 .hw.init = &(struct clk_init_data){ 952 .hw.init = &(struct clk_init_data){
803 .name = "mali_1", 953 .name = "mali_1",
804 .ops = &clk_gate_ops, 954 .ops = &clk_regmap_gate_ops,
805 .parent_names = (const char *[]){ "mali_1_div" }, 955 .parent_names = (const char *[]){ "mali_1_div" },
806 .num_parents = 1, 956 .num_parents = 1,
807 .flags = CLK_SET_RATE_PARENT, 957 .flags = CLK_SET_RATE_PARENT,
808 }, 958 },
809}; 959};
810 960
811static u32 mux_table_mali[] = {0, 1};
812static const char * const gxbb_mali_parent_names[] = { 961static const char * const gxbb_mali_parent_names[] = {
813 "mali_0", "mali_1" 962 "mali_0", "mali_1"
814}; 963};
815 964
816static struct clk_mux gxbb_mali = { 965static struct clk_regmap gxbb_mali = {
817 .reg = (void *)HHI_MALI_CLK_CNTL, 966 .data = &(struct clk_regmap_mux_data){
818 .mask = 1, 967 .offset = HHI_MALI_CLK_CNTL,
819 .shift = 31, 968 .mask = 1,
820 .table = mux_table_mali, 969 .shift = 31,
821 .lock = &meson_clk_lock, 970 },
822 .hw.init = &(struct clk_init_data){ 971 .hw.init = &(struct clk_init_data){
823 .name = "mali", 972 .name = "mali",
824 .ops = &clk_mux_ops, 973 .ops = &clk_regmap_mux_ops,
825 .parent_names = gxbb_mali_parent_names, 974 .parent_names = gxbb_mali_parent_names,
826 .num_parents = 2, 975 .num_parents = 2,
827 .flags = CLK_SET_RATE_NO_REPARENT, 976 .flags = CLK_SET_RATE_NO_REPARENT,
828 }, 977 },
829}; 978};
830 979
831static struct clk_mux gxbb_cts_amclk_sel = { 980static struct clk_regmap gxbb_cts_amclk_sel = {
832 .reg = (void *) HHI_AUD_CLK_CNTL, 981 .data = &(struct clk_regmap_mux_data){
833 .mask = 0x3, 982 .offset = HHI_AUD_CLK_CNTL,
834 .shift = 9, 983 .mask = 0x3,
835 /* Default parent unknown (register reset value: 0) */ 984 .shift = 9,
836 .table = (u32[]){ 1, 2, 3 }, 985 .table = (u32[]){ 1, 2, 3 },
837 .lock = &meson_clk_lock, 986 },
838 .hw.init = &(struct clk_init_data){ 987 .hw.init = &(struct clk_init_data){
839 .name = "cts_amclk_sel", 988 .name = "cts_amclk_sel",
840 .ops = &clk_mux_ops, 989 .ops = &clk_regmap_mux_ops,
841 .parent_names = (const char *[]){ "mpll0", "mpll1", "mpll2" }, 990 .parent_names = (const char *[]){ "mpll0", "mpll1", "mpll2" },
842 .num_parents = 3, 991 .num_parents = 3,
843 .flags = CLK_SET_RATE_PARENT, 992 .flags = CLK_SET_RATE_PARENT,
844 }, 993 },
845}; 994};
846 995
847static struct meson_clk_audio_divider gxbb_cts_amclk_div = { 996static struct clk_regmap gxbb_cts_amclk_div = {
848 .div = { 997 .data = &(struct meson_clk_audio_div_data){
849 .reg_off = HHI_AUD_CLK_CNTL, 998 .div = {
850 .shift = 0, 999 .reg_off = HHI_AUD_CLK_CNTL,
851 .width = 8, 1000 .shift = 0,
1001 .width = 8,
1002 },
1003 .flags = CLK_DIVIDER_ROUND_CLOSEST,
852 }, 1004 },
853 .flags = CLK_DIVIDER_ROUND_CLOSEST,
854 .lock = &meson_clk_lock,
855 .hw.init = &(struct clk_init_data){ 1005 .hw.init = &(struct clk_init_data){
856 .name = "cts_amclk_div", 1006 .name = "cts_amclk_div",
857 .ops = &meson_clk_audio_divider_ops, 1007 .ops = &meson_clk_audio_divider_ops,
@@ -861,71 +1011,75 @@ static struct meson_clk_audio_divider gxbb_cts_amclk_div = {
861 }, 1011 },
862}; 1012};
863 1013
864static struct clk_gate gxbb_cts_amclk = { 1014static struct clk_regmap gxbb_cts_amclk = {
865 .reg = (void *) HHI_AUD_CLK_CNTL, 1015 .data = &(struct clk_regmap_gate_data){
866 .bit_idx = 8, 1016 .offset = HHI_AUD_CLK_CNTL,
867 .lock = &meson_clk_lock, 1017 .bit_idx = 8,
1018 },
868 .hw.init = &(struct clk_init_data){ 1019 .hw.init = &(struct clk_init_data){
869 .name = "cts_amclk", 1020 .name = "cts_amclk",
870 .ops = &clk_gate_ops, 1021 .ops = &clk_regmap_gate_ops,
871 .parent_names = (const char *[]){ "cts_amclk_div" }, 1022 .parent_names = (const char *[]){ "cts_amclk_div" },
872 .num_parents = 1, 1023 .num_parents = 1,
873 .flags = CLK_SET_RATE_PARENT, 1024 .flags = CLK_SET_RATE_PARENT,
874 }, 1025 },
875}; 1026};
876 1027
877static struct clk_mux gxbb_cts_mclk_i958_sel = { 1028static struct clk_regmap gxbb_cts_mclk_i958_sel = {
878 .reg = (void *)HHI_AUD_CLK_CNTL2, 1029 .data = &(struct clk_regmap_mux_data){
879 .mask = 0x3, 1030 .offset = HHI_AUD_CLK_CNTL2,
880 .shift = 25, 1031 .mask = 0x3,
881 /* Default parent unknown (register reset value: 0) */ 1032 .shift = 25,
882 .table = (u32[]){ 1, 2, 3 }, 1033 .table = (u32[]){ 1, 2, 3 },
883 .lock = &meson_clk_lock, 1034 },
884 .hw.init = &(struct clk_init_data) { 1035 .hw.init = &(struct clk_init_data) {
885 .name = "cts_mclk_i958_sel", 1036 .name = "cts_mclk_i958_sel",
886 .ops = &clk_mux_ops, 1037 .ops = &clk_regmap_mux_ops,
887 .parent_names = (const char *[]){ "mpll0", "mpll1", "mpll2" }, 1038 .parent_names = (const char *[]){ "mpll0", "mpll1", "mpll2" },
888 .num_parents = 3, 1039 .num_parents = 3,
889 .flags = CLK_SET_RATE_PARENT, 1040 .flags = CLK_SET_RATE_PARENT,
890 }, 1041 },
891}; 1042};
892 1043
893static struct clk_divider gxbb_cts_mclk_i958_div = { 1044static struct clk_regmap gxbb_cts_mclk_i958_div = {
894 .reg = (void *)HHI_AUD_CLK_CNTL2, 1045 .data = &(struct clk_regmap_div_data){
895 .shift = 16, 1046 .offset = HHI_AUD_CLK_CNTL2,
896 .width = 8, 1047 .shift = 16,
897 .lock = &meson_clk_lock, 1048 .width = 8,
898 .flags = CLK_DIVIDER_ROUND_CLOSEST, 1049 .flags = CLK_DIVIDER_ROUND_CLOSEST,
1050 },
899 .hw.init = &(struct clk_init_data) { 1051 .hw.init = &(struct clk_init_data) {
900 .name = "cts_mclk_i958_div", 1052 .name = "cts_mclk_i958_div",
901 .ops = &clk_divider_ops, 1053 .ops = &clk_regmap_divider_ops,
902 .parent_names = (const char *[]){ "cts_mclk_i958_sel" }, 1054 .parent_names = (const char *[]){ "cts_mclk_i958_sel" },
903 .num_parents = 1, 1055 .num_parents = 1,
904 .flags = CLK_SET_RATE_PARENT, 1056 .flags = CLK_SET_RATE_PARENT,
905 }, 1057 },
906}; 1058};
907 1059
908static struct clk_gate gxbb_cts_mclk_i958 = { 1060static struct clk_regmap gxbb_cts_mclk_i958 = {
909 .reg = (void *)HHI_AUD_CLK_CNTL2, 1061 .data = &(struct clk_regmap_gate_data){
910 .bit_idx = 24, 1062 .offset = HHI_AUD_CLK_CNTL2,
911 .lock = &meson_clk_lock, 1063 .bit_idx = 24,
1064 },
912 .hw.init = &(struct clk_init_data){ 1065 .hw.init = &(struct clk_init_data){
913 .name = "cts_mclk_i958", 1066 .name = "cts_mclk_i958",
914 .ops = &clk_gate_ops, 1067 .ops = &clk_regmap_gate_ops,
915 .parent_names = (const char *[]){ "cts_mclk_i958_div" }, 1068 .parent_names = (const char *[]){ "cts_mclk_i958_div" },
916 .num_parents = 1, 1069 .num_parents = 1,
917 .flags = CLK_SET_RATE_PARENT, 1070 .flags = CLK_SET_RATE_PARENT,
918 }, 1071 },
919}; 1072};
920 1073
921static struct clk_mux gxbb_cts_i958 = { 1074static struct clk_regmap gxbb_cts_i958 = {
922 .reg = (void *)HHI_AUD_CLK_CNTL2, 1075 .data = &(struct clk_regmap_mux_data){
923 .mask = 0x1, 1076 .offset = HHI_AUD_CLK_CNTL2,
924 .shift = 27, 1077 .mask = 0x1,
925 .lock = &meson_clk_lock, 1078 .shift = 27,
926 .hw.init = &(struct clk_init_data){ 1079 },
1080 .hw.init = &(struct clk_init_data){
927 .name = "cts_i958", 1081 .name = "cts_i958",
928 .ops = &clk_mux_ops, 1082 .ops = &clk_regmap_mux_ops,
929 .parent_names = (const char *[]){ "cts_amclk", "cts_mclk_i958" }, 1083 .parent_names = (const char *[]){ "cts_amclk", "cts_mclk_i958" },
930 .num_parents = 2, 1084 .num_parents = 2,
931 /* 1085 /*
@@ -936,27 +1090,29 @@ static struct clk_mux gxbb_cts_i958 = {
936 }, 1090 },
937}; 1091};
938 1092
939static struct clk_divider gxbb_32k_clk_div = { 1093static struct clk_regmap gxbb_32k_clk_div = {
940 .reg = (void *)HHI_32K_CLK_CNTL, 1094 .data = &(struct clk_regmap_div_data){
941 .shift = 0, 1095 .offset = HHI_32K_CLK_CNTL,
942 .width = 14, 1096 .shift = 0,
943 .lock = &meson_clk_lock, 1097 .width = 14,
1098 },
944 .hw.init = &(struct clk_init_data){ 1099 .hw.init = &(struct clk_init_data){
945 .name = "32k_clk_div", 1100 .name = "32k_clk_div",
946 .ops = &clk_divider_ops, 1101 .ops = &clk_regmap_divider_ops,
947 .parent_names = (const char *[]){ "32k_clk_sel" }, 1102 .parent_names = (const char *[]){ "32k_clk_sel" },
948 .num_parents = 1, 1103 .num_parents = 1,
949 .flags = CLK_SET_RATE_PARENT | CLK_DIVIDER_ROUND_CLOSEST, 1104 .flags = CLK_SET_RATE_PARENT | CLK_DIVIDER_ROUND_CLOSEST,
950 }, 1105 },
951}; 1106};
952 1107
953static struct clk_gate gxbb_32k_clk = { 1108static struct clk_regmap gxbb_32k_clk = {
954 .reg = (void *)HHI_32K_CLK_CNTL, 1109 .data = &(struct clk_regmap_gate_data){
955 .bit_idx = 15, 1110 .offset = HHI_32K_CLK_CNTL,
956 .lock = &meson_clk_lock, 1111 .bit_idx = 15,
1112 },
957 .hw.init = &(struct clk_init_data){ 1113 .hw.init = &(struct clk_init_data){
958 .name = "32k_clk", 1114 .name = "32k_clk",
959 .ops = &clk_gate_ops, 1115 .ops = &clk_regmap_gate_ops,
960 .parent_names = (const char *[]){ "32k_clk_div" }, 1116 .parent_names = (const char *[]){ "32k_clk_div" },
961 .num_parents = 1, 1117 .num_parents = 1,
962 .flags = CLK_SET_RATE_PARENT, 1118 .flags = CLK_SET_RATE_PARENT,
@@ -967,14 +1123,15 @@ static const char * const gxbb_32k_clk_parent_names[] = {
967 "xtal", "cts_slow_oscin", "fclk_div3", "fclk_div5" 1123 "xtal", "cts_slow_oscin", "fclk_div3", "fclk_div5"
968}; 1124};
969 1125
970static struct clk_mux gxbb_32k_clk_sel = { 1126static struct clk_regmap gxbb_32k_clk_sel = {
971 .reg = (void *)HHI_32K_CLK_CNTL, 1127 .data = &(struct clk_regmap_mux_data){
972 .mask = 0x3, 1128 .offset = HHI_32K_CLK_CNTL,
973 .shift = 16, 1129 .mask = 0x3,
974 .lock = &meson_clk_lock, 1130 .shift = 16,
975 .hw.init = &(struct clk_init_data){ 1131 },
1132 .hw.init = &(struct clk_init_data){
976 .name = "32k_clk_sel", 1133 .name = "32k_clk_sel",
977 .ops = &clk_mux_ops, 1134 .ops = &clk_regmap_mux_ops,
978 .parent_names = gxbb_32k_clk_parent_names, 1135 .parent_names = gxbb_32k_clk_parent_names,
979 .num_parents = 4, 1136 .num_parents = 4,
980 .flags = CLK_SET_RATE_PARENT, 1137 .flags = CLK_SET_RATE_PARENT,
@@ -993,42 +1150,45 @@ static const char * const gxbb_sd_emmc_clk0_parent_names[] = {
993}; 1150};
994 1151
995/* SDIO clock */ 1152/* SDIO clock */
996static struct clk_mux gxbb_sd_emmc_a_clk0_sel = { 1153static struct clk_regmap gxbb_sd_emmc_a_clk0_sel = {
997 .reg = (void *)HHI_SD_EMMC_CLK_CNTL, 1154 .data = &(struct clk_regmap_mux_data){
998 .mask = 0x7, 1155 .offset = HHI_SD_EMMC_CLK_CNTL,
999 .shift = 9, 1156 .mask = 0x7,
1000 .lock = &meson_clk_lock, 1157 .shift = 9,
1158 },
1001 .hw.init = &(struct clk_init_data) { 1159 .hw.init = &(struct clk_init_data) {
1002 .name = "sd_emmc_a_clk0_sel", 1160 .name = "sd_emmc_a_clk0_sel",
1003 .ops = &clk_mux_ops, 1161 .ops = &clk_regmap_mux_ops,
1004 .parent_names = gxbb_sd_emmc_clk0_parent_names, 1162 .parent_names = gxbb_sd_emmc_clk0_parent_names,
1005 .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_names), 1163 .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_names),
1006 .flags = CLK_SET_RATE_PARENT, 1164 .flags = CLK_SET_RATE_PARENT,
1007 }, 1165 },
1008}; 1166};
1009 1167
1010static struct clk_divider gxbb_sd_emmc_a_clk0_div = { 1168static struct clk_regmap gxbb_sd_emmc_a_clk0_div = {
1011 .reg = (void *)HHI_SD_EMMC_CLK_CNTL, 1169 .data = &(struct clk_regmap_div_data){
1012 .shift = 0, 1170 .offset = HHI_SD_EMMC_CLK_CNTL,
1013 .width = 7, 1171 .shift = 0,
1014 .lock = &meson_clk_lock, 1172 .width = 7,
1015 .flags = CLK_DIVIDER_ROUND_CLOSEST, 1173 .flags = CLK_DIVIDER_ROUND_CLOSEST,
1174 },
1016 .hw.init = &(struct clk_init_data) { 1175 .hw.init = &(struct clk_init_data) {
1017 .name = "sd_emmc_a_clk0_div", 1176 .name = "sd_emmc_a_clk0_div",
1018 .ops = &clk_divider_ops, 1177 .ops = &clk_regmap_divider_ops,
1019 .parent_names = (const char *[]){ "sd_emmc_a_clk0_sel" }, 1178 .parent_names = (const char *[]){ "sd_emmc_a_clk0_sel" },
1020 .num_parents = 1, 1179 .num_parents = 1,
1021 .flags = CLK_SET_RATE_PARENT, 1180 .flags = CLK_SET_RATE_PARENT,
1022 }, 1181 },
1023}; 1182};
1024 1183
1025static struct clk_gate gxbb_sd_emmc_a_clk0 = { 1184static struct clk_regmap gxbb_sd_emmc_a_clk0 = {
1026 .reg = (void *)HHI_SD_EMMC_CLK_CNTL, 1185 .data = &(struct clk_regmap_gate_data){
1027 .bit_idx = 7, 1186 .offset = HHI_SD_EMMC_CLK_CNTL,
1028 .lock = &meson_clk_lock, 1187 .bit_idx = 7,
1188 },
1029 .hw.init = &(struct clk_init_data){ 1189 .hw.init = &(struct clk_init_data){
1030 .name = "sd_emmc_a_clk0", 1190 .name = "sd_emmc_a_clk0",
1031 .ops = &clk_gate_ops, 1191 .ops = &clk_regmap_gate_ops,
1032 .parent_names = (const char *[]){ "sd_emmc_a_clk0_div" }, 1192 .parent_names = (const char *[]){ "sd_emmc_a_clk0_div" },
1033 .num_parents = 1, 1193 .num_parents = 1,
1034 .flags = CLK_SET_RATE_PARENT, 1194 .flags = CLK_SET_RATE_PARENT,
@@ -1036,42 +1196,45 @@ static struct clk_gate gxbb_sd_emmc_a_clk0 = {
1036}; 1196};
1037 1197
1038/* SDcard clock */ 1198/* SDcard clock */
1039static struct clk_mux gxbb_sd_emmc_b_clk0_sel = { 1199static struct clk_regmap gxbb_sd_emmc_b_clk0_sel = {
1040 .reg = (void *)HHI_SD_EMMC_CLK_CNTL, 1200 .data = &(struct clk_regmap_mux_data){
1041 .mask = 0x7, 1201 .offset = HHI_SD_EMMC_CLK_CNTL,
1042 .shift = 25, 1202 .mask = 0x7,
1043 .lock = &meson_clk_lock, 1203 .shift = 25,
1204 },
1044 .hw.init = &(struct clk_init_data) { 1205 .hw.init = &(struct clk_init_data) {
1045 .name = "sd_emmc_b_clk0_sel", 1206 .name = "sd_emmc_b_clk0_sel",
1046 .ops = &clk_mux_ops, 1207 .ops = &clk_regmap_mux_ops,
1047 .parent_names = gxbb_sd_emmc_clk0_parent_names, 1208 .parent_names = gxbb_sd_emmc_clk0_parent_names,
1048 .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_names), 1209 .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_names),
1049 .flags = CLK_SET_RATE_PARENT, 1210 .flags = CLK_SET_RATE_PARENT,
1050 }, 1211 },
1051}; 1212};
1052 1213
1053static struct clk_divider gxbb_sd_emmc_b_clk0_div = { 1214static struct clk_regmap gxbb_sd_emmc_b_clk0_div = {
1054 .reg = (void *)HHI_SD_EMMC_CLK_CNTL, 1215 .data = &(struct clk_regmap_div_data){
1055 .shift = 16, 1216 .offset = HHI_SD_EMMC_CLK_CNTL,
1056 .width = 7, 1217 .shift = 16,
1057 .lock = &meson_clk_lock, 1218 .width = 7,
1058 .flags = CLK_DIVIDER_ROUND_CLOSEST, 1219 .flags = CLK_DIVIDER_ROUND_CLOSEST,
1220 },
1059 .hw.init = &(struct clk_init_data) { 1221 .hw.init = &(struct clk_init_data) {
1060 .name = "sd_emmc_b_clk0_div", 1222 .name = "sd_emmc_b_clk0_div",
1061 .ops = &clk_divider_ops, 1223 .ops = &clk_regmap_divider_ops,
1062 .parent_names = (const char *[]){ "sd_emmc_b_clk0_sel" }, 1224 .parent_names = (const char *[]){ "sd_emmc_b_clk0_sel" },
1063 .num_parents = 1, 1225 .num_parents = 1,
1064 .flags = CLK_SET_RATE_PARENT, 1226 .flags = CLK_SET_RATE_PARENT,
1065 }, 1227 },
1066}; 1228};
1067 1229
1068static struct clk_gate gxbb_sd_emmc_b_clk0 = { 1230static struct clk_regmap gxbb_sd_emmc_b_clk0 = {
1069 .reg = (void *)HHI_SD_EMMC_CLK_CNTL, 1231 .data = &(struct clk_regmap_gate_data){
1070 .bit_idx = 23, 1232 .offset = HHI_SD_EMMC_CLK_CNTL,
1071 .lock = &meson_clk_lock, 1233 .bit_idx = 23,
1234 },
1072 .hw.init = &(struct clk_init_data){ 1235 .hw.init = &(struct clk_init_data){
1073 .name = "sd_emmc_b_clk0", 1236 .name = "sd_emmc_b_clk0",
1074 .ops = &clk_gate_ops, 1237 .ops = &clk_regmap_gate_ops,
1075 .parent_names = (const char *[]){ "sd_emmc_b_clk0_div" }, 1238 .parent_names = (const char *[]){ "sd_emmc_b_clk0_div" },
1076 .num_parents = 1, 1239 .num_parents = 1,
1077 .flags = CLK_SET_RATE_PARENT, 1240 .flags = CLK_SET_RATE_PARENT,
@@ -1079,42 +1242,45 @@ static struct clk_gate gxbb_sd_emmc_b_clk0 = {
1079}; 1242};
1080 1243
1081/* EMMC/NAND clock */ 1244/* EMMC/NAND clock */
1082static struct clk_mux gxbb_sd_emmc_c_clk0_sel = { 1245static struct clk_regmap gxbb_sd_emmc_c_clk0_sel = {
1083 .reg = (void *)HHI_NAND_CLK_CNTL, 1246 .data = &(struct clk_regmap_mux_data){
1084 .mask = 0x7, 1247 .offset = HHI_NAND_CLK_CNTL,
1085 .shift = 9, 1248 .mask = 0x7,
1086 .lock = &meson_clk_lock, 1249 .shift = 9,
1250 },
1087 .hw.init = &(struct clk_init_data) { 1251 .hw.init = &(struct clk_init_data) {
1088 .name = "sd_emmc_c_clk0_sel", 1252 .name = "sd_emmc_c_clk0_sel",
1089 .ops = &clk_mux_ops, 1253 .ops = &clk_regmap_mux_ops,
1090 .parent_names = gxbb_sd_emmc_clk0_parent_names, 1254 .parent_names = gxbb_sd_emmc_clk0_parent_names,
1091 .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_names), 1255 .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_names),
1092 .flags = CLK_SET_RATE_PARENT, 1256 .flags = CLK_SET_RATE_PARENT,
1093 }, 1257 },
1094}; 1258};
1095 1259
1096static struct clk_divider gxbb_sd_emmc_c_clk0_div = { 1260static struct clk_regmap gxbb_sd_emmc_c_clk0_div = {
1097 .reg = (void *)HHI_NAND_CLK_CNTL, 1261 .data = &(struct clk_regmap_div_data){
1098 .shift = 0, 1262 .offset = HHI_NAND_CLK_CNTL,
1099 .width = 7, 1263 .shift = 0,
1100 .lock = &meson_clk_lock, 1264 .width = 7,
1101 .flags = CLK_DIVIDER_ROUND_CLOSEST, 1265 .flags = CLK_DIVIDER_ROUND_CLOSEST,
1266 },
1102 .hw.init = &(struct clk_init_data) { 1267 .hw.init = &(struct clk_init_data) {
1103 .name = "sd_emmc_c_clk0_div", 1268 .name = "sd_emmc_c_clk0_div",
1104 .ops = &clk_divider_ops, 1269 .ops = &clk_regmap_divider_ops,
1105 .parent_names = (const char *[]){ "sd_emmc_c_clk0_sel" }, 1270 .parent_names = (const char *[]){ "sd_emmc_c_clk0_sel" },
1106 .num_parents = 1, 1271 .num_parents = 1,
1107 .flags = CLK_SET_RATE_PARENT, 1272 .flags = CLK_SET_RATE_PARENT,
1108 }, 1273 },
1109}; 1274};
1110 1275
1111static struct clk_gate gxbb_sd_emmc_c_clk0 = { 1276static struct clk_regmap gxbb_sd_emmc_c_clk0 = {
1112 .reg = (void *)HHI_NAND_CLK_CNTL, 1277 .data = &(struct clk_regmap_gate_data){
1113 .bit_idx = 7, 1278 .offset = HHI_NAND_CLK_CNTL,
1114 .lock = &meson_clk_lock, 1279 .bit_idx = 7,
1280 },
1115 .hw.init = &(struct clk_init_data){ 1281 .hw.init = &(struct clk_init_data){
1116 .name = "sd_emmc_c_clk0", 1282 .name = "sd_emmc_c_clk0",
1117 .ops = &clk_gate_ops, 1283 .ops = &clk_regmap_gate_ops,
1118 .parent_names = (const char *[]){ "sd_emmc_c_clk0_div" }, 1284 .parent_names = (const char *[]){ "sd_emmc_c_clk0_div" },
1119 .num_parents = 1, 1285 .num_parents = 1,
1120 .flags = CLK_SET_RATE_PARENT, 1286 .flags = CLK_SET_RATE_PARENT,
@@ -1123,20 +1289,19 @@ static struct clk_gate gxbb_sd_emmc_c_clk0 = {
1123 1289
1124/* VPU Clock */ 1290/* VPU Clock */
1125 1291
1126static u32 mux_table_vpu[] = {0, 1, 2, 3};
1127static const char * const gxbb_vpu_parent_names[] = { 1292static const char * const gxbb_vpu_parent_names[] = {
1128 "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7" 1293 "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7"
1129}; 1294};
1130 1295
1131static struct clk_mux gxbb_vpu_0_sel = { 1296static struct clk_regmap gxbb_vpu_0_sel = {
1132 .reg = (void *)HHI_VPU_CLK_CNTL, 1297 .data = &(struct clk_regmap_mux_data){
1133 .mask = 0x3, 1298 .offset = HHI_VPU_CLK_CNTL,
1134 .shift = 9, 1299 .mask = 0x3,
1135 .lock = &meson_clk_lock, 1300 .shift = 9,
1136 .table = mux_table_vpu, 1301 },
1137 .hw.init = &(struct clk_init_data){ 1302 .hw.init = &(struct clk_init_data){
1138 .name = "vpu_0_sel", 1303 .name = "vpu_0_sel",
1139 .ops = &clk_mux_ops, 1304 .ops = &clk_regmap_mux_ops,
1140 /* 1305 /*
1141 * bits 9:10 selects from 4 possible parents: 1306 * bits 9:10 selects from 4 possible parents:
1142 * fclk_div4, fclk_div3, fclk_div5, fclk_div7, 1307 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
@@ -1147,42 +1312,44 @@ static struct clk_mux gxbb_vpu_0_sel = {
1147 }, 1312 },
1148}; 1313};
1149 1314
1150static struct clk_divider gxbb_vpu_0_div = { 1315static struct clk_regmap gxbb_vpu_0_div = {
1151 .reg = (void *)HHI_VPU_CLK_CNTL, 1316 .data = &(struct clk_regmap_div_data){
1152 .shift = 0, 1317 .offset = HHI_VPU_CLK_CNTL,
1153 .width = 7, 1318 .shift = 0,
1154 .lock = &meson_clk_lock, 1319 .width = 7,
1320 },
1155 .hw.init = &(struct clk_init_data){ 1321 .hw.init = &(struct clk_init_data){
1156 .name = "vpu_0_div", 1322 .name = "vpu_0_div",
1157 .ops = &clk_divider_ops, 1323 .ops = &clk_regmap_divider_ops,
1158 .parent_names = (const char *[]){ "vpu_0_sel" }, 1324 .parent_names = (const char *[]){ "vpu_0_sel" },
1159 .num_parents = 1, 1325 .num_parents = 1,
1160 .flags = CLK_SET_RATE_PARENT, 1326 .flags = CLK_SET_RATE_PARENT,
1161 }, 1327 },
1162}; 1328};
1163 1329
1164static struct clk_gate gxbb_vpu_0 = { 1330static struct clk_regmap gxbb_vpu_0 = {
1165 .reg = (void *)HHI_VPU_CLK_CNTL, 1331 .data = &(struct clk_regmap_gate_data){
1166 .bit_idx = 8, 1332 .offset = HHI_VPU_CLK_CNTL,
1167 .lock = &meson_clk_lock, 1333 .bit_idx = 8,
1334 },
1168 .hw.init = &(struct clk_init_data) { 1335 .hw.init = &(struct clk_init_data) {
1169 .name = "vpu_0", 1336 .name = "vpu_0",
1170 .ops = &clk_gate_ops, 1337 .ops = &clk_regmap_gate_ops,
1171 .parent_names = (const char *[]){ "vpu_0_div" }, 1338 .parent_names = (const char *[]){ "vpu_0_div" },
1172 .num_parents = 1, 1339 .num_parents = 1,
1173 .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 1340 .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
1174 }, 1341 },
1175}; 1342};
1176 1343
1177static struct clk_mux gxbb_vpu_1_sel = { 1344static struct clk_regmap gxbb_vpu_1_sel = {
1178 .reg = (void *)HHI_VPU_CLK_CNTL, 1345 .data = &(struct clk_regmap_mux_data){
1179 .mask = 0x3, 1346 .offset = HHI_VPU_CLK_CNTL,
1180 .shift = 25, 1347 .mask = 0x3,
1181 .lock = &meson_clk_lock, 1348 .shift = 25,
1182 .table = mux_table_vpu, 1349 },
1183 .hw.init = &(struct clk_init_data){ 1350 .hw.init = &(struct clk_init_data){
1184 .name = "vpu_1_sel", 1351 .name = "vpu_1_sel",
1185 .ops = &clk_mux_ops, 1352 .ops = &clk_regmap_mux_ops,
1186 /* 1353 /*
1187 * bits 25:26 selects from 4 possible parents: 1354 * bits 25:26 selects from 4 possible parents:
1188 * fclk_div4, fclk_div3, fclk_div5, fclk_div7, 1355 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
@@ -1193,41 +1360,44 @@ static struct clk_mux gxbb_vpu_1_sel = {
1193 }, 1360 },
1194}; 1361};
1195 1362
1196static struct clk_divider gxbb_vpu_1_div = { 1363static struct clk_regmap gxbb_vpu_1_div = {
1197 .reg = (void *)HHI_VPU_CLK_CNTL, 1364 .data = &(struct clk_regmap_div_data){
1198 .shift = 16, 1365 .offset = HHI_VPU_CLK_CNTL,
1199 .width = 7, 1366 .shift = 16,
1200 .lock = &meson_clk_lock, 1367 .width = 7,
1368 },
1201 .hw.init = &(struct clk_init_data){ 1369 .hw.init = &(struct clk_init_data){
1202 .name = "vpu_1_div", 1370 .name = "vpu_1_div",
1203 .ops = &clk_divider_ops, 1371 .ops = &clk_regmap_divider_ops,
1204 .parent_names = (const char *[]){ "vpu_1_sel" }, 1372 .parent_names = (const char *[]){ "vpu_1_sel" },
1205 .num_parents = 1, 1373 .num_parents = 1,
1206 .flags = CLK_SET_RATE_PARENT, 1374 .flags = CLK_SET_RATE_PARENT,
1207 }, 1375 },
1208}; 1376};
1209 1377
1210static struct clk_gate gxbb_vpu_1 = { 1378static struct clk_regmap gxbb_vpu_1 = {
1211 .reg = (void *)HHI_VPU_CLK_CNTL, 1379 .data = &(struct clk_regmap_gate_data){
1212 .bit_idx = 24, 1380 .offset = HHI_VPU_CLK_CNTL,
1213 .lock = &meson_clk_lock, 1381 .bit_idx = 24,
1382 },
1214 .hw.init = &(struct clk_init_data) { 1383 .hw.init = &(struct clk_init_data) {
1215 .name = "vpu_1", 1384 .name = "vpu_1",
1216 .ops = &clk_gate_ops, 1385 .ops = &clk_regmap_gate_ops,
1217 .parent_names = (const char *[]){ "vpu_1_div" }, 1386 .parent_names = (const char *[]){ "vpu_1_div" },
1218 .num_parents = 1, 1387 .num_parents = 1,
1219 .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 1388 .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
1220 }, 1389 },
1221}; 1390};
1222 1391
1223static struct clk_mux gxbb_vpu = { 1392static struct clk_regmap gxbb_vpu = {
1224 .reg = (void *)HHI_VPU_CLK_CNTL, 1393 .data = &(struct clk_regmap_mux_data){
1225 .mask = 1, 1394 .offset = HHI_VPU_CLK_CNTL,
1226 .shift = 31, 1395 .mask = 1,
1227 .lock = &meson_clk_lock, 1396 .shift = 31,
1397 },
1228 .hw.init = &(struct clk_init_data){ 1398 .hw.init = &(struct clk_init_data){
1229 .name = "vpu", 1399 .name = "vpu",
1230 .ops = &clk_mux_ops, 1400 .ops = &clk_regmap_mux_ops,
1231 /* 1401 /*
1232 * bit 31 selects from 2 possible parents: 1402 * bit 31 selects from 2 possible parents:
1233 * vpu_0 or vpu_1 1403 * vpu_0 or vpu_1
@@ -1240,20 +1410,19 @@ static struct clk_mux gxbb_vpu = {
1240 1410
1241/* VAPB Clock */ 1411/* VAPB Clock */
1242 1412
1243static u32 mux_table_vapb[] = {0, 1, 2, 3};
1244static const char * const gxbb_vapb_parent_names[] = { 1413static const char * const gxbb_vapb_parent_names[] = {
1245 "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7" 1414 "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7"
1246}; 1415};
1247 1416
1248static struct clk_mux gxbb_vapb_0_sel = { 1417static struct clk_regmap gxbb_vapb_0_sel = {
1249 .reg = (void *)HHI_VAPBCLK_CNTL, 1418 .data = &(struct clk_regmap_mux_data){
1250 .mask = 0x3, 1419 .offset = HHI_VAPBCLK_CNTL,
1251 .shift = 9, 1420 .mask = 0x3,
1252 .lock = &meson_clk_lock, 1421 .shift = 9,
1253 .table = mux_table_vapb, 1422 },
1254 .hw.init = &(struct clk_init_data){ 1423 .hw.init = &(struct clk_init_data){
1255 .name = "vapb_0_sel", 1424 .name = "vapb_0_sel",
1256 .ops = &clk_mux_ops, 1425 .ops = &clk_regmap_mux_ops,
1257 /* 1426 /*
1258 * bits 9:10 selects from 4 possible parents: 1427 * bits 9:10 selects from 4 possible parents:
1259 * fclk_div4, fclk_div3, fclk_div5, fclk_div7, 1428 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
@@ -1264,42 +1433,44 @@ static struct clk_mux gxbb_vapb_0_sel = {
1264 }, 1433 },
1265}; 1434};
1266 1435
1267static struct clk_divider gxbb_vapb_0_div = { 1436static struct clk_regmap gxbb_vapb_0_div = {
1268 .reg = (void *)HHI_VAPBCLK_CNTL, 1437 .data = &(struct clk_regmap_div_data){
1269 .shift = 0, 1438 .offset = HHI_VAPBCLK_CNTL,
1270 .width = 7, 1439 .shift = 0,
1271 .lock = &meson_clk_lock, 1440 .width = 7,
1441 },
1272 .hw.init = &(struct clk_init_data){ 1442 .hw.init = &(struct clk_init_data){
1273 .name = "vapb_0_div", 1443 .name = "vapb_0_div",
1274 .ops = &clk_divider_ops, 1444 .ops = &clk_regmap_divider_ops,
1275 .parent_names = (const char *[]){ "vapb_0_sel" }, 1445 .parent_names = (const char *[]){ "vapb_0_sel" },
1276 .num_parents = 1, 1446 .num_parents = 1,
1277 .flags = CLK_SET_RATE_PARENT, 1447 .flags = CLK_SET_RATE_PARENT,
1278 }, 1448 },
1279}; 1449};
1280 1450
1281static struct clk_gate gxbb_vapb_0 = { 1451static struct clk_regmap gxbb_vapb_0 = {
1282 .reg = (void *)HHI_VAPBCLK_CNTL, 1452 .data = &(struct clk_regmap_gate_data){
1283 .bit_idx = 8, 1453 .offset = HHI_VAPBCLK_CNTL,
1284 .lock = &meson_clk_lock, 1454 .bit_idx = 8,
1455 },
1285 .hw.init = &(struct clk_init_data) { 1456 .hw.init = &(struct clk_init_data) {
1286 .name = "vapb_0", 1457 .name = "vapb_0",
1287 .ops = &clk_gate_ops, 1458 .ops = &clk_regmap_gate_ops,
1288 .parent_names = (const char *[]){ "vapb_0_div" }, 1459 .parent_names = (const char *[]){ "vapb_0_div" },
1289 .num_parents = 1, 1460 .num_parents = 1,
1290 .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 1461 .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
1291 }, 1462 },
1292}; 1463};
1293 1464
1294static struct clk_mux gxbb_vapb_1_sel = { 1465static struct clk_regmap gxbb_vapb_1_sel = {
1295 .reg = (void *)HHI_VAPBCLK_CNTL, 1466 .data = &(struct clk_regmap_mux_data){
1296 .mask = 0x3, 1467 .offset = HHI_VAPBCLK_CNTL,
1297 .shift = 25, 1468 .mask = 0x3,
1298 .lock = &meson_clk_lock, 1469 .shift = 25,
1299 .table = mux_table_vapb, 1470 },
1300 .hw.init = &(struct clk_init_data){ 1471 .hw.init = &(struct clk_init_data){
1301 .name = "vapb_1_sel", 1472 .name = "vapb_1_sel",
1302 .ops = &clk_mux_ops, 1473 .ops = &clk_regmap_mux_ops,
1303 /* 1474 /*
1304 * bits 25:26 selects from 4 possible parents: 1475 * bits 25:26 selects from 4 possible parents:
1305 * fclk_div4, fclk_div3, fclk_div5, fclk_div7, 1476 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
@@ -1310,41 +1481,44 @@ static struct clk_mux gxbb_vapb_1_sel = {
1310 }, 1481 },
1311}; 1482};
1312 1483
1313static struct clk_divider gxbb_vapb_1_div = { 1484static struct clk_regmap gxbb_vapb_1_div = {
1314 .reg = (void *)HHI_VAPBCLK_CNTL, 1485 .data = &(struct clk_regmap_div_data){
1315 .shift = 16, 1486 .offset = HHI_VAPBCLK_CNTL,
1316 .width = 7, 1487 .shift = 16,
1317 .lock = &meson_clk_lock, 1488 .width = 7,
1489 },
1318 .hw.init = &(struct clk_init_data){ 1490 .hw.init = &(struct clk_init_data){
1319 .name = "vapb_1_div", 1491 .name = "vapb_1_div",
1320 .ops = &clk_divider_ops, 1492 .ops = &clk_regmap_divider_ops,
1321 .parent_names = (const char *[]){ "vapb_1_sel" }, 1493 .parent_names = (const char *[]){ "vapb_1_sel" },
1322 .num_parents = 1, 1494 .num_parents = 1,
1323 .flags = CLK_SET_RATE_PARENT, 1495 .flags = CLK_SET_RATE_PARENT,
1324 }, 1496 },
1325}; 1497};
1326 1498
1327static struct clk_gate gxbb_vapb_1 = { 1499static struct clk_regmap gxbb_vapb_1 = {
1328 .reg = (void *)HHI_VAPBCLK_CNTL, 1500 .data = &(struct clk_regmap_gate_data){
1329 .bit_idx = 24, 1501 .offset = HHI_VAPBCLK_CNTL,
1330 .lock = &meson_clk_lock, 1502 .bit_idx = 24,
1503 },
1331 .hw.init = &(struct clk_init_data) { 1504 .hw.init = &(struct clk_init_data) {
1332 .name = "vapb_1", 1505 .name = "vapb_1",
1333 .ops = &clk_gate_ops, 1506 .ops = &clk_regmap_gate_ops,
1334 .parent_names = (const char *[]){ "vapb_1_div" }, 1507 .parent_names = (const char *[]){ "vapb_1_div" },
1335 .num_parents = 1, 1508 .num_parents = 1,
1336 .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 1509 .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
1337 }, 1510 },
1338}; 1511};
1339 1512
1340static struct clk_mux gxbb_vapb_sel = { 1513static struct clk_regmap gxbb_vapb_sel = {
1341 .reg = (void *)HHI_VAPBCLK_CNTL, 1514 .data = &(struct clk_regmap_mux_data){
1342 .mask = 1, 1515 .offset = HHI_VAPBCLK_CNTL,
1343 .shift = 31, 1516 .mask = 1,
1344 .lock = &meson_clk_lock, 1517 .shift = 31,
1518 },
1345 .hw.init = &(struct clk_init_data){ 1519 .hw.init = &(struct clk_init_data){
1346 .name = "vapb_sel", 1520 .name = "vapb_sel",
1347 .ops = &clk_mux_ops, 1521 .ops = &clk_regmap_mux_ops,
1348 /* 1522 /*
1349 * bit 31 selects from 2 possible parents: 1523 * bit 31 selects from 2 possible parents:
1350 * vapb_0 or vapb_1 1524 * vapb_0 or vapb_1
@@ -1355,13 +1529,14 @@ static struct clk_mux gxbb_vapb_sel = {
1355 }, 1529 },
1356}; 1530};
1357 1531
1358static struct clk_gate gxbb_vapb = { 1532static struct clk_regmap gxbb_vapb = {
1359 .reg = (void *)HHI_VAPBCLK_CNTL, 1533 .data = &(struct clk_regmap_gate_data){
1360 .bit_idx = 30, 1534 .offset = HHI_VAPBCLK_CNTL,
1361 .lock = &meson_clk_lock, 1535 .bit_idx = 30,
1536 },
1362 .hw.init = &(struct clk_init_data) { 1537 .hw.init = &(struct clk_init_data) {
1363 .name = "vapb", 1538 .name = "vapb",
1364 .ops = &clk_gate_ops, 1539 .ops = &clk_regmap_gate_ops,
1365 .parent_names = (const char *[]){ "vapb_sel" }, 1540 .parent_names = (const char *[]){ "vapb_sel" },
1366 .num_parents = 1, 1541 .num_parents = 1,
1367 .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 1542 .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
@@ -1601,6 +1776,16 @@ static struct clk_hw_onecell_data gxbb_hw_onecell_data = {
1601 [CLKID_VAPB_1] = &gxbb_vapb_1.hw, 1776 [CLKID_VAPB_1] = &gxbb_vapb_1.hw,
1602 [CLKID_VAPB_SEL] = &gxbb_vapb_sel.hw, 1777 [CLKID_VAPB_SEL] = &gxbb_vapb_sel.hw,
1603 [CLKID_VAPB] = &gxbb_vapb.hw, 1778 [CLKID_VAPB] = &gxbb_vapb.hw,
1779 [CLKID_HDMI_PLL_PRE_MULT] = &gxbb_hdmi_pll_pre_mult.hw,
1780 [CLKID_MPLL0_DIV] = &gxbb_mpll0_div.hw,
1781 [CLKID_MPLL1_DIV] = &gxbb_mpll1_div.hw,
1782 [CLKID_MPLL2_DIV] = &gxbb_mpll2_div.hw,
1783 [CLKID_MPLL_PREDIV] = &gxbb_mpll_prediv.hw,
1784 [CLKID_FCLK_DIV2_DIV] = &gxbb_fclk_div2_div.hw,
1785 [CLKID_FCLK_DIV3_DIV] = &gxbb_fclk_div3_div.hw,
1786 [CLKID_FCLK_DIV4_DIV] = &gxbb_fclk_div4_div.hw,
1787 [CLKID_FCLK_DIV5_DIV] = &gxbb_fclk_div5_div.hw,
1788 [CLKID_FCLK_DIV7_DIV] = &gxbb_fclk_div7_div.hw,
1604 [NR_CLKS] = NULL, 1789 [NR_CLKS] = NULL,
1605 }, 1790 },
1606 .num = NR_CLKS, 1791 .num = NR_CLKS,
@@ -1609,7 +1794,7 @@ static struct clk_hw_onecell_data gxbb_hw_onecell_data = {
1609static struct clk_hw_onecell_data gxl_hw_onecell_data = { 1794static struct clk_hw_onecell_data gxl_hw_onecell_data = {
1610 .hws = { 1795 .hws = {
1611 [CLKID_SYS_PLL] = &gxbb_sys_pll.hw, 1796 [CLKID_SYS_PLL] = &gxbb_sys_pll.hw,
1612 [CLKID_HDMI_PLL] = &gxbb_hdmi_pll.hw, 1797 [CLKID_HDMI_PLL] = &gxl_hdmi_pll.hw,
1613 [CLKID_FIXED_PLL] = &gxbb_fixed_pll.hw, 1798 [CLKID_FIXED_PLL] = &gxbb_fixed_pll.hw,
1614 [CLKID_FCLK_DIV2] = &gxbb_fclk_div2.hw, 1799 [CLKID_FCLK_DIV2] = &gxbb_fclk_div2.hw,
1615 [CLKID_FCLK_DIV3] = &gxbb_fclk_div3.hw, 1800 [CLKID_FCLK_DIV3] = &gxbb_fclk_div3.hw,
@@ -1748,34 +1933,31 @@ static struct clk_hw_onecell_data gxl_hw_onecell_data = {
1748 [CLKID_VAPB_1] = &gxbb_vapb_1.hw, 1933 [CLKID_VAPB_1] = &gxbb_vapb_1.hw,
1749 [CLKID_VAPB_SEL] = &gxbb_vapb_sel.hw, 1934 [CLKID_VAPB_SEL] = &gxbb_vapb_sel.hw,
1750 [CLKID_VAPB] = &gxbb_vapb.hw, 1935 [CLKID_VAPB] = &gxbb_vapb.hw,
1936 [CLKID_MPLL0_DIV] = &gxbb_mpll0_div.hw,
1937 [CLKID_MPLL1_DIV] = &gxbb_mpll1_div.hw,
1938 [CLKID_MPLL2_DIV] = &gxbb_mpll2_div.hw,
1939 [CLKID_MPLL_PREDIV] = &gxbb_mpll_prediv.hw,
1940 [CLKID_FCLK_DIV2_DIV] = &gxbb_fclk_div2_div.hw,
1941 [CLKID_FCLK_DIV3_DIV] = &gxbb_fclk_div3_div.hw,
1942 [CLKID_FCLK_DIV4_DIV] = &gxbb_fclk_div4_div.hw,
1943 [CLKID_FCLK_DIV5_DIV] = &gxbb_fclk_div5_div.hw,
1944 [CLKID_FCLK_DIV7_DIV] = &gxbb_fclk_div7_div.hw,
1751 [NR_CLKS] = NULL, 1945 [NR_CLKS] = NULL,
1752 }, 1946 },
1753 .num = NR_CLKS, 1947 .num = NR_CLKS,
1754}; 1948};
1755 1949
1756/* Convenience tables to populate base addresses in .probe */ 1950static struct clk_regmap *const gxbb_clk_regmaps[] = {
1757
1758static struct meson_clk_pll *const gxbb_clk_plls[] = {
1759 &gxbb_fixed_pll,
1760 &gxbb_hdmi_pll,
1761 &gxbb_sys_pll,
1762 &gxbb_gp0_pll, 1951 &gxbb_gp0_pll,
1763};
1764
1765static struct meson_clk_pll *const gxl_clk_plls[] = {
1766 &gxbb_fixed_pll,
1767 &gxbb_hdmi_pll, 1952 &gxbb_hdmi_pll,
1768 &gxbb_sys_pll,
1769 &gxl_gp0_pll,
1770}; 1953};
1771 1954
1772static struct meson_clk_mpll *const gxbb_clk_mplls[] = { 1955static struct clk_regmap *const gxl_clk_regmaps[] = {
1773 &gxbb_mpll0, 1956 &gxl_gp0_pll,
1774 &gxbb_mpll1, 1957 &gxl_hdmi_pll,
1775 &gxbb_mpll2,
1776}; 1958};
1777 1959
1778static struct clk_gate *const gxbb_clk_gates[] = { 1960static struct clk_regmap *const gx_clk_regmaps[] = {
1779 &gxbb_clk81, 1961 &gxbb_clk81,
1780 &gxbb_ddr, 1962 &gxbb_ddr,
1781 &gxbb_dos, 1963 &gxbb_dos,
@@ -1872,9 +2054,19 @@ static struct clk_gate *const gxbb_clk_gates[] = {
1872 &gxbb_vapb_0, 2054 &gxbb_vapb_0,
1873 &gxbb_vapb_1, 2055 &gxbb_vapb_1,
1874 &gxbb_vapb, 2056 &gxbb_vapb,
1875}; 2057 &gxbb_mpeg_clk_div,
1876 2058 &gxbb_sar_adc_clk_div,
1877static struct clk_mux *const gxbb_clk_muxes[] = { 2059 &gxbb_mali_0_div,
2060 &gxbb_mali_1_div,
2061 &gxbb_cts_mclk_i958_div,
2062 &gxbb_32k_clk_div,
2063 &gxbb_sd_emmc_a_clk0_div,
2064 &gxbb_sd_emmc_b_clk0_div,
2065 &gxbb_sd_emmc_c_clk0_div,
2066 &gxbb_vpu_0_div,
2067 &gxbb_vpu_1_div,
2068 &gxbb_vapb_0_div,
2069 &gxbb_vapb_1_div,
1878 &gxbb_mpeg_clk_sel, 2070 &gxbb_mpeg_clk_sel,
1879 &gxbb_sar_adc_clk_sel, 2071 &gxbb_sar_adc_clk_sel,
1880 &gxbb_mali_0_sel, 2072 &gxbb_mali_0_sel,
@@ -1893,73 +2085,38 @@ static struct clk_mux *const gxbb_clk_muxes[] = {
1893 &gxbb_vapb_0_sel, 2085 &gxbb_vapb_0_sel,
1894 &gxbb_vapb_1_sel, 2086 &gxbb_vapb_1_sel,
1895 &gxbb_vapb_sel, 2087 &gxbb_vapb_sel,
1896}; 2088 &gxbb_mpll0,
1897 2089 &gxbb_mpll1,
1898static struct clk_divider *const gxbb_clk_dividers[] = { 2090 &gxbb_mpll2,
1899 &gxbb_mpeg_clk_div, 2091 &gxbb_mpll0_div,
1900 &gxbb_sar_adc_clk_div, 2092 &gxbb_mpll1_div,
1901 &gxbb_mali_0_div, 2093 &gxbb_mpll2_div,
1902 &gxbb_mali_1_div,
1903 &gxbb_cts_mclk_i958_div,
1904 &gxbb_32k_clk_div,
1905 &gxbb_sd_emmc_a_clk0_div,
1906 &gxbb_sd_emmc_b_clk0_div,
1907 &gxbb_sd_emmc_c_clk0_div,
1908 &gxbb_vpu_0_div,
1909 &gxbb_vpu_1_div,
1910 &gxbb_vapb_0_div,
1911 &gxbb_vapb_1_div,
1912};
1913
1914static struct meson_clk_audio_divider *const gxbb_audio_dividers[] = {
1915 &gxbb_cts_amclk_div, 2094 &gxbb_cts_amclk_div,
2095 &gxbb_fixed_pll,
2096 &gxbb_sys_pll,
2097 &gxbb_mpll_prediv,
2098 &gxbb_fclk_div2,
2099 &gxbb_fclk_div3,
2100 &gxbb_fclk_div4,
2101 &gxbb_fclk_div5,
2102 &gxbb_fclk_div7,
1916}; 2103};
1917 2104
1918struct clkc_data { 2105struct clkc_data {
1919 struct clk_gate *const *clk_gates; 2106 struct clk_regmap *const *regmap_clks;
1920 unsigned int clk_gates_count; 2107 unsigned int regmap_clks_count;
1921 struct meson_clk_mpll *const *clk_mplls;
1922 unsigned int clk_mplls_count;
1923 struct meson_clk_pll *const *clk_plls;
1924 unsigned int clk_plls_count;
1925 struct clk_mux *const *clk_muxes;
1926 unsigned int clk_muxes_count;
1927 struct clk_divider *const *clk_dividers;
1928 unsigned int clk_dividers_count;
1929 struct meson_clk_audio_divider *const *clk_audio_dividers;
1930 unsigned int clk_audio_dividers_count;
1931 struct clk_hw_onecell_data *hw_onecell_data; 2108 struct clk_hw_onecell_data *hw_onecell_data;
1932}; 2109};
1933 2110
1934static const struct clkc_data gxbb_clkc_data = { 2111static const struct clkc_data gxbb_clkc_data = {
1935 .clk_gates = gxbb_clk_gates, 2112 .regmap_clks = gxbb_clk_regmaps,
1936 .clk_gates_count = ARRAY_SIZE(gxbb_clk_gates), 2113 .regmap_clks_count = ARRAY_SIZE(gxbb_clk_regmaps),
1937 .clk_mplls = gxbb_clk_mplls,
1938 .clk_mplls_count = ARRAY_SIZE(gxbb_clk_mplls),
1939 .clk_plls = gxbb_clk_plls,
1940 .clk_plls_count = ARRAY_SIZE(gxbb_clk_plls),
1941 .clk_muxes = gxbb_clk_muxes,
1942 .clk_muxes_count = ARRAY_SIZE(gxbb_clk_muxes),
1943 .clk_dividers = gxbb_clk_dividers,
1944 .clk_dividers_count = ARRAY_SIZE(gxbb_clk_dividers),
1945 .clk_audio_dividers = gxbb_audio_dividers,
1946 .clk_audio_dividers_count = ARRAY_SIZE(gxbb_audio_dividers),
1947 .hw_onecell_data = &gxbb_hw_onecell_data, 2114 .hw_onecell_data = &gxbb_hw_onecell_data,
1948}; 2115};
1949 2116
1950static const struct clkc_data gxl_clkc_data = { 2117static const struct clkc_data gxl_clkc_data = {
1951 .clk_gates = gxbb_clk_gates, 2118 .regmap_clks = gxl_clk_regmaps,
1952 .clk_gates_count = ARRAY_SIZE(gxbb_clk_gates), 2119 .regmap_clks_count = ARRAY_SIZE(gxl_clk_regmaps),
1953 .clk_mplls = gxbb_clk_mplls,
1954 .clk_mplls_count = ARRAY_SIZE(gxbb_clk_mplls),
1955 .clk_plls = gxl_clk_plls,
1956 .clk_plls_count = ARRAY_SIZE(gxl_clk_plls),
1957 .clk_muxes = gxbb_clk_muxes,
1958 .clk_muxes_count = ARRAY_SIZE(gxbb_clk_muxes),
1959 .clk_dividers = gxbb_clk_dividers,
1960 .clk_dividers_count = ARRAY_SIZE(gxbb_clk_dividers),
1961 .clk_audio_dividers = gxbb_audio_dividers,
1962 .clk_audio_dividers_count = ARRAY_SIZE(gxbb_audio_dividers),
1963 .hw_onecell_data = &gxl_hw_onecell_data, 2120 .hw_onecell_data = &gxl_hw_onecell_data,
1964}; 2121};
1965 2122
@@ -1969,71 +2126,79 @@ static const struct of_device_id clkc_match_table[] = {
1969 {}, 2126 {},
1970}; 2127};
1971 2128
2129static const struct regmap_config clkc_regmap_config = {
2130 .reg_bits = 32,
2131 .val_bits = 32,
2132 .reg_stride = 4,
2133};
2134
1972static int gxbb_clkc_probe(struct platform_device *pdev) 2135static int gxbb_clkc_probe(struct platform_device *pdev)
1973{ 2136{
1974 const struct clkc_data *clkc_data; 2137 const struct clkc_data *clkc_data;
2138 struct resource *res;
1975 void __iomem *clk_base; 2139 void __iomem *clk_base;
1976 int ret, clkid, i; 2140 struct regmap *map;
2141 int ret, i;
1977 struct device *dev = &pdev->dev; 2142 struct device *dev = &pdev->dev;
1978 2143
1979 clkc_data = of_device_get_match_data(&pdev->dev); 2144 clkc_data = of_device_get_match_data(dev);
1980 if (!clkc_data) 2145 if (!clkc_data)
1981 return -EINVAL; 2146 return -EINVAL;
1982 2147
1983 /* Generic clocks and PLLs */ 2148 /* Get the hhi system controller node if available */
1984 clk_base = of_iomap(dev->of_node, 0); 2149 map = syscon_node_to_regmap(of_get_parent(dev->of_node));
1985 if (!clk_base) { 2150 if (IS_ERR(map)) {
1986 pr_err("%s: Unable to map clk base\n", __func__); 2151 dev_err(dev,
1987 return -ENXIO; 2152 "failed to get HHI regmap - Trying obsolete regs\n");
1988 }
1989
1990 /* Populate base address for PLLs */
1991 for (i = 0; i < clkc_data->clk_plls_count; i++)
1992 clkc_data->clk_plls[i]->base = clk_base;
1993
1994 /* Populate base address for MPLLs */
1995 for (i = 0; i < clkc_data->clk_mplls_count; i++)
1996 clkc_data->clk_mplls[i]->base = clk_base;
1997 2153
1998 /* Populate base address for gates */ 2154 /*
1999 for (i = 0; i < clkc_data->clk_gates_count; i++) 2155 * FIXME: HHI registers should be accessed through
2000 clkc_data->clk_gates[i]->reg = clk_base + 2156 * the appropriate system controller. This is required because
2001 (u64)clkc_data->clk_gates[i]->reg; 2157 * there is more than just clocks in this register space
2002 2158 *
2003 /* Populate base address for muxes */ 2159 * This fallback method is only provided temporarily until
2004 for (i = 0; i < clkc_data->clk_muxes_count; i++) 2160 * all the platform DTs are properly using the syscon node
2005 clkc_data->clk_muxes[i]->reg = clk_base + 2161 */
2006 (u64)clkc_data->clk_muxes[i]->reg; 2162 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2163 if (!res)
2164 return -EINVAL;
2165
2166 clk_base = devm_ioremap(dev, res->start, resource_size(res));
2167 if (!clk_base) {
2168 dev_err(dev, "Unable to map clk base\n");
2169 return -ENXIO;
2170 }
2171
2172 map = devm_regmap_init_mmio(dev, clk_base,
2173 &clkc_regmap_config);
2174 if (IS_ERR(map))
2175 return PTR_ERR(map);
2176 }
2007 2177
2008 /* Populate base address for dividers */ 2178 /* Populate regmap for the common regmap backed clocks */
2009 for (i = 0; i < clkc_data->clk_dividers_count; i++) 2179 for (i = 0; i < ARRAY_SIZE(gx_clk_regmaps); i++)
2010 clkc_data->clk_dividers[i]->reg = clk_base + 2180 gx_clk_regmaps[i]->map = map;
2011 (u64)clkc_data->clk_dividers[i]->reg;
2012 2181
2013 /* Populate base address for the audio dividers */ 2182 /* Populate regmap for soc specific clocks */
2014 for (i = 0; i < clkc_data->clk_audio_dividers_count; i++) 2183 for (i = 0; i < clkc_data->regmap_clks_count; i++)
2015 clkc_data->clk_audio_dividers[i]->base = clk_base; 2184 clkc_data->regmap_clks[i]->map = map;
2016 2185
2017 /* 2186 /* Register all clks */
2018 * register all clks 2187 for (i = 0; i < clkc_data->hw_onecell_data->num; i++) {
2019 */
2020 for (clkid = 0; clkid < clkc_data->hw_onecell_data->num; clkid++) {
2021 /* array might be sparse */ 2188 /* array might be sparse */
2022 if (!clkc_data->hw_onecell_data->hws[clkid]) 2189 if (!clkc_data->hw_onecell_data->hws[i])
2023 continue; 2190 continue;
2024 2191
2025 ret = devm_clk_hw_register(dev, 2192 ret = devm_clk_hw_register(dev,
2026 clkc_data->hw_onecell_data->hws[clkid]); 2193 clkc_data->hw_onecell_data->hws[i]);
2027 if (ret) 2194 if (ret) {
2028 goto iounmap; 2195 dev_err(dev, "Clock registration failed\n");
2196 return ret;
2197 }
2029 } 2198 }
2030 2199
2031 return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, 2200 return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
2032 clkc_data->hw_onecell_data); 2201 clkc_data->hw_onecell_data);
2033
2034iounmap:
2035 iounmap(clk_base);
2036 return ret;
2037} 2202}
2038 2203
2039static struct platform_driver gxbb_driver = { 2204static struct platform_driver gxbb_driver = {
diff --git a/drivers/clk/meson/gxbb.h b/drivers/clk/meson/gxbb.h
index aee6fbba2004..9febf3f03739 100644
--- a/drivers/clk/meson/gxbb.h
+++ b/drivers/clk/meson/gxbb.h
@@ -194,8 +194,18 @@
194#define CLKID_VPU_1_DIV 130 194#define CLKID_VPU_1_DIV 130
195#define CLKID_VAPB_0_DIV 134 195#define CLKID_VAPB_0_DIV 134
196#define CLKID_VAPB_1_DIV 137 196#define CLKID_VAPB_1_DIV 137
197 197#define CLKID_HDMI_PLL_PRE_MULT 141
198#define NR_CLKS 141 198#define CLKID_MPLL0_DIV 142
199#define CLKID_MPLL1_DIV 143
200#define CLKID_MPLL2_DIV 144
201#define CLKID_MPLL_PREDIV 145
202#define CLKID_FCLK_DIV2_DIV 146
203#define CLKID_FCLK_DIV3_DIV 147
204#define CLKID_FCLK_DIV4_DIV 148
205#define CLKID_FCLK_DIV5_DIV 149
206#define CLKID_FCLK_DIV7_DIV 150
207
208#define NR_CLKS 151
199 209
200/* include the CLKIDs that have been made part of the DT binding */ 210/* include the CLKIDs that have been made part of the DT binding */
201#include <dt-bindings/clock/gxbb-clkc.h> 211#include <dt-bindings/clock/gxbb-clkc.h>
diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c
index 3ffea80c1308..cc2992493e0b 100644
--- a/drivers/clk/meson/meson8b.c
+++ b/drivers/clk/meson/meson8b.c
@@ -23,14 +23,16 @@
23 23
24#include <linux/clk.h> 24#include <linux/clk.h>
25#include <linux/clk-provider.h> 25#include <linux/clk-provider.h>
26#include <linux/init.h>
26#include <linux/of_address.h> 27#include <linux/of_address.h>
27#include <linux/platform_device.h> 28#include <linux/platform_device.h>
28#include <linux/reset-controller.h> 29#include <linux/reset-controller.h>
29#include <linux/slab.h> 30#include <linux/slab.h>
30#include <linux/init.h> 31#include <linux/regmap.h>
31 32
32#include "clkc.h" 33#include "clkc.h"
33#include "meson8b.h" 34#include "meson8b.h"
35#include "clk-regmap.h"
34 36
35static DEFINE_SPINLOCK(meson_clk_lock); 37static DEFINE_SPINLOCK(meson_clk_lock);
36 38
@@ -97,20 +99,6 @@ static const struct pll_rate_table sys_pll_rate_table[] = {
97 { /* sentinel */ }, 99 { /* sentinel */ },
98}; 100};
99 101
100static const struct clk_div_table cpu_div_table[] = {
101 { .val = 1, .div = 1 },
102 { .val = 2, .div = 2 },
103 { .val = 3, .div = 3 },
104 { .val = 2, .div = 4 },
105 { .val = 3, .div = 6 },
106 { .val = 4, .div = 8 },
107 { .val = 5, .div = 10 },
108 { .val = 6, .div = 12 },
109 { .val = 7, .div = 14 },
110 { .val = 8, .div = 16 },
111 { /* sentinel */ },
112};
113
114static struct clk_fixed_rate meson8b_xtal = { 102static struct clk_fixed_rate meson8b_xtal = {
115 .fixed_rate = 24000000, 103 .fixed_rate = 24000000,
116 .hw.init = &(struct clk_init_data){ 104 .hw.init = &(struct clk_init_data){
@@ -120,23 +108,39 @@ static struct clk_fixed_rate meson8b_xtal = {
120 }, 108 },
121}; 109};
122 110
123static struct meson_clk_pll meson8b_fixed_pll = { 111static struct clk_regmap meson8b_fixed_pll = {
124 .m = { 112 .data = &(struct meson_clk_pll_data){
125 .reg_off = HHI_MPLL_CNTL, 113 .m = {
126 .shift = 0, 114 .reg_off = HHI_MPLL_CNTL,
127 .width = 9, 115 .shift = 0,
128 }, 116 .width = 9,
129 .n = { 117 },
130 .reg_off = HHI_MPLL_CNTL, 118 .n = {
131 .shift = 9, 119 .reg_off = HHI_MPLL_CNTL,
132 .width = 5, 120 .shift = 9,
133 }, 121 .width = 5,
134 .od = { 122 },
135 .reg_off = HHI_MPLL_CNTL, 123 .od = {
136 .shift = 16, 124 .reg_off = HHI_MPLL_CNTL,
137 .width = 2, 125 .shift = 16,
126 .width = 2,
127 },
128 .frac = {
129 .reg_off = HHI_MPLL_CNTL2,
130 .shift = 0,
131 .width = 12,
132 },
133 .l = {
134 .reg_off = HHI_MPLL_CNTL,
135 .shift = 31,
136 .width = 1,
137 },
138 .rst = {
139 .reg_off = HHI_MPLL_CNTL,
140 .shift = 29,
141 .width = 1,
142 },
138 }, 143 },
139 .lock = &meson_clk_lock,
140 .hw.init = &(struct clk_init_data){ 144 .hw.init = &(struct clk_init_data){
141 .name = "fixed_pll", 145 .name = "fixed_pll",
142 .ops = &meson_clk_pll_ro_ops, 146 .ops = &meson_clk_pll_ro_ops,
@@ -146,23 +150,34 @@ static struct meson_clk_pll meson8b_fixed_pll = {
146 }, 150 },
147}; 151};
148 152
149static struct meson_clk_pll meson8b_vid_pll = { 153static struct clk_regmap meson8b_vid_pll = {
150 .m = { 154 .data = &(struct meson_clk_pll_data){
151 .reg_off = HHI_VID_PLL_CNTL, 155 .m = {
152 .shift = 0, 156 .reg_off = HHI_VID_PLL_CNTL,
153 .width = 9, 157 .shift = 0,
158 .width = 9,
159 },
160 .n = {
161 .reg_off = HHI_VID_PLL_CNTL,
162 .shift = 9,
163 .width = 5,
164 },
165 .od = {
166 .reg_off = HHI_VID_PLL_CNTL,
167 .shift = 16,
168 .width = 2,
169 },
170 .l = {
171 .reg_off = HHI_VID_PLL_CNTL,
172 .shift = 31,
173 .width = 1,
174 },
175 .rst = {
176 .reg_off = HHI_VID_PLL_CNTL,
177 .shift = 29,
178 .width = 1,
179 },
154 }, 180 },
155 .n = {
156 .reg_off = HHI_VID_PLL_CNTL,
157 .shift = 9,
158 .width = 5,
159 },
160 .od = {
161 .reg_off = HHI_VID_PLL_CNTL,
162 .shift = 16,
163 .width = 2,
164 },
165 .lock = &meson_clk_lock,
166 .hw.init = &(struct clk_init_data){ 181 .hw.init = &(struct clk_init_data){
167 .name = "vid_pll", 182 .name = "vid_pll",
168 .ops = &meson_clk_pll_ro_ops, 183 .ops = &meson_clk_pll_ro_ops,
@@ -172,213 +187,317 @@ static struct meson_clk_pll meson8b_vid_pll = {
172 }, 187 },
173}; 188};
174 189
175static struct meson_clk_pll meson8b_sys_pll = { 190static struct clk_regmap meson8b_sys_pll = {
176 .m = { 191 .data = &(struct meson_clk_pll_data){
177 .reg_off = HHI_SYS_PLL_CNTL, 192 .m = {
178 .shift = 0, 193 .reg_off = HHI_SYS_PLL_CNTL,
179 .width = 9, 194 .shift = 0,
180 }, 195 .width = 9,
181 .n = { 196 },
182 .reg_off = HHI_SYS_PLL_CNTL, 197 .n = {
183 .shift = 9, 198 .reg_off = HHI_SYS_PLL_CNTL,
184 .width = 5, 199 .shift = 9,
200 .width = 5,
201 },
202 .od = {
203 .reg_off = HHI_SYS_PLL_CNTL,
204 .shift = 16,
205 .width = 2,
206 },
207 .l = {
208 .reg_off = HHI_SYS_PLL_CNTL,
209 .shift = 31,
210 .width = 1,
211 },
212 .rst = {
213 .reg_off = HHI_SYS_PLL_CNTL,
214 .shift = 29,
215 .width = 1,
216 },
217 .table = sys_pll_rate_table,
185 }, 218 },
186 .od = {
187 .reg_off = HHI_SYS_PLL_CNTL,
188 .shift = 16,
189 .width = 2,
190 },
191 .rate_table = sys_pll_rate_table,
192 .rate_count = ARRAY_SIZE(sys_pll_rate_table),
193 .lock = &meson_clk_lock,
194 .hw.init = &(struct clk_init_data){ 219 .hw.init = &(struct clk_init_data){
195 .name = "sys_pll", 220 .name = "sys_pll",
196 .ops = &meson_clk_pll_ops, 221 .ops = &meson_clk_pll_ro_ops,
197 .parent_names = (const char *[]){ "xtal" }, 222 .parent_names = (const char *[]){ "xtal" },
198 .num_parents = 1, 223 .num_parents = 1,
199 .flags = CLK_GET_RATE_NOCACHE, 224 .flags = CLK_GET_RATE_NOCACHE,
200 }, 225 },
201}; 226};
202 227
203static struct clk_fixed_factor meson8b_fclk_div2 = { 228static struct clk_fixed_factor meson8b_fclk_div2_div = {
204 .mult = 1, 229 .mult = 1,
205 .div = 2, 230 .div = 2,
206 .hw.init = &(struct clk_init_data){ 231 .hw.init = &(struct clk_init_data){
207 .name = "fclk_div2", 232 .name = "fclk_div2_div",
208 .ops = &clk_fixed_factor_ops, 233 .ops = &clk_fixed_factor_ops,
209 .parent_names = (const char *[]){ "fixed_pll" }, 234 .parent_names = (const char *[]){ "fixed_pll" },
210 .num_parents = 1, 235 .num_parents = 1,
211 }, 236 },
212}; 237};
213 238
214static struct clk_fixed_factor meson8b_fclk_div3 = { 239static struct clk_regmap meson8b_fclk_div2 = {
240 .data = &(struct clk_regmap_gate_data){
241 .offset = HHI_MPLL_CNTL6,
242 .bit_idx = 27,
243 },
244 .hw.init = &(struct clk_init_data){
245 .name = "fclk_div2",
246 .ops = &clk_regmap_gate_ops,
247 .parent_names = (const char *[]){ "fclk_div2_div" },
248 .num_parents = 1,
249 },
250};
251
252static struct clk_fixed_factor meson8b_fclk_div3_div = {
215 .mult = 1, 253 .mult = 1,
216 .div = 3, 254 .div = 3,
217 .hw.init = &(struct clk_init_data){ 255 .hw.init = &(struct clk_init_data){
218 .name = "fclk_div3", 256 .name = "fclk_div_div3",
219 .ops = &clk_fixed_factor_ops, 257 .ops = &clk_fixed_factor_ops,
220 .parent_names = (const char *[]){ "fixed_pll" }, 258 .parent_names = (const char *[]){ "fixed_pll" },
221 .num_parents = 1, 259 .num_parents = 1,
222 }, 260 },
223}; 261};
224 262
225static struct clk_fixed_factor meson8b_fclk_div4 = { 263static struct clk_regmap meson8b_fclk_div3 = {
264 .data = &(struct clk_regmap_gate_data){
265 .offset = HHI_MPLL_CNTL6,
266 .bit_idx = 28,
267 },
268 .hw.init = &(struct clk_init_data){
269 .name = "fclk_div3",
270 .ops = &clk_regmap_gate_ops,
271 .parent_names = (const char *[]){ "fclk_div3_div" },
272 .num_parents = 1,
273 },
274};
275
276static struct clk_fixed_factor meson8b_fclk_div4_div = {
226 .mult = 1, 277 .mult = 1,
227 .div = 4, 278 .div = 4,
228 .hw.init = &(struct clk_init_data){ 279 .hw.init = &(struct clk_init_data){
229 .name = "fclk_div4", 280 .name = "fclk_div4_div",
230 .ops = &clk_fixed_factor_ops, 281 .ops = &clk_fixed_factor_ops,
231 .parent_names = (const char *[]){ "fixed_pll" }, 282 .parent_names = (const char *[]){ "fixed_pll" },
232 .num_parents = 1, 283 .num_parents = 1,
233 }, 284 },
234}; 285};
235 286
236static struct clk_fixed_factor meson8b_fclk_div5 = { 287static struct clk_regmap meson8b_fclk_div4 = {
288 .data = &(struct clk_regmap_gate_data){
289 .offset = HHI_MPLL_CNTL6,
290 .bit_idx = 29,
291 },
292 .hw.init = &(struct clk_init_data){
293 .name = "fclk_div4",
294 .ops = &clk_regmap_gate_ops,
295 .parent_names = (const char *[]){ "fclk_div4_div" },
296 .num_parents = 1,
297 },
298};
299
300static struct clk_fixed_factor meson8b_fclk_div5_div = {
237 .mult = 1, 301 .mult = 1,
238 .div = 5, 302 .div = 5,
239 .hw.init = &(struct clk_init_data){ 303 .hw.init = &(struct clk_init_data){
240 .name = "fclk_div5", 304 .name = "fclk_div5_div",
241 .ops = &clk_fixed_factor_ops, 305 .ops = &clk_fixed_factor_ops,
242 .parent_names = (const char *[]){ "fixed_pll" }, 306 .parent_names = (const char *[]){ "fixed_pll" },
243 .num_parents = 1, 307 .num_parents = 1,
244 }, 308 },
245}; 309};
246 310
247static struct clk_fixed_factor meson8b_fclk_div7 = { 311static struct clk_regmap meson8b_fclk_div5 = {
312 .data = &(struct clk_regmap_gate_data){
313 .offset = HHI_MPLL_CNTL6,
314 .bit_idx = 30,
315 },
316 .hw.init = &(struct clk_init_data){
317 .name = "fclk_div5",
318 .ops = &clk_regmap_gate_ops,
319 .parent_names = (const char *[]){ "fclk_div5_div" },
320 .num_parents = 1,
321 },
322};
323
324static struct clk_fixed_factor meson8b_fclk_div7_div = {
248 .mult = 1, 325 .mult = 1,
249 .div = 7, 326 .div = 7,
250 .hw.init = &(struct clk_init_data){ 327 .hw.init = &(struct clk_init_data){
251 .name = "fclk_div7", 328 .name = "fclk_div7_div",
252 .ops = &clk_fixed_factor_ops, 329 .ops = &clk_fixed_factor_ops,
253 .parent_names = (const char *[]){ "fixed_pll" }, 330 .parent_names = (const char *[]){ "fixed_pll" },
254 .num_parents = 1, 331 .num_parents = 1,
255 }, 332 },
256}; 333};
257 334
258static struct meson_clk_mpll meson8b_mpll0 = { 335static struct clk_regmap meson8b_fclk_div7 = {
259 .sdm = { 336 .data = &(struct clk_regmap_gate_data){
260 .reg_off = HHI_MPLL_CNTL7, 337 .offset = HHI_MPLL_CNTL6,
261 .shift = 0, 338 .bit_idx = 31,
262 .width = 14,
263 }, 339 },
264 .sdm_en = { 340 .hw.init = &(struct clk_init_data){
265 .reg_off = HHI_MPLL_CNTL7, 341 .name = "fclk_div7",
266 .shift = 15, 342 .ops = &clk_regmap_gate_ops,
267 .width = 1, 343 .parent_names = (const char *[]){ "fclk_div7_div" },
344 .num_parents = 1,
268 }, 345 },
269 .n2 = { 346};
270 .reg_off = HHI_MPLL_CNTL7, 347
271 .shift = 16, 348static struct clk_regmap meson8b_mpll_prediv = {
272 .width = 9, 349 .data = &(struct clk_regmap_div_data){
350 .offset = HHI_MPLL_CNTL5,
351 .shift = 12,
352 .width = 1,
273 }, 353 },
274 .en = { 354 .hw.init = &(struct clk_init_data){
275 .reg_off = HHI_MPLL_CNTL7, 355 .name = "mpll_prediv",
276 .shift = 14, 356 .ops = &clk_regmap_divider_ro_ops,
277 .width = 1, 357 .parent_names = (const char *[]){ "fixed_pll" },
358 .num_parents = 1,
278 }, 359 },
279 .ssen = { 360};
280 .reg_off = HHI_MPLL_CNTL, 361
281 .shift = 25, 362static struct clk_regmap meson8b_mpll0_div = {
282 .width = 1, 363 .data = &(struct meson_clk_mpll_data){
364 .sdm = {
365 .reg_off = HHI_MPLL_CNTL7,
366 .shift = 0,
367 .width = 14,
368 },
369 .sdm_en = {
370 .reg_off = HHI_MPLL_CNTL7,
371 .shift = 15,
372 .width = 1,
373 },
374 .n2 = {
375 .reg_off = HHI_MPLL_CNTL7,
376 .shift = 16,
377 .width = 9,
378 },
379 .ssen = {
380 .reg_off = HHI_MPLL_CNTL,
381 .shift = 25,
382 .width = 1,
383 },
384 .lock = &meson_clk_lock,
283 }, 385 },
284 .lock = &meson_clk_lock,
285 .hw.init = &(struct clk_init_data){ 386 .hw.init = &(struct clk_init_data){
286 .name = "mpll0", 387 .name = "mpll0_div",
287 .ops = &meson_clk_mpll_ops, 388 .ops = &meson_clk_mpll_ops,
288 .parent_names = (const char *[]){ "fixed_pll" }, 389 .parent_names = (const char *[]){ "mpll_prediv" },
289 .num_parents = 1, 390 .num_parents = 1,
290 }, 391 },
291}; 392};
292 393
293static struct meson_clk_mpll meson8b_mpll1 = { 394static struct clk_regmap meson8b_mpll0 = {
294 .sdm = { 395 .data = &(struct clk_regmap_gate_data){
295 .reg_off = HHI_MPLL_CNTL8, 396 .offset = HHI_MPLL_CNTL7,
296 .shift = 0, 397 .bit_idx = 14,
297 .width = 14,
298 }, 398 },
299 .sdm_en = { 399 .hw.init = &(struct clk_init_data){
300 .reg_off = HHI_MPLL_CNTL8, 400 .name = "mpll0",
301 .shift = 15, 401 .ops = &clk_regmap_gate_ops,
302 .width = 1, 402 .parent_names = (const char *[]){ "mpll0_div" },
303 }, 403 .num_parents = 1,
304 .n2 = { 404 .flags = CLK_SET_RATE_PARENT,
305 .reg_off = HHI_MPLL_CNTL8,
306 .shift = 16,
307 .width = 9,
308 }, 405 },
309 .en = { 406};
310 .reg_off = HHI_MPLL_CNTL8, 407
311 .shift = 14, 408static struct clk_regmap meson8b_mpll1_div = {
312 .width = 1, 409 .data = &(struct meson_clk_mpll_data){
410 .sdm = {
411 .reg_off = HHI_MPLL_CNTL8,
412 .shift = 0,
413 .width = 14,
414 },
415 .sdm_en = {
416 .reg_off = HHI_MPLL_CNTL8,
417 .shift = 15,
418 .width = 1,
419 },
420 .n2 = {
421 .reg_off = HHI_MPLL_CNTL8,
422 .shift = 16,
423 .width = 9,
424 },
425 .lock = &meson_clk_lock,
313 }, 426 },
314 .lock = &meson_clk_lock,
315 .hw.init = &(struct clk_init_data){ 427 .hw.init = &(struct clk_init_data){
316 .name = "mpll1", 428 .name = "mpll1_div",
317 .ops = &meson_clk_mpll_ops, 429 .ops = &meson_clk_mpll_ops,
318 .parent_names = (const char *[]){ "fixed_pll" }, 430 .parent_names = (const char *[]){ "mpll_prediv" },
319 .num_parents = 1, 431 .num_parents = 1,
320 }, 432 },
321}; 433};
322 434
323static struct meson_clk_mpll meson8b_mpll2 = { 435static struct clk_regmap meson8b_mpll1 = {
324 .sdm = { 436 .data = &(struct clk_regmap_gate_data){
325 .reg_off = HHI_MPLL_CNTL9, 437 .offset = HHI_MPLL_CNTL8,
326 .shift = 0, 438 .bit_idx = 14,
327 .width = 14,
328 },
329 .sdm_en = {
330 .reg_off = HHI_MPLL_CNTL9,
331 .shift = 15,
332 .width = 1,
333 }, 439 },
334 .n2 = { 440 .hw.init = &(struct clk_init_data){
335 .reg_off = HHI_MPLL_CNTL9, 441 .name = "mpll1",
336 .shift = 16, 442 .ops = &clk_regmap_gate_ops,
337 .width = 9, 443 .parent_names = (const char *[]){ "mpll1_div" },
444 .num_parents = 1,
445 .flags = CLK_SET_RATE_PARENT,
338 }, 446 },
339 .en = { 447};
340 .reg_off = HHI_MPLL_CNTL9, 448
341 .shift = 14, 449static struct clk_regmap meson8b_mpll2_div = {
342 .width = 1, 450 .data = &(struct meson_clk_mpll_data){
451 .sdm = {
452 .reg_off = HHI_MPLL_CNTL9,
453 .shift = 0,
454 .width = 14,
455 },
456 .sdm_en = {
457 .reg_off = HHI_MPLL_CNTL9,
458 .shift = 15,
459 .width = 1,
460 },
461 .n2 = {
462 .reg_off = HHI_MPLL_CNTL9,
463 .shift = 16,
464 .width = 9,
465 },
466 .lock = &meson_clk_lock,
343 }, 467 },
344 .lock = &meson_clk_lock,
345 .hw.init = &(struct clk_init_data){ 468 .hw.init = &(struct clk_init_data){
346 .name = "mpll2", 469 .name = "mpll2_div",
347 .ops = &meson_clk_mpll_ops, 470 .ops = &meson_clk_mpll_ops,
348 .parent_names = (const char *[]){ "fixed_pll" }, 471 .parent_names = (const char *[]){ "mpll_prediv" },
349 .num_parents = 1, 472 .num_parents = 1,
350 }, 473 },
351}; 474};
352 475
353/* 476static struct clk_regmap meson8b_mpll2 = {
354 * FIXME cpu clocks and the legacy composite clocks (e.g. clk81) are both PLL 477 .data = &(struct clk_regmap_gate_data){
355 * post-dividers and should be modeled with their respective PLLs via the 478 .offset = HHI_MPLL_CNTL9,
356 * forthcoming coordinated clock rates feature 479 .bit_idx = 14,
357 */ 480 },
358static struct meson_clk_cpu meson8b_cpu_clk = {
359 .reg_off = HHI_SYS_CPU_CLK_CNTL1,
360 .div_table = cpu_div_table,
361 .clk_nb.notifier_call = meson_clk_cpu_notifier_cb,
362 .hw.init = &(struct clk_init_data){ 481 .hw.init = &(struct clk_init_data){
363 .name = "cpu_clk", 482 .name = "mpll2",
364 .ops = &meson_clk_cpu_ops, 483 .ops = &clk_regmap_gate_ops,
365 .parent_names = (const char *[]){ "sys_pll" }, 484 .parent_names = (const char *[]){ "mpll2_div" },
366 .num_parents = 1, 485 .num_parents = 1,
486 .flags = CLK_SET_RATE_PARENT,
367 }, 487 },
368}; 488};
369 489
370static u32 mux_table_clk81[] = { 6, 5, 7 }; 490static u32 mux_table_clk81[] = { 6, 5, 7 };
371 491static struct clk_regmap meson8b_mpeg_clk_sel = {
372struct clk_mux meson8b_mpeg_clk_sel = { 492 .data = &(struct clk_regmap_mux_data){
373 .reg = (void *)HHI_MPEG_CLK_CNTL, 493 .offset = HHI_MPEG_CLK_CNTL,
374 .mask = 0x7, 494 .mask = 0x7,
375 .shift = 12, 495 .shift = 12,
376 .flags = CLK_MUX_READ_ONLY, 496 .table = mux_table_clk81,
377 .table = mux_table_clk81, 497 },
378 .lock = &meson_clk_lock,
379 .hw.init = &(struct clk_init_data){ 498 .hw.init = &(struct clk_init_data){
380 .name = "mpeg_clk_sel", 499 .name = "mpeg_clk_sel",
381 .ops = &clk_mux_ro_ops, 500 .ops = &clk_regmap_mux_ro_ops,
382 /* 501 /*
383 * FIXME bits 14:12 selects from 8 possible parents: 502 * FIXME bits 14:12 selects from 8 possible parents:
384 * xtal, 1'b0 (wtf), fclk_div7, mpll_clkout1, mpll_clkout2, 503 * xtal, 1'b0 (wtf), fclk_div7, mpll_clkout1, mpll_clkout2,
@@ -387,34 +506,136 @@ struct clk_mux meson8b_mpeg_clk_sel = {
387 .parent_names = (const char *[]){ "fclk_div3", "fclk_div4", 506 .parent_names = (const char *[]){ "fclk_div3", "fclk_div4",
388 "fclk_div5" }, 507 "fclk_div5" },
389 .num_parents = 3, 508 .num_parents = 3,
390 .flags = (CLK_SET_RATE_NO_REPARENT | CLK_IGNORE_UNUSED),
391 }, 509 },
392}; 510};
393 511
394struct clk_divider meson8b_mpeg_clk_div = { 512static struct clk_regmap meson8b_mpeg_clk_div = {
395 .reg = (void *)HHI_MPEG_CLK_CNTL, 513 .data = &(struct clk_regmap_div_data){
396 .shift = 0, 514 .offset = HHI_MPEG_CLK_CNTL,
397 .width = 7, 515 .shift = 0,
398 .lock = &meson_clk_lock, 516 .width = 7,
517 },
399 .hw.init = &(struct clk_init_data){ 518 .hw.init = &(struct clk_init_data){
400 .name = "mpeg_clk_div", 519 .name = "mpeg_clk_div",
401 .ops = &clk_divider_ops, 520 .ops = &clk_regmap_divider_ro_ops,
402 .parent_names = (const char *[]){ "mpeg_clk_sel" }, 521 .parent_names = (const char *[]){ "mpeg_clk_sel" },
403 .num_parents = 1, 522 .num_parents = 1,
404 .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED),
405 }, 523 },
406}; 524};
407 525
408struct clk_gate meson8b_clk81 = { 526static struct clk_regmap meson8b_clk81 = {
409 .reg = (void *)HHI_MPEG_CLK_CNTL, 527 .data = &(struct clk_regmap_gate_data){
410 .bit_idx = 7, 528 .offset = HHI_MPEG_CLK_CNTL,
411 .lock = &meson_clk_lock, 529 .bit_idx = 7,
530 },
412 .hw.init = &(struct clk_init_data){ 531 .hw.init = &(struct clk_init_data){
413 .name = "clk81", 532 .name = "clk81",
414 .ops = &clk_gate_ops, 533 .ops = &clk_regmap_gate_ops,
415 .parent_names = (const char *[]){ "mpeg_clk_div" }, 534 .parent_names = (const char *[]){ "mpeg_clk_div" },
416 .num_parents = 1, 535 .num_parents = 1,
417 .flags = (CLK_SET_RATE_PARENT | CLK_IS_CRITICAL), 536 .flags = CLK_IS_CRITICAL,
537 },
538};
539
540static struct clk_regmap meson8b_cpu_in_sel = {
541 .data = &(struct clk_regmap_mux_data){
542 .offset = HHI_SYS_CPU_CLK_CNTL0,
543 .mask = 0x1,
544 .shift = 0,
545 },
546 .hw.init = &(struct clk_init_data){
547 .name = "cpu_in_sel",
548 .ops = &clk_regmap_mux_ro_ops,
549 .parent_names = (const char *[]){ "xtal", "sys_pll" },
550 .num_parents = 2,
551 .flags = (CLK_SET_RATE_PARENT |
552 CLK_SET_RATE_NO_REPARENT),
553 },
554};
555
556static struct clk_fixed_factor meson8b_cpu_div2 = {
557 .mult = 1,
558 .div = 2,
559 .hw.init = &(struct clk_init_data){
560 .name = "cpu_div2",
561 .ops = &clk_fixed_factor_ops,
562 .parent_names = (const char *[]){ "cpu_in_sel" },
563 .num_parents = 1,
564 .flags = CLK_SET_RATE_PARENT,
565 },
566};
567
568static struct clk_fixed_factor meson8b_cpu_div3 = {
569 .mult = 1,
570 .div = 3,
571 .hw.init = &(struct clk_init_data){
572 .name = "cpu_div3",
573 .ops = &clk_fixed_factor_ops,
574 .parent_names = (const char *[]){ "cpu_in_sel" },
575 .num_parents = 1,
576 .flags = CLK_SET_RATE_PARENT,
577 },
578};
579
580static const struct clk_div_table cpu_scale_table[] = {
581 { .val = 2, .div = 4 },
582 { .val = 3, .div = 6 },
583 { .val = 4, .div = 8 },
584 { .val = 5, .div = 10 },
585 { .val = 6, .div = 12 },
586 { .val = 7, .div = 14 },
587 { .val = 8, .div = 16 },
588 { /* sentinel */ },
589};
590
591static struct clk_regmap meson8b_cpu_scale_div = {
592 .data = &(struct clk_regmap_div_data){
593 .offset = HHI_SYS_CPU_CLK_CNTL1,
594 .shift = 20,
595 .width = 9,
596 .table = cpu_scale_table,
597 .flags = CLK_DIVIDER_ALLOW_ZERO,
598 },
599 .hw.init = &(struct clk_init_data){
600 .name = "cpu_scale_div",
601 .ops = &clk_regmap_divider_ro_ops,
602 .parent_names = (const char *[]){ "cpu_in_sel" },
603 .num_parents = 1,
604 .flags = CLK_SET_RATE_PARENT,
605 },
606};
607
608static struct clk_regmap meson8b_cpu_scale_out_sel = {
609 .data = &(struct clk_regmap_mux_data){
610 .offset = HHI_SYS_CPU_CLK_CNTL0,
611 .mask = 0x3,
612 .shift = 2,
613 },
614 .hw.init = &(struct clk_init_data){
615 .name = "cpu_scale_out_sel",
616 .ops = &clk_regmap_mux_ro_ops,
617 .parent_names = (const char *[]) { "cpu_in_sel",
618 "cpu_div2",
619 "cpu_div3",
620 "cpu_scale_div" },
621 .num_parents = 4,
622 .flags = CLK_SET_RATE_PARENT,
623 },
624};
625
626static struct clk_regmap meson8b_cpu_clk = {
627 .data = &(struct clk_regmap_mux_data){
628 .offset = HHI_SYS_CPU_CLK_CNTL0,
629 .mask = 0x1,
630 .shift = 7,
631 },
632 .hw.init = &(struct clk_init_data){
633 .name = "cpu_clk",
634 .ops = &clk_regmap_mux_ro_ops,
635 .parent_names = (const char *[]){ "xtal", "cpu_out_sel" },
636 .num_parents = 2,
637 .flags = (CLK_SET_RATE_PARENT |
638 CLK_SET_RATE_NO_REPARENT),
418 }, 639 },
419}; 640};
420 641
@@ -599,24 +820,26 @@ static struct clk_hw_onecell_data meson8b_hw_onecell_data = {
599 [CLKID_MPLL0] = &meson8b_mpll0.hw, 820 [CLKID_MPLL0] = &meson8b_mpll0.hw,
600 [CLKID_MPLL1] = &meson8b_mpll1.hw, 821 [CLKID_MPLL1] = &meson8b_mpll1.hw,
601 [CLKID_MPLL2] = &meson8b_mpll2.hw, 822 [CLKID_MPLL2] = &meson8b_mpll2.hw,
823 [CLKID_MPLL0_DIV] = &meson8b_mpll0_div.hw,
824 [CLKID_MPLL1_DIV] = &meson8b_mpll1_div.hw,
825 [CLKID_MPLL2_DIV] = &meson8b_mpll2_div.hw,
826 [CLKID_CPU_IN_SEL] = &meson8b_cpu_in_sel.hw,
827 [CLKID_CPU_DIV2] = &meson8b_cpu_div2.hw,
828 [CLKID_CPU_DIV3] = &meson8b_cpu_div3.hw,
829 [CLKID_CPU_SCALE_DIV] = &meson8b_cpu_scale_div.hw,
830 [CLKID_CPU_SCALE_OUT_SEL] = &meson8b_cpu_scale_out_sel.hw,
831 [CLKID_MPLL_PREDIV] = &meson8b_mpll_prediv.hw,
832 [CLKID_FCLK_DIV2_DIV] = &meson8b_fclk_div2_div.hw,
833 [CLKID_FCLK_DIV3_DIV] = &meson8b_fclk_div3_div.hw,
834 [CLKID_FCLK_DIV4_DIV] = &meson8b_fclk_div4_div.hw,
835 [CLKID_FCLK_DIV5_DIV] = &meson8b_fclk_div5_div.hw,
836 [CLKID_FCLK_DIV7_DIV] = &meson8b_fclk_div7_div.hw,
602 [CLK_NR_CLKS] = NULL, 837 [CLK_NR_CLKS] = NULL,
603 }, 838 },
604 .num = CLK_NR_CLKS, 839 .num = CLK_NR_CLKS,
605}; 840};
606 841
607static struct meson_clk_pll *const meson8b_clk_plls[] = { 842static struct clk_regmap *const meson8b_clk_regmaps[] = {
608 &meson8b_fixed_pll,
609 &meson8b_vid_pll,
610 &meson8b_sys_pll,
611};
612
613static struct meson_clk_mpll *const meson8b_clk_mplls[] = {
614 &meson8b_mpll0,
615 &meson8b_mpll1,
616 &meson8b_mpll2,
617};
618
619static struct clk_gate *const meson8b_clk_gates[] = {
620 &meson8b_clk81, 843 &meson8b_clk81,
621 &meson8b_ddr, 844 &meson8b_ddr,
622 &meson8b_dos, 845 &meson8b_dos,
@@ -695,14 +918,27 @@ static struct clk_gate *const meson8b_clk_gates[] = {
695 &meson8b_ao_ahb_sram, 918 &meson8b_ao_ahb_sram,
696 &meson8b_ao_ahb_bus, 919 &meson8b_ao_ahb_bus,
697 &meson8b_ao_iface, 920 &meson8b_ao_iface,
698};
699
700static struct clk_mux *const meson8b_clk_muxes[] = {
701 &meson8b_mpeg_clk_sel,
702};
703
704static struct clk_divider *const meson8b_clk_dividers[] = {
705 &meson8b_mpeg_clk_div, 921 &meson8b_mpeg_clk_div,
922 &meson8b_mpeg_clk_sel,
923 &meson8b_mpll0,
924 &meson8b_mpll1,
925 &meson8b_mpll2,
926 &meson8b_mpll0_div,
927 &meson8b_mpll1_div,
928 &meson8b_mpll2_div,
929 &meson8b_fixed_pll,
930 &meson8b_vid_pll,
931 &meson8b_sys_pll,
932 &meson8b_cpu_in_sel,
933 &meson8b_cpu_scale_div,
934 &meson8b_cpu_scale_out_sel,
935 &meson8b_cpu_clk,
936 &meson8b_mpll_prediv,
937 &meson8b_fclk_div2,
938 &meson8b_fclk_div3,
939 &meson8b_fclk_div4,
940 &meson8b_fclk_div5,
941 &meson8b_fclk_div7,
706}; 942};
707 943
708static const struct meson8b_clk_reset_line { 944static const struct meson8b_clk_reset_line {
@@ -804,82 +1040,45 @@ static const struct reset_control_ops meson8b_clk_reset_ops = {
804 .deassert = meson8b_clk_reset_deassert, 1040 .deassert = meson8b_clk_reset_deassert,
805}; 1041};
806 1042
1043static const struct regmap_config clkc_regmap_config = {
1044 .reg_bits = 32,
1045 .val_bits = 32,
1046 .reg_stride = 4,
1047};
1048
807static int meson8b_clkc_probe(struct platform_device *pdev) 1049static int meson8b_clkc_probe(struct platform_device *pdev)
808{ 1050{
809 int ret, clkid, i; 1051 int ret, i;
810 struct clk_hw *parent_hw;
811 struct clk *parent_clk;
812 struct device *dev = &pdev->dev; 1052 struct device *dev = &pdev->dev;
1053 struct regmap *map;
813 1054
814 if (!clk_base) 1055 if (!clk_base)
815 return -ENXIO; 1056 return -ENXIO;
816 1057
817 /* Populate base address for PLLs */ 1058 map = devm_regmap_init_mmio(dev, clk_base, &clkc_regmap_config);
818 for (i = 0; i < ARRAY_SIZE(meson8b_clk_plls); i++) 1059 if (IS_ERR(map))
819 meson8b_clk_plls[i]->base = clk_base; 1060 return PTR_ERR(map);
820
821 /* Populate base address for MPLLs */
822 for (i = 0; i < ARRAY_SIZE(meson8b_clk_mplls); i++)
823 meson8b_clk_mplls[i]->base = clk_base;
824
825 /* Populate the base address for CPU clk */
826 meson8b_cpu_clk.base = clk_base;
827
828 /* Populate base address for gates */
829 for (i = 0; i < ARRAY_SIZE(meson8b_clk_gates); i++)
830 meson8b_clk_gates[i]->reg = clk_base +
831 (u32)meson8b_clk_gates[i]->reg;
832
833 /* Populate base address for muxes */
834 for (i = 0; i < ARRAY_SIZE(meson8b_clk_muxes); i++)
835 meson8b_clk_muxes[i]->reg = clk_base +
836 (u32)meson8b_clk_muxes[i]->reg;
837 1061
838 /* Populate base address for dividers */ 1062 /* Populate regmap for the regmap backed clocks */
839 for (i = 0; i < ARRAY_SIZE(meson8b_clk_dividers); i++) 1063 for (i = 0; i < ARRAY_SIZE(meson8b_clk_regmaps); i++)
840 meson8b_clk_dividers[i]->reg = clk_base + 1064 meson8b_clk_regmaps[i]->map = map;
841 (u32)meson8b_clk_dividers[i]->reg;
842 1065
843 /* 1066 /*
844 * register all clks 1067 * register all clks
845 * CLKID_UNUSED = 0, so skip it and start with CLKID_XTAL = 1 1068 * CLKID_UNUSED = 0, so skip it and start with CLKID_XTAL = 1
846 */ 1069 */
847 for (clkid = CLKID_XTAL; clkid < CLK_NR_CLKS; clkid++) { 1070 for (i = CLKID_XTAL; i < CLK_NR_CLKS; i++) {
848 /* array might be sparse */ 1071 /* array might be sparse */
849 if (!meson8b_hw_onecell_data.hws[clkid]) 1072 if (!meson8b_hw_onecell_data.hws[i])
850 continue; 1073 continue;
851 1074
852 /* FIXME convert to devm_clk_register */ 1075 ret = devm_clk_hw_register(dev, meson8b_hw_onecell_data.hws[i]);
853 ret = devm_clk_hw_register(dev, meson8b_hw_onecell_data.hws[clkid]);
854 if (ret) 1076 if (ret)
855 return ret; 1077 return ret;
856 } 1078 }
857 1079
858 /* 1080 return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
859 * Register CPU clk notifier 1081 &meson8b_hw_onecell_data);
860 *
861 * FIXME this is wrong for a lot of reasons. First, the muxes should be
862 * struct clk_hw objects. Second, we shouldn't program the muxes in
863 * notifier handlers. The tricky programming sequence will be handled
864 * by the forthcoming coordinated clock rates mechanism once that
865 * feature is released.
866 *
867 * Furthermore, looking up the parent this way is terrible. At some
868 * point we will stop allocating a default struct clk when registering
869 * a new clk_hw, and this hack will no longer work. Releasing the ccr
870 * feature before that time solves the problem :-)
871 */
872 parent_hw = clk_hw_get_parent(&meson8b_cpu_clk.hw);
873 parent_clk = parent_hw->clk;
874 ret = clk_notifier_register(parent_clk, &meson8b_cpu_clk.clk_nb);
875 if (ret) {
876 pr_err("%s: failed to register clock notifier for cpu_clk\n",
877 __func__);
878 return ret;
879 }
880
881 return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get,
882 &meson8b_hw_onecell_data);
883} 1082}
884 1083
885static const struct of_device_id meson8b_clkc_match_table[] = { 1084static const struct of_device_id meson8b_clkc_match_table[] = {
diff --git a/drivers/clk/meson/meson8b.h b/drivers/clk/meson/meson8b.h
index 2eaf8a52e7dd..6e414bd36981 100644
--- a/drivers/clk/meson/meson8b.h
+++ b/drivers/clk/meson/meson8b.h
@@ -69,7 +69,22 @@
69 * will remain defined here. 69 * will remain defined here.
70 */ 70 */
71 71
72#define CLK_NR_CLKS 96 72#define CLKID_MPLL0_DIV 96
73#define CLKID_MPLL1_DIV 97
74#define CLKID_MPLL2_DIV 98
75#define CLKID_CPU_IN_SEL 99
76#define CLKID_CPU_DIV2 100
77#define CLKID_CPU_DIV3 101
78#define CLKID_CPU_SCALE_DIV 102
79#define CLKID_CPU_SCALE_OUT_SEL 103
80#define CLKID_MPLL_PREDIV 104
81#define CLKID_FCLK_DIV2_DIV 105
82#define CLKID_FCLK_DIV3_DIV 106
83#define CLKID_FCLK_DIV4_DIV 107
84#define CLKID_FCLK_DIV5_DIV 108
85#define CLKID_FCLK_DIV7_DIV 109
86
87#define CLK_NR_CLKS 110
73 88
74/* 89/*
75 * include the CLKID and RESETID that have 90 * include the CLKID and RESETID that have
diff --git a/drivers/clk/nxp/clk-lpc32xx.c b/drivers/clk/nxp/clk-lpc32xx.c
index f5d815f577e0..5eeecee17b69 100644
--- a/drivers/clk/nxp/clk-lpc32xx.c
+++ b/drivers/clk/nxp/clk-lpc32xx.c
@@ -67,6 +67,7 @@
67#define LPC32XX_USB_CLK_STS 0xF8 67#define LPC32XX_USB_CLK_STS 0xF8
68 68
69static struct regmap_config lpc32xx_scb_regmap_config = { 69static struct regmap_config lpc32xx_scb_regmap_config = {
70 .name = "scb",
70 .reg_bits = 32, 71 .reg_bits = 32,
71 .val_bits = 32, 72 .val_bits = 32,
72 .reg_stride = 4, 73 .reg_stride = 4,
diff --git a/drivers/clk/qcom/clk-regmap-divider.c b/drivers/clk/qcom/clk-regmap-divider.c
index 4e9b8c2c8980..1ee75a5e93f4 100644
--- a/drivers/clk/qcom/clk-regmap-divider.c
+++ b/drivers/clk/qcom/clk-regmap-divider.c
@@ -28,22 +28,14 @@ static long div_round_ro_rate(struct clk_hw *hw, unsigned long rate,
28{ 28{
29 struct clk_regmap_div *divider = to_clk_regmap_div(hw); 29 struct clk_regmap_div *divider = to_clk_regmap_div(hw);
30 struct clk_regmap *clkr = &divider->clkr; 30 struct clk_regmap *clkr = &divider->clkr;
31 u32 div; 31 u32 val;
32 struct clk_hw *hw_parent = clk_hw_get_parent(hw);
33
34 regmap_read(clkr->regmap, divider->reg, &div);
35 div >>= divider->shift;
36 div &= BIT(divider->width) - 1;
37 div += 1;
38
39 if (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) {
40 if (!hw_parent)
41 return -EINVAL;
42 32
43 *prate = clk_hw_round_rate(hw_parent, rate * div); 33 regmap_read(clkr->regmap, divider->reg, &val);
44 } 34 val >>= divider->shift;
35 val &= BIT(divider->width) - 1;
45 36
46 return DIV_ROUND_UP_ULL((u64)*prate, div); 37 return divider_ro_round_rate(hw, rate, prate, NULL, divider->width,
38 CLK_DIVIDER_ROUND_CLOSEST, val);
47} 39}
48 40
49static long div_round_rate(struct clk_hw *hw, unsigned long rate, 41static long div_round_rate(struct clk_hw *hw, unsigned long rate,
diff --git a/drivers/clk/qcom/clk-rpm.c b/drivers/clk/qcom/clk-rpm.c
index c60f61b10c7f..b94981447664 100644
--- a/drivers/clk/qcom/clk-rpm.c
+++ b/drivers/clk/qcom/clk-rpm.c
@@ -29,6 +29,7 @@
29 29
30#define QCOM_RPM_MISC_CLK_TYPE 0x306b6c63 30#define QCOM_RPM_MISC_CLK_TYPE 0x306b6c63
31#define QCOM_RPM_SCALING_ENABLE_ID 0x2 31#define QCOM_RPM_SCALING_ENABLE_ID 0x2
32#define QCOM_RPM_XO_MODE_ON 0x2
32 33
33#define DEFINE_CLK_RPM(_platform, _name, _active, r_id) \ 34#define DEFINE_CLK_RPM(_platform, _name, _active, r_id) \
34 static struct clk_rpm _platform##_##_active; \ 35 static struct clk_rpm _platform##_##_active; \
@@ -56,6 +57,18 @@
56 }, \ 57 }, \
57 } 58 }
58 59
60#define DEFINE_CLK_RPM_XO_BUFFER(_platform, _name, _active, offset) \
61 static struct clk_rpm _platform##_##_name = { \
62 .rpm_clk_id = QCOM_RPM_CXO_BUFFERS, \
63 .xo_offset = (offset), \
64 .hw.init = &(struct clk_init_data){ \
65 .ops = &clk_rpm_xo_ops, \
66 .name = #_name, \
67 .parent_names = (const char *[]){ "cxo_board" }, \
68 .num_parents = 1, \
69 }, \
70 }
71
59#define DEFINE_CLK_RPM_FIXED(_platform, _name, _active, r_id, r) \ 72#define DEFINE_CLK_RPM_FIXED(_platform, _name, _active, r_id, r) \
60 static struct clk_rpm _platform##_##_name = { \ 73 static struct clk_rpm _platform##_##_name = { \
61 .rpm_clk_id = (r_id), \ 74 .rpm_clk_id = (r_id), \
@@ -126,8 +139,11 @@
126 139
127#define to_clk_rpm(_hw) container_of(_hw, struct clk_rpm, hw) 140#define to_clk_rpm(_hw) container_of(_hw, struct clk_rpm, hw)
128 141
142struct rpm_cc;
143
129struct clk_rpm { 144struct clk_rpm {
130 const int rpm_clk_id; 145 const int rpm_clk_id;
146 const int xo_offset;
131 const bool active_only; 147 const bool active_only;
132 unsigned long rate; 148 unsigned long rate;
133 bool enabled; 149 bool enabled;
@@ -135,12 +151,15 @@ struct clk_rpm {
135 struct clk_rpm *peer; 151 struct clk_rpm *peer;
136 struct clk_hw hw; 152 struct clk_hw hw;
137 struct qcom_rpm *rpm; 153 struct qcom_rpm *rpm;
154 struct rpm_cc *rpm_cc;
138}; 155};
139 156
140struct rpm_cc { 157struct rpm_cc {
141 struct qcom_rpm *rpm; 158 struct qcom_rpm *rpm;
142 struct clk_rpm **clks; 159 struct clk_rpm **clks;
143 size_t num_clks; 160 size_t num_clks;
161 u32 xo_buffer_value;
162 struct mutex xo_lock;
144}; 163};
145 164
146struct rpm_clk_desc { 165struct rpm_clk_desc {
@@ -159,7 +178,8 @@ static int clk_rpm_handoff(struct clk_rpm *r)
159 * The vendor tree simply reads the status for this 178 * The vendor tree simply reads the status for this
160 * RPM clock. 179 * RPM clock.
161 */ 180 */
162 if (r->rpm_clk_id == QCOM_RPM_PLL_4) 181 if (r->rpm_clk_id == QCOM_RPM_PLL_4 ||
182 r->rpm_clk_id == QCOM_RPM_CXO_BUFFERS)
163 return 0; 183 return 0;
164 184
165 ret = qcom_rpm_write(r->rpm, QCOM_RPM_ACTIVE_STATE, 185 ret = qcom_rpm_write(r->rpm, QCOM_RPM_ACTIVE_STATE,
@@ -288,6 +308,46 @@ out:
288 mutex_unlock(&rpm_clk_lock); 308 mutex_unlock(&rpm_clk_lock);
289} 309}
290 310
311static int clk_rpm_xo_prepare(struct clk_hw *hw)
312{
313 struct clk_rpm *r = to_clk_rpm(hw);
314 struct rpm_cc *rcc = r->rpm_cc;
315 int ret, clk_id = r->rpm_clk_id;
316 u32 value;
317
318 mutex_lock(&rcc->xo_lock);
319
320 value = rcc->xo_buffer_value | (QCOM_RPM_XO_MODE_ON << r->xo_offset);
321 ret = qcom_rpm_write(r->rpm, QCOM_RPM_ACTIVE_STATE, clk_id, &value, 1);
322 if (!ret) {
323 r->enabled = true;
324 rcc->xo_buffer_value = value;
325 }
326
327 mutex_unlock(&rcc->xo_lock);
328
329 return ret;
330}
331
332static void clk_rpm_xo_unprepare(struct clk_hw *hw)
333{
334 struct clk_rpm *r = to_clk_rpm(hw);
335 struct rpm_cc *rcc = r->rpm_cc;
336 int ret, clk_id = r->rpm_clk_id;
337 u32 value;
338
339 mutex_lock(&rcc->xo_lock);
340
341 value = rcc->xo_buffer_value & ~(QCOM_RPM_XO_MODE_ON << r->xo_offset);
342 ret = qcom_rpm_write(r->rpm, QCOM_RPM_ACTIVE_STATE, clk_id, &value, 1);
343 if (!ret) {
344 r->enabled = false;
345 rcc->xo_buffer_value = value;
346 }
347
348 mutex_unlock(&rcc->xo_lock);
349}
350
291static int clk_rpm_fixed_prepare(struct clk_hw *hw) 351static int clk_rpm_fixed_prepare(struct clk_hw *hw)
292{ 352{
293 struct clk_rpm *r = to_clk_rpm(hw); 353 struct clk_rpm *r = to_clk_rpm(hw);
@@ -378,6 +438,11 @@ static unsigned long clk_rpm_recalc_rate(struct clk_hw *hw,
378 return r->rate; 438 return r->rate;
379} 439}
380 440
441static const struct clk_ops clk_rpm_xo_ops = {
442 .prepare = clk_rpm_xo_prepare,
443 .unprepare = clk_rpm_xo_unprepare,
444};
445
381static const struct clk_ops clk_rpm_fixed_ops = { 446static const struct clk_ops clk_rpm_fixed_ops = {
382 .prepare = clk_rpm_fixed_prepare, 447 .prepare = clk_rpm_fixed_prepare,
383 .unprepare = clk_rpm_fixed_unprepare, 448 .unprepare = clk_rpm_fixed_unprepare,
@@ -449,6 +514,11 @@ DEFINE_CLK_RPM(apq8064, mmfpb_clk, mmfpb_a_clk, QCOM_RPM_MMFPB_CLK);
449DEFINE_CLK_RPM(apq8064, sfab_clk, sfab_a_clk, QCOM_RPM_SYS_FABRIC_CLK); 514DEFINE_CLK_RPM(apq8064, sfab_clk, sfab_a_clk, QCOM_RPM_SYS_FABRIC_CLK);
450DEFINE_CLK_RPM(apq8064, sfpb_clk, sfpb_a_clk, QCOM_RPM_SFPB_CLK); 515DEFINE_CLK_RPM(apq8064, sfpb_clk, sfpb_a_clk, QCOM_RPM_SFPB_CLK);
451DEFINE_CLK_RPM(apq8064, qdss_clk, qdss_a_clk, QCOM_RPM_QDSS_CLK); 516DEFINE_CLK_RPM(apq8064, qdss_clk, qdss_a_clk, QCOM_RPM_QDSS_CLK);
517DEFINE_CLK_RPM_XO_BUFFER(apq8064, xo_d0_clk, xo_d0_a_clk, 0);
518DEFINE_CLK_RPM_XO_BUFFER(apq8064, xo_d1_clk, xo_d1_a_clk, 8);
519DEFINE_CLK_RPM_XO_BUFFER(apq8064, xo_a0_clk, xo_a0_a_clk, 16);
520DEFINE_CLK_RPM_XO_BUFFER(apq8064, xo_a1_clk, xo_a1_a_clk, 24);
521DEFINE_CLK_RPM_XO_BUFFER(apq8064, xo_a2_clk, xo_a2_a_clk, 28);
452 522
453static struct clk_rpm *apq8064_clks[] = { 523static struct clk_rpm *apq8064_clks[] = {
454 [RPM_APPS_FABRIC_CLK] = &apq8064_afab_clk, 524 [RPM_APPS_FABRIC_CLK] = &apq8064_afab_clk,
@@ -469,6 +539,11 @@ static struct clk_rpm *apq8064_clks[] = {
469 [RPM_SFPB_A_CLK] = &apq8064_sfpb_a_clk, 539 [RPM_SFPB_A_CLK] = &apq8064_sfpb_a_clk,
470 [RPM_QDSS_CLK] = &apq8064_qdss_clk, 540 [RPM_QDSS_CLK] = &apq8064_qdss_clk,
471 [RPM_QDSS_A_CLK] = &apq8064_qdss_a_clk, 541 [RPM_QDSS_A_CLK] = &apq8064_qdss_a_clk,
542 [RPM_XO_D0] = &apq8064_xo_d0_clk,
543 [RPM_XO_D1] = &apq8064_xo_d1_clk,
544 [RPM_XO_A0] = &apq8064_xo_a0_clk,
545 [RPM_XO_A1] = &apq8064_xo_a1_clk,
546 [RPM_XO_A2] = &apq8064_xo_a2_clk,
472}; 547};
473 548
474static const struct rpm_clk_desc rpm_clk_apq8064 = { 549static const struct rpm_clk_desc rpm_clk_apq8064 = {
@@ -526,12 +601,14 @@ static int rpm_clk_probe(struct platform_device *pdev)
526 601
527 rcc->clks = rpm_clks; 602 rcc->clks = rpm_clks;
528 rcc->num_clks = num_clks; 603 rcc->num_clks = num_clks;
604 mutex_init(&rcc->xo_lock);
529 605
530 for (i = 0; i < num_clks; i++) { 606 for (i = 0; i < num_clks; i++) {
531 if (!rpm_clks[i]) 607 if (!rpm_clks[i])
532 continue; 608 continue;
533 609
534 rpm_clks[i]->rpm = rpm; 610 rpm_clks[i]->rpm = rpm;
611 rpm_clks[i]->rpm_cc = rcc;
535 612
536 ret = clk_rpm_handoff(rpm_clks[i]); 613 ret = clk_rpm_handoff(rpm_clks[i]);
537 if (ret) 614 if (ret)
diff --git a/drivers/clk/qcom/clk-smd-rpm.c b/drivers/clk/qcom/clk-smd-rpm.c
index c26d9007bfc4..850c02a52248 100644
--- a/drivers/clk/qcom/clk-smd-rpm.c
+++ b/drivers/clk/qcom/clk-smd-rpm.c
@@ -686,7 +686,7 @@ static int rpm_smd_clk_probe(struct platform_device *pdev)
686 goto err; 686 goto err;
687 } 687 }
688 688
689 ret = of_clk_add_hw_provider(pdev->dev.of_node, qcom_smdrpm_clk_hw_get, 689 ret = devm_of_clk_add_hw_provider(&pdev->dev, qcom_smdrpm_clk_hw_get,
690 rcc); 690 rcc);
691 if (ret) 691 if (ret)
692 goto err; 692 goto err;
@@ -697,19 +697,12 @@ err:
697 return ret; 697 return ret;
698} 698}
699 699
700static int rpm_smd_clk_remove(struct platform_device *pdev)
701{
702 of_clk_del_provider(pdev->dev.of_node);
703 return 0;
704}
705
706static struct platform_driver rpm_smd_clk_driver = { 700static struct platform_driver rpm_smd_clk_driver = {
707 .driver = { 701 .driver = {
708 .name = "qcom-clk-smd-rpm", 702 .name = "qcom-clk-smd-rpm",
709 .of_match_table = rpm_smd_clk_match_table, 703 .of_match_table = rpm_smd_clk_match_table,
710 }, 704 },
711 .probe = rpm_smd_clk_probe, 705 .probe = rpm_smd_clk_probe,
712 .remove = rpm_smd_clk_remove,
713}; 706};
714 707
715static int __init rpm_smd_clk_init(void) 708static int __init rpm_smd_clk_init(void)
diff --git a/drivers/clk/qcom/gcc-msm8996.c b/drivers/clk/qcom/gcc-msm8996.c
index 5d7451209206..3d6452932797 100644
--- a/drivers/clk/qcom/gcc-msm8996.c
+++ b/drivers/clk/qcom/gcc-msm8996.c
@@ -2895,7 +2895,7 @@ static struct clk_branch gcc_aggre0_snoc_axi_clk = {
2895 .name = "gcc_aggre0_snoc_axi_clk", 2895 .name = "gcc_aggre0_snoc_axi_clk",
2896 .parent_names = (const char *[]){ "system_noc_clk_src" }, 2896 .parent_names = (const char *[]){ "system_noc_clk_src" },
2897 .num_parents = 1, 2897 .num_parents = 1,
2898 .flags = CLK_SET_RATE_PARENT, 2898 .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
2899 .ops = &clk_branch2_ops, 2899 .ops = &clk_branch2_ops,
2900 }, 2900 },
2901 }, 2901 },
@@ -2910,7 +2910,7 @@ static struct clk_branch gcc_aggre0_cnoc_ahb_clk = {
2910 .name = "gcc_aggre0_cnoc_ahb_clk", 2910 .name = "gcc_aggre0_cnoc_ahb_clk",
2911 .parent_names = (const char *[]){ "config_noc_clk_src" }, 2911 .parent_names = (const char *[]){ "config_noc_clk_src" },
2912 .num_parents = 1, 2912 .num_parents = 1,
2913 .flags = CLK_SET_RATE_PARENT, 2913 .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
2914 .ops = &clk_branch2_ops, 2914 .ops = &clk_branch2_ops,
2915 }, 2915 },
2916 }, 2916 },
@@ -2925,7 +2925,7 @@ static struct clk_branch gcc_smmu_aggre0_axi_clk = {
2925 .name = "gcc_smmu_aggre0_axi_clk", 2925 .name = "gcc_smmu_aggre0_axi_clk",
2926 .parent_names = (const char *[]){ "system_noc_clk_src" }, 2926 .parent_names = (const char *[]){ "system_noc_clk_src" },
2927 .num_parents = 1, 2927 .num_parents = 1,
2928 .flags = CLK_SET_RATE_PARENT, 2928 .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
2929 .ops = &clk_branch2_ops, 2929 .ops = &clk_branch2_ops,
2930 }, 2930 },
2931 }, 2931 },
@@ -2940,7 +2940,7 @@ static struct clk_branch gcc_smmu_aggre0_ahb_clk = {
2940 .name = "gcc_smmu_aggre0_ahb_clk", 2940 .name = "gcc_smmu_aggre0_ahb_clk",
2941 .parent_names = (const char *[]){ "config_noc_clk_src" }, 2941 .parent_names = (const char *[]){ "config_noc_clk_src" },
2942 .num_parents = 1, 2942 .num_parents = 1,
2943 .flags = CLK_SET_RATE_PARENT, 2943 .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
2944 .ops = &clk_branch2_ops, 2944 .ops = &clk_branch2_ops,
2945 }, 2945 },
2946 }, 2946 },
diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
index ef8900bc077f..513826393158 100644
--- a/drivers/clk/samsung/Makefile
+++ b/drivers/clk/samsung/Makefile
@@ -8,9 +8,11 @@ obj-$(CONFIG_SOC_EXYNOS3250) += clk-exynos3250.o
8obj-$(CONFIG_ARCH_EXYNOS4) += clk-exynos4.o 8obj-$(CONFIG_ARCH_EXYNOS4) += clk-exynos4.o
9obj-$(CONFIG_ARCH_EXYNOS4) += clk-exynos4412-isp.o 9obj-$(CONFIG_ARCH_EXYNOS4) += clk-exynos4412-isp.o
10obj-$(CONFIG_SOC_EXYNOS5250) += clk-exynos5250.o 10obj-$(CONFIG_SOC_EXYNOS5250) += clk-exynos5250.o
11obj-$(CONFIG_SOC_EXYNOS5250) += clk-exynos5-subcmu.o
11obj-$(CONFIG_SOC_EXYNOS5260) += clk-exynos5260.o 12obj-$(CONFIG_SOC_EXYNOS5260) += clk-exynos5260.o
12obj-$(CONFIG_SOC_EXYNOS5410) += clk-exynos5410.o 13obj-$(CONFIG_SOC_EXYNOS5410) += clk-exynos5410.o
13obj-$(CONFIG_SOC_EXYNOS5420) += clk-exynos5420.o 14obj-$(CONFIG_SOC_EXYNOS5420) += clk-exynos5420.o
15obj-$(CONFIG_SOC_EXYNOS5420) += clk-exynos5-subcmu.o
14obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynos5433.o 16obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynos5433.o
15obj-$(CONFIG_SOC_EXYNOS5440) += clk-exynos5440.o 17obj-$(CONFIG_SOC_EXYNOS5440) += clk-exynos5440.o
16obj-$(CONFIG_EXYNOS_AUDSS_CLK_CON) += clk-exynos-audss.o 18obj-$(CONFIG_EXYNOS_AUDSS_CLK_CON) += clk-exynos-audss.o
diff --git a/drivers/clk/samsung/clk-exynos-audss.c b/drivers/clk/samsung/clk-exynos-audss.c
index 5bfc92ee3129..b4b057c7301c 100644
--- a/drivers/clk/samsung/clk-exynos-audss.c
+++ b/drivers/clk/samsung/clk-exynos-audss.c
@@ -143,10 +143,8 @@ static int exynos_audss_clk_probe(struct platform_device *pdev)
143 143
144 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 144 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
145 reg_base = devm_ioremap_resource(dev, res); 145 reg_base = devm_ioremap_resource(dev, res);
146 if (IS_ERR(reg_base)) { 146 if (IS_ERR(reg_base))
147 dev_err(dev, "failed to map audss registers\n");
148 return PTR_ERR(reg_base); 147 return PTR_ERR(reg_base);
149 }
150 148
151 epll = ERR_PTR(-ENODEV); 149 epll = ERR_PTR(-ENODEV);
152 150
diff --git a/drivers/clk/samsung/clk-exynos3250.c b/drivers/clk/samsung/clk-exynos3250.c
index 1b81e283f605..27c9d23657b3 100644
--- a/drivers/clk/samsung/clk-exynos3250.c
+++ b/drivers/clk/samsung/clk-exynos3250.c
@@ -670,73 +670,73 @@ static const struct samsung_gate_clock gate_clks[] __initconst = {
670 670
671/* APLL & MPLL & BPLL & UPLL */ 671/* APLL & MPLL & BPLL & UPLL */
672static const struct samsung_pll_rate_table exynos3250_pll_rates[] __initconst = { 672static const struct samsung_pll_rate_table exynos3250_pll_rates[] __initconst = {
673 PLL_35XX_RATE(1200000000, 400, 4, 1), 673 PLL_35XX_RATE(24 * MHZ, 1200000000, 400, 4, 1),
674 PLL_35XX_RATE(1100000000, 275, 3, 1), 674 PLL_35XX_RATE(24 * MHZ, 1100000000, 275, 3, 1),
675 PLL_35XX_RATE(1066000000, 533, 6, 1), 675 PLL_35XX_RATE(24 * MHZ, 1066000000, 533, 6, 1),
676 PLL_35XX_RATE(1000000000, 250, 3, 1), 676 PLL_35XX_RATE(24 * MHZ, 1000000000, 250, 3, 1),
677 PLL_35XX_RATE( 960000000, 320, 4, 1), 677 PLL_35XX_RATE(24 * MHZ, 960000000, 320, 4, 1),
678 PLL_35XX_RATE( 900000000, 300, 4, 1), 678 PLL_35XX_RATE(24 * MHZ, 900000000, 300, 4, 1),
679 PLL_35XX_RATE( 850000000, 425, 6, 1), 679 PLL_35XX_RATE(24 * MHZ, 850000000, 425, 6, 1),
680 PLL_35XX_RATE( 800000000, 200, 3, 1), 680 PLL_35XX_RATE(24 * MHZ, 800000000, 200, 3, 1),
681 PLL_35XX_RATE( 700000000, 175, 3, 1), 681 PLL_35XX_RATE(24 * MHZ, 700000000, 175, 3, 1),
682 PLL_35XX_RATE( 667000000, 667, 12, 1), 682 PLL_35XX_RATE(24 * MHZ, 667000000, 667, 12, 1),
683 PLL_35XX_RATE( 600000000, 400, 4, 2), 683 PLL_35XX_RATE(24 * MHZ, 600000000, 400, 4, 2),
684 PLL_35XX_RATE( 533000000, 533, 6, 2), 684 PLL_35XX_RATE(24 * MHZ, 533000000, 533, 6, 2),
685 PLL_35XX_RATE( 520000000, 260, 3, 2), 685 PLL_35XX_RATE(24 * MHZ, 520000000, 260, 3, 2),
686 PLL_35XX_RATE( 500000000, 250, 3, 2), 686 PLL_35XX_RATE(24 * MHZ, 500000000, 250, 3, 2),
687 PLL_35XX_RATE( 400000000, 200, 3, 2), 687 PLL_35XX_RATE(24 * MHZ, 400000000, 200, 3, 2),
688 PLL_35XX_RATE( 200000000, 200, 3, 3), 688 PLL_35XX_RATE(24 * MHZ, 200000000, 200, 3, 3),
689 PLL_35XX_RATE( 100000000, 200, 3, 4), 689 PLL_35XX_RATE(24 * MHZ, 100000000, 200, 3, 4),
690 { /* sentinel */ } 690 { /* sentinel */ }
691}; 691};
692 692
693/* EPLL */ 693/* EPLL */
694static const struct samsung_pll_rate_table exynos3250_epll_rates[] __initconst = { 694static const struct samsung_pll_rate_table exynos3250_epll_rates[] __initconst = {
695 PLL_36XX_RATE(800000000, 200, 3, 1, 0), 695 PLL_36XX_RATE(24 * MHZ, 800000000, 200, 3, 1, 0),
696 PLL_36XX_RATE(288000000, 96, 2, 2, 0), 696 PLL_36XX_RATE(24 * MHZ, 288000000, 96, 2, 2, 0),
697 PLL_36XX_RATE(192000000, 128, 2, 3, 0), 697 PLL_36XX_RATE(24 * MHZ, 192000000, 128, 2, 3, 0),
698 PLL_36XX_RATE(144000000, 96, 2, 3, 0), 698 PLL_36XX_RATE(24 * MHZ, 144000000, 96, 2, 3, 0),
699 PLL_36XX_RATE( 96000000, 128, 2, 4, 0), 699 PLL_36XX_RATE(24 * MHZ, 96000000, 128, 2, 4, 0),
700 PLL_36XX_RATE( 84000000, 112, 2, 4, 0), 700 PLL_36XX_RATE(24 * MHZ, 84000000, 112, 2, 4, 0),
701 PLL_36XX_RATE( 80000004, 106, 2, 4, 43691), 701 PLL_36XX_RATE(24 * MHZ, 80000003, 106, 2, 4, 43691),
702 PLL_36XX_RATE( 73728000, 98, 2, 4, 19923), 702 PLL_36XX_RATE(24 * MHZ, 73728000, 98, 2, 4, 19923),
703 PLL_36XX_RATE( 67737598, 270, 3, 5, 62285), 703 PLL_36XX_RATE(24 * MHZ, 67737598, 270, 3, 5, 62285),
704 PLL_36XX_RATE( 65535999, 174, 2, 5, 49982), 704 PLL_36XX_RATE(24 * MHZ, 65535999, 174, 2, 5, 49982),
705 PLL_36XX_RATE( 50000000, 200, 3, 5, 0), 705 PLL_36XX_RATE(24 * MHZ, 50000000, 200, 3, 5, 0),
706 PLL_36XX_RATE( 49152002, 131, 2, 5, 4719), 706 PLL_36XX_RATE(24 * MHZ, 49152002, 131, 2, 5, 4719),
707 PLL_36XX_RATE( 48000000, 128, 2, 5, 0), 707 PLL_36XX_RATE(24 * MHZ, 48000000, 128, 2, 5, 0),
708 PLL_36XX_RATE( 45158401, 180, 3, 5, 41524), 708 PLL_36XX_RATE(24 * MHZ, 45158401, 180, 3, 5, 41524),
709 { /* sentinel */ } 709 { /* sentinel */ }
710}; 710};
711 711
712/* VPLL */ 712/* VPLL */
713static const struct samsung_pll_rate_table exynos3250_vpll_rates[] __initconst = { 713static const struct samsung_pll_rate_table exynos3250_vpll_rates[] __initconst = {
714 PLL_36XX_RATE(600000000, 100, 2, 1, 0), 714 PLL_36XX_RATE(24 * MHZ, 600000000, 100, 2, 1, 0),
715 PLL_36XX_RATE(533000000, 266, 3, 2, 32768), 715 PLL_36XX_RATE(24 * MHZ, 533000000, 266, 3, 2, 32768),
716 PLL_36XX_RATE(519230987, 173, 2, 2, 5046), 716 PLL_36XX_RATE(24 * MHZ, 519230987, 173, 2, 2, 5046),
717 PLL_36XX_RATE(500000000, 250, 3, 2, 0), 717 PLL_36XX_RATE(24 * MHZ, 500000000, 250, 3, 2, 0),
718 PLL_36XX_RATE(445500000, 148, 2, 2, 32768), 718 PLL_36XX_RATE(24 * MHZ, 445500000, 148, 2, 2, 32768),
719 PLL_36XX_RATE(445055007, 148, 2, 2, 23047), 719 PLL_36XX_RATE(24 * MHZ, 445055007, 148, 2, 2, 23047),
720 PLL_36XX_RATE(400000000, 200, 3, 2, 0), 720 PLL_36XX_RATE(24 * MHZ, 400000000, 200, 3, 2, 0),
721 PLL_36XX_RATE(371250000, 123, 2, 2, 49152), 721 PLL_36XX_RATE(24 * MHZ, 371250000, 123, 2, 2, 49152),
722 PLL_36XX_RATE(370878997, 185, 3, 2, 28803), 722 PLL_36XX_RATE(24 * MHZ, 370878997, 185, 3, 2, 28803),
723 PLL_36XX_RATE(340000000, 170, 3, 2, 0), 723 PLL_36XX_RATE(24 * MHZ, 340000000, 170, 3, 2, 0),
724 PLL_36XX_RATE(335000015, 111, 2, 2, 43691), 724 PLL_36XX_RATE(24 * MHZ, 335000015, 111, 2, 2, 43691),
725 PLL_36XX_RATE(333000000, 111, 2, 2, 0), 725 PLL_36XX_RATE(24 * MHZ, 333000000, 111, 2, 2, 0),
726 PLL_36XX_RATE(330000000, 110, 2, 2, 0), 726 PLL_36XX_RATE(24 * MHZ, 330000000, 110, 2, 2, 0),
727 PLL_36XX_RATE(320000015, 106, 2, 2, 43691), 727 PLL_36XX_RATE(24 * MHZ, 320000015, 106, 2, 2, 43691),
728 PLL_36XX_RATE(300000000, 100, 2, 2, 0), 728 PLL_36XX_RATE(24 * MHZ, 300000000, 100, 2, 2, 0),
729 PLL_36XX_RATE(275000000, 275, 3, 3, 0), 729 PLL_36XX_RATE(24 * MHZ, 275000000, 275, 3, 3, 0),
730 PLL_36XX_RATE(222750000, 148, 2, 3, 32768), 730 PLL_36XX_RATE(24 * MHZ, 222750000, 148, 2, 3, 32768),
731 PLL_36XX_RATE(222528007, 148, 2, 3, 23069), 731 PLL_36XX_RATE(24 * MHZ, 222528007, 148, 2, 3, 23069),
732 PLL_36XX_RATE(160000000, 160, 3, 3, 0), 732 PLL_36XX_RATE(24 * MHZ, 160000000, 160, 3, 3, 0),
733 PLL_36XX_RATE(148500000, 99, 2, 3, 0), 733 PLL_36XX_RATE(24 * MHZ, 148500000, 99, 2, 3, 0),
734 PLL_36XX_RATE(148352005, 98, 2, 3, 59070), 734 PLL_36XX_RATE(24 * MHZ, 148352005, 98, 2, 3, 59070),
735 PLL_36XX_RATE(108000000, 144, 2, 4, 0), 735 PLL_36XX_RATE(24 * MHZ, 108000000, 144, 2, 4, 0),
736 PLL_36XX_RATE( 74250000, 99, 2, 4, 0), 736 PLL_36XX_RATE(24 * MHZ, 74250000, 99, 2, 4, 0),
737 PLL_36XX_RATE( 74176002, 98, 3, 4, 59070), 737 PLL_36XX_RATE(24 * MHZ, 74176002, 98, 2, 4, 59070),
738 PLL_36XX_RATE( 54054000, 216, 3, 5, 14156), 738 PLL_36XX_RATE(24 * MHZ, 54054000, 216, 3, 5, 14156),
739 PLL_36XX_RATE( 54000000, 144, 2, 5, 0), 739 PLL_36XX_RATE(24 * MHZ, 54000000, 144, 2, 5, 0),
740 { /* sentinel */ } 740 { /* sentinel */ }
741}; 741};
742 742
diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
index 134f25f2a913..0421960eb963 100644
--- a/drivers/clk/samsung/clk-exynos4.c
+++ b/drivers/clk/samsung/clk-exynos4.c
@@ -1266,77 +1266,78 @@ static const struct of_device_id ext_clk_match[] __initconst = {
1266 1266
1267/* PLLs PMS values */ 1267/* PLLs PMS values */
1268static const struct samsung_pll_rate_table exynos4210_apll_rates[] __initconst = { 1268static const struct samsung_pll_rate_table exynos4210_apll_rates[] __initconst = {
1269 PLL_45XX_RATE(1200000000, 150, 3, 1, 28), 1269 PLL_4508_RATE(24 * MHZ, 1200000000, 150, 3, 1, 28),
1270 PLL_45XX_RATE(1000000000, 250, 6, 1, 28), 1270 PLL_4508_RATE(24 * MHZ, 1000000000, 250, 6, 1, 28),
1271 PLL_45XX_RATE( 800000000, 200, 6, 1, 28), 1271 PLL_4508_RATE(24 * MHZ, 800000000, 200, 6, 1, 28),
1272 PLL_45XX_RATE( 666857142, 389, 14, 1, 13), 1272 PLL_4508_RATE(24 * MHZ, 666857142, 389, 14, 1, 13),
1273 PLL_45XX_RATE( 600000000, 100, 4, 1, 13), 1273 PLL_4508_RATE(24 * MHZ, 600000000, 100, 4, 1, 13),
1274 PLL_45XX_RATE( 533000000, 533, 24, 1, 5), 1274 PLL_4508_RATE(24 * MHZ, 533000000, 533, 24, 1, 5),
1275 PLL_45XX_RATE( 500000000, 250, 6, 2, 28), 1275 PLL_4508_RATE(24 * MHZ, 500000000, 250, 6, 2, 28),
1276 PLL_45XX_RATE( 400000000, 200, 6, 2, 28), 1276 PLL_4508_RATE(24 * MHZ, 400000000, 200, 6, 2, 28),
1277 PLL_45XX_RATE( 200000000, 200, 6, 3, 28), 1277 PLL_4508_RATE(24 * MHZ, 200000000, 200, 6, 3, 28),
1278 { /* sentinel */ } 1278 { /* sentinel */ }
1279}; 1279};
1280 1280
1281static const struct samsung_pll_rate_table exynos4210_epll_rates[] __initconst = { 1281static const struct samsung_pll_rate_table exynos4210_epll_rates[] __initconst = {
1282 PLL_4600_RATE(192000000, 48, 3, 1, 0, 0), 1282 PLL_4600_RATE(24 * MHZ, 192000000, 48, 3, 1, 0, 0),
1283 PLL_4600_RATE(180633605, 45, 3, 1, 10381, 0), 1283 PLL_4600_RATE(24 * MHZ, 180633605, 45, 3, 1, 10381, 0),
1284 PLL_4600_RATE(180000000, 45, 3, 1, 0, 0), 1284 PLL_4600_RATE(24 * MHZ, 180000000, 45, 3, 1, 0, 0),
1285 PLL_4600_RATE( 73727996, 73, 3, 3, 47710, 1), 1285 PLL_4600_RATE(24 * MHZ, 73727996, 73, 3, 3, 47710, 1),
1286 PLL_4600_RATE( 67737602, 90, 4, 3, 20762, 1), 1286 PLL_4600_RATE(24 * MHZ, 67737602, 90, 4, 3, 20762, 1),
1287 PLL_4600_RATE( 49151992, 49, 3, 3, 9961, 0), 1287 PLL_4600_RATE(24 * MHZ, 49151992, 49, 3, 3, 9961, 0),
1288 PLL_4600_RATE( 45158401, 45, 3, 3, 10381, 0), 1288 PLL_4600_RATE(24 * MHZ, 45158401, 45, 3, 3, 10381, 0),
1289 { /* sentinel */ } 1289 { /* sentinel */ }
1290}; 1290};
1291 1291
1292static const struct samsung_pll_rate_table exynos4210_vpll_rates[] __initconst = { 1292static const struct samsung_pll_rate_table exynos4210_vpll_rates[] __initconst = {
1293 PLL_4650_RATE(360000000, 44, 3, 0, 1024, 0, 14, 0), 1293 PLL_4650_RATE(24 * MHZ, 360000000, 44, 3, 0, 1024, 0, 14, 0),
1294 PLL_4650_RATE(324000000, 53, 2, 1, 1024, 1, 1, 1), 1294 PLL_4650_RATE(24 * MHZ, 324000000, 53, 2, 1, 1024, 1, 1, 1),
1295 PLL_4650_RATE(259617187, 63, 3, 1, 1950, 0, 20, 1), 1295 PLL_4650_RATE(24 * MHZ, 259617187, 63, 3, 1, 1950, 0, 20, 1),
1296 PLL_4650_RATE(110000000, 53, 3, 2, 2048, 0, 17, 0), 1296 PLL_4650_RATE(24 * MHZ, 110000000, 53, 3, 2, 2048, 0, 17, 0),
1297 PLL_4650_RATE( 55360351, 53, 3, 3, 2417, 0, 17, 0), 1297 PLL_4650_RATE(24 * MHZ, 55360351, 53, 3, 3, 2417, 0, 17, 0),
1298 { /* sentinel */ } 1298 { /* sentinel */ }
1299}; 1299};
1300 1300
1301static const struct samsung_pll_rate_table exynos4x12_apll_rates[] __initconst = { 1301static const struct samsung_pll_rate_table exynos4x12_apll_rates[] __initconst = {
1302 PLL_35XX_RATE(1704000000, 213, 3, 0), 1302 PLL_35XX_RATE(24 * MHZ, 1704000000, 213, 3, 0),
1303 PLL_35XX_RATE(1600000000, 200, 3, 0), 1303 PLL_35XX_RATE(24 * MHZ, 1600000000, 200, 3, 0),
1304 PLL_35XX_RATE(1500000000, 250, 4, 0), 1304 PLL_35XX_RATE(24 * MHZ, 1500000000, 250, 4, 0),
1305 PLL_35XX_RATE(1400000000, 175, 3, 0), 1305 PLL_35XX_RATE(24 * MHZ, 1400000000, 175, 3, 0),
1306 PLL_35XX_RATE(1300000000, 325, 6, 0), 1306 PLL_35XX_RATE(24 * MHZ, 1300000000, 325, 6, 0),
1307 PLL_35XX_RATE(1200000000, 200, 4, 0), 1307 PLL_35XX_RATE(24 * MHZ, 1200000000, 200, 4, 0),
1308 PLL_35XX_RATE(1100000000, 275, 6, 0), 1308 PLL_35XX_RATE(24 * MHZ, 1100000000, 275, 6, 0),
1309 PLL_35XX_RATE(1000000000, 125, 3, 0), 1309 PLL_35XX_RATE(24 * MHZ, 1000000000, 125, 3, 0),
1310 PLL_35XX_RATE( 900000000, 150, 4, 0), 1310 PLL_35XX_RATE(24 * MHZ, 900000000, 150, 4, 0),
1311 PLL_35XX_RATE( 800000000, 100, 3, 0), 1311 PLL_35XX_RATE(24 * MHZ, 800000000, 100, 3, 0),
1312 PLL_35XX_RATE( 700000000, 175, 3, 1), 1312 PLL_35XX_RATE(24 * MHZ, 700000000, 175, 3, 1),
1313 PLL_35XX_RATE( 600000000, 200, 4, 1), 1313 PLL_35XX_RATE(24 * MHZ, 600000000, 200, 4, 1),
1314 PLL_35XX_RATE( 500000000, 125, 3, 1), 1314 PLL_35XX_RATE(24 * MHZ, 500000000, 125, 3, 1),
1315 PLL_35XX_RATE( 400000000, 100, 3, 1), 1315 PLL_35XX_RATE(24 * MHZ, 400000000, 100, 3, 1),
1316 PLL_35XX_RATE( 300000000, 200, 4, 2), 1316 PLL_35XX_RATE(24 * MHZ, 300000000, 200, 4, 2),
1317 PLL_35XX_RATE( 200000000, 100, 3, 2), 1317 PLL_35XX_RATE(24 * MHZ, 200000000, 100, 3, 2),
1318 { /* sentinel */ } 1318 { /* sentinel */ }
1319}; 1319};
1320 1320
1321static const struct samsung_pll_rate_table exynos4x12_epll_rates[] __initconst = { 1321static const struct samsung_pll_rate_table exynos4x12_epll_rates[] __initconst = {
1322 PLL_36XX_RATE(192000000, 48, 3, 1, 0), 1322 PLL_36XX_RATE(24 * MHZ, 196608001, 197, 3, 3, -25690),
1323 PLL_36XX_RATE(180633605, 45, 3, 1, 10381), 1323 PLL_36XX_RATE(24 * MHZ, 192000000, 48, 3, 1, 0),
1324 PLL_36XX_RATE(180000000, 45, 3, 1, 0), 1324 PLL_36XX_RATE(24 * MHZ, 180633605, 45, 3, 1, 10381),
1325 PLL_36XX_RATE( 73727996, 73, 3, 3, 47710), 1325 PLL_36XX_RATE(24 * MHZ, 180000000, 45, 3, 1, 0),
1326 PLL_36XX_RATE( 67737602, 90, 4, 3, 20762), 1326 PLL_36XX_RATE(24 * MHZ, 73727996, 73, 3, 3, 47710),
1327 PLL_36XX_RATE( 49151992, 49, 3, 3, 9961), 1327 PLL_36XX_RATE(24 * MHZ, 67737602, 90, 4, 3, 20762),
1328 PLL_36XX_RATE( 45158401, 45, 3, 3, 10381), 1328 PLL_36XX_RATE(24 * MHZ, 49151992, 49, 3, 3, 9961),
1329 PLL_36XX_RATE(24 * MHZ, 45158401, 45, 3, 3, 10381),
1329 { /* sentinel */ } 1330 { /* sentinel */ }
1330}; 1331};
1331 1332
1332static const struct samsung_pll_rate_table exynos4x12_vpll_rates[] __initconst = { 1333static const struct samsung_pll_rate_table exynos4x12_vpll_rates[] __initconst = {
1333 PLL_36XX_RATE(533000000, 133, 3, 1, 16384), 1334 PLL_36XX_RATE(24 * MHZ, 533000000, 133, 3, 1, 16384),
1334 PLL_36XX_RATE(440000000, 110, 3, 1, 0), 1335 PLL_36XX_RATE(24 * MHZ, 440000000, 110, 3, 1, 0),
1335 PLL_36XX_RATE(350000000, 175, 3, 2, 0), 1336 PLL_36XX_RATE(24 * MHZ, 350000000, 175, 3, 2, 0),
1336 PLL_36XX_RATE(266000000, 133, 3, 2, 0), 1337 PLL_36XX_RATE(24 * MHZ, 266000000, 133, 3, 2, 0),
1337 PLL_36XX_RATE(160000000, 160, 3, 3, 0), 1338 PLL_36XX_RATE(24 * MHZ, 160000000, 160, 3, 3, 0),
1338 PLL_36XX_RATE(106031250, 53, 3, 2, 1024), 1339 PLL_36XX_RATE(24 * MHZ, 106031250, 53, 3, 2, 1024),
1339 PLL_36XX_RATE( 53015625, 53, 3, 3, 1024), 1340 PLL_36XX_RATE(24 * MHZ, 53015625, 53, 3, 3, 1024),
1340 { /* sentinel */ } 1341 { /* sentinel */ }
1341}; 1342};
1342 1343
diff --git a/drivers/clk/samsung/clk-exynos5-subcmu.c b/drivers/clk/samsung/clk-exynos5-subcmu.c
new file mode 100644
index 000000000000..93306283d764
--- /dev/null
+++ b/drivers/clk/samsung/clk-exynos5-subcmu.c
@@ -0,0 +1,189 @@
1// SPDX-License-Identifier: GPL-2.0
2//
3// Copyright (c) 2018 Samsung Electronics Co., Ltd.
4// Author: Marek Szyprowski <m.szyprowski@samsung.com>
5// Common Clock Framework support for Exynos5 power-domain dependent clocks
6
7#include <linux/of_platform.h>
8#include <linux/platform_device.h>
9#include <linux/pm_domain.h>
10#include <linux/pm_runtime.h>
11
12#include "clk.h"
13#include "clk-exynos5-subcmu.h"
14
15static struct samsung_clk_provider *ctx;
16static const struct exynos5_subcmu_info *cmu;
17static int nr_cmus;
18
19static void exynos5_subcmu_clk_save(void __iomem *base,
20 struct exynos5_subcmu_reg_dump *rd,
21 unsigned int num_regs)
22{
23 for (; num_regs > 0; --num_regs, ++rd) {
24 rd->save = readl(base + rd->offset);
25 writel((rd->save & ~rd->mask) | rd->value, base + rd->offset);
26 rd->save &= rd->mask;
27 }
28};
29
30static void exynos5_subcmu_clk_restore(void __iomem *base,
31 struct exynos5_subcmu_reg_dump *rd,
32 unsigned int num_regs)
33{
34 for (; num_regs > 0; --num_regs, ++rd)
35 writel((readl(base + rd->offset) & ~rd->mask) | rd->save,
36 base + rd->offset);
37}
38
39static void exynos5_subcmu_defer_gate(struct samsung_clk_provider *ctx,
40 const struct samsung_gate_clock *list, int nr_clk)
41{
42 while (nr_clk--)
43 samsung_clk_add_lookup(ctx, ERR_PTR(-EPROBE_DEFER), list++->id);
44}
45
46/*
47 * Pass the needed clock provider context and register sub-CMU clocks
48 *
49 * NOTE: This function has to be called from the main, OF_CLK_DECLARE-
50 * initialized clock provider driver. This happens very early during boot
51 * process. Then this driver, during core_initcall registers two platform
52 * drivers: one which binds to the same device-tree node as OF_CLK_DECLARE
53 * driver and second, for handling its per-domain child-devices. Those
54 * platform drivers are bound to their devices a bit later in arch_initcall,
55 * when OF-core populates all device-tree nodes.
56 */
57void exynos5_subcmus_init(struct samsung_clk_provider *_ctx, int _nr_cmus,
58 const struct exynos5_subcmu_info *_cmu)
59{
60 ctx = _ctx;
61 cmu = _cmu;
62 nr_cmus = _nr_cmus;
63
64 for (; _nr_cmus--; _cmu++) {
65 exynos5_subcmu_defer_gate(ctx, _cmu->gate_clks,
66 _cmu->nr_gate_clks);
67 exynos5_subcmu_clk_save(ctx->reg_base, _cmu->suspend_regs,
68 _cmu->nr_suspend_regs);
69 }
70}
71
72static int __maybe_unused exynos5_subcmu_suspend(struct device *dev)
73{
74 struct exynos5_subcmu_info *info = dev_get_drvdata(dev);
75 unsigned long flags;
76
77 spin_lock_irqsave(&ctx->lock, flags);
78 exynos5_subcmu_clk_save(ctx->reg_base, info->suspend_regs,
79 info->nr_suspend_regs);
80 spin_unlock_irqrestore(&ctx->lock, flags);
81
82 return 0;
83}
84
85static int __maybe_unused exynos5_subcmu_resume(struct device *dev)
86{
87 struct exynos5_subcmu_info *info = dev_get_drvdata(dev);
88 unsigned long flags;
89
90 spin_lock_irqsave(&ctx->lock, flags);
91 exynos5_subcmu_clk_restore(ctx->reg_base, info->suspend_regs,
92 info->nr_suspend_regs);
93 spin_unlock_irqrestore(&ctx->lock, flags);
94
95 return 0;
96}
97
98static int __init exynos5_subcmu_probe(struct platform_device *pdev)
99{
100 struct device *dev = &pdev->dev;
101 struct exynos5_subcmu_info *info = dev_get_drvdata(dev);
102
103 pm_runtime_set_suspended(dev);
104 pm_runtime_enable(dev);
105 pm_runtime_get(dev);
106
107 ctx->dev = dev;
108 samsung_clk_register_div(ctx, info->div_clks, info->nr_div_clks);
109 samsung_clk_register_gate(ctx, info->gate_clks, info->nr_gate_clks);
110 ctx->dev = NULL;
111
112 pm_runtime_put_sync(dev);
113
114 return 0;
115}
116
117static const struct dev_pm_ops exynos5_subcmu_pm_ops = {
118 SET_RUNTIME_PM_OPS(exynos5_subcmu_suspend,
119 exynos5_subcmu_resume, NULL)
120 SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
121 pm_runtime_force_resume)
122};
123
124static struct platform_driver exynos5_subcmu_driver __refdata = {
125 .driver = {
126 .name = "exynos5-subcmu",
127 .suppress_bind_attrs = true,
128 .pm = &exynos5_subcmu_pm_ops,
129 },
130 .probe = exynos5_subcmu_probe,
131};
132
133static int __init exynos5_clk_register_subcmu(struct device *parent,
134 const struct exynos5_subcmu_info *info,
135 struct device_node *pd_node)
136{
137 struct of_phandle_args genpdspec = { .np = pd_node };
138 struct platform_device *pdev;
139
140 pdev = platform_device_alloc(info->pd_name, -1);
141 pdev->dev.parent = parent;
142 pdev->driver_override = "exynos5-subcmu";
143 platform_set_drvdata(pdev, (void *)info);
144 of_genpd_add_device(&genpdspec, &pdev->dev);
145 platform_device_add(pdev);
146
147 return 0;
148}
149
150static int __init exynos5_clk_probe(struct platform_device *pdev)
151{
152 struct device_node *np;
153 const char *name;
154 int i;
155
156 for_each_compatible_node(np, NULL, "samsung,exynos4210-pd") {
157 if (of_property_read_string(np, "label", &name) < 0)
158 continue;
159 for (i = 0; i < nr_cmus; i++)
160 if (strcmp(cmu[i].pd_name, name) == 0)
161 exynos5_clk_register_subcmu(&pdev->dev,
162 &cmu[i], np);
163 }
164 return 0;
165}
166
167static const struct of_device_id exynos5_clk_of_match[] = {
168 { .compatible = "samsung,exynos5250-clock", },
169 { .compatible = "samsung,exynos5420-clock", },
170 { .compatible = "samsung,exynos5800-clock", },
171 { },
172};
173
174static struct platform_driver exynos5_clk_driver __refdata = {
175 .driver = {
176 .name = "exynos5-clock",
177 .of_match_table = exynos5_clk_of_match,
178 .suppress_bind_attrs = true,
179 },
180 .probe = exynos5_clk_probe,
181};
182
183static int __init exynos5_clk_drv_init(void)
184{
185 platform_driver_register(&exynos5_clk_driver);
186 platform_driver_register(&exynos5_subcmu_driver);
187 return 0;
188}
189core_initcall(exynos5_clk_drv_init);
diff --git a/drivers/clk/samsung/clk-exynos5-subcmu.h b/drivers/clk/samsung/clk-exynos5-subcmu.h
new file mode 100644
index 000000000000..755ee8aaa3de
--- /dev/null
+++ b/drivers/clk/samsung/clk-exynos5-subcmu.h
@@ -0,0 +1,26 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2
3#ifndef __CLK_EXYNOS5_SUBCMU_H
4#define __CLK_EXYNOS5_SUBCMU_H
5
6struct exynos5_subcmu_reg_dump {
7 u32 offset;
8 u32 value;
9 u32 mask;
10 u32 save;
11};
12
13struct exynos5_subcmu_info {
14 const struct samsung_div_clock *div_clks;
15 unsigned int nr_div_clks;
16 const struct samsung_gate_clock *gate_clks;
17 unsigned int nr_gate_clks;
18 struct exynos5_subcmu_reg_dump *suspend_regs;
19 unsigned int nr_suspend_regs;
20 const char *pd_name;
21};
22
23void exynos5_subcmus_init(struct samsung_clk_provider *ctx, int nr_cmus,
24 const struct exynos5_subcmu_info *cmu);
25
26#endif
diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c
index 9b073c98a891..347fd80c351b 100644
--- a/drivers/clk/samsung/clk-exynos5250.c
+++ b/drivers/clk/samsung/clk-exynos5250.c
@@ -18,6 +18,7 @@
18 18
19#include "clk.h" 19#include "clk.h"
20#include "clk-cpu.h" 20#include "clk-cpu.h"
21#include "clk-exynos5-subcmu.h"
21 22
22#define APLL_LOCK 0x0 23#define APLL_LOCK 0x0
23#define APLL_CON0 0x100 24#define APLL_CON0 0x100
@@ -560,6 +561,8 @@ static const struct samsung_gate_clock exynos5250_gate_clks[] __initconst = {
560 0), 561 0),
561 GATE(CLK_GSCL3, "gscl3", "mout_aclk266_gscl_sub", GATE_IP_GSCL, 3, 0, 562 GATE(CLK_GSCL3, "gscl3", "mout_aclk266_gscl_sub", GATE_IP_GSCL, 3, 0,
562 0), 563 0),
564 GATE(CLK_CAMIF_TOP, "camif_top", "mout_aclk266_gscl_sub",
565 GATE_IP_GSCL, 4, 0, 0),
563 GATE(CLK_GSCL_WA, "gscl_wa", "div_gscl_wa", GATE_IP_GSCL, 5, 0, 0), 566 GATE(CLK_GSCL_WA, "gscl_wa", "div_gscl_wa", GATE_IP_GSCL, 5, 0, 0),
564 GATE(CLK_GSCL_WB, "gscl_wb", "div_gscl_wb", GATE_IP_GSCL, 6, 0, 0), 567 GATE(CLK_GSCL_WB, "gscl_wb", "div_gscl_wb", GATE_IP_GSCL, 6, 0, 0),
565 GATE(CLK_SMMU_GSCL0, "smmu_gscl0", "mout_aclk266_gscl_sub", 568 GATE(CLK_SMMU_GSCL0, "smmu_gscl0", "mout_aclk266_gscl_sub",
@@ -570,18 +573,11 @@ static const struct samsung_gate_clock exynos5250_gate_clks[] __initconst = {
570 GATE_IP_GSCL, 9, 0, 0), 573 GATE_IP_GSCL, 9, 0, 0),
571 GATE(CLK_SMMU_GSCL3, "smmu_gscl3", "mout_aclk266_gscl_sub", 574 GATE(CLK_SMMU_GSCL3, "smmu_gscl3", "mout_aclk266_gscl_sub",
572 GATE_IP_GSCL, 10, 0, 0), 575 GATE_IP_GSCL, 10, 0, 0),
576 GATE(CLK_SMMU_FIMC_LITE0, "smmu_fimc_lite0", "mout_aclk266_gscl_sub",
577 GATE_IP_GSCL, 11, 0, 0),
578 GATE(CLK_SMMU_FIMC_LITE1, "smmu_fimc_lite1", "mout_aclk266_gscl_sub",
579 GATE_IP_GSCL, 12, 0, 0),
573 580
574 GATE(CLK_FIMD1, "fimd1", "mout_aclk200_disp1_sub", GATE_IP_DISP1, 0, 0,
575 0),
576 GATE(CLK_MIE1, "mie1", "mout_aclk200_disp1_sub", GATE_IP_DISP1, 1, 0,
577 0),
578 GATE(CLK_DSIM0, "dsim0", "mout_aclk200_disp1_sub", GATE_IP_DISP1, 3, 0,
579 0),
580 GATE(CLK_DP, "dp", "mout_aclk200_disp1_sub", GATE_IP_DISP1, 4, 0, 0),
581 GATE(CLK_MIXER, "mixer", "mout_aclk200_disp1_sub", GATE_IP_DISP1, 5, 0,
582 0),
583 GATE(CLK_HDMI, "hdmi", "mout_aclk200_disp1_sub", GATE_IP_DISP1, 6, 0,
584 0),
585 581
586 GATE(CLK_MFC, "mfc", "mout_aclk333_sub", GATE_IP_MFC, 0, 0, 0), 582 GATE(CLK_MFC, "mfc", "mout_aclk333_sub", GATE_IP_MFC, 0, 0, 0),
587 GATE(CLK_SMMU_MFCR, "smmu_mfcr", "mout_aclk333_sub", GATE_IP_MFC, 1, 0, 583 GATE(CLK_SMMU_MFCR, "smmu_mfcr", "mout_aclk333_sub", GATE_IP_MFC, 1, 0,
@@ -671,10 +667,6 @@ static const struct samsung_gate_clock exynos5250_gate_clks[] __initconst = {
671 GATE(CLK_WDT, "wdt", "div_aclk66", GATE_IP_PERIS, 19, 0, 0), 667 GATE(CLK_WDT, "wdt", "div_aclk66", GATE_IP_PERIS, 19, 0, 0),
672 GATE(CLK_RTC, "rtc", "div_aclk66", GATE_IP_PERIS, 20, 0, 0), 668 GATE(CLK_RTC, "rtc", "div_aclk66", GATE_IP_PERIS, 20, 0, 0),
673 GATE(CLK_TMU, "tmu", "div_aclk66", GATE_IP_PERIS, 21, 0, 0), 669 GATE(CLK_TMU, "tmu", "div_aclk66", GATE_IP_PERIS, 21, 0, 0),
674 GATE(CLK_SMMU_TV, "smmu_tv", "mout_aclk200_disp1_sub",
675 GATE_IP_DISP1, 9, 0, 0),
676 GATE(CLK_SMMU_FIMD1, "smmu_fimd1", "mout_aclk200_disp1_sub",
677 GATE_IP_DISP1, 8, 0, 0),
678 GATE(CLK_SMMU_2D, "smmu_2d", "div_aclk200", GATE_IP_ACP, 7, 0, 0), 670 GATE(CLK_SMMU_2D, "smmu_2d", "div_aclk200", GATE_IP_ACP, 7, 0, 0),
679 GATE(CLK_SMMU_FIMC_ISP, "smmu_fimc_isp", "mout_aclk_266_isp_sub", 671 GATE(CLK_SMMU_FIMC_ISP, "smmu_fimc_isp", "mout_aclk_266_isp_sub",
680 GATE_IP_ISP0, 8, 0, 0), 672 GATE_IP_ISP0, 8, 0, 0),
@@ -698,48 +690,80 @@ static const struct samsung_gate_clock exynos5250_gate_clks[] __initconst = {
698 GATE_IP_ISP1, 7, 0, 0), 690 GATE_IP_ISP1, 7, 0, 0),
699}; 691};
700 692
693static const struct samsung_gate_clock exynos5250_disp_gate_clks[] __initconst = {
694 GATE(CLK_FIMD1, "fimd1", "mout_aclk200_disp1_sub", GATE_IP_DISP1, 0, 0,
695 0),
696 GATE(CLK_MIE1, "mie1", "mout_aclk200_disp1_sub", GATE_IP_DISP1, 1, 0,
697 0),
698 GATE(CLK_DSIM0, "dsim0", "mout_aclk200_disp1_sub", GATE_IP_DISP1, 3, 0,
699 0),
700 GATE(CLK_DP, "dp", "mout_aclk200_disp1_sub", GATE_IP_DISP1, 4, 0, 0),
701 GATE(CLK_MIXER, "mixer", "mout_aclk200_disp1_sub", GATE_IP_DISP1, 5, 0,
702 0),
703 GATE(CLK_HDMI, "hdmi", "mout_aclk200_disp1_sub", GATE_IP_DISP1, 6, 0,
704 0),
705 GATE(CLK_SMMU_TV, "smmu_tv", "mout_aclk200_disp1_sub",
706 GATE_IP_DISP1, 9, 0, 0),
707 GATE(CLK_SMMU_FIMD1, "smmu_fimd1", "mout_aclk200_disp1_sub",
708 GATE_IP_DISP1, 8, 0, 0),
709};
710
711static struct exynos5_subcmu_reg_dump exynos5250_disp_suspend_regs[] = {
712 { GATE_IP_DISP1, 0xffffffff, 0xffffffff }, /* DISP1 gates */
713 { SRC_TOP3, 0, BIT(4) }, /* MUX mout_aclk200_disp1_sub */
714 { SRC_TOP3, 0, BIT(6) }, /* MUX mout_aclk300_disp1_sub */
715};
716
717static const struct exynos5_subcmu_info exynos5250_disp_subcmu = {
718 .gate_clks = exynos5250_disp_gate_clks,
719 .nr_gate_clks = ARRAY_SIZE(exynos5250_disp_gate_clks),
720 .suspend_regs = exynos5250_disp_suspend_regs,
721 .nr_suspend_regs = ARRAY_SIZE(exynos5250_disp_suspend_regs),
722 .pd_name = "DISP1",
723};
724
701static const struct samsung_pll_rate_table vpll_24mhz_tbl[] __initconst = { 725static const struct samsung_pll_rate_table vpll_24mhz_tbl[] __initconst = {
702 /* sorted in descending order */ 726 /* sorted in descending order */
703 /* PLL_36XX_RATE(rate, m, p, s, k) */ 727 /* PLL_36XX_RATE(rate, m, p, s, k) */
704 PLL_36XX_RATE(266000000, 266, 3, 3, 0), 728 PLL_36XX_RATE(24 * MHZ, 266000000, 266, 3, 3, 0),
705 /* Not in UM, but need for eDP on snow */ 729 /* Not in UM, but need for eDP on snow */
706 PLL_36XX_RATE(70500000, 94, 2, 4, 0), 730 PLL_36XX_RATE(24 * MHZ, 70500000, 94, 2, 4, 0),
707 { }, 731 { },
708}; 732};
709 733
710static const struct samsung_pll_rate_table epll_24mhz_tbl[] __initconst = { 734static const struct samsung_pll_rate_table epll_24mhz_tbl[] __initconst = {
711 /* sorted in descending order */ 735 /* sorted in descending order */
712 /* PLL_36XX_RATE(rate, m, p, s, k) */ 736 /* PLL_36XX_RATE(rate, m, p, s, k) */
713 PLL_36XX_RATE(192000000, 64, 2, 2, 0), 737 PLL_36XX_RATE(24 * MHZ, 192000000, 64, 2, 2, 0),
714 PLL_36XX_RATE(180633600, 90, 3, 2, 20762), 738 PLL_36XX_RATE(24 * MHZ, 180633605, 90, 3, 2, 20762),
715 PLL_36XX_RATE(180000000, 90, 3, 2, 0), 739 PLL_36XX_RATE(24 * MHZ, 180000000, 90, 3, 2, 0),
716 PLL_36XX_RATE(73728000, 98, 2, 4, 19923), 740 PLL_36XX_RATE(24 * MHZ, 73728000, 98, 2, 4, 19923),
717 PLL_36XX_RATE(67737600, 90, 2, 4, 20762), 741 PLL_36XX_RATE(24 * MHZ, 67737602, 90, 2, 4, 20762),
718 PLL_36XX_RATE(49152000, 98, 3, 4, 19923), 742 PLL_36XX_RATE(24 * MHZ, 49152000, 98, 3, 4, 19923),
719 PLL_36XX_RATE(45158400, 90, 3, 4, 20762), 743 PLL_36XX_RATE(24 * MHZ, 45158401, 90, 3, 4, 20762),
720 PLL_36XX_RATE(32768000, 131, 3, 5, 4719), 744 PLL_36XX_RATE(24 * MHZ, 32768001, 131, 3, 5, 4719),
721 { }, 745 { },
722}; 746};
723 747
724static const struct samsung_pll_rate_table apll_24mhz_tbl[] __initconst = { 748static const struct samsung_pll_rate_table apll_24mhz_tbl[] __initconst = {
725 /* sorted in descending order */ 749 /* sorted in descending order */
726 /* PLL_35XX_RATE(rate, m, p, s) */ 750 /* PLL_35XX_RATE(fin, rate, m, p, s) */
727 PLL_35XX_RATE(1700000000, 425, 6, 0), 751 PLL_35XX_RATE(24 * MHZ, 1700000000, 425, 6, 0),
728 PLL_35XX_RATE(1600000000, 200, 3, 0), 752 PLL_35XX_RATE(24 * MHZ, 1600000000, 200, 3, 0),
729 PLL_35XX_RATE(1500000000, 250, 4, 0), 753 PLL_35XX_RATE(24 * MHZ, 1500000000, 250, 4, 0),
730 PLL_35XX_RATE(1400000000, 175, 3, 0), 754 PLL_35XX_RATE(24 * MHZ, 1400000000, 175, 3, 0),
731 PLL_35XX_RATE(1300000000, 325, 6, 0), 755 PLL_35XX_RATE(24 * MHZ, 1300000000, 325, 6, 0),
732 PLL_35XX_RATE(1200000000, 200, 4, 0), 756 PLL_35XX_RATE(24 * MHZ, 1200000000, 200, 4, 0),
733 PLL_35XX_RATE(1100000000, 275, 6, 0), 757 PLL_35XX_RATE(24 * MHZ, 1100000000, 275, 6, 0),
734 PLL_35XX_RATE(1000000000, 125, 3, 0), 758 PLL_35XX_RATE(24 * MHZ, 1000000000, 125, 3, 0),
735 PLL_35XX_RATE(900000000, 150, 4, 0), 759 PLL_35XX_RATE(24 * MHZ, 900000000, 150, 4, 0),
736 PLL_35XX_RATE(800000000, 100, 3, 0), 760 PLL_35XX_RATE(24 * MHZ, 800000000, 100, 3, 0),
737 PLL_35XX_RATE(700000000, 175, 3, 1), 761 PLL_35XX_RATE(24 * MHZ, 700000000, 175, 3, 1),
738 PLL_35XX_RATE(600000000, 200, 4, 1), 762 PLL_35XX_RATE(24 * MHZ, 600000000, 200, 4, 1),
739 PLL_35XX_RATE(500000000, 125, 3, 1), 763 PLL_35XX_RATE(24 * MHZ, 500000000, 125, 3, 1),
740 PLL_35XX_RATE(400000000, 100, 3, 1), 764 PLL_35XX_RATE(24 * MHZ, 400000000, 100, 3, 1),
741 PLL_35XX_RATE(300000000, 200, 4, 2), 765 PLL_35XX_RATE(24 * MHZ, 300000000, 200, 4, 2),
742 PLL_35XX_RATE(200000000, 100, 3, 2), 766 PLL_35XX_RATE(24 * MHZ, 200000000, 100, 3, 2),
743}; 767};
744 768
745static struct samsung_pll_clock exynos5250_plls[nr_plls] __initdata = { 769static struct samsung_pll_clock exynos5250_plls[nr_plls] __initdata = {
@@ -859,10 +883,11 @@ static void __init exynos5250_clk_init(struct device_node *np)
859 __raw_writel(tmp, reg_base + PWR_CTRL2); 883 __raw_writel(tmp, reg_base + PWR_CTRL2);
860 884
861 exynos5250_clk_sleep_init(); 885 exynos5250_clk_sleep_init();
886 exynos5_subcmus_init(ctx, 1, &exynos5250_disp_subcmu);
862 887
863 samsung_clk_of_add_provider(np, ctx); 888 samsung_clk_of_add_provider(np, ctx);
864 889
865 pr_info("Exynos5250: clock setup completed, armclk=%ld\n", 890 pr_info("Exynos5250: clock setup completed, armclk=%ld\n",
866 _get_rate("div_arm2")); 891 _get_rate("div_arm2"));
867} 892}
868CLK_OF_DECLARE(exynos5250_clk, "samsung,exynos5250-clock", exynos5250_clk_init); 893CLK_OF_DECLARE_DRIVER(exynos5250_clk, "samsung,exynos5250-clock", exynos5250_clk_init);
diff --git a/drivers/clk/samsung/clk-exynos5260.c b/drivers/clk/samsung/clk-exynos5260.c
index fd1d9bfc151b..2cc2583abd87 100644
--- a/drivers/clk/samsung/clk-exynos5260.c
+++ b/drivers/clk/samsung/clk-exynos5260.c
@@ -23,57 +23,57 @@
23 * DISP_PLL, EGL_PLL, KFC_PLL, MEM_PLL, BUS_PLL, MEDIA_PLL, G3D_PLL. 23 * DISP_PLL, EGL_PLL, KFC_PLL, MEM_PLL, BUS_PLL, MEDIA_PLL, G3D_PLL.
24 */ 24 */
25static const struct samsung_pll_rate_table pll2550_24mhz_tbl[] __initconst = { 25static const struct samsung_pll_rate_table pll2550_24mhz_tbl[] __initconst = {
26 PLL_35XX_RATE(1700000000, 425, 6, 0), 26 PLL_35XX_RATE(24 * MHZ, 1700000000, 425, 6, 0),
27 PLL_35XX_RATE(1600000000, 200, 3, 0), 27 PLL_35XX_RATE(24 * MHZ, 1600000000, 200, 3, 0),
28 PLL_35XX_RATE(1500000000, 250, 4, 0), 28 PLL_35XX_RATE(24 * MHZ, 1500000000, 250, 4, 0),
29 PLL_35XX_RATE(1400000000, 175, 3, 0), 29 PLL_35XX_RATE(24 * MHZ, 1400000000, 175, 3, 0),
30 PLL_35XX_RATE(1300000000, 325, 6, 0), 30 PLL_35XX_RATE(24 * MHZ, 1300000000, 325, 6, 0),
31 PLL_35XX_RATE(1200000000, 400, 4, 1), 31 PLL_35XX_RATE(24 * MHZ, 1200000000, 400, 4, 1),
32 PLL_35XX_RATE(1100000000, 275, 3, 1), 32 PLL_35XX_RATE(24 * MHZ, 1100000000, 275, 3, 1),
33 PLL_35XX_RATE(1000000000, 250, 3, 1), 33 PLL_35XX_RATE(24 * MHZ, 1000000000, 250, 3, 1),
34 PLL_35XX_RATE(933000000, 311, 4, 1), 34 PLL_35XX_RATE(24 * MHZ, 933000000, 311, 4, 1),
35 PLL_35XX_RATE(900000000, 300, 4, 1), 35 PLL_35XX_RATE(24 * MHZ, 900000000, 300, 4, 1),
36 PLL_35XX_RATE(800000000, 200, 3, 1), 36 PLL_35XX_RATE(24 * MHZ, 800000000, 200, 3, 1),
37 PLL_35XX_RATE(733000000, 733, 12, 1), 37 PLL_35XX_RATE(24 * MHZ, 733000000, 733, 12, 1),
38 PLL_35XX_RATE(700000000, 175, 3, 1), 38 PLL_35XX_RATE(24 * MHZ, 700000000, 175, 3, 1),
39 PLL_35XX_RATE(667000000, 667, 12, 1), 39 PLL_35XX_RATE(24 * MHZ, 667000000, 667, 12, 1),
40 PLL_35XX_RATE(633000000, 211, 4, 1), 40 PLL_35XX_RATE(24 * MHZ, 633000000, 211, 4, 1),
41 PLL_35XX_RATE(620000000, 310, 3, 2), 41 PLL_35XX_RATE(24 * MHZ, 620000000, 310, 3, 2),
42 PLL_35XX_RATE(600000000, 400, 4, 2), 42 PLL_35XX_RATE(24 * MHZ, 600000000, 400, 4, 2),
43 PLL_35XX_RATE(543000000, 362, 4, 2), 43 PLL_35XX_RATE(24 * MHZ, 543000000, 362, 4, 2),
44 PLL_35XX_RATE(533000000, 533, 6, 2), 44 PLL_35XX_RATE(24 * MHZ, 533000000, 533, 6, 2),
45 PLL_35XX_RATE(500000000, 250, 3, 2), 45 PLL_35XX_RATE(24 * MHZ, 500000000, 250, 3, 2),
46 PLL_35XX_RATE(450000000, 300, 4, 2), 46 PLL_35XX_RATE(24 * MHZ, 450000000, 300, 4, 2),
47 PLL_35XX_RATE(400000000, 200, 3, 2), 47 PLL_35XX_RATE(24 * MHZ, 400000000, 200, 3, 2),
48 PLL_35XX_RATE(350000000, 175, 3, 2), 48 PLL_35XX_RATE(24 * MHZ, 350000000, 175, 3, 2),
49 PLL_35XX_RATE(300000000, 400, 4, 3), 49 PLL_35XX_RATE(24 * MHZ, 300000000, 400, 4, 3),
50 PLL_35XX_RATE(266000000, 266, 3, 3), 50 PLL_35XX_RATE(24 * MHZ, 266000000, 266, 3, 3),
51 PLL_35XX_RATE(200000000, 200, 3, 3), 51 PLL_35XX_RATE(24 * MHZ, 200000000, 200, 3, 3),
52 PLL_35XX_RATE(160000000, 160, 3, 3), 52 PLL_35XX_RATE(24 * MHZ, 160000000, 160, 3, 3),
53}; 53};
54 54
55/* 55/*
56 * Applicable for 2650 Type PLL for AUD_PLL. 56 * Applicable for 2650 Type PLL for AUD_PLL.
57 */ 57 */
58static const struct samsung_pll_rate_table pll2650_24mhz_tbl[] __initconst = { 58static const struct samsung_pll_rate_table pll2650_24mhz_tbl[] __initconst = {
59 PLL_36XX_RATE(1600000000, 200, 3, 0, 0), 59 PLL_36XX_RATE(24 * MHZ, 1600000000, 200, 3, 0, 0),
60 PLL_36XX_RATE(1200000000, 100, 2, 0, 0), 60 PLL_36XX_RATE(24 * MHZ, 1200000000, 100, 2, 0, 0),
61 PLL_36XX_RATE(1000000000, 250, 3, 1, 0), 61 PLL_36XX_RATE(24 * MHZ, 1000000000, 250, 3, 1, 0),
62 PLL_36XX_RATE(800000000, 200, 3, 1, 0), 62 PLL_36XX_RATE(24 * MHZ, 800000000, 200, 3, 1, 0),
63 PLL_36XX_RATE(600000000, 100, 2, 1, 0), 63 PLL_36XX_RATE(24 * MHZ, 600000000, 100, 2, 1, 0),
64 PLL_36XX_RATE(532000000, 266, 3, 2, 0), 64 PLL_36XX_RATE(24 * MHZ, 532000000, 266, 3, 2, 0),
65 PLL_36XX_RATE(480000000, 160, 2, 2, 0), 65 PLL_36XX_RATE(24 * MHZ, 480000000, 160, 2, 2, 0),
66 PLL_36XX_RATE(432000000, 144, 2, 2, 0), 66 PLL_36XX_RATE(24 * MHZ, 432000000, 144, 2, 2, 0),
67 PLL_36XX_RATE(400000000, 200, 3, 2, 0), 67 PLL_36XX_RATE(24 * MHZ, 400000000, 200, 3, 2, 0),
68 PLL_36XX_RATE(394073130, 459, 7, 2, 49282), 68 PLL_36XX_RATE(24 * MHZ, 394073128, 459, 7, 2, 49282),
69 PLL_36XX_RATE(333000000, 111, 2, 2, 0), 69 PLL_36XX_RATE(24 * MHZ, 333000000, 111, 2, 2, 0),
70 PLL_36XX_RATE(300000000, 100, 2, 2, 0), 70 PLL_36XX_RATE(24 * MHZ, 300000000, 100, 2, 2, 0),
71 PLL_36XX_RATE(266000000, 266, 3, 3, 0), 71 PLL_36XX_RATE(24 * MHZ, 266000000, 266, 3, 3, 0),
72 PLL_36XX_RATE(200000000, 200, 3, 3, 0), 72 PLL_36XX_RATE(24 * MHZ, 200000000, 200, 3, 3, 0),
73 PLL_36XX_RATE(166000000, 166, 3, 3, 0), 73 PLL_36XX_RATE(24 * MHZ, 166000000, 166, 3, 3, 0),
74 PLL_36XX_RATE(133000000, 266, 3, 4, 0), 74 PLL_36XX_RATE(24 * MHZ, 133000000, 266, 3, 4, 0),
75 PLL_36XX_RATE(100000000, 200, 3, 4, 0), 75 PLL_36XX_RATE(24 * MHZ, 100000000, 200, 3, 4, 0),
76 PLL_36XX_RATE(66000000, 176, 2, 5, 0), 76 PLL_36XX_RATE(24 * MHZ, 66000000, 176, 2, 5, 0),
77}; 77};
78 78
79/* CMU_AUD */ 79/* CMU_AUD */
diff --git a/drivers/clk/samsung/clk-exynos5410.c b/drivers/clk/samsung/clk-exynos5410.c
index fc471a49e8f4..0a0b09591e6f 100644
--- a/drivers/clk/samsung/clk-exynos5410.c
+++ b/drivers/clk/samsung/clk-exynos5410.c
@@ -226,16 +226,16 @@ static const struct samsung_gate_clock exynos5410_gate_clks[] __initconst = {
226}; 226};
227 227
228static const struct samsung_pll_rate_table exynos5410_pll2550x_24mhz_tbl[] __initconst = { 228static const struct samsung_pll_rate_table exynos5410_pll2550x_24mhz_tbl[] __initconst = {
229 PLL_36XX_RATE(400000000U, 200, 3, 2, 0), 229 PLL_36XX_RATE(24 * MHZ, 400000000U, 200, 3, 2, 0),
230 PLL_36XX_RATE(333000000U, 111, 2, 2, 0), 230 PLL_36XX_RATE(24 * MHZ, 333000000U, 111, 2, 2, 0),
231 PLL_36XX_RATE(300000000U, 100, 2, 2, 0), 231 PLL_36XX_RATE(24 * MHZ, 300000000U, 100, 2, 2, 0),
232 PLL_36XX_RATE(266000000U, 266, 3, 3, 0), 232 PLL_36XX_RATE(24 * MHZ, 266000000U, 266, 3, 3, 0),
233 PLL_36XX_RATE(200000000U, 200, 3, 3, 0), 233 PLL_36XX_RATE(24 * MHZ, 200000000U, 200, 3, 3, 0),
234 PLL_36XX_RATE(192000000U, 192, 3, 3, 0), 234 PLL_36XX_RATE(24 * MHZ, 192000000U, 192, 3, 3, 0),
235 PLL_36XX_RATE(166000000U, 166, 3, 3, 0), 235 PLL_36XX_RATE(24 * MHZ, 166000000U, 166, 3, 3, 0),
236 PLL_36XX_RATE(133000000U, 266, 3, 4, 0), 236 PLL_36XX_RATE(24 * MHZ, 133000000U, 266, 3, 4, 0),
237 PLL_36XX_RATE(100000000U, 200, 3, 4, 0), 237 PLL_36XX_RATE(24 * MHZ, 100000000U, 200, 3, 4, 0),
238 PLL_36XX_RATE(66000000U, 176, 2, 5, 0), 238 PLL_36XX_RATE(24 * MHZ, 66000000U, 176, 2, 5, 0),
239}; 239};
240 240
241static struct samsung_pll_clock exynos5410_plls[nr_plls] __initdata = { 241static struct samsung_pll_clock exynos5410_plls[nr_plls] __initdata = {
diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c
index 45d34f601e9e..95e1bf69449b 100644
--- a/drivers/clk/samsung/clk-exynos5420.c
+++ b/drivers/clk/samsung/clk-exynos5420.c
@@ -19,6 +19,7 @@
19 19
20#include "clk.h" 20#include "clk.h"
21#include "clk-cpu.h" 21#include "clk-cpu.h"
22#include "clk-exynos5-subcmu.h"
22 23
23#define APLL_LOCK 0x0 24#define APLL_LOCK 0x0
24#define APLL_CON0 0x100 25#define APLL_CON0 0x100
@@ -620,7 +621,8 @@ static const struct samsung_mux_clock exynos5420_mux_clks[] __initconst = {
620 621
621 MUX(CLK_MOUT_MX_MSPLL_CCORE, "mout_mx_mspll_ccore", 622 MUX(CLK_MOUT_MX_MSPLL_CCORE, "mout_mx_mspll_ccore",
622 mout_group5_5800_p, SRC_TOP7, 16, 2), 623 mout_group5_5800_p, SRC_TOP7, 16, 2),
623 MUX(0, "mout_mau_epll_clk", mout_mau_epll_clk_p, SRC_TOP7, 20, 2), 624 MUX_F(0, "mout_mau_epll_clk", mout_mau_epll_clk_p, SRC_TOP7, 20, 2,
625 CLK_SET_RATE_PARENT, 0),
624 626
625 MUX(0, "mout_fimd1", mout_group3_p, SRC_DISP10, 4, 1), 627 MUX(0, "mout_fimd1", mout_group3_p, SRC_DISP10, 4, 1),
626}; 628};
@@ -863,7 +865,6 @@ static const struct samsung_div_clock exynos5x_div_clks[] __initconst = {
863 DIV(0, "dout_mipi1", "mout_mipi1", DIV_DISP10, 16, 8), 865 DIV(0, "dout_mipi1", "mout_mipi1", DIV_DISP10, 16, 8),
864 DIV(0, "dout_dp1", "mout_dp1", DIV_DISP10, 24, 4), 866 DIV(0, "dout_dp1", "mout_dp1", DIV_DISP10, 24, 4),
865 DIV(CLK_DOUT_PIXEL, "dout_hdmi_pixel", "mout_pixel", DIV_DISP10, 28, 4), 867 DIV(CLK_DOUT_PIXEL, "dout_hdmi_pixel", "mout_pixel", DIV_DISP10, 28, 4),
866 DIV(0, "dout_disp1_blk", "aclk200_disp1", DIV2_RATIO0, 16, 2),
867 DIV(CLK_DOUT_ACLK400_DISP1, "dout_aclk400_disp1", 868 DIV(CLK_DOUT_ACLK400_DISP1, "dout_aclk400_disp1",
868 "mout_aclk400_disp1", DIV_TOP2, 4, 3), 869 "mout_aclk400_disp1", DIV_TOP2, 4, 3),
869 870
@@ -912,8 +913,6 @@ static const struct samsung_div_clock exynos5x_div_clks[] __initconst = {
912 DIV(0, "dout_spi1", "mout_spi1", DIV_PERIC1, 24, 4), 913 DIV(0, "dout_spi1", "mout_spi1", DIV_PERIC1, 24, 4),
913 DIV(0, "dout_spi2", "mout_spi2", DIV_PERIC1, 28, 4), 914 DIV(0, "dout_spi2", "mout_spi2", DIV_PERIC1, 28, 4),
914 915
915 /* Mfc Block */
916 DIV(0, "dout_mfc_blk", "mout_user_aclk333", DIV4_RATIO, 0, 2),
917 916
918 /* PCM */ 917 /* PCM */
919 DIV(0, "dout_pcm1", "dout_audio1", DIV_PERIC2, 16, 8), 918 DIV(0, "dout_pcm1", "dout_audio1", DIV_PERIC2, 16, 8),
@@ -932,8 +931,6 @@ static const struct samsung_div_clock exynos5x_div_clks[] __initconst = {
932 DIV(0, "dout_spi2_pre", "dout_spi2", DIV_PERIC4, 24, 8), 931 DIV(0, "dout_spi2_pre", "dout_spi2", DIV_PERIC4, 24, 8),
933 932
934 /* GSCL Block */ 933 /* GSCL Block */
935 DIV(0, "dout_gscl_blk_300", "mout_user_aclk300_gscl",
936 DIV2_RATIO0, 4, 2),
937 DIV(0, "dout_gscl_blk_333", "aclk333_432_gscl", DIV2_RATIO0, 6, 2), 934 DIV(0, "dout_gscl_blk_333", "aclk333_432_gscl", DIV2_RATIO0, 6, 2),
938 935
939 /* MSCL Block */ 936 /* MSCL Block */
@@ -1190,8 +1187,6 @@ static const struct samsung_gate_clock exynos5x_gate_clks[] __initconst = {
1190 GATE(CLK_SCLK_GSCL_WB, "sclk_gscl_wb", "mout_user_aclk333_432_gscl", 1187 GATE(CLK_SCLK_GSCL_WB, "sclk_gscl_wb", "mout_user_aclk333_432_gscl",
1191 GATE_TOP_SCLK_GSCL, 7, 0, 0), 1188 GATE_TOP_SCLK_GSCL, 7, 0, 0),
1192 1189
1193 GATE(CLK_GSCL0, "gscl0", "aclk300_gscl", GATE_IP_GSCL0, 0, 0, 0),
1194 GATE(CLK_GSCL1, "gscl1", "aclk300_gscl", GATE_IP_GSCL0, 1, 0, 0),
1195 GATE(CLK_FIMC_3AA, "fimc_3aa", "aclk333_432_gscl", 1190 GATE(CLK_FIMC_3AA, "fimc_3aa", "aclk333_432_gscl",
1196 GATE_IP_GSCL0, 4, 0, 0), 1191 GATE_IP_GSCL0, 4, 0, 0),
1197 GATE(CLK_FIMC_LITE0, "fimc_lite0", "aclk333_432_gscl", 1192 GATE(CLK_FIMC_LITE0, "fimc_lite0", "aclk333_432_gscl",
@@ -1205,10 +1200,6 @@ static const struct samsung_gate_clock exynos5x_gate_clks[] __initconst = {
1205 GATE_IP_GSCL1, 3, 0, 0), 1200 GATE_IP_GSCL1, 3, 0, 0),
1206 GATE(CLK_SMMU_FIMCL1, "smmu_fimcl1", "dout_gscl_blk_333", 1201 GATE(CLK_SMMU_FIMCL1, "smmu_fimcl1", "dout_gscl_blk_333",
1207 GATE_IP_GSCL1, 4, 0, 0), 1202 GATE_IP_GSCL1, 4, 0, 0),
1208 GATE(CLK_SMMU_GSCL0, "smmu_gscl0", "dout_gscl_blk_300",
1209 GATE_IP_GSCL1, 6, 0, 0),
1210 GATE(CLK_SMMU_GSCL1, "smmu_gscl1", "dout_gscl_blk_300",
1211 GATE_IP_GSCL1, 7, 0, 0),
1212 GATE(CLK_GSCL_WA, "gscl_wa", "sclk_gscl_wa", GATE_IP_GSCL1, 12, 0, 0), 1203 GATE(CLK_GSCL_WA, "gscl_wa", "sclk_gscl_wa", GATE_IP_GSCL1, 12, 0, 0),
1213 GATE(CLK_GSCL_WB, "gscl_wb", "sclk_gscl_wb", GATE_IP_GSCL1, 13, 0, 0), 1204 GATE(CLK_GSCL_WB, "gscl_wb", "sclk_gscl_wb", GATE_IP_GSCL1, 13, 0, 0),
1214 GATE(CLK_SMMU_FIMCL3, "smmu_fimcl3,", "dout_gscl_blk_333", 1205 GATE(CLK_SMMU_FIMCL3, "smmu_fimcl3,", "dout_gscl_blk_333",
@@ -1227,18 +1218,6 @@ static const struct samsung_gate_clock exynos5x_gate_clks[] __initconst = {
1227 GATE(CLK_SMMU_MSCL2, "smmu_mscl2", "dout_mscl_blk", 1218 GATE(CLK_SMMU_MSCL2, "smmu_mscl2", "dout_mscl_blk",
1228 GATE_IP_MSCL, 10, 0, 0), 1219 GATE_IP_MSCL, 10, 0, 0),
1229 1220
1230 GATE(CLK_FIMD1, "fimd1", "aclk300_disp1", GATE_IP_DISP1, 0, 0, 0),
1231 GATE(CLK_DSIM1, "dsim1", "aclk200_disp1", GATE_IP_DISP1, 3, 0, 0),
1232 GATE(CLK_DP1, "dp1", "aclk200_disp1", GATE_IP_DISP1, 4, 0, 0),
1233 GATE(CLK_MIXER, "mixer", "aclk200_disp1", GATE_IP_DISP1, 5, 0, 0),
1234 GATE(CLK_HDMI, "hdmi", "aclk200_disp1", GATE_IP_DISP1, 6, 0, 0),
1235 GATE(CLK_SMMU_FIMD1M0, "smmu_fimd1m0", "dout_disp1_blk",
1236 GATE_IP_DISP1, 7, 0, 0),
1237 GATE(CLK_SMMU_FIMD1M1, "smmu_fimd1m1", "dout_disp1_blk",
1238 GATE_IP_DISP1, 8, 0, 0),
1239 GATE(CLK_SMMU_MIXER, "smmu_mixer", "aclk200_disp1",
1240 GATE_IP_DISP1, 9, 0, 0),
1241
1242 /* ISP */ 1221 /* ISP */
1243 GATE(CLK_SCLK_UART_ISP, "sclk_uart_isp", "dout_uart_isp", 1222 GATE(CLK_SCLK_UART_ISP, "sclk_uart_isp", "dout_uart_isp",
1244 GATE_TOP_SCLK_ISP, 0, CLK_SET_RATE_PARENT, 0), 1223 GATE_TOP_SCLK_ISP, 0, CLK_SET_RATE_PARENT, 0),
@@ -1255,48 +1234,138 @@ static const struct samsung_gate_clock exynos5x_gate_clks[] __initconst = {
1255 GATE(CLK_SCLK_ISP_SENSOR2, "sclk_isp_sensor2", "dout_isp_sensor2", 1234 GATE(CLK_SCLK_ISP_SENSOR2, "sclk_isp_sensor2", "dout_isp_sensor2",
1256 GATE_TOP_SCLK_ISP, 12, CLK_SET_RATE_PARENT, 0), 1235 GATE_TOP_SCLK_ISP, 12, CLK_SET_RATE_PARENT, 0),
1257 1236
1237 GATE(CLK_G3D, "g3d", "mout_user_aclk_g3d", GATE_IP_G3D, 9, 0, 0),
1238};
1239
1240static const struct samsung_div_clock exynos5x_disp_div_clks[] __initconst = {
1241 DIV(0, "dout_disp1_blk", "aclk200_disp1", DIV2_RATIO0, 16, 2),
1242};
1243
1244static const struct samsung_gate_clock exynos5x_disp_gate_clks[] __initconst = {
1245 GATE(CLK_FIMD1, "fimd1", "aclk300_disp1", GATE_IP_DISP1, 0, 0, 0),
1246 GATE(CLK_DSIM1, "dsim1", "aclk200_disp1", GATE_IP_DISP1, 3, 0, 0),
1247 GATE(CLK_DP1, "dp1", "aclk200_disp1", GATE_IP_DISP1, 4, 0, 0),
1248 GATE(CLK_MIXER, "mixer", "aclk200_disp1", GATE_IP_DISP1, 5, 0, 0),
1249 GATE(CLK_HDMI, "hdmi", "aclk200_disp1", GATE_IP_DISP1, 6, 0, 0),
1250 GATE(CLK_SMMU_FIMD1M0, "smmu_fimd1m0", "dout_disp1_blk",
1251 GATE_IP_DISP1, 7, 0, 0),
1252 GATE(CLK_SMMU_FIMD1M1, "smmu_fimd1m1", "dout_disp1_blk",
1253 GATE_IP_DISP1, 8, 0, 0),
1254 GATE(CLK_SMMU_MIXER, "smmu_mixer", "aclk200_disp1",
1255 GATE_IP_DISP1, 9, 0, 0),
1256};
1257
1258static struct exynos5_subcmu_reg_dump exynos5x_disp_suspend_regs[] = {
1259 { GATE_IP_DISP1, 0xffffffff, 0xffffffff }, /* DISP1 gates */
1260 { SRC_TOP5, 0, BIT(0) }, /* MUX mout_user_aclk400_disp1 */
1261 { SRC_TOP5, 0, BIT(24) }, /* MUX mout_user_aclk300_disp1 */
1262 { SRC_TOP3, 0, BIT(8) }, /* MUX mout_user_aclk200_disp1 */
1263 { DIV2_RATIO0, 0, 0x30000 }, /* DIV dout_disp1_blk */
1264};
1265
1266static const struct samsung_div_clock exynos5x_gsc_div_clks[] __initconst = {
1267 DIV(0, "dout_gscl_blk_300", "mout_user_aclk300_gscl",
1268 DIV2_RATIO0, 4, 2),
1269};
1270
1271static const struct samsung_gate_clock exynos5x_gsc_gate_clks[] __initconst = {
1272 GATE(CLK_GSCL0, "gscl0", "aclk300_gscl", GATE_IP_GSCL0, 0, 0, 0),
1273 GATE(CLK_GSCL1, "gscl1", "aclk300_gscl", GATE_IP_GSCL0, 1, 0, 0),
1274 GATE(CLK_SMMU_GSCL0, "smmu_gscl0", "dout_gscl_blk_300",
1275 GATE_IP_GSCL1, 6, 0, 0),
1276 GATE(CLK_SMMU_GSCL1, "smmu_gscl1", "dout_gscl_blk_300",
1277 GATE_IP_GSCL1, 7, 0, 0),
1278};
1279
1280static struct exynos5_subcmu_reg_dump exynos5x_gsc_suspend_regs[] = {
1281 { GATE_IP_GSCL0, 0x3, 0x3 }, /* GSC gates */
1282 { GATE_IP_GSCL1, 0xc0, 0xc0 }, /* GSC gates */
1283 { SRC_TOP5, 0, BIT(28) }, /* MUX mout_user_aclk300_gscl */
1284 { DIV2_RATIO0, 0, 0x30 }, /* DIV dout_gscl_blk_300 */
1285};
1286
1287static const struct samsung_div_clock exynos5x_mfc_div_clks[] __initconst = {
1288 DIV(0, "dout_mfc_blk", "mout_user_aclk333", DIV4_RATIO, 0, 2),
1289};
1290
1291static const struct samsung_gate_clock exynos5x_mfc_gate_clks[] __initconst = {
1258 GATE(CLK_MFC, "mfc", "aclk333", GATE_IP_MFC, 0, 0, 0), 1292 GATE(CLK_MFC, "mfc", "aclk333", GATE_IP_MFC, 0, 0, 0),
1259 GATE(CLK_SMMU_MFCL, "smmu_mfcl", "dout_mfc_blk", GATE_IP_MFC, 1, 0, 0), 1293 GATE(CLK_SMMU_MFCL, "smmu_mfcl", "dout_mfc_blk", GATE_IP_MFC, 1, 0, 0),
1260 GATE(CLK_SMMU_MFCR, "smmu_mfcr", "dout_mfc_blk", GATE_IP_MFC, 2, 0, 0), 1294 GATE(CLK_SMMU_MFCR, "smmu_mfcr", "dout_mfc_blk", GATE_IP_MFC, 2, 0, 0),
1295};
1261 1296
1262 GATE(CLK_G3D, "g3d", "mout_user_aclk_g3d", GATE_IP_G3D, 9, 0, 0), 1297static struct exynos5_subcmu_reg_dump exynos5x_mfc_suspend_regs[] = {
1298 { GATE_IP_MFC, 0xffffffff, 0xffffffff }, /* MFC gates */
1299 { SRC_TOP4, 0, BIT(28) }, /* MUX mout_user_aclk333 */
1300 { DIV4_RATIO, 0, 0x3 }, /* DIV dout_mfc_blk */
1301};
1302
1303static const struct exynos5_subcmu_info exynos5x_subcmus[] = {
1304 {
1305 .div_clks = exynos5x_disp_div_clks,
1306 .nr_div_clks = ARRAY_SIZE(exynos5x_disp_div_clks),
1307 .gate_clks = exynos5x_disp_gate_clks,
1308 .nr_gate_clks = ARRAY_SIZE(exynos5x_disp_gate_clks),
1309 .suspend_regs = exynos5x_disp_suspend_regs,
1310 .nr_suspend_regs = ARRAY_SIZE(exynos5x_disp_suspend_regs),
1311 .pd_name = "DISP",
1312 }, {
1313 .div_clks = exynos5x_gsc_div_clks,
1314 .nr_div_clks = ARRAY_SIZE(exynos5x_gsc_div_clks),
1315 .gate_clks = exynos5x_gsc_gate_clks,
1316 .nr_gate_clks = ARRAY_SIZE(exynos5x_gsc_gate_clks),
1317 .suspend_regs = exynos5x_gsc_suspend_regs,
1318 .nr_suspend_regs = ARRAY_SIZE(exynos5x_gsc_suspend_regs),
1319 .pd_name = "GSC",
1320 }, {
1321 .div_clks = exynos5x_mfc_div_clks,
1322 .nr_div_clks = ARRAY_SIZE(exynos5x_mfc_div_clks),
1323 .gate_clks = exynos5x_mfc_gate_clks,
1324 .nr_gate_clks = ARRAY_SIZE(exynos5x_mfc_gate_clks),
1325 .suspend_regs = exynos5x_mfc_suspend_regs,
1326 .nr_suspend_regs = ARRAY_SIZE(exynos5x_mfc_suspend_regs),
1327 .pd_name = "MFC",
1328 },
1263}; 1329};
1264 1330
1265static const struct samsung_pll_rate_table exynos5420_pll2550x_24mhz_tbl[] __initconst = { 1331static const struct samsung_pll_rate_table exynos5420_pll2550x_24mhz_tbl[] __initconst = {
1266 PLL_35XX_RATE(2000000000, 250, 3, 0), 1332 PLL_35XX_RATE(24 * MHZ, 2000000000, 250, 3, 0),
1267 PLL_35XX_RATE(1900000000, 475, 6, 0), 1333 PLL_35XX_RATE(24 * MHZ, 1900000000, 475, 6, 0),
1268 PLL_35XX_RATE(1800000000, 225, 3, 0), 1334 PLL_35XX_RATE(24 * MHZ, 1800000000, 225, 3, 0),
1269 PLL_35XX_RATE(1700000000, 425, 6, 0), 1335 PLL_35XX_RATE(24 * MHZ, 1700000000, 425, 6, 0),
1270 PLL_35XX_RATE(1600000000, 200, 3, 0), 1336 PLL_35XX_RATE(24 * MHZ, 1600000000, 200, 3, 0),
1271 PLL_35XX_RATE(1500000000, 250, 4, 0), 1337 PLL_35XX_RATE(24 * MHZ, 1500000000, 250, 4, 0),
1272 PLL_35XX_RATE(1400000000, 175, 3, 0), 1338 PLL_35XX_RATE(24 * MHZ, 1400000000, 175, 3, 0),
1273 PLL_35XX_RATE(1300000000, 325, 6, 0), 1339 PLL_35XX_RATE(24 * MHZ, 1300000000, 325, 6, 0),
1274 PLL_35XX_RATE(1200000000, 200, 2, 1), 1340 PLL_35XX_RATE(24 * MHZ, 1200000000, 200, 2, 1),
1275 PLL_35XX_RATE(1100000000, 275, 3, 1), 1341 PLL_35XX_RATE(24 * MHZ, 1100000000, 275, 3, 1),
1276 PLL_35XX_RATE(1000000000, 250, 3, 1), 1342 PLL_35XX_RATE(24 * MHZ, 1000000000, 250, 3, 1),
1277 PLL_35XX_RATE(900000000, 150, 2, 1), 1343 PLL_35XX_RATE(24 * MHZ, 900000000, 150, 2, 1),
1278 PLL_35XX_RATE(800000000, 200, 3, 1), 1344 PLL_35XX_RATE(24 * MHZ, 800000000, 200, 3, 1),
1279 PLL_35XX_RATE(700000000, 175, 3, 1), 1345 PLL_35XX_RATE(24 * MHZ, 700000000, 175, 3, 1),
1280 PLL_35XX_RATE(600000000, 200, 2, 2), 1346 PLL_35XX_RATE(24 * MHZ, 600000000, 200, 2, 2),
1281 PLL_35XX_RATE(500000000, 250, 3, 2), 1347 PLL_35XX_RATE(24 * MHZ, 500000000, 250, 3, 2),
1282 PLL_35XX_RATE(400000000, 200, 3, 2), 1348 PLL_35XX_RATE(24 * MHZ, 400000000, 200, 3, 2),
1283 PLL_35XX_RATE(300000000, 200, 2, 3), 1349 PLL_35XX_RATE(24 * MHZ, 300000000, 200, 2, 3),
1284 PLL_35XX_RATE(200000000, 200, 3, 3), 1350 PLL_35XX_RATE(24 * MHZ, 200000000, 200, 3, 3),
1285}; 1351};
1286 1352
1287static const struct samsung_pll_rate_table exynos5420_epll_24mhz_tbl[] = { 1353static const struct samsung_pll_rate_table exynos5420_epll_24mhz_tbl[] = {
1288 PLL_36XX_RATE(600000000U, 100, 2, 1, 0), 1354 PLL_36XX_RATE(24 * MHZ, 600000000U, 100, 2, 1, 0),
1289 PLL_36XX_RATE(400000000U, 200, 3, 2, 0), 1355 PLL_36XX_RATE(24 * MHZ, 400000000U, 200, 3, 2, 0),
1290 PLL_36XX_RATE(393216003U, 197, 3, 2, -25690), 1356 PLL_36XX_RATE(24 * MHZ, 393216003U, 197, 3, 2, -25690),
1291 PLL_36XX_RATE(361267218U, 301, 5, 2, 3671), 1357 PLL_36XX_RATE(24 * MHZ, 361267218U, 301, 5, 2, 3671),
1292 PLL_36XX_RATE(200000000U, 200, 3, 3, 0), 1358 PLL_36XX_RATE(24 * MHZ, 200000000U, 200, 3, 3, 0),
1293 PLL_36XX_RATE(196608001U, 197, 3, 3, -25690), 1359 PLL_36XX_RATE(24 * MHZ, 196608001U, 197, 3, 3, -25690),
1294 PLL_36XX_RATE(180633609U, 301, 5, 3, 3671), 1360 PLL_36XX_RATE(24 * MHZ, 180633609U, 301, 5, 3, 3671),
1295 PLL_36XX_RATE(131072006U, 131, 3, 3, 4719), 1361 PLL_36XX_RATE(24 * MHZ, 131072006U, 131, 3, 3, 4719),
1296 PLL_36XX_RATE(100000000U, 200, 3, 4, 0), 1362 PLL_36XX_RATE(24 * MHZ, 100000000U, 200, 3, 4, 0),
1297 PLL_36XX_RATE( 65536003U, 131, 3, 4, 4719), 1363 PLL_36XX_RATE(24 * MHZ, 73728000U, 98, 2, 4, 19923),
1298 PLL_36XX_RATE( 49152000U, 197, 3, 5, -25690), 1364 PLL_36XX_RATE(24 * MHZ, 67737602U, 90, 2, 4, 20762),
1299 PLL_36XX_RATE( 32768001U, 131, 3, 5, 4719), 1365 PLL_36XX_RATE(24 * MHZ, 65536003U, 131, 3, 4, 4719),
1366 PLL_36XX_RATE(24 * MHZ, 49152000U, 197, 3, 5, -25690),
1367 PLL_36XX_RATE(24 * MHZ, 45158401U, 90, 3, 4, 20762),
1368 PLL_36XX_RATE(24 * MHZ, 32768001U, 131, 3, 5, 4719),
1300}; 1369};
1301 1370
1302static struct samsung_pll_clock exynos5x_plls[nr_plls] __initdata = { 1371static struct samsung_pll_clock exynos5x_plls[nr_plls] __initdata = {
@@ -1472,6 +1541,8 @@ static void __init exynos5x_clk_init(struct device_node *np,
1472 exynos5420_kfcclk_d, ARRAY_SIZE(exynos5420_kfcclk_d), 0); 1541 exynos5420_kfcclk_d, ARRAY_SIZE(exynos5420_kfcclk_d), 0);
1473 1542
1474 exynos5420_clk_sleep_init(); 1543 exynos5420_clk_sleep_init();
1544 exynos5_subcmus_init(ctx, ARRAY_SIZE(exynos5x_subcmus),
1545 exynos5x_subcmus);
1475 1546
1476 samsung_clk_of_add_provider(np, ctx); 1547 samsung_clk_of_add_provider(np, ctx);
1477} 1548}
@@ -1480,10 +1551,12 @@ static void __init exynos5420_clk_init(struct device_node *np)
1480{ 1551{
1481 exynos5x_clk_init(np, EXYNOS5420); 1552 exynos5x_clk_init(np, EXYNOS5420);
1482} 1553}
1483CLK_OF_DECLARE(exynos5420_clk, "samsung,exynos5420-clock", exynos5420_clk_init); 1554CLK_OF_DECLARE_DRIVER(exynos5420_clk, "samsung,exynos5420-clock",
1555 exynos5420_clk_init);
1484 1556
1485static void __init exynos5800_clk_init(struct device_node *np) 1557static void __init exynos5800_clk_init(struct device_node *np)
1486{ 1558{
1487 exynos5x_clk_init(np, EXYNOS5800); 1559 exynos5x_clk_init(np, EXYNOS5800);
1488} 1560}
1489CLK_OF_DECLARE(exynos5800_clk, "samsung,exynos5800-clock", exynos5800_clk_init); 1561CLK_OF_DECLARE_DRIVER(exynos5800_clk, "samsung,exynos5800-clock",
1562 exynos5800_clk_init);
diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c
index db270908037a..5305ace514b2 100644
--- a/drivers/clk/samsung/clk-exynos5433.c
+++ b/drivers/clk/samsung/clk-exynos5433.c
@@ -703,68 +703,69 @@ static const struct samsung_gate_clock top_gate_clks[] __initconst = {
703 * & MPHY_PLL & G3D_PLL & DISP_PLL & ISP_PLL 703 * & MPHY_PLL & G3D_PLL & DISP_PLL & ISP_PLL
704 */ 704 */
705static const struct samsung_pll_rate_table exynos5433_pll_rates[] __initconst = { 705static const struct samsung_pll_rate_table exynos5433_pll_rates[] __initconst = {
706 PLL_35XX_RATE(2500000000U, 625, 6, 0), 706 PLL_35XX_RATE(24 * MHZ, 2500000000U, 625, 6, 0),
707 PLL_35XX_RATE(2400000000U, 500, 5, 0), 707 PLL_35XX_RATE(24 * MHZ, 2400000000U, 500, 5, 0),
708 PLL_35XX_RATE(2300000000U, 575, 6, 0), 708 PLL_35XX_RATE(24 * MHZ, 2300000000U, 575, 6, 0),
709 PLL_35XX_RATE(2200000000U, 550, 6, 0), 709 PLL_35XX_RATE(24 * MHZ, 2200000000U, 550, 6, 0),
710 PLL_35XX_RATE(2100000000U, 350, 4, 0), 710 PLL_35XX_RATE(24 * MHZ, 2100000000U, 350, 4, 0),
711 PLL_35XX_RATE(2000000000U, 500, 6, 0), 711 PLL_35XX_RATE(24 * MHZ, 2000000000U, 500, 6, 0),
712 PLL_35XX_RATE(1900000000U, 475, 6, 0), 712 PLL_35XX_RATE(24 * MHZ, 1900000000U, 475, 6, 0),
713 PLL_35XX_RATE(1800000000U, 375, 5, 0), 713 PLL_35XX_RATE(24 * MHZ, 1800000000U, 375, 5, 0),
714 PLL_35XX_RATE(1700000000U, 425, 6, 0), 714 PLL_35XX_RATE(24 * MHZ, 1700000000U, 425, 6, 0),
715 PLL_35XX_RATE(1600000000U, 400, 6, 0), 715 PLL_35XX_RATE(24 * MHZ, 1600000000U, 400, 6, 0),
716 PLL_35XX_RATE(1500000000U, 250, 4, 0), 716 PLL_35XX_RATE(24 * MHZ, 1500000000U, 250, 4, 0),
717 PLL_35XX_RATE(1400000000U, 350, 6, 0), 717 PLL_35XX_RATE(24 * MHZ, 1400000000U, 350, 6, 0),
718 PLL_35XX_RATE(1332000000U, 222, 4, 0), 718 PLL_35XX_RATE(24 * MHZ, 1332000000U, 222, 4, 0),
719 PLL_35XX_RATE(1300000000U, 325, 6, 0), 719 PLL_35XX_RATE(24 * MHZ, 1300000000U, 325, 6, 0),
720 PLL_35XX_RATE(1200000000U, 500, 5, 1), 720 PLL_35XX_RATE(24 * MHZ, 1200000000U, 500, 5, 1),
721 PLL_35XX_RATE(1100000000U, 550, 6, 1), 721 PLL_35XX_RATE(24 * MHZ, 1100000000U, 550, 6, 1),
722 PLL_35XX_RATE(1086000000U, 362, 4, 1), 722 PLL_35XX_RATE(24 * MHZ, 1086000000U, 362, 4, 1),
723 PLL_35XX_RATE(1066000000U, 533, 6, 1), 723 PLL_35XX_RATE(24 * MHZ, 1066000000U, 533, 6, 1),
724 PLL_35XX_RATE(1000000000U, 500, 6, 1), 724 PLL_35XX_RATE(24 * MHZ, 1000000000U, 500, 6, 1),
725 PLL_35XX_RATE(933000000U, 311, 4, 1), 725 PLL_35XX_RATE(24 * MHZ, 933000000U, 311, 4, 1),
726 PLL_35XX_RATE(921000000U, 307, 4, 1), 726 PLL_35XX_RATE(24 * MHZ, 921000000U, 307, 4, 1),
727 PLL_35XX_RATE(900000000U, 375, 5, 1), 727 PLL_35XX_RATE(24 * MHZ, 900000000U, 375, 5, 1),
728 PLL_35XX_RATE(825000000U, 275, 4, 1), 728 PLL_35XX_RATE(24 * MHZ, 825000000U, 275, 4, 1),
729 PLL_35XX_RATE(800000000U, 400, 6, 1), 729 PLL_35XX_RATE(24 * MHZ, 800000000U, 400, 6, 1),
730 PLL_35XX_RATE(733000000U, 733, 12, 1), 730 PLL_35XX_RATE(24 * MHZ, 733000000U, 733, 12, 1),
731 PLL_35XX_RATE(700000000U, 175, 3, 1), 731 PLL_35XX_RATE(24 * MHZ, 700000000U, 175, 3, 1),
732 PLL_35XX_RATE(667000000U, 222, 4, 1), 732 PLL_35XX_RATE(24 * MHZ, 666000000U, 222, 4, 1),
733 PLL_35XX_RATE(633000000U, 211, 4, 1), 733 PLL_35XX_RATE(24 * MHZ, 633000000U, 211, 4, 1),
734 PLL_35XX_RATE(600000000U, 500, 5, 2), 734 PLL_35XX_RATE(24 * MHZ, 600000000U, 500, 5, 2),
735 PLL_35XX_RATE(552000000U, 460, 5, 2), 735 PLL_35XX_RATE(24 * MHZ, 552000000U, 460, 5, 2),
736 PLL_35XX_RATE(550000000U, 550, 6, 2), 736 PLL_35XX_RATE(24 * MHZ, 550000000U, 550, 6, 2),
737 PLL_35XX_RATE(543000000U, 362, 4, 2), 737 PLL_35XX_RATE(24 * MHZ, 543000000U, 362, 4, 2),
738 PLL_35XX_RATE(533000000U, 533, 6, 2), 738 PLL_35XX_RATE(24 * MHZ, 533000000U, 533, 6, 2),
739 PLL_35XX_RATE(500000000U, 500, 6, 2), 739 PLL_35XX_RATE(24 * MHZ, 500000000U, 500, 6, 2),
740 PLL_35XX_RATE(444000000U, 370, 5, 2), 740 PLL_35XX_RATE(24 * MHZ, 444000000U, 370, 5, 2),
741 PLL_35XX_RATE(420000000U, 350, 5, 2), 741 PLL_35XX_RATE(24 * MHZ, 420000000U, 350, 5, 2),
742 PLL_35XX_RATE(400000000U, 400, 6, 2), 742 PLL_35XX_RATE(24 * MHZ, 400000000U, 400, 6, 2),
743 PLL_35XX_RATE(350000000U, 350, 6, 2), 743 PLL_35XX_RATE(24 * MHZ, 350000000U, 350, 6, 2),
744 PLL_35XX_RATE(333000000U, 222, 4, 2), 744 PLL_35XX_RATE(24 * MHZ, 333000000U, 222, 4, 2),
745 PLL_35XX_RATE(300000000U, 500, 5, 3), 745 PLL_35XX_RATE(24 * MHZ, 300000000U, 500, 5, 3),
746 PLL_35XX_RATE(278000000U, 556, 6, 3), 746 PLL_35XX_RATE(24 * MHZ, 278000000U, 556, 6, 3),
747 PLL_35XX_RATE(266000000U, 532, 6, 3), 747 PLL_35XX_RATE(24 * MHZ, 266000000U, 532, 6, 3),
748 PLL_35XX_RATE(250000000U, 500, 6, 3), 748 PLL_35XX_RATE(24 * MHZ, 250000000U, 500, 6, 3),
749 PLL_35XX_RATE(200000000U, 400, 6, 3), 749 PLL_35XX_RATE(24 * MHZ, 200000000U, 400, 6, 3),
750 PLL_35XX_RATE(166000000U, 332, 6, 3), 750 PLL_35XX_RATE(24 * MHZ, 166000000U, 332, 6, 3),
751 PLL_35XX_RATE(160000000U, 320, 6, 3), 751 PLL_35XX_RATE(24 * MHZ, 160000000U, 320, 6, 3),
752 PLL_35XX_RATE(133000000U, 532, 6, 4), 752 PLL_35XX_RATE(24 * MHZ, 133000000U, 532, 6, 4),
753 PLL_35XX_RATE(100000000U, 400, 6, 4), 753 PLL_35XX_RATE(24 * MHZ, 100000000U, 400, 6, 4),
754 { /* sentinel */ } 754 { /* sentinel */ }
755}; 755};
756 756
757/* AUD_PLL */ 757/* AUD_PLL */
758static const struct samsung_pll_rate_table exynos5433_aud_pll_rates[] __initconst = { 758static const struct samsung_pll_rate_table exynos5433_aud_pll_rates[] __initconst = {
759 PLL_36XX_RATE(400000000U, 200, 3, 2, 0), 759 PLL_36XX_RATE(24 * MHZ, 400000000U, 200, 3, 2, 0),
760 PLL_36XX_RATE(393216000U, 197, 3, 2, -25690), 760 PLL_36XX_RATE(24 * MHZ, 393216003U, 197, 3, 2, -25690),
761 PLL_36XX_RATE(384000000U, 128, 2, 2, 0), 761 PLL_36XX_RATE(24 * MHZ, 384000000U, 128, 2, 2, 0),
762 PLL_36XX_RATE(368640000U, 246, 4, 2, -15729), 762 PLL_36XX_RATE(24 * MHZ, 368639991U, 246, 4, 2, -15729),
763 PLL_36XX_RATE(361507200U, 181, 3, 2, -16148), 763 PLL_36XX_RATE(24 * MHZ, 361507202U, 181, 3, 2, -16148),
764 PLL_36XX_RATE(338688000U, 113, 2, 2, -6816), 764 PLL_36XX_RATE(24 * MHZ, 338687988U, 113, 2, 2, -6816),
765 PLL_36XX_RATE(294912000U, 98, 1, 3, 19923), 765 PLL_36XX_RATE(24 * MHZ, 294912002U, 98, 1, 3, 19923),
766 PLL_36XX_RATE(288000000U, 96, 1, 3, 0), 766 PLL_36XX_RATE(24 * MHZ, 288000000U, 96, 1, 3, 0),
767 PLL_36XX_RATE(252000000U, 84, 1, 3, 0), 767 PLL_36XX_RATE(24 * MHZ, 252000000U, 84, 1, 3, 0),
768 PLL_36XX_RATE(24 * MHZ, 196608001U, 197, 3, 3, -25690),
768 { /* sentinel */ } 769 { /* sentinel */ }
769}; 770};
770 771
@@ -1672,7 +1673,7 @@ static const struct samsung_gate_clock peric_gate_clks[] __initconst = {
1672 ENABLE_SCLK_PERIC, 11, CLK_SET_RATE_PARENT, 0), 1673 ENABLE_SCLK_PERIC, 11, CLK_SET_RATE_PARENT, 0),
1673 GATE(CLK_SCLK_IOCLK_I2S1_BCLK, "sclk_ioclk_i2s1_bclk", 1674 GATE(CLK_SCLK_IOCLK_I2S1_BCLK, "sclk_ioclk_i2s1_bclk",
1674 "ioclk_i2s1_bclk_in", ENABLE_SCLK_PERIC, 10, 1675 "ioclk_i2s1_bclk_in", ENABLE_SCLK_PERIC, 10,
1675 CLK_SET_RATE_PARENT, 0), 1676 CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0),
1676 GATE(CLK_SCLK_SPDIF, "sclk_spdif", "sclk_spdif_peric", 1677 GATE(CLK_SCLK_SPDIF, "sclk_spdif", "sclk_spdif_peric",
1677 ENABLE_SCLK_PERIC, 8, CLK_SET_RATE_PARENT, 0), 1678 ENABLE_SCLK_PERIC, 8, CLK_SET_RATE_PARENT, 0),
1678 GATE(CLK_SCLK_PCM1, "sclk_pcm1", "sclk_pcm1_peric", 1679 GATE(CLK_SCLK_PCM1, "sclk_pcm1", "sclk_pcm1_peric",
@@ -5513,10 +5514,8 @@ static int __init exynos5433_cmu_probe(struct platform_device *pdev)
5513 5514
5514 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 5515 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
5515 reg_base = devm_ioremap_resource(dev, res); 5516 reg_base = devm_ioremap_resource(dev, res);
5516 if (IS_ERR(reg_base)) { 5517 if (IS_ERR(reg_base))
5517 dev_err(dev, "failed to map registers\n");
5518 return PTR_ERR(reg_base); 5518 return PTR_ERR(reg_base);
5519 }
5520 5519
5521 for (i = 0; i < info->nr_clk_ids; ++i) 5520 for (i = 0; i < info->nr_clk_ids; ++i)
5522 ctx->clk_data.hws[i] = ERR_PTR(-ENOENT); 5521 ctx->clk_data.hws[i] = ERR_PTR(-ENOENT);
diff --git a/drivers/clk/samsung/clk-exynos7.c b/drivers/clk/samsung/clk-exynos7.c
index 5931a4140c3d..492d51691080 100644
--- a/drivers/clk/samsung/clk-exynos7.c
+++ b/drivers/clk/samsung/clk-exynos7.c
@@ -140,7 +140,7 @@ static const struct samsung_div_clock topc_div_clks[] __initconst = {
140}; 140};
141 141
142static const struct samsung_pll_rate_table pll1460x_24mhz_tbl[] __initconst = { 142static const struct samsung_pll_rate_table pll1460x_24mhz_tbl[] __initconst = {
143 PLL_36XX_RATE(491520000, 20, 1, 0, 31457), 143 PLL_36XX_RATE(24 * MHZ, 491519897, 20, 1, 0, 31457),
144 {}, 144 {},
145}; 145};
146 146
diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h
index 61eb8abbfd9c..ca57b3dfa814 100644
--- a/drivers/clk/samsung/clk-pll.h
+++ b/drivers/clk/samsung/clk-pll.h
@@ -41,35 +41,62 @@ enum samsung_pll_type {
41 pll_1460x, 41 pll_1460x,
42}; 42};
43 43
44#define PLL_35XX_RATE(_rate, _m, _p, _s) \ 44#define PLL_RATE(_fin, _m, _p, _s, _k, _ks) \
45 ((u64)(_fin) * (BIT(_ks) * (_m) + (_k)) / BIT(_ks) / ((_p) << (_s)))
46#define PLL_VALID_RATE(_fin, _fout, _m, _p, _s, _k, _ks) ((_fout) + \
47 BUILD_BUG_ON_ZERO(PLL_RATE(_fin, _m, _p, _s, _k, _ks) != (_fout)))
48
49#define PLL_35XX_RATE(_fin, _rate, _m, _p, _s) \
50 { \
51 .rate = PLL_VALID_RATE(_fin, _rate, \
52 _m, _p, _s, 0, 16), \
53 .mdiv = (_m), \
54 .pdiv = (_p), \
55 .sdiv = (_s), \
56 }
57
58#define PLL_S3C2410_MPLL_RATE(_fin, _rate, _m, _p, _s) \
59 { \
60 .rate = PLL_VALID_RATE(_fin, _rate, \
61 _m + 8, _p + 2, _s, 0, 16), \
62 .mdiv = (_m), \
63 .pdiv = (_p), \
64 .sdiv = (_s), \
65 }
66
67#define PLL_S3C2440_MPLL_RATE(_fin, _rate, _m, _p, _s) \
45 { \ 68 { \
46 .rate = (_rate), \ 69 .rate = PLL_VALID_RATE(_fin, _rate, \
70 2 * (_m + 8), _p + 2, _s, 0, 16), \
47 .mdiv = (_m), \ 71 .mdiv = (_m), \
48 .pdiv = (_p), \ 72 .pdiv = (_p), \
49 .sdiv = (_s), \ 73 .sdiv = (_s), \
50 } 74 }
51 75
52#define PLL_36XX_RATE(_rate, _m, _p, _s, _k) \ 76#define PLL_36XX_RATE(_fin, _rate, _m, _p, _s, _k) \
53 { \ 77 { \
54 .rate = (_rate), \ 78 .rate = PLL_VALID_RATE(_fin, _rate, \
79 _m, _p, _s, _k, 16), \
55 .mdiv = (_m), \ 80 .mdiv = (_m), \
56 .pdiv = (_p), \ 81 .pdiv = (_p), \
57 .sdiv = (_s), \ 82 .sdiv = (_s), \
58 .kdiv = (_k), \ 83 .kdiv = (_k), \
59 } 84 }
60 85
61#define PLL_45XX_RATE(_rate, _m, _p, _s, _afc) \ 86#define PLL_4508_RATE(_fin, _rate, _m, _p, _s, _afc) \
62 { \ 87 { \
63 .rate = (_rate), \ 88 .rate = PLL_VALID_RATE(_fin, _rate, \
89 _m, _p, _s - 1, 0, 16), \
64 .mdiv = (_m), \ 90 .mdiv = (_m), \
65 .pdiv = (_p), \ 91 .pdiv = (_p), \
66 .sdiv = (_s), \ 92 .sdiv = (_s), \
67 .afc = (_afc), \ 93 .afc = (_afc), \
68 } 94 }
69 95
70#define PLL_4600_RATE(_rate, _m, _p, _s, _k, _vsel) \ 96#define PLL_4600_RATE(_fin, _rate, _m, _p, _s, _k, _vsel) \
71 { \ 97 { \
72 .rate = (_rate), \ 98 .rate = PLL_VALID_RATE(_fin, _rate, \
99 _m, _p, _s, _k, 16), \
73 .mdiv = (_m), \ 100 .mdiv = (_m), \
74 .pdiv = (_p), \ 101 .pdiv = (_p), \
75 .sdiv = (_s), \ 102 .sdiv = (_s), \
@@ -77,9 +104,10 @@ enum samsung_pll_type {
77 .vsel = (_vsel), \ 104 .vsel = (_vsel), \
78 } 105 }
79 106
80#define PLL_4650_RATE(_rate, _m, _p, _s, _k, _mfr, _mrr, _vsel) \ 107#define PLL_4650_RATE(_fin, _rate, _m, _p, _s, _k, _mfr, _mrr, _vsel) \
81 { \ 108 { \
82 .rate = (_rate), \ 109 .rate = PLL_VALID_RATE(_fin, _rate, \
110 _m, _p, _s, _k, 10), \
83 .mdiv = (_m), \ 111 .mdiv = (_m), \
84 .pdiv = (_p), \ 112 .pdiv = (_p), \
85 .sdiv = (_s), \ 113 .sdiv = (_s), \
diff --git a/drivers/clk/samsung/clk-s3c2410.c b/drivers/clk/samsung/clk-s3c2410.c
index e0650c33863b..a9c887475054 100644
--- a/drivers/clk/samsung/clk-s3c2410.c
+++ b/drivers/clk/samsung/clk-s3c2410.c
@@ -95,7 +95,7 @@ static void __init s3c2410_clk_sleep_init(void) {}
95 95
96PNAME(fclk_p) = { "mpll", "div_slow" }; 96PNAME(fclk_p) = { "mpll", "div_slow" };
97 97
98struct samsung_mux_clock s3c2410_common_muxes[] __initdata = { 98static struct samsung_mux_clock s3c2410_common_muxes[] __initdata = {
99 MUX(FCLK, "fclk", fclk_p, CLKSLOW, 4, 1), 99 MUX(FCLK, "fclk", fclk_p, CLKSLOW, 4, 1),
100}; 100};
101 101
@@ -111,12 +111,12 @@ static struct clk_div_table divslow_d[] = {
111 { /* sentinel */ }, 111 { /* sentinel */ },
112}; 112};
113 113
114struct samsung_div_clock s3c2410_common_dividers[] __initdata = { 114static struct samsung_div_clock s3c2410_common_dividers[] __initdata = {
115 DIV_T(0, "div_slow", "xti", CLKSLOW, 0, 3, divslow_d), 115 DIV_T(0, "div_slow", "xti", CLKSLOW, 0, 3, divslow_d),
116 DIV(PCLK, "pclk", "hclk", CLKDIVN, 0, 1), 116 DIV(PCLK, "pclk", "hclk", CLKDIVN, 0, 1),
117}; 117};
118 118
119struct samsung_gate_clock s3c2410_common_gates[] __initdata = { 119static struct samsung_gate_clock s3c2410_common_gates[] __initdata = {
120 GATE(PCLK_SPI, "spi", "pclk", CLKCON, 18, 0, 0), 120 GATE(PCLK_SPI, "spi", "pclk", CLKCON, 18, 0, 0),
121 GATE(PCLK_I2S, "i2s", "pclk", CLKCON, 17, 0, 0), 121 GATE(PCLK_I2S, "i2s", "pclk", CLKCON, 17, 0, 0),
122 GATE(PCLK_I2C, "i2c", "pclk", CLKCON, 16, 0, 0), 122 GATE(PCLK_I2C, "i2c", "pclk", CLKCON, 16, 0, 0),
@@ -135,7 +135,7 @@ struct samsung_gate_clock s3c2410_common_gates[] __initdata = {
135}; 135};
136 136
137/* should be added _after_ the soc-specific clocks are created */ 137/* should be added _after_ the soc-specific clocks are created */
138struct samsung_clock_alias s3c2410_common_aliases[] __initdata = { 138static struct samsung_clock_alias s3c2410_common_aliases[] __initdata = {
139 ALIAS(PCLK_I2C, "s3c2410-i2c.0", "i2c"), 139 ALIAS(PCLK_I2C, "s3c2410-i2c.0", "i2c"),
140 ALIAS(PCLK_ADC, NULL, "adc"), 140 ALIAS(PCLK_ADC, NULL, "adc"),
141 ALIAS(PCLK_RTC, NULL, "rtc"), 141 ALIAS(PCLK_RTC, NULL, "rtc"),
@@ -162,34 +162,34 @@ struct samsung_clock_alias s3c2410_common_aliases[] __initdata = {
162static struct samsung_pll_rate_table pll_s3c2410_12mhz_tbl[] __initdata = { 162static struct samsung_pll_rate_table pll_s3c2410_12mhz_tbl[] __initdata = {
163 /* sorted in descending order */ 163 /* sorted in descending order */
164 /* 2410A extras */ 164 /* 2410A extras */
165 PLL_35XX_RATE(270000000, 127, 1, 1), 165 PLL_S3C2410_MPLL_RATE(12 * MHZ, 270000000, 127, 1, 1),
166 PLL_35XX_RATE(268000000, 126, 1, 1), 166 PLL_S3C2410_MPLL_RATE(12 * MHZ, 268000000, 126, 1, 1),
167 PLL_35XX_RATE(266000000, 125, 1, 1), 167 PLL_S3C2410_MPLL_RATE(12 * MHZ, 266000000, 125, 1, 1),
168 PLL_35XX_RATE(226000000, 105, 1, 1), 168 PLL_S3C2410_MPLL_RATE(12 * MHZ, 226000000, 105, 1, 1),
169 PLL_35XX_RATE(210000000, 132, 2, 1), 169 PLL_S3C2410_MPLL_RATE(12 * MHZ, 210000000, 132, 2, 1),
170 /* 2410 common */ 170 /* 2410 common */
171 PLL_35XX_RATE(203000000, 161, 3, 1), 171 PLL_S3C2410_MPLL_RATE(12 * MHZ, 202800000, 161, 3, 1),
172 PLL_35XX_RATE(192000000, 88, 1, 1), 172 PLL_S3C2410_MPLL_RATE(12 * MHZ, 192000000, 88, 1, 1),
173 PLL_35XX_RATE(186000000, 85, 1, 1), 173 PLL_S3C2410_MPLL_RATE(12 * MHZ, 186000000, 85, 1, 1),
174 PLL_35XX_RATE(180000000, 82, 1, 1), 174 PLL_S3C2410_MPLL_RATE(12 * MHZ, 180000000, 82, 1, 1),
175 PLL_35XX_RATE(170000000, 77, 1, 1), 175 PLL_S3C2410_MPLL_RATE(12 * MHZ, 170000000, 77, 1, 1),
176 PLL_35XX_RATE(158000000, 71, 1, 1), 176 PLL_S3C2410_MPLL_RATE(12 * MHZ, 158000000, 71, 1, 1),
177 PLL_35XX_RATE(152000000, 68, 1, 1), 177 PLL_S3C2410_MPLL_RATE(12 * MHZ, 152000000, 68, 1, 1),
178 PLL_35XX_RATE(147000000, 90, 2, 1), 178 PLL_S3C2410_MPLL_RATE(12 * MHZ, 147000000, 90, 2, 1),
179 PLL_35XX_RATE(135000000, 82, 2, 1), 179 PLL_S3C2410_MPLL_RATE(12 * MHZ, 135000000, 82, 2, 1),
180 PLL_35XX_RATE(124000000, 116, 1, 2), 180 PLL_S3C2410_MPLL_RATE(12 * MHZ, 124000000, 116, 1, 2),
181 PLL_35XX_RATE(118000000, 150, 2, 2), 181 PLL_S3C2410_MPLL_RATE(12 * MHZ, 118500000, 150, 2, 2),
182 PLL_35XX_RATE(113000000, 105, 1, 2), 182 PLL_S3C2410_MPLL_RATE(12 * MHZ, 113000000, 105, 1, 2),
183 PLL_35XX_RATE(101000000, 127, 2, 2), 183 PLL_S3C2410_MPLL_RATE(12 * MHZ, 101250000, 127, 2, 2),
184 PLL_35XX_RATE(90000000, 112, 2, 2), 184 PLL_S3C2410_MPLL_RATE(12 * MHZ, 90000000, 112, 2, 2),
185 PLL_35XX_RATE(85000000, 105, 2, 2), 185 PLL_S3C2410_MPLL_RATE(12 * MHZ, 84750000, 105, 2, 2),
186 PLL_35XX_RATE(79000000, 71, 1, 2), 186 PLL_S3C2410_MPLL_RATE(12 * MHZ, 79000000, 71, 1, 2),
187 PLL_35XX_RATE(68000000, 82, 2, 2), 187 PLL_S3C2410_MPLL_RATE(12 * MHZ, 67500000, 82, 2, 2),
188 PLL_35XX_RATE(56000000, 142, 2, 3), 188 PLL_S3C2410_MPLL_RATE(12 * MHZ, 56250000, 142, 2, 3),
189 PLL_35XX_RATE(48000000, 120, 2, 3), 189 PLL_S3C2410_MPLL_RATE(12 * MHZ, 48000000, 120, 2, 3),
190 PLL_35XX_RATE(51000000, 161, 3, 3), 190 PLL_S3C2410_MPLL_RATE(12 * MHZ, 50700000, 161, 3, 3),
191 PLL_35XX_RATE(45000000, 82, 1, 3), 191 PLL_S3C2410_MPLL_RATE(12 * MHZ, 45000000, 82, 1, 3),
192 PLL_35XX_RATE(34000000, 82, 2, 3), 192 PLL_S3C2410_MPLL_RATE(12 * MHZ, 33750000, 82, 2, 3),
193 { /* sentinel */ }, 193 { /* sentinel */ },
194}; 194};
195 195
@@ -200,11 +200,11 @@ static struct samsung_pll_clock s3c2410_plls[] __initdata = {
200 LOCKTIME, UPLLCON, NULL), 200 LOCKTIME, UPLLCON, NULL),
201}; 201};
202 202
203struct samsung_div_clock s3c2410_dividers[] __initdata = { 203static struct samsung_div_clock s3c2410_dividers[] __initdata = {
204 DIV(HCLK, "hclk", "mpll", CLKDIVN, 1, 1), 204 DIV(HCLK, "hclk", "mpll", CLKDIVN, 1, 1),
205}; 205};
206 206
207struct samsung_fixed_factor_clock s3c2410_ffactor[] __initdata = { 207static struct samsung_fixed_factor_clock s3c2410_ffactor[] __initdata = {
208 /* 208 /*
209 * armclk is directly supplied by the fclk, without 209 * armclk is directly supplied by the fclk, without
210 * switching possibility like on the s3c244x below. 210 * switching possibility like on the s3c244x below.
@@ -215,7 +215,7 @@ struct samsung_fixed_factor_clock s3c2410_ffactor[] __initdata = {
215 FFACTOR(UCLK, "uclk", "upll", 1, 1, 0), 215 FFACTOR(UCLK, "uclk", "upll", 1, 1, 0),
216}; 216};
217 217
218struct samsung_clock_alias s3c2410_aliases[] __initdata = { 218static struct samsung_clock_alias s3c2410_aliases[] __initdata = {
219 ALIAS(PCLK_UART0, "s3c2410-uart.0", "uart"), 219 ALIAS(PCLK_UART0, "s3c2410-uart.0", "uart"),
220 ALIAS(PCLK_UART1, "s3c2410-uart.1", "uart"), 220 ALIAS(PCLK_UART1, "s3c2410-uart.1", "uart"),
221 ALIAS(PCLK_UART2, "s3c2410-uart.2", "uart"), 221 ALIAS(PCLK_UART2, "s3c2410-uart.2", "uart"),
@@ -229,33 +229,33 @@ struct samsung_clock_alias s3c2410_aliases[] __initdata = {
229 229
230static struct samsung_pll_rate_table pll_s3c244x_12mhz_tbl[] __initdata = { 230static struct samsung_pll_rate_table pll_s3c244x_12mhz_tbl[] __initdata = {
231 /* sorted in descending order */ 231 /* sorted in descending order */
232 PLL_35XX_RATE(400000000, 0x5c, 1, 1), 232 PLL_S3C2440_MPLL_RATE(12 * MHZ, 400000000, 0x5c, 1, 1),
233 PLL_35XX_RATE(390000000, 0x7a, 2, 1), 233 PLL_S3C2440_MPLL_RATE(12 * MHZ, 390000000, 0x7a, 2, 1),
234 PLL_35XX_RATE(380000000, 0x57, 1, 1), 234 PLL_S3C2440_MPLL_RATE(12 * MHZ, 380000000, 0x57, 1, 1),
235 PLL_35XX_RATE(370000000, 0xb1, 4, 1), 235 PLL_S3C2440_MPLL_RATE(12 * MHZ, 370000000, 0xb1, 4, 1),
236 PLL_35XX_RATE(360000000, 0x70, 2, 1), 236 PLL_S3C2440_MPLL_RATE(12 * MHZ, 360000000, 0x70, 2, 1),
237 PLL_35XX_RATE(350000000, 0xa7, 4, 1), 237 PLL_S3C2440_MPLL_RATE(12 * MHZ, 350000000, 0xa7, 4, 1),
238 PLL_35XX_RATE(340000000, 0x4d, 1, 1), 238 PLL_S3C2440_MPLL_RATE(12 * MHZ, 340000000, 0x4d, 1, 1),
239 PLL_35XX_RATE(330000000, 0x66, 2, 1), 239 PLL_S3C2440_MPLL_RATE(12 * MHZ, 330000000, 0x66, 2, 1),
240 PLL_35XX_RATE(320000000, 0x98, 4, 1), 240 PLL_S3C2440_MPLL_RATE(12 * MHZ, 320000000, 0x98, 4, 1),
241 PLL_35XX_RATE(310000000, 0x93, 4, 1), 241 PLL_S3C2440_MPLL_RATE(12 * MHZ, 310000000, 0x93, 4, 1),
242 PLL_35XX_RATE(300000000, 0x75, 3, 1), 242 PLL_S3C2440_MPLL_RATE(12 * MHZ, 300000000, 0x75, 3, 1),
243 PLL_35XX_RATE(240000000, 0x70, 1, 2), 243 PLL_S3C2440_MPLL_RATE(12 * MHZ, 240000000, 0x70, 1, 2),
244 PLL_35XX_RATE(230000000, 0x6b, 1, 2), 244 PLL_S3C2440_MPLL_RATE(12 * MHZ, 230000000, 0x6b, 1, 2),
245 PLL_35XX_RATE(220000000, 0x66, 1, 2), 245 PLL_S3C2440_MPLL_RATE(12 * MHZ, 220000000, 0x66, 1, 2),
246 PLL_35XX_RATE(210000000, 0x84, 2, 2), 246 PLL_S3C2440_MPLL_RATE(12 * MHZ, 210000000, 0x84, 2, 2),
247 PLL_35XX_RATE(200000000, 0x5c, 1, 2), 247 PLL_S3C2440_MPLL_RATE(12 * MHZ, 200000000, 0x5c, 1, 2),
248 PLL_35XX_RATE(190000000, 0x57, 1, 2), 248 PLL_S3C2440_MPLL_RATE(12 * MHZ, 190000000, 0x57, 1, 2),
249 PLL_35XX_RATE(180000000, 0x70, 2, 2), 249 PLL_S3C2440_MPLL_RATE(12 * MHZ, 180000000, 0x70, 2, 2),
250 PLL_35XX_RATE(170000000, 0x4d, 1, 2), 250 PLL_S3C2440_MPLL_RATE(12 * MHZ, 170000000, 0x4d, 1, 2),
251 PLL_35XX_RATE(160000000, 0x98, 4, 2), 251 PLL_S3C2440_MPLL_RATE(12 * MHZ, 160000000, 0x98, 4, 2),
252 PLL_35XX_RATE(150000000, 0x75, 3, 2), 252 PLL_S3C2440_MPLL_RATE(12 * MHZ, 150000000, 0x75, 3, 2),
253 PLL_35XX_RATE(120000000, 0x70, 1, 3), 253 PLL_S3C2440_MPLL_RATE(12 * MHZ, 120000000, 0x70, 1, 3),
254 PLL_35XX_RATE(110000000, 0x66, 1, 3), 254 PLL_S3C2440_MPLL_RATE(12 * MHZ, 110000000, 0x66, 1, 3),
255 PLL_35XX_RATE(100000000, 0x5c, 1, 3), 255 PLL_S3C2440_MPLL_RATE(12 * MHZ, 100000000, 0x5c, 1, 3),
256 PLL_35XX_RATE(90000000, 0x70, 2, 3), 256 PLL_S3C2440_MPLL_RATE(12 * MHZ, 90000000, 0x70, 2, 3),
257 PLL_35XX_RATE(80000000, 0x98, 4, 3), 257 PLL_S3C2440_MPLL_RATE(12 * MHZ, 80000000, 0x98, 4, 3),
258 PLL_35XX_RATE(75000000, 0x75, 3, 3), 258 PLL_S3C2440_MPLL_RATE(12 * MHZ, 75000000, 0x75, 3, 3),
259 { /* sentinel */ }, 259 { /* sentinel */ },
260}; 260};
261 261
@@ -269,12 +269,12 @@ static struct samsung_pll_clock s3c244x_common_plls[] __initdata = {
269PNAME(hclk_p) = { "fclk", "div_hclk_2", "div_hclk_4", "div_hclk_3" }; 269PNAME(hclk_p) = { "fclk", "div_hclk_2", "div_hclk_4", "div_hclk_3" };
270PNAME(armclk_p) = { "fclk", "hclk" }; 270PNAME(armclk_p) = { "fclk", "hclk" };
271 271
272struct samsung_mux_clock s3c244x_common_muxes[] __initdata = { 272static struct samsung_mux_clock s3c244x_common_muxes[] __initdata = {
273 MUX(HCLK, "hclk", hclk_p, CLKDIVN, 1, 2), 273 MUX(HCLK, "hclk", hclk_p, CLKDIVN, 1, 2),
274 MUX(ARMCLK, "armclk", armclk_p, CAMDIVN, 12, 1), 274 MUX(ARMCLK, "armclk", armclk_p, CAMDIVN, 12, 1),
275}; 275};
276 276
277struct samsung_fixed_factor_clock s3c244x_common_ffactor[] __initdata = { 277static struct samsung_fixed_factor_clock s3c244x_common_ffactor[] __initdata = {
278 FFACTOR(0, "div_hclk_2", "fclk", 1, 2, 0), 278 FFACTOR(0, "div_hclk_2", "fclk", 1, 2, 0),
279 FFACTOR(0, "ff_cam", "div_cam", 2, 1, CLK_SET_RATE_PARENT), 279 FFACTOR(0, "ff_cam", "div_cam", 2, 1, CLK_SET_RATE_PARENT),
280}; 280};
@@ -291,7 +291,7 @@ static struct clk_div_table div_hclk_3_d[] = {
291 { /* sentinel */ }, 291 { /* sentinel */ },
292}; 292};
293 293
294struct samsung_div_clock s3c244x_common_dividers[] __initdata = { 294static struct samsung_div_clock s3c244x_common_dividers[] __initdata = {
295 DIV(UCLK, "uclk", "upll", CLKDIVN, 3, 1), 295 DIV(UCLK, "uclk", "upll", CLKDIVN, 3, 1),
296 DIV(0, "div_hclk", "fclk", CLKDIVN, 1, 1), 296 DIV(0, "div_hclk", "fclk", CLKDIVN, 1, 1),
297 DIV_T(0, "div_hclk_4", "fclk", CAMDIVN, 9, 1, div_hclk_4_d), 297 DIV_T(0, "div_hclk_4", "fclk", CAMDIVN, 9, 1, div_hclk_4_d),
@@ -299,11 +299,11 @@ struct samsung_div_clock s3c244x_common_dividers[] __initdata = {
299 DIV(0, "div_cam", "upll", CAMDIVN, 0, 3), 299 DIV(0, "div_cam", "upll", CAMDIVN, 0, 3),
300}; 300};
301 301
302struct samsung_gate_clock s3c244x_common_gates[] __initdata = { 302static struct samsung_gate_clock s3c244x_common_gates[] __initdata = {
303 GATE(HCLK_CAM, "cam", "hclk", CLKCON, 19, 0, 0), 303 GATE(HCLK_CAM, "cam", "hclk", CLKCON, 19, 0, 0),
304}; 304};
305 305
306struct samsung_clock_alias s3c244x_common_aliases[] __initdata = { 306static struct samsung_clock_alias s3c244x_common_aliases[] __initdata = {
307 ALIAS(PCLK_UART0, "s3c2440-uart.0", "uart"), 307 ALIAS(PCLK_UART0, "s3c2440-uart.0", "uart"),
308 ALIAS(PCLK_UART1, "s3c2440-uart.1", "uart"), 308 ALIAS(PCLK_UART1, "s3c2440-uart.1", "uart"),
309 ALIAS(PCLK_UART2, "s3c2440-uart.2", "uart"), 309 ALIAS(PCLK_UART2, "s3c2440-uart.2", "uart"),
@@ -318,23 +318,23 @@ struct samsung_clock_alias s3c244x_common_aliases[] __initdata = {
318 318
319PNAME(s3c2440_camif_p) = { "upll", "ff_cam" }; 319PNAME(s3c2440_camif_p) = { "upll", "ff_cam" };
320 320
321struct samsung_mux_clock s3c2440_muxes[] __initdata = { 321static struct samsung_mux_clock s3c2440_muxes[] __initdata = {
322 MUX(CAMIF, "camif", s3c2440_camif_p, CAMDIVN, 4, 1), 322 MUX(CAMIF, "camif", s3c2440_camif_p, CAMDIVN, 4, 1),
323}; 323};
324 324
325struct samsung_gate_clock s3c2440_gates[] __initdata = { 325static struct samsung_gate_clock s3c2440_gates[] __initdata = {
326 GATE(PCLK_AC97, "ac97", "pclk", CLKCON, 20, 0, 0), 326 GATE(PCLK_AC97, "ac97", "pclk", CLKCON, 20, 0, 0),
327}; 327};
328 328
329/* S3C2442 specific clocks */ 329/* S3C2442 specific clocks */
330 330
331struct samsung_fixed_factor_clock s3c2442_ffactor[] __initdata = { 331static struct samsung_fixed_factor_clock s3c2442_ffactor[] __initdata = {
332 FFACTOR(0, "upll_3", "upll", 1, 3, 0), 332 FFACTOR(0, "upll_3", "upll", 1, 3, 0),
333}; 333};
334 334
335PNAME(s3c2442_camif_p) = { "upll", "ff_cam", "upll", "upll_3" }; 335PNAME(s3c2442_camif_p) = { "upll", "ff_cam", "upll", "upll_3" };
336 336
337struct samsung_mux_clock s3c2442_muxes[] __initdata = { 337static struct samsung_mux_clock s3c2442_muxes[] __initdata = {
338 MUX(CAMIF, "camif", s3c2442_camif_p, CAMDIVN, 4, 2), 338 MUX(CAMIF, "camif", s3c2442_camif_p, CAMDIVN, 4, 2),
339}; 339};
340 340
@@ -343,7 +343,7 @@ struct samsung_mux_clock s3c2442_muxes[] __initdata = {
343 * Only necessary until the devicetree-move is complete 343 * Only necessary until the devicetree-move is complete
344 */ 344 */
345#define XTI 1 345#define XTI 1
346struct samsung_fixed_rate_clock s3c2410_common_frate_clks[] __initdata = { 346static struct samsung_fixed_rate_clock s3c2410_common_frate_clks[] __initdata = {
347 FRATE(XTI, "xti", NULL, 0, 0), 347 FRATE(XTI, "xti", NULL, 0, 0),
348}; 348};
349 349
@@ -468,18 +468,18 @@ void __init s3c2410_common_clk_init(struct device_node *np, unsigned long xti_f,
468 468
469static void __init s3c2410_clk_init(struct device_node *np) 469static void __init s3c2410_clk_init(struct device_node *np)
470{ 470{
471 s3c2410_common_clk_init(np, 0, S3C2410, 0); 471 s3c2410_common_clk_init(np, 0, S3C2410, NULL);
472} 472}
473CLK_OF_DECLARE(s3c2410_clk, "samsung,s3c2410-clock", s3c2410_clk_init); 473CLK_OF_DECLARE(s3c2410_clk, "samsung,s3c2410-clock", s3c2410_clk_init);
474 474
475static void __init s3c2440_clk_init(struct device_node *np) 475static void __init s3c2440_clk_init(struct device_node *np)
476{ 476{
477 s3c2410_common_clk_init(np, 0, S3C2440, 0); 477 s3c2410_common_clk_init(np, 0, S3C2440, NULL);
478} 478}
479CLK_OF_DECLARE(s3c2440_clk, "samsung,s3c2440-clock", s3c2440_clk_init); 479CLK_OF_DECLARE(s3c2440_clk, "samsung,s3c2440-clock", s3c2440_clk_init);
480 480
481static void __init s3c2442_clk_init(struct device_node *np) 481static void __init s3c2442_clk_init(struct device_node *np)
482{ 482{
483 s3c2410_common_clk_init(np, 0, S3C2442, 0); 483 s3c2410_common_clk_init(np, 0, S3C2442, NULL);
484} 484}
485CLK_OF_DECLARE(s3c2442_clk, "samsung,s3c2442-clock", s3c2442_clk_init); 485CLK_OF_DECLARE(s3c2442_clk, "samsung,s3c2442-clock", s3c2442_clk_init);
diff --git a/drivers/clk/samsung/clk-s3c2412.c b/drivers/clk/samsung/clk-s3c2412.c
index b8340a49921b..6bc94d3aff78 100644
--- a/drivers/clk/samsung/clk-s3c2412.c
+++ b/drivers/clk/samsung/clk-s3c2412.c
@@ -27,11 +27,6 @@
27#define CLKSRC 0x1c 27#define CLKSRC 0x1c
28#define SWRST 0x30 28#define SWRST 0x30
29 29
30/* list of PLLs to be registered */
31enum s3c2412_plls {
32 mpll, upll,
33};
34
35static void __iomem *reg_base; 30static void __iomem *reg_base;
36 31
37#ifdef CONFIG_PM_SLEEP 32#ifdef CONFIG_PM_SLEEP
@@ -98,7 +93,7 @@ static struct clk_div_table divxti_d[] = {
98 { /* sentinel */ }, 93 { /* sentinel */ },
99}; 94};
100 95
101struct samsung_div_clock s3c2412_dividers[] __initdata = { 96static struct samsung_div_clock s3c2412_dividers[] __initdata = {
102 DIV_T(0, "div_xti", "xti", CLKSRC, 0, 3, divxti_d), 97 DIV_T(0, "div_xti", "xti", CLKSRC, 0, 3, divxti_d),
103 DIV(0, "div_cam", "mux_cam", CLKDIVN, 16, 4), 98 DIV(0, "div_cam", "mux_cam", CLKDIVN, 16, 4),
104 DIV(0, "div_i2s", "mux_i2s", CLKDIVN, 12, 4), 99 DIV(0, "div_i2s", "mux_i2s", CLKDIVN, 12, 4),
@@ -110,7 +105,7 @@ struct samsung_div_clock s3c2412_dividers[] __initdata = {
110 DIV(HCLK, "hclk", "armdiv", CLKDIVN, 0, 2), 105 DIV(HCLK, "hclk", "armdiv", CLKDIVN, 0, 2),
111}; 106};
112 107
113struct samsung_fixed_factor_clock s3c2412_ffactor[] __initdata = { 108static struct samsung_fixed_factor_clock s3c2412_ffactor[] __initdata = {
114 FFACTOR(0, "ff_hclk", "hclk", 2, 1, CLK_SET_RATE_PARENT), 109 FFACTOR(0, "ff_hclk", "hclk", 2, 1, CLK_SET_RATE_PARENT),
115}; 110};
116 111
@@ -130,7 +125,7 @@ PNAME(msysclk_p) = { "mdivclk", "mpll" };
130PNAME(mdivclk_p) = { "xti", "div_xti" }; 125PNAME(mdivclk_p) = { "xti", "div_xti" };
131PNAME(armclk_p) = { "armdiv", "hclk" }; 126PNAME(armclk_p) = { "armdiv", "hclk" };
132 127
133struct samsung_mux_clock s3c2412_muxes[] __initdata = { 128static struct samsung_mux_clock s3c2412_muxes[] __initdata = {
134 MUX(0, "erefclk", erefclk_p, CLKSRC, 14, 2), 129 MUX(0, "erefclk", erefclk_p, CLKSRC, 14, 2),
135 MUX(0, "urefclk", urefclk_p, CLKSRC, 12, 2), 130 MUX(0, "urefclk", urefclk_p, CLKSRC, 12, 2),
136 MUX(0, "mux_cam", camclk_p, CLKSRC, 11, 1), 131 MUX(0, "mux_cam", camclk_p, CLKSRC, 11, 1),
@@ -144,13 +139,11 @@ struct samsung_mux_clock s3c2412_muxes[] __initdata = {
144}; 139};
145 140
146static struct samsung_pll_clock s3c2412_plls[] __initdata = { 141static struct samsung_pll_clock s3c2412_plls[] __initdata = {
147 [mpll] = PLL(pll_s3c2440_mpll, MPLL, "mpll", "xti", 142 PLL(pll_s3c2440_mpll, MPLL, "mpll", "xti", LOCKTIME, MPLLCON, NULL),
148 LOCKTIME, MPLLCON, NULL), 143 PLL(pll_s3c2410_upll, UPLL, "upll", "urefclk", LOCKTIME, UPLLCON, NULL),
149 [upll] = PLL(pll_s3c2410_upll, UPLL, "upll", "urefclk",
150 LOCKTIME, UPLLCON, NULL),
151}; 144};
152 145
153struct samsung_gate_clock s3c2412_gates[] __initdata = { 146static struct samsung_gate_clock s3c2412_gates[] __initdata = {
154 GATE(PCLK_WDT, "wdt", "pclk", CLKCON, 28, 0, 0), 147 GATE(PCLK_WDT, "wdt", "pclk", CLKCON, 28, 0, 0),
155 GATE(PCLK_SPI, "spi", "pclk", CLKCON, 27, 0, 0), 148 GATE(PCLK_SPI, "spi", "pclk", CLKCON, 27, 0, 0),
156 GATE(PCLK_I2S, "i2s", "pclk", CLKCON, 26, 0, 0), 149 GATE(PCLK_I2S, "i2s", "pclk", CLKCON, 26, 0, 0),
@@ -181,7 +174,7 @@ struct samsung_gate_clock s3c2412_gates[] __initdata = {
181 GATE(HCLK_DMA0, "dma0", "hclk", CLKCON, 0, CLK_IGNORE_UNUSED, 0), 174 GATE(HCLK_DMA0, "dma0", "hclk", CLKCON, 0, CLK_IGNORE_UNUSED, 0),
182}; 175};
183 176
184struct samsung_clock_alias s3c2412_aliases[] __initdata = { 177static struct samsung_clock_alias s3c2412_aliases[] __initdata = {
185 ALIAS(PCLK_UART0, "s3c2412-uart.0", "uart"), 178 ALIAS(PCLK_UART0, "s3c2412-uart.0", "uart"),
186 ALIAS(PCLK_UART1, "s3c2412-uart.1", "uart"), 179 ALIAS(PCLK_UART1, "s3c2412-uart.1", "uart"),
187 ALIAS(PCLK_UART2, "s3c2412-uart.2", "uart"), 180 ALIAS(PCLK_UART2, "s3c2412-uart.2", "uart"),
@@ -231,7 +224,7 @@ static struct notifier_block s3c2412_restart_handler = {
231 * Only necessary until the devicetree-move is complete 224 * Only necessary until the devicetree-move is complete
232 */ 225 */
233#define XTI 1 226#define XTI 1
234struct samsung_fixed_rate_clock s3c2412_common_frate_clks[] __initdata = { 227static struct samsung_fixed_rate_clock s3c2412_common_frate_clks[] __initdata = {
235 FRATE(XTI, "xti", NULL, 0, 0), 228 FRATE(XTI, "xti", NULL, 0, 0),
236 FRATE(0, "ext", NULL, 0, 0), 229 FRATE(0, "ext", NULL, 0, 0),
237}; 230};
@@ -296,6 +289,6 @@ void __init s3c2412_common_clk_init(struct device_node *np, unsigned long xti_f,
296 289
297static void __init s3c2412_clk_init(struct device_node *np) 290static void __init s3c2412_clk_init(struct device_node *np)
298{ 291{
299 s3c2412_common_clk_init(np, 0, 0, 0); 292 s3c2412_common_clk_init(np, 0, 0, NULL);
300} 293}
301CLK_OF_DECLARE(s3c2412_clk, "samsung,s3c2412-clock", s3c2412_clk_init); 294CLK_OF_DECLARE(s3c2412_clk, "samsung,s3c2412-clock", s3c2412_clk_init);
diff --git a/drivers/clk/samsung/clk-s3c2443.c b/drivers/clk/samsung/clk-s3c2443.c
index d94b85a42356..c46e6d5bc9bc 100644
--- a/drivers/clk/samsung/clk-s3c2443.c
+++ b/drivers/clk/samsung/clk-s3c2443.c
@@ -41,11 +41,6 @@ enum supported_socs {
41 S3C2450, 41 S3C2450,
42}; 42};
43 43
44/* list of PLLs to be registered */
45enum s3c2443_plls {
46 mpll, epll,
47};
48
49static void __iomem *reg_base; 44static void __iomem *reg_base;
50 45
51#ifdef CONFIG_PM_SLEEP 46#ifdef CONFIG_PM_SLEEP
@@ -113,7 +108,7 @@ PNAME(msysclk_p) = { "mpllref", "mpll" };
113PNAME(armclk_p) = { "armdiv" , "hclk" }; 108PNAME(armclk_p) = { "armdiv" , "hclk" };
114PNAME(i2s0_p) = { "div_i2s0", "ext_i2s", "epllref", "epllref" }; 109PNAME(i2s0_p) = { "div_i2s0", "ext_i2s", "epllref", "epllref" };
115 110
116struct samsung_mux_clock s3c2443_common_muxes[] __initdata = { 111static struct samsung_mux_clock s3c2443_common_muxes[] __initdata = {
117 MUX(0, "epllref", epllref_p, CLKSRC, 7, 2), 112 MUX(0, "epllref", epllref_p, CLKSRC, 7, 2),
118 MUX(ESYSCLK, "esysclk", esysclk_p, CLKSRC, 6, 1), 113 MUX(ESYSCLK, "esysclk", esysclk_p, CLKSRC, 6, 1),
119 MUX(0, "mpllref", mpllref_p, CLKSRC, 3, 1), 114 MUX(0, "mpllref", mpllref_p, CLKSRC, 3, 1),
@@ -141,7 +136,7 @@ static struct clk_div_table mdivclk_d[] = {
141 { /* sentinel */ }, 136 { /* sentinel */ },
142}; 137};
143 138
144struct samsung_div_clock s3c2443_common_dividers[] __initdata = { 139static struct samsung_div_clock s3c2443_common_dividers[] __initdata = {
145 DIV_T(0, "mdivclk", "xti", CLKDIV0, 6, 3, mdivclk_d), 140 DIV_T(0, "mdivclk", "xti", CLKDIV0, 6, 3, mdivclk_d),
146 DIV(0, "prediv", "msysclk", CLKDIV0, 4, 2), 141 DIV(0, "prediv", "msysclk", CLKDIV0, 4, 2),
147 DIV_T(HCLK, "hclk", "prediv", CLKDIV0, 0, 2, hclk_d), 142 DIV_T(HCLK, "hclk", "prediv", CLKDIV0, 0, 2, hclk_d),
@@ -154,7 +149,7 @@ struct samsung_div_clock s3c2443_common_dividers[] __initdata = {
154 DIV(0, "div_usbhost", "esysclk", CLKDIV1, 4, 2), 149 DIV(0, "div_usbhost", "esysclk", CLKDIV1, 4, 2),
155}; 150};
156 151
157struct samsung_gate_clock s3c2443_common_gates[] __initdata = { 152static struct samsung_gate_clock s3c2443_common_gates[] __initdata = {
158 GATE(SCLK_HSMMC_EXT, "sclk_hsmmcext", "ext", SCLKCON, 13, 0, 0), 153 GATE(SCLK_HSMMC_EXT, "sclk_hsmmcext", "ext", SCLKCON, 13, 0, 0),
159 GATE(SCLK_HSMMC1, "sclk_hsmmc1", "div_hsmmc1", SCLKCON, 12, 0, 0), 154 GATE(SCLK_HSMMC1, "sclk_hsmmc1", "div_hsmmc1", SCLKCON, 12, 0, 0),
160 GATE(SCLK_FIMD, "sclk_fimd", "div_fimd", SCLKCON, 10, 0, 0), 155 GATE(SCLK_FIMD, "sclk_fimd", "div_fimd", SCLKCON, 10, 0, 0),
@@ -188,7 +183,7 @@ struct samsung_gate_clock s3c2443_common_gates[] __initdata = {
188 GATE(PCLK_UART0, "uart0", "pclk", PCLKCON, 0, 0, 0), 183 GATE(PCLK_UART0, "uart0", "pclk", PCLKCON, 0, 0, 0),
189}; 184};
190 185
191struct samsung_clock_alias s3c2443_common_aliases[] __initdata = { 186static struct samsung_clock_alias s3c2443_common_aliases[] __initdata = {
192 ALIAS(MSYSCLK, NULL, "msysclk"), 187 ALIAS(MSYSCLK, NULL, "msysclk"),
193 ALIAS(ARMCLK, NULL, "armclk"), 188 ALIAS(ARMCLK, NULL, "armclk"),
194 ALIAS(MPLL, NULL, "mpll"), 189 ALIAS(MPLL, NULL, "mpll"),
@@ -225,10 +220,8 @@ struct samsung_clock_alias s3c2443_common_aliases[] __initdata = {
225/* S3C2416 specific clocks */ 220/* S3C2416 specific clocks */
226 221
227static struct samsung_pll_clock s3c2416_pll_clks[] __initdata = { 222static struct samsung_pll_clock s3c2416_pll_clks[] __initdata = {
228 [mpll] = PLL(pll_6552_s3c2416, MPLL, "mpll", "mpllref", 223 PLL(pll_6552_s3c2416, MPLL, "mpll", "mpllref", LOCKCON0, MPLLCON, NULL),
229 LOCKCON0, MPLLCON, NULL), 224 PLL(pll_6553, EPLL, "epll", "epllref", LOCKCON1, EPLLCON, NULL),
230 [epll] = PLL(pll_6553, EPLL, "epll", "epllref",
231 LOCKCON1, EPLLCON, NULL),
232}; 225};
233 226
234PNAME(s3c2416_hsmmc0_p) = { "sclk_hsmmc0", "sclk_hsmmcext" }; 227PNAME(s3c2416_hsmmc0_p) = { "sclk_hsmmc0", "sclk_hsmmcext" };
@@ -245,19 +238,19 @@ static struct clk_div_table armdiv_s3c2416_d[] = {
245 { /* sentinel */ }, 238 { /* sentinel */ },
246}; 239};
247 240
248struct samsung_div_clock s3c2416_dividers[] __initdata = { 241static struct samsung_div_clock s3c2416_dividers[] __initdata = {
249 DIV_T(ARMDIV, "armdiv", "msysclk", CLKDIV0, 9, 3, armdiv_s3c2416_d), 242 DIV_T(ARMDIV, "armdiv", "msysclk", CLKDIV0, 9, 3, armdiv_s3c2416_d),
250 DIV(0, "div_hsspi0_mpll", "msysclk", CLKDIV2, 0, 4), 243 DIV(0, "div_hsspi0_mpll", "msysclk", CLKDIV2, 0, 4),
251 DIV(0, "div_hsmmc0", "esysclk", CLKDIV2, 6, 2), 244 DIV(0, "div_hsmmc0", "esysclk", CLKDIV2, 6, 2),
252}; 245};
253 246
254struct samsung_mux_clock s3c2416_muxes[] __initdata = { 247static struct samsung_mux_clock s3c2416_muxes[] __initdata = {
255 MUX(MUX_HSMMC0, "mux_hsmmc0", s3c2416_hsmmc0_p, CLKSRC, 16, 1), 248 MUX(MUX_HSMMC0, "mux_hsmmc0", s3c2416_hsmmc0_p, CLKSRC, 16, 1),
256 MUX(MUX_HSMMC1, "mux_hsmmc1", s3c2416_hsmmc1_p, CLKSRC, 17, 1), 249 MUX(MUX_HSMMC1, "mux_hsmmc1", s3c2416_hsmmc1_p, CLKSRC, 17, 1),
257 MUX(MUX_HSSPI0, "mux_hsspi0", s3c2416_hsspi0_p, CLKSRC, 18, 1), 250 MUX(MUX_HSSPI0, "mux_hsspi0", s3c2416_hsspi0_p, CLKSRC, 18, 1),
258}; 251};
259 252
260struct samsung_gate_clock s3c2416_gates[] __initdata = { 253static struct samsung_gate_clock s3c2416_gates[] __initdata = {
261 GATE(0, "hsspi0_mpll", "div_hsspi0_mpll", SCLKCON, 19, 0, 0), 254 GATE(0, "hsspi0_mpll", "div_hsspi0_mpll", SCLKCON, 19, 0, 0),
262 GATE(0, "hsspi0_epll", "div_hsspi0_epll", SCLKCON, 14, 0, 0), 255 GATE(0, "hsspi0_epll", "div_hsspi0_epll", SCLKCON, 14, 0, 0),
263 GATE(0, "sclk_hsmmc0", "div_hsmmc0", SCLKCON, 6, 0, 0), 256 GATE(0, "sclk_hsmmc0", "div_hsmmc0", SCLKCON, 6, 0, 0),
@@ -267,7 +260,7 @@ struct samsung_gate_clock s3c2416_gates[] __initdata = {
267 GATE(PCLK_PCM, "pcm", "pclk", PCLKCON, 19, 0, 0), 260 GATE(PCLK_PCM, "pcm", "pclk", PCLKCON, 19, 0, 0),
268}; 261};
269 262
270struct samsung_clock_alias s3c2416_aliases[] __initdata = { 263static struct samsung_clock_alias s3c2416_aliases[] __initdata = {
271 ALIAS(HCLK_HSMMC0, "s3c-sdhci.0", "hsmmc"), 264 ALIAS(HCLK_HSMMC0, "s3c-sdhci.0", "hsmmc"),
272 ALIAS(HCLK_HSMMC0, "s3c-sdhci.0", "mmc_busclk.0"), 265 ALIAS(HCLK_HSMMC0, "s3c-sdhci.0", "mmc_busclk.0"),
273 ALIAS(MUX_HSMMC0, "s3c-sdhci.0", "mmc_busclk.2"), 266 ALIAS(MUX_HSMMC0, "s3c-sdhci.0", "mmc_busclk.2"),
@@ -279,10 +272,8 @@ struct samsung_clock_alias s3c2416_aliases[] __initdata = {
279/* S3C2443 specific clocks */ 272/* S3C2443 specific clocks */
280 273
281static struct samsung_pll_clock s3c2443_pll_clks[] __initdata = { 274static struct samsung_pll_clock s3c2443_pll_clks[] __initdata = {
282 [mpll] = PLL(pll_3000, MPLL, "mpll", "mpllref", 275 PLL(pll_3000, MPLL, "mpll", "mpllref", LOCKCON0, MPLLCON, NULL),
283 LOCKCON0, MPLLCON, NULL), 276 PLL(pll_2126, EPLL, "epll", "epllref", LOCKCON1, EPLLCON, NULL),
284 [epll] = PLL(pll_2126, EPLL, "epll", "epllref",
285 LOCKCON1, EPLLCON, NULL),
286}; 277};
287 278
288static struct clk_div_table armdiv_s3c2443_d[] = { 279static struct clk_div_table armdiv_s3c2443_d[] = {
@@ -297,12 +288,12 @@ static struct clk_div_table armdiv_s3c2443_d[] = {
297 { /* sentinel */ }, 288 { /* sentinel */ },
298}; 289};
299 290
300struct samsung_div_clock s3c2443_dividers[] __initdata = { 291static struct samsung_div_clock s3c2443_dividers[] __initdata = {
301 DIV_T(ARMDIV, "armdiv", "msysclk", CLKDIV0, 9, 4, armdiv_s3c2443_d), 292 DIV_T(ARMDIV, "armdiv", "msysclk", CLKDIV0, 9, 4, armdiv_s3c2443_d),
302 DIV(0, "div_cam", "esysclk", CLKDIV1, 26, 4), 293 DIV(0, "div_cam", "esysclk", CLKDIV1, 26, 4),
303}; 294};
304 295
305struct samsung_gate_clock s3c2443_gates[] __initdata = { 296static struct samsung_gate_clock s3c2443_gates[] __initdata = {
306 GATE(SCLK_HSSPI0, "sclk_hsspi0", "div_hsspi0_epll", SCLKCON, 14, 0, 0), 297 GATE(SCLK_HSSPI0, "sclk_hsspi0", "div_hsspi0_epll", SCLKCON, 14, 0, 0),
307 GATE(SCLK_CAM, "sclk_cam", "div_cam", SCLKCON, 11, 0, 0), 298 GATE(SCLK_CAM, "sclk_cam", "div_cam", SCLKCON, 11, 0, 0),
308 GATE(HCLK_CFC, "cfc", "hclk", HCLKCON, 17, CLK_IGNORE_UNUSED, 0), 299 GATE(HCLK_CFC, "cfc", "hclk", HCLKCON, 17, CLK_IGNORE_UNUSED, 0),
@@ -311,7 +302,7 @@ struct samsung_gate_clock s3c2443_gates[] __initdata = {
311 GATE(PCLK_SDI, "sdi", "pclk", PCLKCON, 5, 0, 0), 302 GATE(PCLK_SDI, "sdi", "pclk", PCLKCON, 5, 0, 0),
312}; 303};
313 304
314struct samsung_clock_alias s3c2443_aliases[] __initdata = { 305static struct samsung_clock_alias s3c2443_aliases[] __initdata = {
315 ALIAS(SCLK_HSSPI0, "s3c2443-spi.0", "spi_busclk2"), 306 ALIAS(SCLK_HSSPI0, "s3c2443-spi.0", "spi_busclk2"),
316 ALIAS(SCLK_HSMMC1, "s3c-sdhci.1", "mmc_busclk.2"), 307 ALIAS(SCLK_HSMMC1, "s3c-sdhci.1", "mmc_busclk.2"),
317 ALIAS(SCLK_CAM, NULL, "camif-upll"), 308 ALIAS(SCLK_CAM, NULL, "camif-upll"),
@@ -327,20 +318,20 @@ PNAME(s3c2450_cam_p) = { "div_cam", "hclk" };
327PNAME(s3c2450_hsspi1_p) = { "hsspi1_epll", "hsspi1_mpll" }; 318PNAME(s3c2450_hsspi1_p) = { "hsspi1_epll", "hsspi1_mpll" };
328PNAME(i2s1_p) = { "div_i2s1", "ext_i2s", "epllref", "epllref" }; 319PNAME(i2s1_p) = { "div_i2s1", "ext_i2s", "epllref", "epllref" };
329 320
330struct samsung_div_clock s3c2450_dividers[] __initdata = { 321static struct samsung_div_clock s3c2450_dividers[] __initdata = {
331 DIV(0, "div_cam", "esysclk", CLKDIV1, 26, 4), 322 DIV(0, "div_cam", "esysclk", CLKDIV1, 26, 4),
332 DIV(0, "div_hsspi1_epll", "esysclk", CLKDIV2, 24, 2), 323 DIV(0, "div_hsspi1_epll", "esysclk", CLKDIV2, 24, 2),
333 DIV(0, "div_hsspi1_mpll", "msysclk", CLKDIV2, 16, 4), 324 DIV(0, "div_hsspi1_mpll", "msysclk", CLKDIV2, 16, 4),
334 DIV(0, "div_i2s1", "esysclk", CLKDIV2, 12, 4), 325 DIV(0, "div_i2s1", "esysclk", CLKDIV2, 12, 4),
335}; 326};
336 327
337struct samsung_mux_clock s3c2450_muxes[] __initdata = { 328static struct samsung_mux_clock s3c2450_muxes[] __initdata = {
338 MUX(0, "mux_cam", s3c2450_cam_p, CLKSRC, 20, 1), 329 MUX(0, "mux_cam", s3c2450_cam_p, CLKSRC, 20, 1),
339 MUX(MUX_HSSPI1, "mux_hsspi1", s3c2450_hsspi1_p, CLKSRC, 19, 1), 330 MUX(MUX_HSSPI1, "mux_hsspi1", s3c2450_hsspi1_p, CLKSRC, 19, 1),
340 MUX(0, "mux_i2s1", i2s1_p, CLKSRC, 12, 2), 331 MUX(0, "mux_i2s1", i2s1_p, CLKSRC, 12, 2),
341}; 332};
342 333
343struct samsung_gate_clock s3c2450_gates[] __initdata = { 334static struct samsung_gate_clock s3c2450_gates[] __initdata = {
344 GATE(SCLK_I2S1, "sclk_i2s1", "div_i2s1", SCLKCON, 5, 0, 0), 335 GATE(SCLK_I2S1, "sclk_i2s1", "div_i2s1", SCLKCON, 5, 0, 0),
345 GATE(HCLK_CFC, "cfc", "hclk", HCLKCON, 17, 0, 0), 336 GATE(HCLK_CFC, "cfc", "hclk", HCLKCON, 17, 0, 0),
346 GATE(HCLK_CAM, "cam", "hclk", HCLKCON, 8, 0, 0), 337 GATE(HCLK_CAM, "cam", "hclk", HCLKCON, 8, 0, 0),
@@ -351,7 +342,7 @@ struct samsung_gate_clock s3c2450_gates[] __initdata = {
351 GATE(PCLK_SPI1, "spi1", "pclk", PCLKCON, 14, 0, 0), 342 GATE(PCLK_SPI1, "spi1", "pclk", PCLKCON, 14, 0, 0),
352}; 343};
353 344
354struct samsung_clock_alias s3c2450_aliases[] __initdata = { 345static struct samsung_clock_alias s3c2450_aliases[] __initdata = {
355 ALIAS(PCLK_SPI1, "s3c2443-spi.1", "spi"), 346 ALIAS(PCLK_SPI1, "s3c2443-spi.1", "spi"),
356 ALIAS(PCLK_SPI1, "s3c2443-spi.1", "spi_busclk0"), 347 ALIAS(PCLK_SPI1, "s3c2443-spi.1", "spi_busclk0"),
357 ALIAS(MUX_HSSPI1, "s3c2443-spi.1", "spi_busclk2"), 348 ALIAS(MUX_HSSPI1, "s3c2443-spi.1", "spi_busclk2"),
@@ -374,7 +365,7 @@ static struct notifier_block s3c2443_restart_handler = {
374 * fixed rate clocks generated outside the soc 365 * fixed rate clocks generated outside the soc
375 * Only necessary until the devicetree-move is complete 366 * Only necessary until the devicetree-move is complete
376 */ 367 */
377struct samsung_fixed_rate_clock s3c2443_common_frate_clks[] __initdata = { 368static struct samsung_fixed_rate_clock s3c2443_common_frate_clks[] __initdata = {
378 FRATE(0, "xti", NULL, 0, 0), 369 FRATE(0, "xti", NULL, 0, 0),
379 FRATE(0, "ext", NULL, 0, 0), 370 FRATE(0, "ext", NULL, 0, 0),
380 FRATE(0, "ext_i2s", NULL, 0, 0), 371 FRATE(0, "ext_i2s", NULL, 0, 0),
@@ -470,18 +461,18 @@ void __init s3c2443_common_clk_init(struct device_node *np, unsigned long xti_f,
470 461
471static void __init s3c2416_clk_init(struct device_node *np) 462static void __init s3c2416_clk_init(struct device_node *np)
472{ 463{
473 s3c2443_common_clk_init(np, 0, S3C2416, 0); 464 s3c2443_common_clk_init(np, 0, S3C2416, NULL);
474} 465}
475CLK_OF_DECLARE(s3c2416_clk, "samsung,s3c2416-clock", s3c2416_clk_init); 466CLK_OF_DECLARE(s3c2416_clk, "samsung,s3c2416-clock", s3c2416_clk_init);
476 467
477static void __init s3c2443_clk_init(struct device_node *np) 468static void __init s3c2443_clk_init(struct device_node *np)
478{ 469{
479 s3c2443_common_clk_init(np, 0, S3C2443, 0); 470 s3c2443_common_clk_init(np, 0, S3C2443, NULL);
480} 471}
481CLK_OF_DECLARE(s3c2443_clk, "samsung,s3c2443-clock", s3c2443_clk_init); 472CLK_OF_DECLARE(s3c2443_clk, "samsung,s3c2443-clock", s3c2443_clk_init);
482 473
483static void __init s3c2450_clk_init(struct device_node *np) 474static void __init s3c2450_clk_init(struct device_node *np)
484{ 475{
485 s3c2443_common_clk_init(np, 0, S3C2450, 0); 476 s3c2443_common_clk_init(np, 0, S3C2450, NULL);
486} 477}
487CLK_OF_DECLARE(s3c2450_clk, "samsung,s3c2450-clock", s3c2450_clk_init); 478CLK_OF_DECLARE(s3c2450_clk, "samsung,s3c2450-clock", s3c2450_clk_init);
diff --git a/drivers/clk/samsung/clk-s3c64xx.c b/drivers/clk/samsung/clk-s3c64xx.c
index 7306867a0ab8..6db01cf5ab83 100644
--- a/drivers/clk/samsung/clk-s3c64xx.c
+++ b/drivers/clk/samsung/clk-s3c64xx.c
@@ -56,11 +56,6 @@
56#define GATE_ON(_id, cname, pname, o, b) \ 56#define GATE_ON(_id, cname, pname, o, b) \
57 GATE(_id, cname, pname, o, b, CLK_IGNORE_UNUSED, 0) 57 GATE(_id, cname, pname, o, b, CLK_IGNORE_UNUSED, 0)
58 58
59/* list of PLLs to be registered */
60enum s3c64xx_plls {
61 apll, mpll, epll,
62};
63
64static void __iomem *reg_base; 59static void __iomem *reg_base;
65static bool is_s3c6400; 60static bool is_s3c6400;
66 61
@@ -364,12 +359,12 @@ GATE_CLOCKS(s3c6410_gate_clks) __initdata = {
364 359
365/* List of PLL clocks. */ 360/* List of PLL clocks. */
366static struct samsung_pll_clock s3c64xx_pll_clks[] __initdata = { 361static struct samsung_pll_clock s3c64xx_pll_clks[] __initdata = {
367 [apll] = PLL(pll_6552, FOUT_APLL, "fout_apll", "fin_pll", 362 PLL(pll_6552, FOUT_APLL, "fout_apll", "fin_pll",
368 APLL_LOCK, APLL_CON, NULL), 363 APLL_LOCK, APLL_CON, NULL),
369 [mpll] = PLL(pll_6552, FOUT_MPLL, "fout_mpll", "fin_pll", 364 PLL(pll_6552, FOUT_MPLL, "fout_mpll", "fin_pll",
370 MPLL_LOCK, MPLL_CON, NULL), 365 MPLL_LOCK, MPLL_CON, NULL),
371 [epll] = PLL(pll_6553, FOUT_EPLL, "fout_epll", "fin_pll", 366 PLL(pll_6553, FOUT_EPLL, "fout_epll", "fin_pll",
372 EPLL_LOCK, EPLL_CON0, NULL), 367 EPLL_LOCK, EPLL_CON0, NULL),
373}; 368};
374 369
375/* Aliases for common s3c64xx clocks. */ 370/* Aliases for common s3c64xx clocks. */
diff --git a/drivers/clk/sprd/sc9860-clk.c b/drivers/clk/sprd/sc9860-clk.c
index ed5c027df0f4..9980ab55271b 100644
--- a/drivers/clk/sprd/sc9860-clk.c
+++ b/drivers/clk/sprd/sc9860-clk.c
@@ -959,6 +959,44 @@ static SPRD_SC_GATE_CLK(sdio2_2x_en, "sdio2-2x-en", "aon-apb", 0x13c,
959 0x1000, BIT(6), 0, 0); 959 0x1000, BIT(6), 0, 0);
960static SPRD_SC_GATE_CLK(emmc_2x_en, "emmc-2x-en", "aon-apb", 0x13c, 960static SPRD_SC_GATE_CLK(emmc_2x_en, "emmc-2x-en", "aon-apb", 0x13c,
961 0x1000, BIT(9), 0, 0); 961 0x1000, BIT(9), 0, 0);
962static SPRD_SC_GATE_CLK(arch_rtc_eb, "arch-rtc-eb", "aon-apb", 0x10,
963 0x1000, BIT(0), CLK_IGNORE_UNUSED, 0);
964static SPRD_SC_GATE_CLK(kpb_rtc_eb, "kpb-rtc-eb", "aon-apb", 0x10,
965 0x1000, BIT(1), CLK_IGNORE_UNUSED, 0);
966static SPRD_SC_GATE_CLK(aon_syst_rtc_eb, "aon-syst-rtc-eb", "aon-apb", 0x10,
967 0x1000, BIT(2), CLK_IGNORE_UNUSED, 0);
968static SPRD_SC_GATE_CLK(ap_syst_rtc_eb, "ap-syst-rtc-eb", "aon-apb", 0x10,
969 0x1000, BIT(3), CLK_IGNORE_UNUSED, 0);
970static SPRD_SC_GATE_CLK(aon_tmr_rtc_eb, "aon-tmr-rtc-eb", "aon-apb", 0x10,
971 0x1000, BIT(4), CLK_IGNORE_UNUSED, 0);
972static SPRD_SC_GATE_CLK(ap_tmr0_rtc_eb, "ap-tmr0-rtc-eb", "aon-apb", 0x10,
973 0x1000, BIT(5), CLK_IGNORE_UNUSED, 0);
974static SPRD_SC_GATE_CLK(eic_rtc_eb, "eic-rtc-eb", "aon-apb", 0x10,
975 0x1000, BIT(6), CLK_IGNORE_UNUSED, 0);
976static SPRD_SC_GATE_CLK(eic_rtcdv5_eb, "eic-rtcdv5-eb", "aon-apb", 0x10,
977 0x1000, BIT(7), CLK_IGNORE_UNUSED, 0);
978static SPRD_SC_GATE_CLK(ap_wdg_rtc_eb, "ap-wdg-rtc-eb", "aon-apb", 0x10,
979 0x1000, BIT(9), CLK_IGNORE_UNUSED, 0);
980static SPRD_SC_GATE_CLK(ap_tmr1_rtc_eb, "ap-tmr1-rtc-eb", "aon-apb", 0x10,
981 0x1000, BIT(15), CLK_IGNORE_UNUSED, 0);
982static SPRD_SC_GATE_CLK(ap_tmr2_rtc_eb, "ap-tmr2-rtc-eb", "aon-apb", 0x10,
983 0x1000, BIT(16), CLK_IGNORE_UNUSED, 0);
984static SPRD_SC_GATE_CLK(dcxo_tmr_rtc_eb, "dcxo-tmr-rtc-eb", "aon-apb", 0x10,
985 0x1000, BIT(17), CLK_IGNORE_UNUSED, 0);
986static SPRD_SC_GATE_CLK(bb_cal_rtc_eb, "bb-cal-rtc-eb", "aon-apb", 0x10,
987 0x1000, BIT(18), CLK_IGNORE_UNUSED, 0);
988static SPRD_SC_GATE_CLK(avs_big_rtc_eb, "avs-big-rtc-eb", "aon-apb", 0x10,
989 0x1000, BIT(20), CLK_IGNORE_UNUSED, 0);
990static SPRD_SC_GATE_CLK(avs_lit_rtc_eb, "avs-lit-rtc-eb", "aon-apb", 0x10,
991 0x1000, BIT(21), CLK_IGNORE_UNUSED, 0);
992static SPRD_SC_GATE_CLK(avs_gpu0_rtc_eb, "avs-gpu0-rtc-eb", "aon-apb", 0x10,
993 0x1000, BIT(22), CLK_IGNORE_UNUSED, 0);
994static SPRD_SC_GATE_CLK(avs_gpu1_rtc_eb, "avs-gpu1-rtc-eb", "aon-apb", 0x10,
995 0x1000, BIT(23), CLK_IGNORE_UNUSED, 0);
996static SPRD_SC_GATE_CLK(gpu_ts_eb, "gpu-ts-eb", "aon-apb", 0x10,
997 0x1000, BIT(24), CLK_IGNORE_UNUSED, 0);
998static SPRD_SC_GATE_CLK(rtcdv10_eb, "rtcdv10-eb", "aon-apb", 0x10,
999 0x1000, BIT(27), CLK_IGNORE_UNUSED, 0);
962 1000
963static struct sprd_clk_common *sc9860_aon_gate[] = { 1001static struct sprd_clk_common *sc9860_aon_gate[] = {
964 /* address base is 0x402e0000 */ 1002 /* address base is 0x402e0000 */
@@ -1030,6 +1068,25 @@ static struct sprd_clk_common *sc9860_aon_gate[] = {
1030 &sdio1_2x_en.common, 1068 &sdio1_2x_en.common,
1031 &sdio2_2x_en.common, 1069 &sdio2_2x_en.common,
1032 &emmc_2x_en.common, 1070 &emmc_2x_en.common,
1071 &arch_rtc_eb.common,
1072 &kpb_rtc_eb.common,
1073 &aon_syst_rtc_eb.common,
1074 &ap_syst_rtc_eb.common,
1075 &aon_tmr_rtc_eb.common,
1076 &ap_tmr0_rtc_eb.common,
1077 &eic_rtc_eb.common,
1078 &eic_rtcdv5_eb.common,
1079 &ap_wdg_rtc_eb.common,
1080 &ap_tmr1_rtc_eb.common,
1081 &ap_tmr2_rtc_eb.common,
1082 &dcxo_tmr_rtc_eb.common,
1083 &bb_cal_rtc_eb.common,
1084 &avs_big_rtc_eb.common,
1085 &avs_lit_rtc_eb.common,
1086 &avs_gpu0_rtc_eb.common,
1087 &avs_gpu1_rtc_eb.common,
1088 &gpu_ts_eb.common,
1089 &rtcdv10_eb.common,
1033}; 1090};
1034 1091
1035static struct clk_hw_onecell_data sc9860_aon_gate_hws = { 1092static struct clk_hw_onecell_data sc9860_aon_gate_hws = {
@@ -1102,6 +1159,25 @@ static struct clk_hw_onecell_data sc9860_aon_gate_hws = {
1102 [CLK_SDIO1_2X_EN] = &sdio1_2x_en.common.hw, 1159 [CLK_SDIO1_2X_EN] = &sdio1_2x_en.common.hw,
1103 [CLK_SDIO2_2X_EN] = &sdio2_2x_en.common.hw, 1160 [CLK_SDIO2_2X_EN] = &sdio2_2x_en.common.hw,
1104 [CLK_EMMC_2X_EN] = &emmc_2x_en.common.hw, 1161 [CLK_EMMC_2X_EN] = &emmc_2x_en.common.hw,
1162 [CLK_ARCH_RTC_EB] = &arch_rtc_eb.common.hw,
1163 [CLK_KPB_RTC_EB] = &kpb_rtc_eb.common.hw,
1164 [CLK_AON_SYST_RTC_EB] = &aon_syst_rtc_eb.common.hw,
1165 [CLK_AP_SYST_RTC_EB] = &ap_syst_rtc_eb.common.hw,
1166 [CLK_AON_TMR_RTC_EB] = &aon_tmr_rtc_eb.common.hw,
1167 [CLK_AP_TMR0_RTC_EB] = &ap_tmr0_rtc_eb.common.hw,
1168 [CLK_EIC_RTC_EB] = &eic_rtc_eb.common.hw,
1169 [CLK_EIC_RTCDV5_EB] = &eic_rtcdv5_eb.common.hw,
1170 [CLK_AP_WDG_RTC_EB] = &ap_wdg_rtc_eb.common.hw,
1171 [CLK_AP_TMR1_RTC_EB] = &ap_tmr1_rtc_eb.common.hw,
1172 [CLK_AP_TMR2_RTC_EB] = &ap_tmr2_rtc_eb.common.hw,
1173 [CLK_DCXO_TMR_RTC_EB] = &dcxo_tmr_rtc_eb.common.hw,
1174 [CLK_BB_CAL_RTC_EB] = &bb_cal_rtc_eb.common.hw,
1175 [CLK_AVS_BIG_RTC_EB] = &avs_big_rtc_eb.common.hw,
1176 [CLK_AVS_LIT_RTC_EB] = &avs_lit_rtc_eb.common.hw,
1177 [CLK_AVS_GPU0_RTC_EB] = &avs_gpu0_rtc_eb.common.hw,
1178 [CLK_AVS_GPU1_RTC_EB] = &avs_gpu1_rtc_eb.common.hw,
1179 [CLK_GPU_TS_EB] = &gpu_ts_eb.common.hw,
1180 [CLK_RTCDV10_EB] = &rtcdv10_eb.common.hw,
1105 }, 1181 },
1106 .num = CLK_AON_GATE_NUM, 1182 .num = CLK_AON_GATE_NUM,
1107}; 1183};
diff --git a/drivers/clk/tegra/clk-emc.c b/drivers/clk/tegra/clk-emc.c
index 11a5066e5c27..5234acd30e89 100644
--- a/drivers/clk/tegra/clk-emc.c
+++ b/drivers/clk/tegra/clk-emc.c
@@ -515,7 +515,7 @@ struct clk *tegra_clk_register_emc(void __iomem *base, struct device_node *np,
515 515
516 init.name = "emc"; 516 init.name = "emc";
517 init.ops = &tegra_clk_emc_ops; 517 init.ops = &tegra_clk_emc_ops;
518 init.flags = 0; 518 init.flags = CLK_IS_CRITICAL;
519 init.parent_names = emc_parent_clk_names; 519 init.parent_names = emc_parent_clk_names;
520 init.num_parents = ARRAY_SIZE(emc_parent_clk_names); 520 init.num_parents = ARRAY_SIZE(emc_parent_clk_names);
521 521
diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c
index 7c369e21c91c..830d1c87fa7c 100644
--- a/drivers/clk/tegra/clk-pll.c
+++ b/drivers/clk/tegra/clk-pll.c
@@ -1151,6 +1151,8 @@ static const struct clk_ops tegra_clk_pllu_ops = {
1151 .enable = clk_pllu_enable, 1151 .enable = clk_pllu_enable,
1152 .disable = clk_pll_disable, 1152 .disable = clk_pll_disable,
1153 .recalc_rate = clk_pll_recalc_rate, 1153 .recalc_rate = clk_pll_recalc_rate,
1154 .round_rate = clk_pll_round_rate,
1155 .set_rate = clk_pll_set_rate,
1154}; 1156};
1155 1157
1156static int _pll_fixed_mdiv(struct tegra_clk_pll_params *pll_params, 1158static int _pll_fixed_mdiv(struct tegra_clk_pll_params *pll_params,
diff --git a/drivers/clk/tegra/clk-tegra-periph.c b/drivers/clk/tegra/clk-tegra-periph.c
index c02711927d79..2acba2986bc6 100644
--- a/drivers/clk/tegra/clk-tegra-periph.c
+++ b/drivers/clk/tegra/clk-tegra-periph.c
@@ -830,7 +830,7 @@ static struct tegra_periph_init_data gate_clks[] = {
830 GATE("xusb_host", "xusb_host_src", 89, 0, tegra_clk_xusb_host, 0), 830 GATE("xusb_host", "xusb_host_src", 89, 0, tegra_clk_xusb_host, 0),
831 GATE("xusb_ss", "xusb_ss_src", 156, 0, tegra_clk_xusb_ss, 0), 831 GATE("xusb_ss", "xusb_ss_src", 156, 0, tegra_clk_xusb_ss, 0),
832 GATE("xusb_dev", "xusb_dev_src", 95, 0, tegra_clk_xusb_dev, 0), 832 GATE("xusb_dev", "xusb_dev_src", 95, 0, tegra_clk_xusb_dev, 0),
833 GATE("emc", "emc_mux", 57, 0, tegra_clk_emc, CLK_IGNORE_UNUSED), 833 GATE("emc", "emc_mux", 57, 0, tegra_clk_emc, CLK_IS_CRITICAL),
834 GATE("sata_cold", "clk_m", 129, TEGRA_PERIPH_ON_APB, tegra_clk_sata_cold, 0), 834 GATE("sata_cold", "clk_m", 129, TEGRA_PERIPH_ON_APB, tegra_clk_sata_cold, 0),
835 GATE("ispa", "isp", 23, 0, tegra_clk_ispa, 0), 835 GATE("ispa", "isp", 23, 0, tegra_clk_ispa, 0),
836 GATE("ispb", "isp", 3, 0, tegra_clk_ispb, 0), 836 GATE("ispb", "isp", 3, 0, tegra_clk_ispb, 0),
diff --git a/drivers/clk/tegra/clk-tegra-super-gen4.c b/drivers/clk/tegra/clk-tegra-super-gen4.c
index 10047107c1dc..89d6b47a27a8 100644
--- a/drivers/clk/tegra/clk-tegra-super-gen4.c
+++ b/drivers/clk/tegra/clk-tegra-super-gen4.c
@@ -125,7 +125,8 @@ static void __init tegra_sclk_init(void __iomem *clk_base,
125 /* SCLK */ 125 /* SCLK */
126 dt_clk = tegra_lookup_dt_id(tegra_clk_sclk, tegra_clks); 126 dt_clk = tegra_lookup_dt_id(tegra_clk_sclk, tegra_clks);
127 if (dt_clk) { 127 if (dt_clk) {
128 clk = clk_register_divider(NULL, "sclk", "sclk_mux", 0, 128 clk = clk_register_divider(NULL, "sclk", "sclk_mux",
129 CLK_IS_CRITICAL,
129 clk_base + SCLK_DIVIDER, 0, 8, 130 clk_base + SCLK_DIVIDER, 0, 8,
130 0, &sysrate_lock); 131 0, &sysrate_lock);
131 *dt_clk = clk; 132 *dt_clk = clk;
@@ -137,7 +138,8 @@ static void __init tegra_sclk_init(void __iomem *clk_base,
137 clk = tegra_clk_register_super_mux("sclk", 138 clk = tegra_clk_register_super_mux("sclk",
138 gen_info->sclk_parents, 139 gen_info->sclk_parents,
139 gen_info->num_sclk_parents, 140 gen_info->num_sclk_parents,
140 CLK_SET_RATE_PARENT, 141 CLK_SET_RATE_PARENT |
142 CLK_IS_CRITICAL,
141 clk_base + SCLK_BURST_POLICY, 143 clk_base + SCLK_BURST_POLICY,
142 0, 4, 0, 0, NULL); 144 0, 4, 0, 0, NULL);
143 *dt_clk = clk; 145 *dt_clk = clk;
@@ -151,7 +153,7 @@ static void __init tegra_sclk_init(void __iomem *clk_base,
151 clk_base + SYSTEM_CLK_RATE, 4, 2, 0, 153 clk_base + SYSTEM_CLK_RATE, 4, 2, 0,
152 &sysrate_lock); 154 &sysrate_lock);
153 clk = clk_register_gate(NULL, "hclk", "hclk_div", 155 clk = clk_register_gate(NULL, "hclk", "hclk_div",
154 CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 156 CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
155 clk_base + SYSTEM_CLK_RATE, 157 clk_base + SYSTEM_CLK_RATE,
156 7, CLK_GATE_SET_TO_DISABLE, &sysrate_lock); 158 7, CLK_GATE_SET_TO_DISABLE, &sysrate_lock);
157 *dt_clk = clk; 159 *dt_clk = clk;
diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c
index 63087d17c3e2..5d5a22d529f5 100644
--- a/drivers/clk/tegra/clk-tegra114.c
+++ b/drivers/clk/tegra/clk-tegra114.c
@@ -955,8 +955,7 @@ static void __init tegra114_pll_init(void __iomem *clk_base,
955 955
956 /* PLLM */ 956 /* PLLM */
957 clk = tegra_clk_register_pllm("pll_m", "pll_ref", clk_base, pmc, 957 clk = tegra_clk_register_pllm("pll_m", "pll_ref", clk_base, pmc,
958 CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, 958 CLK_SET_RATE_GATE, &pll_m_params, NULL);
959 &pll_m_params, NULL);
960 clks[TEGRA114_CLK_PLL_M] = clk; 959 clks[TEGRA114_CLK_PLL_M] = clk;
961 960
962 /* PLLM_OUT1 */ 961 /* PLLM_OUT1 */
@@ -1190,6 +1189,7 @@ static struct tegra_clk_init_table init_table[] __initdata = {
1190 { TEGRA114_CLK_XUSB_HS_SRC, TEGRA114_CLK_XUSB_SS_DIV2, 61200000, 0 }, 1189 { TEGRA114_CLK_XUSB_HS_SRC, TEGRA114_CLK_XUSB_SS_DIV2, 61200000, 0 },
1191 { TEGRA114_CLK_XUSB_FALCON_SRC, TEGRA114_CLK_PLL_P, 204000000, 0 }, 1190 { TEGRA114_CLK_XUSB_FALCON_SRC, TEGRA114_CLK_PLL_P, 204000000, 0 },
1192 { TEGRA114_CLK_XUSB_HOST_SRC, TEGRA114_CLK_PLL_P, 102000000, 0 }, 1191 { TEGRA114_CLK_XUSB_HOST_SRC, TEGRA114_CLK_PLL_P, 102000000, 0 },
1192 { TEGRA114_CLK_VDE, TEGRA114_CLK_CLK_MAX, 600000000, 0 },
1193 /* must be the last entry */ 1193 /* must be the last entry */
1194 { TEGRA114_CLK_CLK_MAX, TEGRA114_CLK_CLK_MAX, 0, 0 }, 1194 { TEGRA114_CLK_CLK_MAX, TEGRA114_CLK_CLK_MAX, 0, 0 },
1195}; 1195};
diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c
index e81ea5b11577..50088e976611 100644
--- a/drivers/clk/tegra/clk-tegra124.c
+++ b/drivers/clk/tegra/clk-tegra124.c
@@ -1089,8 +1089,7 @@ static void __init tegra124_pll_init(void __iomem *clk_base,
1089 1089
1090 /* PLLM */ 1090 /* PLLM */
1091 clk = tegra_clk_register_pllm("pll_m", "pll_ref", clk_base, pmc, 1091 clk = tegra_clk_register_pllm("pll_m", "pll_ref", clk_base, pmc,
1092 CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, 1092 CLK_SET_RATE_GATE, &pll_m_params, NULL);
1093 &pll_m_params, NULL);
1094 clk_register_clkdev(clk, "pll_m", NULL); 1093 clk_register_clkdev(clk, "pll_m", NULL);
1095 clks[TEGRA124_CLK_PLL_M] = clk; 1094 clks[TEGRA124_CLK_PLL_M] = clk;
1096 1095
@@ -1099,7 +1098,7 @@ static void __init tegra124_pll_init(void __iomem *clk_base,
1099 clk_base + PLLM_OUT, 0, TEGRA_DIVIDER_ROUND_UP, 1098 clk_base + PLLM_OUT, 0, TEGRA_DIVIDER_ROUND_UP,
1100 8, 8, 1, NULL); 1099 8, 8, 1, NULL);
1101 clk = tegra_clk_register_pll_out("pll_m_out1", "pll_m_out1_div", 1100 clk = tegra_clk_register_pll_out("pll_m_out1", "pll_m_out1_div",
1102 clk_base + PLLM_OUT, 1, 0, CLK_IGNORE_UNUSED | 1101 clk_base + PLLM_OUT, 1, 0,
1103 CLK_SET_RATE_PARENT, 0, NULL); 1102 CLK_SET_RATE_PARENT, 0, NULL);
1104 clk_register_clkdev(clk, "pll_m_out1", NULL); 1103 clk_register_clkdev(clk, "pll_m_out1", NULL);
1105 clks[TEGRA124_CLK_PLL_M_OUT1] = clk; 1104 clks[TEGRA124_CLK_PLL_M_OUT1] = clk;
@@ -1268,11 +1267,11 @@ static struct tegra_clk_init_table common_init_table[] __initdata = {
1268 { TEGRA124_CLK_I2S2, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0 }, 1267 { TEGRA124_CLK_I2S2, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0 },
1269 { TEGRA124_CLK_I2S3, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0 }, 1268 { TEGRA124_CLK_I2S3, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0 },
1270 { TEGRA124_CLK_I2S4, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0 }, 1269 { TEGRA124_CLK_I2S4, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0 },
1271 { TEGRA124_CLK_VDE, TEGRA124_CLK_PLL_P, 0, 0 }, 1270 { TEGRA124_CLK_VDE, TEGRA124_CLK_CLK_MAX, 600000000, 0 },
1272 { TEGRA124_CLK_HOST1X, TEGRA124_CLK_PLL_P, 136000000, 1 }, 1271 { TEGRA124_CLK_HOST1X, TEGRA124_CLK_PLL_P, 136000000, 1 },
1273 { TEGRA124_CLK_DSIALP, TEGRA124_CLK_PLL_P, 68000000, 0 }, 1272 { TEGRA124_CLK_DSIALP, TEGRA124_CLK_PLL_P, 68000000, 0 },
1274 { TEGRA124_CLK_DSIBLP, TEGRA124_CLK_PLL_P, 68000000, 0 }, 1273 { TEGRA124_CLK_DSIBLP, TEGRA124_CLK_PLL_P, 68000000, 0 },
1275 { TEGRA124_CLK_SCLK, TEGRA124_CLK_PLL_P_OUT2, 102000000, 1 }, 1274 { TEGRA124_CLK_SCLK, TEGRA124_CLK_PLL_P_OUT2, 102000000, 0 },
1276 { TEGRA124_CLK_DFLL_SOC, TEGRA124_CLK_PLL_P, 51000000, 1 }, 1275 { TEGRA124_CLK_DFLL_SOC, TEGRA124_CLK_PLL_P, 51000000, 1 },
1277 { TEGRA124_CLK_DFLL_REF, TEGRA124_CLK_PLL_P, 51000000, 1 }, 1276 { TEGRA124_CLK_DFLL_REF, TEGRA124_CLK_PLL_P, 51000000, 1 },
1278 { TEGRA124_CLK_PLL_C, TEGRA124_CLK_CLK_MAX, 768000000, 0 }, 1277 { TEGRA124_CLK_PLL_C, TEGRA124_CLK_CLK_MAX, 768000000, 0 },
diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c
index cbd5a2e5c569..0ee56dd04cec 100644
--- a/drivers/clk/tegra/clk-tegra20.c
+++ b/drivers/clk/tegra/clk-tegra20.c
@@ -576,6 +576,7 @@ static struct tegra_clk tegra20_clks[tegra_clk_max] __initdata = {
576 [tegra_clk_afi] = { .dt_id = TEGRA20_CLK_AFI, .present = true }, 576 [tegra_clk_afi] = { .dt_id = TEGRA20_CLK_AFI, .present = true },
577 [tegra_clk_fuse] = { .dt_id = TEGRA20_CLK_FUSE, .present = true }, 577 [tegra_clk_fuse] = { .dt_id = TEGRA20_CLK_FUSE, .present = true },
578 [tegra_clk_kfuse] = { .dt_id = TEGRA20_CLK_KFUSE, .present = true }, 578 [tegra_clk_kfuse] = { .dt_id = TEGRA20_CLK_KFUSE, .present = true },
579 [tegra_clk_emc] = { .dt_id = TEGRA20_CLK_EMC, .present = true },
579}; 580};
580 581
581static unsigned long tegra20_clk_measure_input_freq(void) 582static unsigned long tegra20_clk_measure_input_freq(void)
@@ -651,8 +652,7 @@ static void tegra20_pll_init(void)
651 652
652 /* PLLM */ 653 /* PLLM */
653 clk = tegra_clk_register_pll("pll_m", "pll_ref", clk_base, NULL, 654 clk = tegra_clk_register_pll("pll_m", "pll_ref", clk_base, NULL,
654 CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, 655 CLK_SET_RATE_GATE, &pll_m_params, NULL);
655 &pll_m_params, NULL);
656 clks[TEGRA20_CLK_PLL_M] = clk; 656 clks[TEGRA20_CLK_PLL_M] = clk;
657 657
658 /* PLLM_OUT1 */ 658 /* PLLM_OUT1 */
@@ -660,7 +660,7 @@ static void tegra20_pll_init(void)
660 clk_base + PLLM_OUT, 0, TEGRA_DIVIDER_ROUND_UP, 660 clk_base + PLLM_OUT, 0, TEGRA_DIVIDER_ROUND_UP,
661 8, 8, 1, NULL); 661 8, 8, 1, NULL);
662 clk = tegra_clk_register_pll_out("pll_m_out1", "pll_m_out1_div", 662 clk = tegra_clk_register_pll_out("pll_m_out1", "pll_m_out1_div",
663 clk_base + PLLM_OUT, 1, 0, CLK_IGNORE_UNUSED | 663 clk_base + PLLM_OUT, 1, 0,
664 CLK_SET_RATE_PARENT, 0, NULL); 664 CLK_SET_RATE_PARENT, 0, NULL);
665 clks[TEGRA20_CLK_PLL_M_OUT1] = clk; 665 clks[TEGRA20_CLK_PLL_M_OUT1] = clk;
666 666
@@ -723,7 +723,8 @@ static void tegra20_super_clk_init(void)
723 723
724 /* SCLK */ 724 /* SCLK */
725 clk = tegra_clk_register_super_mux("sclk", sclk_parents, 725 clk = tegra_clk_register_super_mux("sclk", sclk_parents,
726 ARRAY_SIZE(sclk_parents), CLK_SET_RATE_PARENT, 726 ARRAY_SIZE(sclk_parents),
727 CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
727 clk_base + SCLK_BURST_POLICY, 0, 4, 0, 0, NULL); 728 clk_base + SCLK_BURST_POLICY, 0, 4, 0, 0, NULL);
728 clks[TEGRA20_CLK_SCLK] = clk; 729 clks[TEGRA20_CLK_SCLK] = clk;
729 730
@@ -814,9 +815,6 @@ static void __init tegra20_periph_clk_init(void)
814 CLK_SET_RATE_NO_REPARENT, 815 CLK_SET_RATE_NO_REPARENT,
815 clk_base + CLK_SOURCE_EMC, 816 clk_base + CLK_SOURCE_EMC,
816 30, 2, 0, &emc_lock); 817 30, 2, 0, &emc_lock);
817 clk = tegra_clk_register_periph_gate("emc", "emc_mux", 0, clk_base, 0,
818 57, periph_clk_enb_refcnt);
819 clks[TEGRA20_CLK_EMC] = clk;
820 818
821 clk = tegra_clk_register_mc("mc", "emc_mux", clk_base + CLK_SOURCE_EMC, 819 clk = tegra_clk_register_mc("mc", "emc_mux", clk_base + CLK_SOURCE_EMC,
822 &emc_lock); 820 &emc_lock);
@@ -1019,13 +1017,12 @@ static struct tegra_clk_init_table init_table[] __initdata = {
1019 { TEGRA20_CLK_PLL_P_OUT2, TEGRA20_CLK_CLK_MAX, 48000000, 1 }, 1017 { TEGRA20_CLK_PLL_P_OUT2, TEGRA20_CLK_CLK_MAX, 48000000, 1 },
1020 { TEGRA20_CLK_PLL_P_OUT3, TEGRA20_CLK_CLK_MAX, 72000000, 1 }, 1018 { TEGRA20_CLK_PLL_P_OUT3, TEGRA20_CLK_CLK_MAX, 72000000, 1 },
1021 { TEGRA20_CLK_PLL_P_OUT4, TEGRA20_CLK_CLK_MAX, 24000000, 1 }, 1019 { TEGRA20_CLK_PLL_P_OUT4, TEGRA20_CLK_CLK_MAX, 24000000, 1 },
1022 { TEGRA20_CLK_PLL_C, TEGRA20_CLK_CLK_MAX, 600000000, 1 }, 1020 { TEGRA20_CLK_PLL_C, TEGRA20_CLK_CLK_MAX, 600000000, 0 },
1023 { TEGRA20_CLK_PLL_C_OUT1, TEGRA20_CLK_CLK_MAX, 216000000, 1 }, 1021 { TEGRA20_CLK_PLL_C_OUT1, TEGRA20_CLK_CLK_MAX, 240000000, 0 },
1024 { TEGRA20_CLK_SCLK, TEGRA20_CLK_PLL_C_OUT1, 0, 1 }, 1022 { TEGRA20_CLK_SCLK, TEGRA20_CLK_PLL_C_OUT1, 240000000, 0 },
1025 { TEGRA20_CLK_HCLK, TEGRA20_CLK_CLK_MAX, 0, 1 }, 1023 { TEGRA20_CLK_HCLK, TEGRA20_CLK_CLK_MAX, 240000000, 0 },
1026 { TEGRA20_CLK_PCLK, TEGRA20_CLK_CLK_MAX, 60000000, 1 }, 1024 { TEGRA20_CLK_PCLK, TEGRA20_CLK_CLK_MAX, 60000000, 0 },
1027 { TEGRA20_CLK_CSITE, TEGRA20_CLK_CLK_MAX, 0, 1 }, 1025 { TEGRA20_CLK_CSITE, TEGRA20_CLK_CLK_MAX, 0, 1 },
1028 { TEGRA20_CLK_EMC, TEGRA20_CLK_CLK_MAX, 0, 1 },
1029 { TEGRA20_CLK_CCLK, TEGRA20_CLK_CLK_MAX, 0, 1 }, 1026 { TEGRA20_CLK_CCLK, TEGRA20_CLK_CLK_MAX, 0, 1 },
1030 { TEGRA20_CLK_UARTA, TEGRA20_CLK_PLL_P, 0, 0 }, 1027 { TEGRA20_CLK_UARTA, TEGRA20_CLK_PLL_P, 0, 0 },
1031 { TEGRA20_CLK_UARTB, TEGRA20_CLK_PLL_P, 0, 0 }, 1028 { TEGRA20_CLK_UARTB, TEGRA20_CLK_PLL_P, 0, 0 },
@@ -1051,6 +1048,7 @@ static struct tegra_clk_init_table init_table[] __initdata = {
1051 { TEGRA20_CLK_DISP2, TEGRA20_CLK_PLL_P, 600000000, 0 }, 1048 { TEGRA20_CLK_DISP2, TEGRA20_CLK_PLL_P, 600000000, 0 },
1052 { TEGRA20_CLK_GR2D, TEGRA20_CLK_PLL_C, 300000000, 0 }, 1049 { TEGRA20_CLK_GR2D, TEGRA20_CLK_PLL_C, 300000000, 0 },
1053 { TEGRA20_CLK_GR3D, TEGRA20_CLK_PLL_C, 300000000, 0 }, 1050 { TEGRA20_CLK_GR3D, TEGRA20_CLK_PLL_C, 300000000, 0 },
1051 { TEGRA20_CLK_VDE, TEGRA20_CLK_CLK_MAX, 300000000, 0 },
1054 /* must be the last entry */ 1052 /* must be the last entry */
1055 { TEGRA20_CLK_CLK_MAX, TEGRA20_CLK_CLK_MAX, 0, 0 }, 1053 { TEGRA20_CLK_CLK_MAX, TEGRA20_CLK_CLK_MAX, 0, 0 },
1056}; 1054};
diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c
index 9e6260869eb9..9fb5d51ccce4 100644
--- a/drivers/clk/tegra/clk-tegra210.c
+++ b/drivers/clk/tegra/clk-tegra210.c
@@ -22,10 +22,12 @@
22#include <linux/of_address.h> 22#include <linux/of_address.h>
23#include <linux/delay.h> 23#include <linux/delay.h>
24#include <linux/export.h> 24#include <linux/export.h>
25#include <linux/mutex.h>
25#include <linux/clk/tegra.h> 26#include <linux/clk/tegra.h>
26#include <dt-bindings/clock/tegra210-car.h> 27#include <dt-bindings/clock/tegra210-car.h>
27#include <dt-bindings/reset/tegra210-car.h> 28#include <dt-bindings/reset/tegra210-car.h>
28#include <linux/iopoll.h> 29#include <linux/iopoll.h>
30#include <soc/tegra/pmc.h>
29 31
30#include "clk.h" 32#include "clk.h"
31#include "clk-id.h" 33#include "clk-id.h"
@@ -41,6 +43,7 @@
41#define CLK_SOURCE_CSITE 0x1d4 43#define CLK_SOURCE_CSITE 0x1d4
42#define CLK_SOURCE_EMC 0x19c 44#define CLK_SOURCE_EMC 0x19c
43#define CLK_SOURCE_SOR1 0x410 45#define CLK_SOURCE_SOR1 0x410
46#define CLK_SOURCE_LA 0x1f8
44 47
45#define PLLC_BASE 0x80 48#define PLLC_BASE 0x80
46#define PLLC_OUT 0x84 49#define PLLC_OUT 0x84
@@ -231,6 +234,30 @@
231#define CLK_RST_CONTROLLER_RST_DEV_Y_SET 0x2a8 234#define CLK_RST_CONTROLLER_RST_DEV_Y_SET 0x2a8
232#define CLK_RST_CONTROLLER_RST_DEV_Y_CLR 0x2ac 235#define CLK_RST_CONTROLLER_RST_DEV_Y_CLR 0x2ac
233 236
237#define LVL2_CLK_GATE_OVRA 0xf8
238#define LVL2_CLK_GATE_OVRC 0x3a0
239#define LVL2_CLK_GATE_OVRD 0x3a4
240#define LVL2_CLK_GATE_OVRE 0x554
241
242/* I2S registers to handle during APE MBIST WAR */
243#define TEGRA210_I2S_BASE 0x1000
244#define TEGRA210_I2S_SIZE 0x100
245#define TEGRA210_I2S_CTRLS 5
246#define TEGRA210_I2S_CG 0x88
247#define TEGRA210_I2S_CTRL 0xa0
248
249/* DISPA registers to handle during MBIST WAR */
250#define DC_CMD_DISPLAY_COMMAND 0xc8
251#define DC_COM_DSC_TOP_CTL 0xcf8
252
253/* VIC register to handle during MBIST WAR */
254#define NV_PVIC_THI_SLCG_OVERRIDE_LOW 0x8c
255
256/* APE, DISPA and VIC base addesses needed for MBIST WAR */
257#define TEGRA210_AHUB_BASE 0x702d0000
258#define TEGRA210_DISPA_BASE 0x54200000
259#define TEGRA210_VIC_BASE 0x54340000
260
234/* 261/*
235 * SDM fractional divisor is 16-bit 2's complement signed number within 262 * SDM fractional divisor is 16-bit 2's complement signed number within
236 * (-2^12 ... 2^12-1) range. Represented in PLL data structure as unsigned 263 * (-2^12 ... 2^12-1) range. Represented in PLL data structure as unsigned
@@ -255,8 +282,22 @@ static struct cpu_clk_suspend_context {
255} tegra210_cpu_clk_sctx; 282} tegra210_cpu_clk_sctx;
256#endif 283#endif
257 284
285struct tegra210_domain_mbist_war {
286 void (*handle_lvl2_ovr)(struct tegra210_domain_mbist_war *mbist);
287 const u32 lvl2_offset;
288 const u32 lvl2_mask;
289 const unsigned int num_clks;
290 const unsigned int *clk_init_data;
291 struct clk_bulk_data *clks;
292};
293
294static struct clk **clks;
295
258static void __iomem *clk_base; 296static void __iomem *clk_base;
259static void __iomem *pmc_base; 297static void __iomem *pmc_base;
298static void __iomem *ahub_base;
299static void __iomem *dispa_base;
300static void __iomem *vic_base;
260 301
261static unsigned long osc_freq; 302static unsigned long osc_freq;
262static unsigned long pll_ref_freq; 303static unsigned long pll_ref_freq;
@@ -267,6 +308,7 @@ static DEFINE_SPINLOCK(pll_re_lock);
267static DEFINE_SPINLOCK(pll_u_lock); 308static DEFINE_SPINLOCK(pll_u_lock);
268static DEFINE_SPINLOCK(sor1_lock); 309static DEFINE_SPINLOCK(sor1_lock);
269static DEFINE_SPINLOCK(emc_lock); 310static DEFINE_SPINLOCK(emc_lock);
311static DEFINE_MUTEX(lvl2_ovr_lock);
270 312
271/* possible OSC frequencies in Hz */ 313/* possible OSC frequencies in Hz */
272static unsigned long tegra210_input_freq[] = { 314static unsigned long tegra210_input_freq[] = {
@@ -310,6 +352,8 @@ static const char *mux_pllmcp_clkm[] = {
310#define PLLA_MISC2_WRITE_MASK 0x06ffffff 352#define PLLA_MISC2_WRITE_MASK 0x06ffffff
311 353
312/* PLLD */ 354/* PLLD */
355#define PLLD_BASE_CSI_CLKSOURCE (1 << 23)
356
313#define PLLD_MISC0_EN_SDM (1 << 16) 357#define PLLD_MISC0_EN_SDM (1 << 16)
314#define PLLD_MISC0_LOCK_OVERRIDE (1 << 17) 358#define PLLD_MISC0_LOCK_OVERRIDE (1 << 17)
315#define PLLD_MISC0_LOCK_ENABLE (1 << 18) 359#define PLLD_MISC0_LOCK_ENABLE (1 << 18)
@@ -513,6 +557,115 @@ void tegra210_set_sata_pll_seq_sw(bool state)
513} 557}
514EXPORT_SYMBOL_GPL(tegra210_set_sata_pll_seq_sw); 558EXPORT_SYMBOL_GPL(tegra210_set_sata_pll_seq_sw);
515 559
560static void tegra210_generic_mbist_war(struct tegra210_domain_mbist_war *mbist)
561{
562 u32 val;
563
564 val = readl_relaxed(clk_base + mbist->lvl2_offset);
565 writel_relaxed(val | mbist->lvl2_mask, clk_base + mbist->lvl2_offset);
566 fence_udelay(1, clk_base);
567 writel_relaxed(val, clk_base + mbist->lvl2_offset);
568 fence_udelay(1, clk_base);
569}
570
571static void tegra210_venc_mbist_war(struct tegra210_domain_mbist_war *mbist)
572{
573 u32 csi_src, ovra, ovre;
574 unsigned long flags = 0;
575
576 spin_lock_irqsave(&pll_d_lock, flags);
577
578 csi_src = readl_relaxed(clk_base + PLLD_BASE);
579 writel_relaxed(csi_src | PLLD_BASE_CSI_CLKSOURCE, clk_base + PLLD_BASE);
580 fence_udelay(1, clk_base);
581
582 ovra = readl_relaxed(clk_base + LVL2_CLK_GATE_OVRA);
583 writel_relaxed(ovra | BIT(15), clk_base + LVL2_CLK_GATE_OVRA);
584 ovre = readl_relaxed(clk_base + LVL2_CLK_GATE_OVRE);
585 writel_relaxed(ovre | BIT(3), clk_base + LVL2_CLK_GATE_OVRE);
586 fence_udelay(1, clk_base);
587
588 writel_relaxed(ovra, clk_base + LVL2_CLK_GATE_OVRA);
589 writel_relaxed(ovre, clk_base + LVL2_CLK_GATE_OVRE);
590 writel_relaxed(csi_src, clk_base + PLLD_BASE);
591 fence_udelay(1, clk_base);
592
593 spin_unlock_irqrestore(&pll_d_lock, flags);
594}
595
596static void tegra210_disp_mbist_war(struct tegra210_domain_mbist_war *mbist)
597{
598 u32 ovra, dsc_top_ctrl;
599
600 ovra = readl_relaxed(clk_base + LVL2_CLK_GATE_OVRA);
601 writel_relaxed(ovra | BIT(1), clk_base + LVL2_CLK_GATE_OVRA);
602 fence_udelay(1, clk_base);
603
604 dsc_top_ctrl = readl_relaxed(dispa_base + DC_COM_DSC_TOP_CTL);
605 writel_relaxed(dsc_top_ctrl | BIT(2), dispa_base + DC_COM_DSC_TOP_CTL);
606 readl_relaxed(dispa_base + DC_CMD_DISPLAY_COMMAND);
607 writel_relaxed(dsc_top_ctrl, dispa_base + DC_COM_DSC_TOP_CTL);
608 readl_relaxed(dispa_base + DC_CMD_DISPLAY_COMMAND);
609
610 writel_relaxed(ovra, clk_base + LVL2_CLK_GATE_OVRA);
611 fence_udelay(1, clk_base);
612}
613
614static void tegra210_vic_mbist_war(struct tegra210_domain_mbist_war *mbist)
615{
616 u32 ovre, val;
617
618 ovre = readl_relaxed(clk_base + LVL2_CLK_GATE_OVRE);
619 writel_relaxed(ovre | BIT(5), clk_base + LVL2_CLK_GATE_OVRE);
620 fence_udelay(1, clk_base);
621
622 val = readl_relaxed(vic_base + NV_PVIC_THI_SLCG_OVERRIDE_LOW);
623 writel_relaxed(val | BIT(0) | GENMASK(7, 2) | BIT(24),
624 vic_base + NV_PVIC_THI_SLCG_OVERRIDE_LOW);
625 fence_udelay(1, vic_base + NV_PVIC_THI_SLCG_OVERRIDE_LOW);
626
627 writel_relaxed(val, vic_base + NV_PVIC_THI_SLCG_OVERRIDE_LOW);
628 readl(vic_base + NV_PVIC_THI_SLCG_OVERRIDE_LOW);
629
630 writel_relaxed(ovre, clk_base + LVL2_CLK_GATE_OVRE);
631 fence_udelay(1, clk_base);
632}
633
634static void tegra210_ape_mbist_war(struct tegra210_domain_mbist_war *mbist)
635{
636 void __iomem *i2s_base;
637 unsigned int i;
638 u32 ovrc, ovre;
639
640 ovrc = readl_relaxed(clk_base + LVL2_CLK_GATE_OVRC);
641 ovre = readl_relaxed(clk_base + LVL2_CLK_GATE_OVRE);
642 writel_relaxed(ovrc | BIT(1), clk_base + LVL2_CLK_GATE_OVRC);
643 writel_relaxed(ovre | BIT(10) | BIT(11),
644 clk_base + LVL2_CLK_GATE_OVRE);
645 fence_udelay(1, clk_base);
646
647 i2s_base = ahub_base + TEGRA210_I2S_BASE;
648
649 for (i = 0; i < TEGRA210_I2S_CTRLS; i++) {
650 u32 i2s_ctrl;
651
652 i2s_ctrl = readl_relaxed(i2s_base + TEGRA210_I2S_CTRL);
653 writel_relaxed(i2s_ctrl | BIT(10),
654 i2s_base + TEGRA210_I2S_CTRL);
655 writel_relaxed(0, i2s_base + TEGRA210_I2S_CG);
656 readl(i2s_base + TEGRA210_I2S_CG);
657 writel_relaxed(1, i2s_base + TEGRA210_I2S_CG);
658 writel_relaxed(i2s_ctrl, i2s_base + TEGRA210_I2S_CTRL);
659 readl(i2s_base + TEGRA210_I2S_CTRL);
660
661 i2s_base += TEGRA210_I2S_SIZE;
662 }
663
664 writel_relaxed(ovrc, clk_base + LVL2_CLK_GATE_OVRC);
665 writel_relaxed(ovre, clk_base + LVL2_CLK_GATE_OVRE);
666 fence_udelay(1, clk_base);
667}
668
516static inline void _pll_misc_chk_default(void __iomem *base, 669static inline void _pll_misc_chk_default(void __iomem *base,
517 struct tegra_clk_pll_params *params, 670 struct tegra_clk_pll_params *params,
518 u8 misc_num, u32 default_val, u32 mask) 671 u8 misc_num, u32 default_val, u32 mask)
@@ -2411,13 +2564,150 @@ static struct tegra_audio_clk_info tegra210_audio_plls[] = {
2411 { "pll_a1", &pll_a1_params, tegra_clk_pll_a1, "pll_ref" }, 2564 { "pll_a1", &pll_a1_params, tegra_clk_pll_a1, "pll_ref" },
2412}; 2565};
2413 2566
2414static struct clk **clks;
2415
2416static const char * const aclk_parents[] = { 2567static const char * const aclk_parents[] = {
2417 "pll_a1", "pll_c", "pll_p", "pll_a_out0", "pll_c2", "pll_c3", 2568 "pll_a1", "pll_c", "pll_p", "pll_a_out0", "pll_c2", "pll_c3",
2418 "clk_m" 2569 "clk_m"
2419}; 2570};
2420 2571
2572static const unsigned int nvjpg_slcg_clkids[] = { TEGRA210_CLK_NVDEC };
2573static const unsigned int nvdec_slcg_clkids[] = { TEGRA210_CLK_NVJPG };
2574static const unsigned int sor_slcg_clkids[] = { TEGRA210_CLK_HDA2CODEC_2X,
2575 TEGRA210_CLK_HDA2HDMI, TEGRA210_CLK_DISP1, TEGRA210_CLK_DISP2 };
2576static const unsigned int disp_slcg_clkids[] = { TEGRA210_CLK_LA,
2577 TEGRA210_CLK_HOST1X};
2578static const unsigned int xusba_slcg_clkids[] = { TEGRA210_CLK_XUSB_HOST,
2579 TEGRA210_CLK_XUSB_DEV };
2580static const unsigned int xusbb_slcg_clkids[] = { TEGRA210_CLK_XUSB_HOST,
2581 TEGRA210_CLK_XUSB_SS };
2582static const unsigned int xusbc_slcg_clkids[] = { TEGRA210_CLK_XUSB_DEV,
2583 TEGRA210_CLK_XUSB_SS };
2584static const unsigned int venc_slcg_clkids[] = { TEGRA210_CLK_HOST1X,
2585 TEGRA210_CLK_PLL_D };
2586static const unsigned int ape_slcg_clkids[] = { TEGRA210_CLK_ACLK,
2587 TEGRA210_CLK_I2S0, TEGRA210_CLK_I2S1, TEGRA210_CLK_I2S2,
2588 TEGRA210_CLK_I2S3, TEGRA210_CLK_I2S4, TEGRA210_CLK_SPDIF_OUT,
2589 TEGRA210_CLK_D_AUDIO };
2590static const unsigned int vic_slcg_clkids[] = { TEGRA210_CLK_HOST1X };
2591
2592static struct tegra210_domain_mbist_war tegra210_pg_mbist_war[] = {
2593 [TEGRA_POWERGATE_VENC] = {
2594 .handle_lvl2_ovr = tegra210_venc_mbist_war,
2595 .num_clks = ARRAY_SIZE(venc_slcg_clkids),
2596 .clk_init_data = venc_slcg_clkids,
2597 },
2598 [TEGRA_POWERGATE_SATA] = {
2599 .handle_lvl2_ovr = tegra210_generic_mbist_war,
2600 .lvl2_offset = LVL2_CLK_GATE_OVRC,
2601 .lvl2_mask = BIT(0) | BIT(17) | BIT(19),
2602 },
2603 [TEGRA_POWERGATE_MPE] = {
2604 .handle_lvl2_ovr = tegra210_generic_mbist_war,
2605 .lvl2_offset = LVL2_CLK_GATE_OVRE,
2606 .lvl2_mask = BIT(2),
2607 },
2608 [TEGRA_POWERGATE_SOR] = {
2609 .handle_lvl2_ovr = tegra210_generic_mbist_war,
2610 .num_clks = ARRAY_SIZE(sor_slcg_clkids),
2611 .clk_init_data = sor_slcg_clkids,
2612 .lvl2_offset = LVL2_CLK_GATE_OVRA,
2613 .lvl2_mask = BIT(1) | BIT(2),
2614 },
2615 [TEGRA_POWERGATE_DIS] = {
2616 .handle_lvl2_ovr = tegra210_disp_mbist_war,
2617 .num_clks = ARRAY_SIZE(disp_slcg_clkids),
2618 .clk_init_data = disp_slcg_clkids,
2619 },
2620 [TEGRA_POWERGATE_DISB] = {
2621 .num_clks = ARRAY_SIZE(disp_slcg_clkids),
2622 .clk_init_data = disp_slcg_clkids,
2623 .handle_lvl2_ovr = tegra210_generic_mbist_war,
2624 .lvl2_offset = LVL2_CLK_GATE_OVRA,
2625 .lvl2_mask = BIT(2),
2626 },
2627 [TEGRA_POWERGATE_XUSBA] = {
2628 .num_clks = ARRAY_SIZE(xusba_slcg_clkids),
2629 .clk_init_data = xusba_slcg_clkids,
2630 .handle_lvl2_ovr = tegra210_generic_mbist_war,
2631 .lvl2_offset = LVL2_CLK_GATE_OVRC,
2632 .lvl2_mask = BIT(30) | BIT(31),
2633 },
2634 [TEGRA_POWERGATE_XUSBB] = {
2635 .num_clks = ARRAY_SIZE(xusbb_slcg_clkids),
2636 .clk_init_data = xusbb_slcg_clkids,
2637 .handle_lvl2_ovr = tegra210_generic_mbist_war,
2638 .lvl2_offset = LVL2_CLK_GATE_OVRC,
2639 .lvl2_mask = BIT(30) | BIT(31),
2640 },
2641 [TEGRA_POWERGATE_XUSBC] = {
2642 .num_clks = ARRAY_SIZE(xusbc_slcg_clkids),
2643 .clk_init_data = xusbc_slcg_clkids,
2644 .handle_lvl2_ovr = tegra210_generic_mbist_war,
2645 .lvl2_offset = LVL2_CLK_GATE_OVRC,
2646 .lvl2_mask = BIT(30) | BIT(31),
2647 },
2648 [TEGRA_POWERGATE_VIC] = {
2649 .num_clks = ARRAY_SIZE(vic_slcg_clkids),
2650 .clk_init_data = vic_slcg_clkids,
2651 .handle_lvl2_ovr = tegra210_vic_mbist_war,
2652 },
2653 [TEGRA_POWERGATE_NVDEC] = {
2654 .num_clks = ARRAY_SIZE(nvdec_slcg_clkids),
2655 .clk_init_data = nvdec_slcg_clkids,
2656 .handle_lvl2_ovr = tegra210_generic_mbist_war,
2657 .lvl2_offset = LVL2_CLK_GATE_OVRC,
2658 .lvl2_mask = BIT(9) | BIT(31),
2659 },
2660 [TEGRA_POWERGATE_NVJPG] = {
2661 .num_clks = ARRAY_SIZE(nvjpg_slcg_clkids),
2662 .clk_init_data = nvjpg_slcg_clkids,
2663 .handle_lvl2_ovr = tegra210_generic_mbist_war,
2664 .lvl2_offset = LVL2_CLK_GATE_OVRC,
2665 .lvl2_mask = BIT(9) | BIT(31),
2666 },
2667 [TEGRA_POWERGATE_AUD] = {
2668 .num_clks = ARRAY_SIZE(ape_slcg_clkids),
2669 .clk_init_data = ape_slcg_clkids,
2670 .handle_lvl2_ovr = tegra210_ape_mbist_war,
2671 },
2672 [TEGRA_POWERGATE_VE2] = {
2673 .handle_lvl2_ovr = tegra210_generic_mbist_war,
2674 .lvl2_offset = LVL2_CLK_GATE_OVRD,
2675 .lvl2_mask = BIT(22),
2676 },
2677};
2678
2679int tegra210_clk_handle_mbist_war(unsigned int id)
2680{
2681 int err;
2682 struct tegra210_domain_mbist_war *mbist_war;
2683
2684 if (id >= ARRAY_SIZE(tegra210_pg_mbist_war)) {
2685 WARN(1, "unknown domain id in MBIST WAR handler\n");
2686 return -EINVAL;
2687 }
2688
2689 mbist_war = &tegra210_pg_mbist_war[id];
2690 if (!mbist_war->handle_lvl2_ovr)
2691 return 0;
2692
2693 if (mbist_war->num_clks && !mbist_war->clks)
2694 return -ENODEV;
2695
2696 err = clk_bulk_prepare_enable(mbist_war->num_clks, mbist_war->clks);
2697 if (err < 0)
2698 return err;
2699
2700 mutex_lock(&lvl2_ovr_lock);
2701
2702 mbist_war->handle_lvl2_ovr(mbist_war);
2703
2704 mutex_unlock(&lvl2_ovr_lock);
2705
2706 clk_bulk_disable_unprepare(mbist_war->num_clks, mbist_war->clks);
2707
2708 return 0;
2709}
2710
2421void tegra210_put_utmipll_in_iddq(void) 2711void tegra210_put_utmipll_in_iddq(void)
2422{ 2712{
2423 u32 reg; 2713 u32 reg;
@@ -2654,6 +2944,13 @@ static struct tegra_periph_init_data tegra210_periph[] = {
2654 sor1_parents_idx, 0, &sor1_lock), 2944 sor1_parents_idx, 0, &sor1_lock),
2655}; 2945};
2656 2946
2947static const char * const la_parents[] = {
2948 "pll_p", "pll_c2", "pll_c", "pll_c3", "pll_re_out1", "pll_a1", "clk_m", "pll_c4_out0"
2949};
2950
2951static struct tegra_clk_periph tegra210_la =
2952 TEGRA_CLK_PERIPH(29, 7, 9, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, 76, 0, NULL, 0);
2953
2657static __init void tegra210_periph_clk_init(void __iomem *clk_base, 2954static __init void tegra210_periph_clk_init(void __iomem *clk_base,
2658 void __iomem *pmc_base) 2955 void __iomem *pmc_base)
2659{ 2956{
@@ -2700,6 +2997,12 @@ static __init void tegra210_periph_clk_init(void __iomem *clk_base,
2700 periph_clk_enb_refcnt); 2997 periph_clk_enb_refcnt);
2701 clks[TEGRA210_CLK_DSIB] = clk; 2998 clks[TEGRA210_CLK_DSIB] = clk;
2702 2999
3000 /* la */
3001 clk = tegra_clk_register_periph("la", la_parents,
3002 ARRAY_SIZE(la_parents), &tegra210_la, clk_base,
3003 CLK_SOURCE_LA, 0);
3004 clks[TEGRA210_CLK_LA] = clk;
3005
2703 /* emc mux */ 3006 /* emc mux */
2704 clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm, 3007 clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm,
2705 ARRAY_SIZE(mux_pllmcp_clkm), 0, 3008 ARRAY_SIZE(mux_pllmcp_clkm), 0,
@@ -3025,7 +3328,7 @@ static struct tegra_clk_init_table init_table[] __initdata = {
3025 { TEGRA210_CLK_I2S4, TEGRA210_CLK_PLL_A_OUT0, 11289600, 0 }, 3328 { TEGRA210_CLK_I2S4, TEGRA210_CLK_PLL_A_OUT0, 11289600, 0 },
3026 { TEGRA210_CLK_HOST1X, TEGRA210_CLK_PLL_P, 136000000, 1 }, 3329 { TEGRA210_CLK_HOST1X, TEGRA210_CLK_PLL_P, 136000000, 1 },
3027 { TEGRA210_CLK_SCLK_MUX, TEGRA210_CLK_PLL_P, 0, 1 }, 3330 { TEGRA210_CLK_SCLK_MUX, TEGRA210_CLK_PLL_P, 0, 1 },
3028 { TEGRA210_CLK_SCLK, TEGRA210_CLK_CLK_MAX, 102000000, 1 }, 3331 { TEGRA210_CLK_SCLK, TEGRA210_CLK_CLK_MAX, 102000000, 0 },
3029 { TEGRA210_CLK_DFLL_SOC, TEGRA210_CLK_PLL_P, 51000000, 1 }, 3332 { TEGRA210_CLK_DFLL_SOC, TEGRA210_CLK_PLL_P, 51000000, 1 },
3030 { TEGRA210_CLK_DFLL_REF, TEGRA210_CLK_PLL_P, 51000000, 1 }, 3333 { TEGRA210_CLK_DFLL_REF, TEGRA210_CLK_PLL_P, 51000000, 1 },
3031 { TEGRA210_CLK_SBC4, TEGRA210_CLK_PLL_P, 12000000, 1 }, 3334 { TEGRA210_CLK_SBC4, TEGRA210_CLK_PLL_P, 12000000, 1 },
@@ -3040,7 +3343,6 @@ static struct tegra_clk_init_table init_table[] __initdata = {
3040 { TEGRA210_CLK_XUSB_DEV_SRC, TEGRA210_CLK_PLL_P_OUT_XUSB, 102000000, 0 }, 3343 { TEGRA210_CLK_XUSB_DEV_SRC, TEGRA210_CLK_PLL_P_OUT_XUSB, 102000000, 0 },
3041 { TEGRA210_CLK_SATA, TEGRA210_CLK_PLL_P, 104000000, 0 }, 3344 { TEGRA210_CLK_SATA, TEGRA210_CLK_PLL_P, 104000000, 0 },
3042 { TEGRA210_CLK_SATA_OOB, TEGRA210_CLK_PLL_P, 204000000, 0 }, 3345 { TEGRA210_CLK_SATA_OOB, TEGRA210_CLK_PLL_P, 204000000, 0 },
3043 { TEGRA210_CLK_EMC, TEGRA210_CLK_CLK_MAX, 0, 1 },
3044 { TEGRA210_CLK_MSELECT, TEGRA210_CLK_CLK_MAX, 0, 1 }, 3346 { TEGRA210_CLK_MSELECT, TEGRA210_CLK_CLK_MAX, 0, 1 },
3045 { TEGRA210_CLK_CSITE, TEGRA210_CLK_CLK_MAX, 0, 1 }, 3347 { TEGRA210_CLK_CSITE, TEGRA210_CLK_CLK_MAX, 0, 1 },
3046 /* TODO find a way to enable this on-demand */ 3348 /* TODO find a way to enable this on-demand */
@@ -3149,6 +3451,37 @@ static int tegra210_reset_deassert(unsigned long id)
3149 return 0; 3451 return 0;
3150} 3452}
3151 3453
3454static void tegra210_mbist_clk_init(void)
3455{
3456 unsigned int i, j;
3457
3458 for (i = 0; i < ARRAY_SIZE(tegra210_pg_mbist_war); i++) {
3459 unsigned int num_clks = tegra210_pg_mbist_war[i].num_clks;
3460 struct clk_bulk_data *clk_data;
3461
3462 if (!num_clks)
3463 continue;
3464
3465 clk_data = kmalloc_array(num_clks, sizeof(*clk_data),
3466 GFP_KERNEL);
3467 if (WARN_ON(!clk_data))
3468 return;
3469
3470 tegra210_pg_mbist_war[i].clks = clk_data;
3471 for (j = 0; j < num_clks; j++) {
3472 int clk_id = tegra210_pg_mbist_war[i].clk_init_data[j];
3473 struct clk *clk = clks[clk_id];
3474
3475 if (WARN(IS_ERR(clk), "clk_id: %d\n", clk_id)) {
3476 kfree(clk_data);
3477 tegra210_pg_mbist_war[i].clks = NULL;
3478 break;
3479 }
3480 clk_data[j].clk = clk;
3481 }
3482 }
3483}
3484
3152/** 3485/**
3153 * tegra210_clock_init - Tegra210-specific clock initialization 3486 * tegra210_clock_init - Tegra210-specific clock initialization
3154 * @np: struct device_node * of the DT node for the SoC CAR IP block 3487 * @np: struct device_node * of the DT node for the SoC CAR IP block
@@ -3183,6 +3516,24 @@ static void __init tegra210_clock_init(struct device_node *np)
3183 return; 3516 return;
3184 } 3517 }
3185 3518
3519 ahub_base = ioremap(TEGRA210_AHUB_BASE, SZ_64K);
3520 if (!ahub_base) {
3521 pr_err("ioremap tegra210 APE failed\n");
3522 return;
3523 }
3524
3525 dispa_base = ioremap(TEGRA210_DISPA_BASE, SZ_256K);
3526 if (!dispa_base) {
3527 pr_err("ioremap tegra210 DISPA failed\n");
3528 return;
3529 }
3530
3531 vic_base = ioremap(TEGRA210_VIC_BASE, SZ_256K);
3532 if (!vic_base) {
3533 pr_err("ioremap tegra210 VIC failed\n");
3534 return;
3535 }
3536
3186 clks = tegra_clk_init(clk_base, TEGRA210_CLK_CLK_MAX, 3537 clks = tegra_clk_init(clk_base, TEGRA210_CLK_CLK_MAX,
3187 TEGRA210_CAR_BANK_COUNT); 3538 TEGRA210_CAR_BANK_COUNT);
3188 if (!clks) 3539 if (!clks)
@@ -3219,6 +3570,8 @@ static void __init tegra210_clock_init(struct device_node *np)
3219 tegra_add_of_provider(np); 3570 tegra_add_of_provider(np);
3220 tegra_register_devclks(devclks, ARRAY_SIZE(devclks)); 3571 tegra_register_devclks(devclks, ARRAY_SIZE(devclks));
3221 3572
3573 tegra210_mbist_clk_init();
3574
3222 tegra_cpu_car_ops = &tegra210_cpu_car_ops; 3575 tegra_cpu_car_ops = &tegra210_cpu_car_ops;
3223} 3576}
3224CLK_OF_DECLARE(tegra210, "nvidia,tegra210-car", tegra210_clock_init); 3577CLK_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 bee84c554932..b316dfb6f6c7 100644
--- a/drivers/clk/tegra/clk-tegra30.c
+++ b/drivers/clk/tegra/clk-tegra30.c
@@ -819,6 +819,7 @@ static struct tegra_clk tegra30_clks[tegra_clk_max] __initdata = {
819 [tegra_clk_pll_a] = { .dt_id = TEGRA30_CLK_PLL_A, .present = true }, 819 [tegra_clk_pll_a] = { .dt_id = TEGRA30_CLK_PLL_A, .present = true },
820 [tegra_clk_pll_a_out0] = { .dt_id = TEGRA30_CLK_PLL_A_OUT0, .present = true }, 820 [tegra_clk_pll_a_out0] = { .dt_id = TEGRA30_CLK_PLL_A_OUT0, .present = true },
821 [tegra_clk_cec] = { .dt_id = TEGRA30_CLK_CEC, .present = true }, 821 [tegra_clk_cec] = { .dt_id = TEGRA30_CLK_CEC, .present = true },
822 [tegra_clk_emc] = { .dt_id = TEGRA30_CLK_EMC, .present = true },
822}; 823};
823 824
824static const char *pll_e_parents[] = { "pll_ref", "pll_p" }; 825static const char *pll_e_parents[] = { "pll_ref", "pll_p" };
@@ -843,8 +844,7 @@ static void __init tegra30_pll_init(void)
843 844
844 /* PLLM */ 845 /* PLLM */
845 clk = tegra_clk_register_pll("pll_m", "pll_ref", clk_base, pmc_base, 846 clk = tegra_clk_register_pll("pll_m", "pll_ref", clk_base, pmc_base,
846 CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, 847 CLK_SET_RATE_GATE, &pll_m_params, NULL);
847 &pll_m_params, NULL);
848 clks[TEGRA30_CLK_PLL_M] = clk; 848 clks[TEGRA30_CLK_PLL_M] = clk;
849 849
850 /* PLLM_OUT1 */ 850 /* PLLM_OUT1 */
@@ -852,7 +852,7 @@ static void __init tegra30_pll_init(void)
852 clk_base + PLLM_OUT, 0, TEGRA_DIVIDER_ROUND_UP, 852 clk_base + PLLM_OUT, 0, TEGRA_DIVIDER_ROUND_UP,
853 8, 8, 1, NULL); 853 8, 8, 1, NULL);
854 clk = tegra_clk_register_pll_out("pll_m_out1", "pll_m_out1_div", 854 clk = tegra_clk_register_pll_out("pll_m_out1", "pll_m_out1_div",
855 clk_base + PLLM_OUT, 1, 0, CLK_IGNORE_UNUSED | 855 clk_base + PLLM_OUT, 1, 0,
856 CLK_SET_RATE_PARENT, 0, NULL); 856 CLK_SET_RATE_PARENT, 0, NULL);
857 clks[TEGRA30_CLK_PLL_M_OUT1] = clk; 857 clks[TEGRA30_CLK_PLL_M_OUT1] = clk;
858 858
@@ -990,7 +990,7 @@ static void __init tegra30_super_clk_init(void)
990 /* SCLK */ 990 /* SCLK */
991 clk = tegra_clk_register_super_mux("sclk", sclk_parents, 991 clk = tegra_clk_register_super_mux("sclk", sclk_parents,
992 ARRAY_SIZE(sclk_parents), 992 ARRAY_SIZE(sclk_parents),
993 CLK_SET_RATE_PARENT, 993 CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
994 clk_base + SCLK_BURST_POLICY, 994 clk_base + SCLK_BURST_POLICY,
995 0, 4, 0, 0, NULL); 995 0, 4, 0, 0, NULL);
996 clks[TEGRA30_CLK_SCLK] = clk; 996 clks[TEGRA30_CLK_SCLK] = clk;
@@ -1060,9 +1060,6 @@ static void __init tegra30_periph_clk_init(void)
1060 CLK_SET_RATE_NO_REPARENT, 1060 CLK_SET_RATE_NO_REPARENT,
1061 clk_base + CLK_SOURCE_EMC, 1061 clk_base + CLK_SOURCE_EMC,
1062 30, 2, 0, &emc_lock); 1062 30, 2, 0, &emc_lock);
1063 clk = tegra_clk_register_periph_gate("emc", "emc_mux", 0, clk_base, 0,
1064 57, periph_clk_enb_refcnt);
1065 clks[TEGRA30_CLK_EMC] = clk;
1066 1063
1067 clk = tegra_clk_register_mc("mc", "emc_mux", clk_base + CLK_SOURCE_EMC, 1064 clk = tegra_clk_register_mc("mc", "emc_mux", clk_base + CLK_SOURCE_EMC,
1068 &emc_lock); 1065 &emc_lock);
@@ -1252,10 +1249,7 @@ static struct tegra_clk_init_table init_table[] __initdata = {
1252 { TEGRA30_CLK_SDMMC1, TEGRA30_CLK_PLL_P, 48000000, 0 }, 1249 { TEGRA30_CLK_SDMMC1, TEGRA30_CLK_PLL_P, 48000000, 0 },
1253 { TEGRA30_CLK_SDMMC2, TEGRA30_CLK_PLL_P, 48000000, 0 }, 1250 { TEGRA30_CLK_SDMMC2, TEGRA30_CLK_PLL_P, 48000000, 0 },
1254 { TEGRA30_CLK_SDMMC3, TEGRA30_CLK_PLL_P, 48000000, 0 }, 1251 { TEGRA30_CLK_SDMMC3, TEGRA30_CLK_PLL_P, 48000000, 0 },
1255 { TEGRA30_CLK_PLL_M, TEGRA30_CLK_CLK_MAX, 0, 1 },
1256 { TEGRA30_CLK_PCLK, TEGRA30_CLK_CLK_MAX, 0, 1 },
1257 { TEGRA30_CLK_CSITE, TEGRA30_CLK_CLK_MAX, 0, 1 }, 1252 { TEGRA30_CLK_CSITE, TEGRA30_CLK_CLK_MAX, 0, 1 },
1258 { TEGRA30_CLK_EMC, TEGRA30_CLK_CLK_MAX, 0, 1 },
1259 { TEGRA30_CLK_MSELECT, TEGRA30_CLK_CLK_MAX, 0, 1 }, 1253 { TEGRA30_CLK_MSELECT, TEGRA30_CLK_CLK_MAX, 0, 1 },
1260 { TEGRA30_CLK_SBC1, TEGRA30_CLK_PLL_P, 100000000, 0 }, 1254 { TEGRA30_CLK_SBC1, TEGRA30_CLK_PLL_P, 100000000, 0 },
1261 { TEGRA30_CLK_SBC2, TEGRA30_CLK_PLL_P, 100000000, 0 }, 1255 { TEGRA30_CLK_SBC2, TEGRA30_CLK_PLL_P, 100000000, 0 },
@@ -1272,6 +1266,7 @@ static struct tegra_clk_init_table init_table[] __initdata = {
1272 { TEGRA30_CLK_GR3D, TEGRA30_CLK_PLL_C, 300000000, 0 }, 1266 { TEGRA30_CLK_GR3D, TEGRA30_CLK_PLL_C, 300000000, 0 },
1273 { TEGRA30_CLK_GR3D2, TEGRA30_CLK_PLL_C, 300000000, 0 }, 1267 { TEGRA30_CLK_GR3D2, TEGRA30_CLK_PLL_C, 300000000, 0 },
1274 { TEGRA30_CLK_PLL_U, TEGRA30_CLK_CLK_MAX, 480000000, 0 }, 1268 { TEGRA30_CLK_PLL_U, TEGRA30_CLK_CLK_MAX, 480000000, 0 },
1269 { TEGRA30_CLK_VDE, TEGRA30_CLK_CLK_MAX, 600000000, 0 },
1275 /* must be the last entry */ 1270 /* must be the last entry */
1276 { TEGRA30_CLK_CLK_MAX, TEGRA30_CLK_CLK_MAX, 0, 0 }, 1271 { TEGRA30_CLK_CLK_MAX, TEGRA30_CLK_CLK_MAX, 0, 0 },
1277}; 1272};
diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h
index 3b2763df51c2..ba7e20e6a82b 100644
--- a/drivers/clk/tegra/clk.h
+++ b/drivers/clk/tegra/clk.h
@@ -812,4 +812,11 @@ int tegra_pll_wait_for_lock(struct tegra_clk_pll *pll);
812u16 tegra_pll_get_fixed_mdiv(struct clk_hw *hw, unsigned long input_rate); 812u16 tegra_pll_get_fixed_mdiv(struct clk_hw *hw, unsigned long input_rate);
813int tegra_pll_p_div_to_hw(struct tegra_clk_pll *pll, u8 p_div); 813int tegra_pll_p_div_to_hw(struct tegra_clk_pll *pll, u8 p_div);
814 814
815/* Combined read fence with delay */
816#define fence_udelay(delay, reg) \
817 do { \
818 readl(reg); \
819 udelay(delay); \
820 } while (0)
821
815#endif /* TEGRA_CLK_H */ 822#endif /* TEGRA_CLK_H */
diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c
index f4d6802a8544..7d22e1af2247 100644
--- a/drivers/clk/ti/clk.c
+++ b/drivers/clk/ti/clk.c
@@ -55,6 +55,29 @@ static void clk_memmap_writel(u32 val, const struct clk_omap_reg *reg)
55 writel_relaxed(val, io->mem + reg->offset); 55 writel_relaxed(val, io->mem + reg->offset);
56} 56}
57 57
58static void _clk_rmw(u32 val, u32 mask, void __iomem *ptr)
59{
60 u32 v;
61
62 v = readl_relaxed(ptr);
63 v &= ~mask;
64 v |= val;
65 writel_relaxed(v, ptr);
66}
67
68static void clk_memmap_rmw(u32 val, u32 mask, const struct clk_omap_reg *reg)
69{
70 struct clk_iomap *io = clk_memmaps[reg->index];
71
72 if (reg->ptr) {
73 _clk_rmw(val, mask, reg->ptr);
74 } else if (io->regmap) {
75 regmap_update_bits(io->regmap, reg->offset, mask, val);
76 } else {
77 _clk_rmw(val, mask, io->mem + reg->offset);
78 }
79}
80
58static u32 clk_memmap_readl(const struct clk_omap_reg *reg) 81static u32 clk_memmap_readl(const struct clk_omap_reg *reg)
59{ 82{
60 u32 val; 83 u32 val;
@@ -89,6 +112,7 @@ int ti_clk_setup_ll_ops(struct ti_clk_ll_ops *ops)
89 ti_clk_ll_ops = ops; 112 ti_clk_ll_ops = ops;
90 ops->clk_readl = clk_memmap_readl; 113 ops->clk_readl = clk_memmap_readl;
91 ops->clk_writel = clk_memmap_writel; 114 ops->clk_writel = clk_memmap_writel;
115 ops->clk_rmw = clk_memmap_rmw;
92 116
93 return 0; 117 return 0;
94} 118}
@@ -251,6 +275,20 @@ int ti_clk_get_reg_addr(struct device_node *node, int index,
251 return 0; 275 return 0;
252} 276}
253 277
278void ti_clk_latch(struct clk_omap_reg *reg, s8 shift)
279{
280 u32 latch;
281
282 if (shift < 0)
283 return;
284
285 latch = 1 << shift;
286
287 ti_clk_ll_ops->clk_rmw(latch, latch, reg);
288 ti_clk_ll_ops->clk_rmw(0, latch, reg);
289 ti_clk_ll_ops->clk_readl(reg); /* OCP barrier */
290}
291
254/** 292/**
255 * omap2_clk_provider_init - init master clock provider 293 * omap2_clk_provider_init - init master clock provider
256 * @parent: master node 294 * @parent: master node
diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
index d9b43bfc2532..90b86aadfda7 100644
--- a/drivers/clk/ti/clock.h
+++ b/drivers/clk/ti/clock.h
@@ -22,6 +22,7 @@ struct clk_omap_divider {
22 u8 shift; 22 u8 shift;
23 u8 width; 23 u8 width;
24 u8 flags; 24 u8 flags;
25 s8 latch;
25 const struct clk_div_table *table; 26 const struct clk_div_table *table;
26}; 27};
27 28
@@ -33,6 +34,7 @@ struct clk_omap_mux {
33 u32 *table; 34 u32 *table;
34 u32 mask; 35 u32 mask;
35 u8 shift; 36 u8 shift;
37 s8 latch;
36 u8 flags; 38 u8 flags;
37}; 39};
38 40
@@ -194,6 +196,8 @@ struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw,
194int ti_clk_add_alias(struct device *dev, struct clk *clk, const char *con); 196int ti_clk_add_alias(struct device *dev, struct clk *clk, const char *con);
195void ti_clk_add_aliases(void); 197void ti_clk_add_aliases(void);
196 198
199void ti_clk_latch(struct clk_omap_reg *reg, s8 shift);
200
197struct clk_hw *ti_clk_build_component_mux(struct ti_clk_mux *setup); 201struct clk_hw *ti_clk_build_component_mux(struct ti_clk_mux *setup);
198 202
199int ti_clk_parse_divider_data(int *div_table, int num_dividers, int max_div, 203int ti_clk_parse_divider_data(int *div_table, int num_dividers, int max_div,
diff --git a/drivers/clk/ti/divider.c b/drivers/clk/ti/divider.c
index 77f93f6d2806..aaa277dd6d99 100644
--- a/drivers/clk/ti/divider.c
+++ b/drivers/clk/ti/divider.c
@@ -263,6 +263,8 @@ static int ti_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
263 val |= value << divider->shift; 263 val |= value << divider->shift;
264 ti_clk_ll_ops->clk_writel(val, &divider->reg); 264 ti_clk_ll_ops->clk_writel(val, &divider->reg);
265 265
266 ti_clk_latch(&divider->reg, divider->latch);
267
266 return 0; 268 return 0;
267} 269}
268 270
@@ -276,7 +278,8 @@ static struct clk *_register_divider(struct device *dev, const char *name,
276 const char *parent_name, 278 const char *parent_name,
277 unsigned long flags, 279 unsigned long flags,
278 struct clk_omap_reg *reg, 280 struct clk_omap_reg *reg,
279 u8 shift, u8 width, u8 clk_divider_flags, 281 u8 shift, u8 width, s8 latch,
282 u8 clk_divider_flags,
280 const struct clk_div_table *table) 283 const struct clk_div_table *table)
281{ 284{
282 struct clk_omap_divider *div; 285 struct clk_omap_divider *div;
@@ -305,6 +308,7 @@ static struct clk *_register_divider(struct device *dev, const char *name,
305 memcpy(&div->reg, reg, sizeof(*reg)); 308 memcpy(&div->reg, reg, sizeof(*reg));
306 div->shift = shift; 309 div->shift = shift;
307 div->width = width; 310 div->width = width;
311 div->latch = latch;
308 div->flags = clk_divider_flags; 312 div->flags = clk_divider_flags;
309 div->hw.init = &init; 313 div->hw.init = &init;
310 div->table = table; 314 div->table = table;
@@ -420,6 +424,7 @@ struct clk_hw *ti_clk_build_component_div(struct ti_clk_divider *setup)
420 div->table = _get_div_table_from_setup(setup, &div->width); 424 div->table = _get_div_table_from_setup(setup, &div->width);
421 425
422 div->shift = setup->bit_shift; 426 div->shift = setup->bit_shift;
427 div->latch = -EINVAL;
423 428
424 return &div->hw; 429 return &div->hw;
425} 430}
@@ -452,7 +457,7 @@ struct clk *ti_clk_register_divider(struct ti_clk *setup)
452 457
453 clk = _register_divider(NULL, setup->name, div->parent, 458 clk = _register_divider(NULL, setup->name, div->parent,
454 flags, &reg, div->bit_shift, 459 flags, &reg, div->bit_shift,
455 width, div_flags, table); 460 width, -EINVAL, div_flags, table);
456 461
457 if (IS_ERR(clk)) 462 if (IS_ERR(clk))
458 kfree(table); 463 kfree(table);
@@ -556,7 +561,7 @@ static int _get_divider_width(struct device_node *node,
556 561
557static int __init ti_clk_divider_populate(struct device_node *node, 562static int __init ti_clk_divider_populate(struct device_node *node,
558 struct clk_omap_reg *reg, const struct clk_div_table **table, 563 struct clk_omap_reg *reg, const struct clk_div_table **table,
559 u32 *flags, u8 *div_flags, u8 *width, u8 *shift) 564 u32 *flags, u8 *div_flags, u8 *width, u8 *shift, s8 *latch)
560{ 565{
561 u32 val; 566 u32 val;
562 int ret; 567 int ret;
@@ -570,6 +575,13 @@ static int __init ti_clk_divider_populate(struct device_node *node,
570 else 575 else
571 *shift = 0; 576 *shift = 0;
572 577
578 if (latch) {
579 if (!of_property_read_u32(node, "ti,latch-bit", &val))
580 *latch = val;
581 else
582 *latch = -EINVAL;
583 }
584
573 *flags = 0; 585 *flags = 0;
574 *div_flags = 0; 586 *div_flags = 0;
575 587
@@ -606,17 +618,18 @@ static void __init of_ti_divider_clk_setup(struct device_node *node)
606 u8 clk_divider_flags = 0; 618 u8 clk_divider_flags = 0;
607 u8 width = 0; 619 u8 width = 0;
608 u8 shift = 0; 620 u8 shift = 0;
621 s8 latch = -EINVAL;
609 const struct clk_div_table *table = NULL; 622 const struct clk_div_table *table = NULL;
610 u32 flags = 0; 623 u32 flags = 0;
611 624
612 parent_name = of_clk_get_parent_name(node, 0); 625 parent_name = of_clk_get_parent_name(node, 0);
613 626
614 if (ti_clk_divider_populate(node, &reg, &table, &flags, 627 if (ti_clk_divider_populate(node, &reg, &table, &flags,
615 &clk_divider_flags, &width, &shift)) 628 &clk_divider_flags, &width, &shift, &latch))
616 goto cleanup; 629 goto cleanup;
617 630
618 clk = _register_divider(NULL, node->name, parent_name, flags, &reg, 631 clk = _register_divider(NULL, node->name, parent_name, flags, &reg,
619 shift, width, clk_divider_flags, table); 632 shift, width, latch, clk_divider_flags, table);
620 633
621 if (!IS_ERR(clk)) { 634 if (!IS_ERR(clk)) {
622 of_clk_add_provider(node, of_clk_src_simple_get, clk); 635 of_clk_add_provider(node, of_clk_src_simple_get, clk);
@@ -639,7 +652,8 @@ static void __init of_ti_composite_divider_clk_setup(struct device_node *node)
639 return; 652 return;
640 653
641 if (ti_clk_divider_populate(node, &div->reg, &div->table, &val, 654 if (ti_clk_divider_populate(node, &div->reg, &div->table, &val,
642 &div->flags, &div->width, &div->shift) < 0) 655 &div->flags, &div->width, &div->shift,
656 NULL) < 0)
643 goto cleanup; 657 goto cleanup;
644 658
645 if (!ti_clk_add_component(node, &div->hw, CLK_COMPONENT_TYPE_DIVIDER)) 659 if (!ti_clk_add_component(node, &div->hw, CLK_COMPONENT_TYPE_DIVIDER))
diff --git a/drivers/clk/ti/mux.c b/drivers/clk/ti/mux.c
index d4705803f3d3..69a4308a5a98 100644
--- a/drivers/clk/ti/mux.c
+++ b/drivers/clk/ti/mux.c
@@ -86,6 +86,7 @@ static int ti_clk_mux_set_parent(struct clk_hw *hw, u8 index)
86 } 86 }
87 val |= index << mux->shift; 87 val |= index << mux->shift;
88 ti_clk_ll_ops->clk_writel(val, &mux->reg); 88 ti_clk_ll_ops->clk_writel(val, &mux->reg);
89 ti_clk_latch(&mux->reg, mux->latch);
89 90
90 return 0; 91 return 0;
91} 92}
@@ -100,7 +101,7 @@ static struct clk *_register_mux(struct device *dev, const char *name,
100 const char * const *parent_names, 101 const char * const *parent_names,
101 u8 num_parents, unsigned long flags, 102 u8 num_parents, unsigned long flags,
102 struct clk_omap_reg *reg, u8 shift, u32 mask, 103 struct clk_omap_reg *reg, u8 shift, u32 mask,
103 u8 clk_mux_flags, u32 *table) 104 s8 latch, u8 clk_mux_flags, u32 *table)
104{ 105{
105 struct clk_omap_mux *mux; 106 struct clk_omap_mux *mux;
106 struct clk *clk; 107 struct clk *clk;
@@ -121,6 +122,7 @@ static struct clk *_register_mux(struct device *dev, const char *name,
121 memcpy(&mux->reg, reg, sizeof(*reg)); 122 memcpy(&mux->reg, reg, sizeof(*reg));
122 mux->shift = shift; 123 mux->shift = shift;
123 mux->mask = mask; 124 mux->mask = mask;
125 mux->latch = latch;
124 mux->flags = clk_mux_flags; 126 mux->flags = clk_mux_flags;
125 mux->table = table; 127 mux->table = table;
126 mux->hw.init = &init; 128 mux->hw.init = &init;
@@ -160,7 +162,7 @@ struct clk *ti_clk_register_mux(struct ti_clk *setup)
160 flags |= CLK_SET_RATE_PARENT; 162 flags |= CLK_SET_RATE_PARENT;
161 163
162 return _register_mux(NULL, setup->name, mux->parents, mux->num_parents, 164 return _register_mux(NULL, setup->name, mux->parents, mux->num_parents,
163 flags, &reg, mux->bit_shift, mask, 165 flags, &reg, mux->bit_shift, mask, -EINVAL,
164 mux_flags, NULL); 166 mux_flags, NULL);
165} 167}
166 168
@@ -179,6 +181,7 @@ static void of_mux_clk_setup(struct device_node *node)
179 u8 clk_mux_flags = 0; 181 u8 clk_mux_flags = 0;
180 u32 mask = 0; 182 u32 mask = 0;
181 u32 shift = 0; 183 u32 shift = 0;
184 s32 latch = -EINVAL;
182 u32 flags = CLK_SET_RATE_NO_REPARENT; 185 u32 flags = CLK_SET_RATE_NO_REPARENT;
183 186
184 num_parents = of_clk_get_parent_count(node); 187 num_parents = of_clk_get_parent_count(node);
@@ -197,6 +200,8 @@ static void of_mux_clk_setup(struct device_node *node)
197 200
198 of_property_read_u32(node, "ti,bit-shift", &shift); 201 of_property_read_u32(node, "ti,bit-shift", &shift);
199 202
203 of_property_read_u32(node, "ti,latch-bit", &latch);
204
200 if (of_property_read_bool(node, "ti,index-starts-at-one")) 205 if (of_property_read_bool(node, "ti,index-starts-at-one"))
201 clk_mux_flags |= CLK_MUX_INDEX_ONE; 206 clk_mux_flags |= CLK_MUX_INDEX_ONE;
202 207
@@ -211,7 +216,8 @@ static void of_mux_clk_setup(struct device_node *node)
211 mask = (1 << fls(mask)) - 1; 216 mask = (1 << fls(mask)) - 1;
212 217
213 clk = _register_mux(NULL, node->name, parent_names, num_parents, 218 clk = _register_mux(NULL, node->name, parent_names, num_parents,
214 flags, &reg, shift, mask, clk_mux_flags, NULL); 219 flags, &reg, shift, mask, latch, clk_mux_flags,
220 NULL);
215 221
216 if (!IS_ERR(clk)) 222 if (!IS_ERR(clk))
217 of_clk_add_provider(node, of_clk_src_simple_get, clk); 223 of_clk_add_provider(node, of_clk_src_simple_get, clk);
@@ -234,6 +240,7 @@ struct clk_hw *ti_clk_build_component_mux(struct ti_clk_mux *setup)
234 return ERR_PTR(-ENOMEM); 240 return ERR_PTR(-ENOMEM);
235 241
236 mux->shift = setup->bit_shift; 242 mux->shift = setup->bit_shift;
243 mux->latch = -EINVAL;
237 244
238 mux->reg.index = setup->module; 245 mux->reg.index = setup->module;
239 mux->reg.offset = setup->reg; 246 mux->reg.offset = setup->reg;
diff --git a/drivers/clk/versatile/clk-vexpress-osc.c b/drivers/clk/versatile/clk-vexpress-osc.c
index e7a868b83fe5..dd08ecb498be 100644
--- a/drivers/clk/versatile/clk-vexpress-osc.c
+++ b/drivers/clk/versatile/clk-vexpress-osc.c
@@ -44,10 +44,10 @@ static long vexpress_osc_round_rate(struct clk_hw *hw, unsigned long rate,
44{ 44{
45 struct vexpress_osc *osc = to_vexpress_osc(hw); 45 struct vexpress_osc *osc = to_vexpress_osc(hw);
46 46
47 if (WARN_ON(osc->rate_min && rate < osc->rate_min)) 47 if (osc->rate_min && rate < osc->rate_min)
48 rate = osc->rate_min; 48 rate = osc->rate_min;
49 49
50 if (WARN_ON(osc->rate_max && rate > osc->rate_max)) 50 if (osc->rate_max && rate > osc->rate_max)
51 rate = osc->rate_max; 51 rate = osc->rate_max;
52 52
53 return rate; 53 return rate;
@@ -104,6 +104,7 @@ static int vexpress_osc_probe(struct platform_device *pdev)
104 return PTR_ERR(clk); 104 return PTR_ERR(clk);
105 105
106 of_clk_add_provider(pdev->dev.of_node, of_clk_src_simple_get, clk); 106 of_clk_add_provider(pdev->dev.of_node, of_clk_src_simple_get, clk);
107 clk_hw_set_rate_range(&osc->hw, osc->rate_min, osc->rate_max);
107 108
108 dev_dbg(&pdev->dev, "Registered clock '%s'\n", init.name); 109 dev_dbg(&pdev->dev, "Registered clock '%s'\n", init.name);
109 110
diff --git a/drivers/soc/samsung/pm_domains.c b/drivers/soc/samsung/pm_domains.c
index b6a436594a19..caf45cf7aa8e 100644
--- a/drivers/soc/samsung/pm_domains.c
+++ b/drivers/soc/samsung/pm_domains.c
@@ -147,6 +147,12 @@ static __init const char *exynos_get_domain_name(struct device_node *node)
147 return kstrdup_const(name, GFP_KERNEL); 147 return kstrdup_const(name, GFP_KERNEL);
148} 148}
149 149
150static const char *soc_force_no_clk[] = {
151 "samsung,exynos5250-clock",
152 "samsung,exynos5420-clock",
153 "samsung,exynos5800-clock",
154};
155
150static __init int exynos4_pm_init_power_domain(void) 156static __init int exynos4_pm_init_power_domain(void)
151{ 157{
152 struct device_node *np; 158 struct device_node *np;
@@ -183,6 +189,11 @@ static __init int exynos4_pm_init_power_domain(void)
183 pd->pd.power_on = exynos_pd_power_on; 189 pd->pd.power_on = exynos_pd_power_on;
184 pd->local_pwr_cfg = pm_domain_cfg->local_pwr_cfg; 190 pd->local_pwr_cfg = pm_domain_cfg->local_pwr_cfg;
185 191
192 for (i = 0; i < ARRAY_SIZE(soc_force_no_clk); i++)
193 if (of_find_compatible_node(NULL, NULL,
194 soc_force_no_clk[i]))
195 goto no_clk;
196
186 for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) { 197 for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) {
187 char clk_name[8]; 198 char clk_name[8];
188 199
diff --git a/include/dt-bindings/clock/axg-clkc.h b/include/dt-bindings/clock/axg-clkc.h
index 941ac70e7f30..555937a25504 100644
--- a/include/dt-bindings/clock/axg-clkc.h
+++ b/include/dt-bindings/clock/axg-clkc.h
@@ -67,5 +67,6 @@
67#define CLKID_AO_I2C 58 67#define CLKID_AO_I2C 58
68#define CLKID_SD_EMMC_B_CLK0 59 68#define CLKID_SD_EMMC_B_CLK0 59
69#define CLKID_SD_EMMC_C_CLK0 60 69#define CLKID_SD_EMMC_C_CLK0 60
70#define CLKID_HIFI_PLL 69
70 71
71#endif /* __AXG_CLKC_H */ 72#endif /* __AXG_CLKC_H */
diff --git a/include/dt-bindings/clock/mt2712-clk.h b/include/dt-bindings/clock/mt2712-clk.h
index 48a8e797a617..76265836a1e1 100644
--- a/include/dt-bindings/clock/mt2712-clk.h
+++ b/include/dt-bindings/clock/mt2712-clk.h
@@ -222,7 +222,13 @@
222#define CLK_TOP_APLL_DIV_PDN5 183 222#define CLK_TOP_APLL_DIV_PDN5 183
223#define CLK_TOP_APLL_DIV_PDN6 184 223#define CLK_TOP_APLL_DIV_PDN6 184
224#define CLK_TOP_APLL_DIV_PDN7 185 224#define CLK_TOP_APLL_DIV_PDN7 185
225#define CLK_TOP_NR_CLK 186 225#define CLK_TOP_APLL1_D3 186
226#define CLK_TOP_APLL1_REF_SEL 187
227#define CLK_TOP_APLL2_REF_SEL 188
228#define CLK_TOP_NFI2X_EN 189
229#define CLK_TOP_NFIECC_EN 190
230#define CLK_TOP_NFI1X_CK_EN 191
231#define CLK_TOP_NR_CLK 192
226 232
227/* INFRACFG */ 233/* INFRACFG */
228 234
@@ -281,7 +287,9 @@
281#define CLK_PERI_MSDC30_3_EN 41 287#define CLK_PERI_MSDC30_3_EN 41
282#define CLK_PERI_MSDC50_0_HCLK_EN 42 288#define CLK_PERI_MSDC50_0_HCLK_EN 42
283#define CLK_PERI_MSDC50_3_HCLK_EN 43 289#define CLK_PERI_MSDC50_3_HCLK_EN 43
284#define CLK_PERI_NR_CLK 44 290#define CLK_PERI_MSDC30_0_QTR_EN 44
291#define CLK_PERI_MSDC30_3_QTR_EN 45
292#define CLK_PERI_NR_CLK 46
285 293
286/* MCUCFG */ 294/* MCUCFG */
287 295
diff --git a/include/dt-bindings/clock/qcom,rpmcc.h b/include/dt-bindings/clock/qcom,rpmcc.h
index b8337a5fa347..c585b82b9c05 100644
--- a/include/dt-bindings/clock/qcom,rpmcc.h
+++ b/include/dt-bindings/clock/qcom,rpmcc.h
@@ -40,6 +40,11 @@
40#define RPM_SMI_CLK 22 40#define RPM_SMI_CLK 22
41#define RPM_SMI_A_CLK 23 41#define RPM_SMI_A_CLK 23
42#define RPM_PLL4_CLK 24 42#define RPM_PLL4_CLK 24
43#define RPM_XO_D0 25
44#define RPM_XO_D1 26
45#define RPM_XO_A0 27
46#define RPM_XO_A1 28
47#define RPM_XO_A2 29
43 48
44/* SMD RPM clocks */ 49/* SMD RPM clocks */
45#define RPM_SMD_XO_CLK_SRC 0 50#define RPM_SMD_XO_CLK_SRC 0
diff --git a/include/dt-bindings/clock/sprd,sc9860-clk.h b/include/dt-bindings/clock/sprd,sc9860-clk.h
index 4cb202f090c2..f2ab4631df0d 100644
--- a/include/dt-bindings/clock/sprd,sc9860-clk.h
+++ b/include/dt-bindings/clock/sprd,sc9860-clk.h
@@ -229,7 +229,26 @@
229#define CLK_SDIO1_2X_EN 65 229#define CLK_SDIO1_2X_EN 65
230#define CLK_SDIO2_2X_EN 66 230#define CLK_SDIO2_2X_EN 66
231#define CLK_EMMC_2X_EN 67 231#define CLK_EMMC_2X_EN 67
232#define CLK_AON_GATE_NUM (CLK_EMMC_2X_EN + 1) 232#define CLK_ARCH_RTC_EB 68
233#define CLK_KPB_RTC_EB 69
234#define CLK_AON_SYST_RTC_EB 70
235#define CLK_AP_SYST_RTC_EB 71
236#define CLK_AON_TMR_RTC_EB 72
237#define CLK_AP_TMR0_RTC_EB 73
238#define CLK_EIC_RTC_EB 74
239#define CLK_EIC_RTCDV5_EB 75
240#define CLK_AP_WDG_RTC_EB 76
241#define CLK_AP_TMR1_RTC_EB 77
242#define CLK_AP_TMR2_RTC_EB 78
243#define CLK_DCXO_TMR_RTC_EB 79
244#define CLK_BB_CAL_RTC_EB 80
245#define CLK_AVS_BIG_RTC_EB 81
246#define CLK_AVS_LIT_RTC_EB 82
247#define CLK_AVS_GPU0_RTC_EB 83
248#define CLK_AVS_GPU1_RTC_EB 84
249#define CLK_GPU_TS_EB 85
250#define CLK_RTCDV10_EB 86
251#define CLK_AON_GATE_NUM (CLK_RTCDV10_EB + 1)
233 252
234#define CLK_LIT_MCU 0 253#define CLK_LIT_MCU 0
235#define CLK_BIG_MCU 1 254#define CLK_BIG_MCU 1
diff --git a/include/dt-bindings/clock/stm32fx-clock.h b/include/dt-bindings/clock/stm32fx-clock.h
index 49bb3c203e5c..58d8b515be55 100644
--- a/include/dt-bindings/clock/stm32fx-clock.h
+++ b/include/dt-bindings/clock/stm32fx-clock.h
@@ -33,11 +33,12 @@
33#define CLK_SAI2 11 33#define CLK_SAI2 11
34#define CLK_I2SQ_PDIV 12 34#define CLK_I2SQ_PDIV 12
35#define CLK_SAIQ_PDIV 13 35#define CLK_SAIQ_PDIV 13
36
37#define END_PRIMARY_CLK 14
38
39#define CLK_HSI 14 36#define CLK_HSI 14
40#define CLK_SYSCLK 15 37#define CLK_SYSCLK 15
38#define CLK_F469_DSI 16
39
40#define END_PRIMARY_CLK 17
41
41#define CLK_HDMI_CEC 16 42#define CLK_HDMI_CEC 16
42#define CLK_SPDIF 17 43#define CLK_SPDIF 17
43#define CLK_USART1 18 44#define CLK_USART1 18
diff --git a/include/dt-bindings/clock/stm32mp1-clks.h b/include/dt-bindings/clock/stm32mp1-clks.h
new file mode 100644
index 000000000000..86e3ec662ef4
--- /dev/null
+++ b/include/dt-bindings/clock/stm32mp1-clks.h
@@ -0,0 +1,254 @@
1/* SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause */
2/*
3 * Copyright (C) STMicroelectronics 2018 - All Rights Reserved
4 * Author: Gabriel Fernandez <gabriel.fernandez@st.com> for STMicroelectronics.
5 */
6
7#ifndef _DT_BINDINGS_STM32MP1_CLKS_H_
8#define _DT_BINDINGS_STM32MP1_CLKS_H_
9
10/* OSCILLATOR clocks */
11#define CK_HSE 0
12#define CK_CSI 1
13#define CK_LSI 2
14#define CK_LSE 3
15#define CK_HSI 4
16#define CK_HSE_DIV2 5
17
18/* Bus clocks */
19#define TIM2 6
20#define TIM3 7
21#define TIM4 8
22#define TIM5 9
23#define TIM6 10
24#define TIM7 11
25#define TIM12 12
26#define TIM13 13
27#define TIM14 14
28#define LPTIM1 15
29#define SPI2 16
30#define SPI3 17
31#define USART2 18
32#define USART3 19
33#define UART4 20
34#define UART5 21
35#define UART7 22
36#define UART8 23
37#define I2C1 24
38#define I2C2 25
39#define I2C3 26
40#define I2C5 27
41#define SPDIF 28
42#define CEC 29
43#define DAC12 30
44#define MDIO 31
45#define TIM1 32
46#define TIM8 33
47#define TIM15 34
48#define TIM16 35
49#define TIM17 36
50#define SPI1 37
51#define SPI4 38
52#define SPI5 39
53#define USART6 40
54#define SAI1 41
55#define SAI2 42
56#define SAI3 43
57#define DFSDM 44
58#define FDCAN 45
59#define LPTIM2 46
60#define LPTIM3 47
61#define LPTIM4 48
62#define LPTIM5 49
63#define SAI4 50
64#define SYSCFG 51
65#define VREF 52
66#define TMPSENS 53
67#define PMBCTRL 54
68#define HDP 55
69#define LTDC 56
70#define DSI 57
71#define IWDG2 58
72#define USBPHY 59
73#define STGENRO 60
74#define SPI6 61
75#define I2C4 62
76#define I2C6 63
77#define USART1 64
78#define RTCAPB 65
79#define TZC 66
80#define TZPC 67
81#define IWDG1 68
82#define BSEC 69
83#define STGEN 70
84#define DMA1 71
85#define DMA2 72
86#define DMAMUX 73
87#define ADC12 74
88#define USBO 75
89#define SDMMC3 76
90#define DCMI 77
91#define CRYP2 78
92#define HASH2 79
93#define RNG2 80
94#define CRC2 81
95#define HSEM 82
96#define IPCC 83
97#define GPIOA 84
98#define GPIOB 85
99#define GPIOC 86
100#define GPIOD 87
101#define GPIOE 88
102#define GPIOF 89
103#define GPIOG 90
104#define GPIOH 91
105#define GPIOI 92
106#define GPIOJ 93
107#define GPIOK 94
108#define GPIOZ 95
109#define CRYP1 96
110#define HASH1 97
111#define RNG1 98
112#define BKPSRAM 99
113#define MDMA 100
114#define GPU 101
115#define ETHCK 102
116#define ETHTX 103
117#define ETHRX 104
118#define ETHMAC 105
119#define FMC 106
120#define QSPI 107
121#define SDMMC1 108
122#define SDMMC2 109
123#define CRC1 110
124#define USBH 111
125#define ETHSTP 112
126
127/* Kernel clocks */
128#define SDMMC1_K 118
129#define SDMMC2_K 119
130#define SDMMC3_K 120
131#define FMC_K 121
132#define QSPI_K 122
133#define ETHCK_K 123
134#define RNG1_K 124
135#define RNG2_K 125
136#define GPU_K 126
137#define USBPHY_K 127
138#define STGEN_K 128
139#define SPDIF_K 129
140#define SPI1_K 130
141#define SPI2_K 131
142#define SPI3_K 132
143#define SPI4_K 133
144#define SPI5_K 134
145#define SPI6_K 135
146#define CEC_K 136
147#define I2C1_K 137
148#define I2C2_K 138
149#define I2C3_K 139
150#define I2C4_K 140
151#define I2C5_K 141
152#define I2C6_K 142
153#define LPTIM1_K 143
154#define LPTIM2_K 144
155#define LPTIM3_K 145
156#define LPTIM4_K 146
157#define LPTIM5_K 147
158#define USART1_K 148
159#define USART2_K 149
160#define USART3_K 150
161#define UART4_K 151
162#define UART5_K 152
163#define USART6_K 153
164#define UART7_K 154
165#define UART8_K 155
166#define DFSDM_K 156
167#define FDCAN_K 157
168#define SAI1_K 158
169#define SAI2_K 159
170#define SAI3_K 160
171#define SAI4_K 161
172#define ADC12_K 162
173#define DSI_K 163
174#define DSI_PX 164
175#define ADFSDM_K 165
176#define USBO_K 166
177#define LTDC_PX 167
178#define DAC12_K 168
179#define ETHPTP_K 169
180
181/* PLL */
182#define PLL1 176
183#define PLL2 177
184#define PLL3 178
185#define PLL4 179
186
187/* ODF */
188#define PLL1_P 180
189#define PLL1_Q 181
190#define PLL1_R 182
191#define PLL2_P 183
192#define PLL2_Q 184
193#define PLL2_R 185
194#define PLL3_P 186
195#define PLL3_Q 187
196#define PLL3_R 188
197#define PLL4_P 189
198#define PLL4_Q 190
199#define PLL4_R 191
200
201/* AUX */
202#define RTC 192
203
204/* MCLK */
205#define CK_PER 193
206#define CK_MPU 194
207#define CK_AXI 195
208#define CK_MCU 196
209
210/* Time base */
211#define TIM2_K 197
212#define TIM3_K 198
213#define TIM4_K 199
214#define TIM5_K 200
215#define TIM6_K 201
216#define TIM7_K 202
217#define TIM12_K 203
218#define TIM13_K 204
219#define TIM14_K 205
220#define TIM1_K 206
221#define TIM8_K 207
222#define TIM15_K 208
223#define TIM16_K 209
224#define TIM17_K 210
225
226/* MCO clocks */
227#define CK_MCO1 211
228#define CK_MCO2 212
229
230/* TRACE & DEBUG clocks */
231#define DBG 213
232#define CK_DBG 214
233#define CK_TRACE 215
234
235/* DDR */
236#define DDRC1 220
237#define DDRC1LP 221
238#define DDRC2 222
239#define DDRC2LP 223
240#define DDRPHYC 224
241#define DDRPHYCLP 225
242#define DDRCAPB 226
243#define DDRCAPBLP 227
244#define AXIDCG 228
245#define DDRPHYCAPB 229
246#define DDRPHYCAPBLP 230
247#define DDRPERFM 231
248
249#define STM32MP1_LAST_CLK 232
250
251#define LTDC_K LTDC_PX
252#define ETHMAC_K ETHCK_K
253
254#endif /* _DT_BINDINGS_STM32MP1_CLKS_H_ */
diff --git a/include/dt-bindings/clock/tegra210-car.h b/include/dt-bindings/clock/tegra210-car.h
index 6422314e46eb..6b77e721f6b1 100644
--- a/include/dt-bindings/clock/tegra210-car.h
+++ b/include/dt-bindings/clock/tegra210-car.h
@@ -95,7 +95,7 @@
95#define TEGRA210_CLK_CSITE 73 95#define TEGRA210_CLK_CSITE 73
96/* 74 */ 96/* 74 */
97/* 75 */ 97/* 75 */
98/* 76 */ 98#define TEGRA210_CLK_LA 76
99/* 77 */ 99/* 77 */
100#define TEGRA210_CLK_SOC_THERM 78 100#define TEGRA210_CLK_SOC_THERM 78
101#define TEGRA210_CLK_DTV 79 101#define TEGRA210_CLK_DTV 79
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index f711be6e8c44..210a890008f9 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -399,6 +399,7 @@ struct clk_divider {
399 spinlock_t *lock; 399 spinlock_t *lock;
400}; 400};
401 401
402#define clk_div_mask(width) ((1 << (width)) - 1)
402#define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw) 403#define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw)
403 404
404#define CLK_DIVIDER_ONE_BASED BIT(0) 405#define CLK_DIVIDER_ONE_BASED BIT(0)
@@ -419,6 +420,10 @@ long divider_round_rate_parent(struct clk_hw *hw, struct clk_hw *parent,
419 unsigned long rate, unsigned long *prate, 420 unsigned long rate, unsigned long *prate,
420 const struct clk_div_table *table, 421 const struct clk_div_table *table,
421 u8 width, unsigned long flags); 422 u8 width, unsigned long flags);
423long divider_ro_round_rate_parent(struct clk_hw *hw, struct clk_hw *parent,
424 unsigned long rate, unsigned long *prate,
425 const struct clk_div_table *table, u8 width,
426 unsigned long flags, unsigned int val);
422int divider_get_val(unsigned long rate, unsigned long parent_rate, 427int divider_get_val(unsigned long rate, unsigned long parent_rate,
423 const struct clk_div_table *table, u8 width, 428 const struct clk_div_table *table, u8 width,
424 unsigned long flags); 429 unsigned long flags);
@@ -449,8 +454,9 @@ void clk_hw_unregister_divider(struct clk_hw *hw);
449 * 454 *
450 * @hw: handle between common and hardware-specific interfaces 455 * @hw: handle between common and hardware-specific interfaces
451 * @reg: register controlling multiplexer 456 * @reg: register controlling multiplexer
457 * @table: array of register values corresponding to the parent index
452 * @shift: shift to multiplexer bit field 458 * @shift: shift to multiplexer bit field
453 * @width: width of mutliplexer bit field 459 * @mask: mask of mutliplexer bit field
454 * @flags: hardware-specific flags 460 * @flags: hardware-specific flags
455 * @lock: register lock 461 * @lock: register lock
456 * 462 *
@@ -510,6 +516,10 @@ struct clk_hw *clk_hw_register_mux_table(struct device *dev, const char *name,
510 void __iomem *reg, u8 shift, u32 mask, 516 void __iomem *reg, u8 shift, u32 mask,
511 u8 clk_mux_flags, u32 *table, spinlock_t *lock); 517 u8 clk_mux_flags, u32 *table, spinlock_t *lock);
512 518
519int clk_mux_val_to_index(struct clk_hw *hw, u32 *table, unsigned int flags,
520 unsigned int val);
521unsigned int clk_mux_index_to_val(u32 *table, unsigned int flags, u8 index);
522
513void clk_unregister_mux(struct clk *clk); 523void clk_unregister_mux(struct clk *clk);
514void clk_hw_unregister_mux(struct clk_hw *hw); 524void clk_hw_unregister_mux(struct clk_hw *hw);
515 525
@@ -774,6 +784,17 @@ static inline long divider_round_rate(struct clk_hw *hw, unsigned long rate,
774 rate, prate, table, width, flags); 784 rate, prate, table, width, flags);
775} 785}
776 786
787static inline long divider_ro_round_rate(struct clk_hw *hw, unsigned long rate,
788 unsigned long *prate,
789 const struct clk_div_table *table,
790 u8 width, unsigned long flags,
791 unsigned int val)
792{
793 return divider_ro_round_rate_parent(hw, clk_hw_get_parent(hw),
794 rate, prate, table, width, flags,
795 val);
796}
797
777/* 798/*
778 * FIXME clock api without lock protection 799 * FIXME clock api without lock protection
779 */ 800 */
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 4c4ef9f34db3..0dbd0885b2c2 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -209,7 +209,7 @@ static inline int clk_prepare(struct clk *clk)
209 return 0; 209 return 0;
210} 210}
211 211
212static inline int clk_bulk_prepare(int num_clks, struct clk_bulk_data *clks) 212static inline int __must_check clk_bulk_prepare(int num_clks, struct clk_bulk_data *clks)
213{ 213{
214 might_sleep(); 214 might_sleep();
215 return 0; 215 return 0;
@@ -603,8 +603,8 @@ static inline struct clk *clk_get(struct device *dev, const char *id)
603 return NULL; 603 return NULL;
604} 604}
605 605
606static inline int clk_bulk_get(struct device *dev, int num_clks, 606static inline int __must_check clk_bulk_get(struct device *dev, int num_clks,
607 struct clk_bulk_data *clks) 607 struct clk_bulk_data *clks)
608{ 608{
609 return 0; 609 return 0;
610} 610}
@@ -614,8 +614,8 @@ static inline struct clk *devm_clk_get(struct device *dev, const char *id)
614 return NULL; 614 return NULL;
615} 615}
616 616
617static inline int devm_clk_bulk_get(struct device *dev, int num_clks, 617static inline int __must_check devm_clk_bulk_get(struct device *dev, int num_clks,
618 struct clk_bulk_data *clks) 618 struct clk_bulk_data *clks)
619{ 619{
620 return 0; 620 return 0;
621} 621}
@@ -645,7 +645,7 @@ static inline int clk_enable(struct clk *clk)
645 return 0; 645 return 0;
646} 646}
647 647
648static inline int clk_bulk_enable(int num_clks, struct clk_bulk_data *clks) 648static inline int __must_check clk_bulk_enable(int num_clks, struct clk_bulk_data *clks)
649{ 649{
650 return 0; 650 return 0;
651} 651}
@@ -719,8 +719,8 @@ static inline void clk_disable_unprepare(struct clk *clk)
719 clk_unprepare(clk); 719 clk_unprepare(clk);
720} 720}
721 721
722static inline int clk_bulk_prepare_enable(int num_clks, 722static inline int __must_check clk_bulk_prepare_enable(int num_clks,
723 struct clk_bulk_data *clks) 723 struct clk_bulk_data *clks)
724{ 724{
725 int ret; 725 int ret;
726 726
diff --git a/include/linux/clk/tegra.h b/include/linux/clk/tegra.h
index d23c9cf26993..afb9edfa5d58 100644
--- a/include/linux/clk/tegra.h
+++ b/include/linux/clk/tegra.h
@@ -128,5 +128,6 @@ extern void tegra210_sata_pll_hw_sequence_start(void);
128extern void tegra210_set_sata_pll_seq_sw(bool state); 128extern void tegra210_set_sata_pll_seq_sw(bool state);
129extern void tegra210_put_utmipll_in_iddq(void); 129extern void tegra210_put_utmipll_in_iddq(void);
130extern void tegra210_put_utmipll_out_iddq(void); 130extern void tegra210_put_utmipll_out_iddq(void);
131extern int tegra210_clk_handle_mbist_war(unsigned int id);
131 132
132#endif /* __LINUX_CLK_TEGRA_H_ */ 133#endif /* __LINUX_CLK_TEGRA_H_ */
diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h
index d18da839b810..9e8611470187 100644
--- a/include/linux/clk/ti.h
+++ b/include/linux/clk/ti.h
@@ -211,6 +211,7 @@ enum {
211 * struct ti_clk_ll_ops - low-level ops for clocks 211 * struct ti_clk_ll_ops - low-level ops for clocks
212 * @clk_readl: pointer to register read function 212 * @clk_readl: pointer to register read function
213 * @clk_writel: pointer to register write function 213 * @clk_writel: pointer to register write function
214 * @clk_rmw: pointer to register read-modify-write function
214 * @clkdm_clk_enable: pointer to clockdomain enable function 215 * @clkdm_clk_enable: pointer to clockdomain enable function
215 * @clkdm_clk_disable: pointer to clockdomain disable function 216 * @clkdm_clk_disable: pointer to clockdomain disable function
216 * @clkdm_lookup: pointer to clockdomain lookup function 217 * @clkdm_lookup: pointer to clockdomain lookup function
@@ -226,6 +227,7 @@ enum {
226struct ti_clk_ll_ops { 227struct ti_clk_ll_ops {
227 u32 (*clk_readl)(const struct clk_omap_reg *reg); 228 u32 (*clk_readl)(const struct clk_omap_reg *reg);
228 void (*clk_writel)(u32 val, const struct clk_omap_reg *reg); 229 void (*clk_writel)(u32 val, const struct clk_omap_reg *reg);
230 void (*clk_rmw)(u32 val, u32 mask, const struct clk_omap_reg *reg);
229 int (*clkdm_clk_enable)(struct clockdomain *clkdm, struct clk *clk); 231 int (*clkdm_clk_enable)(struct clockdomain *clkdm, struct clk *clk);
230 int (*clkdm_clk_disable)(struct clockdomain *clkdm, 232 int (*clkdm_clk_disable)(struct clockdomain *clkdm,
231 struct clk *clk); 233 struct clk *clk);