diff options
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 | |||
268 | enable lock. | 268 | enable lock. |
269 | 269 | ||
270 | The enable lock is a spinlock and is held across calls to the .enable, | 270 | The 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, |
272 | sleep, and calls to the clk_enable(), clk_disable() and clk_is_enabled() API | 272 | and calls to the clk_enable(), clk_disable() API functions are allowed in |
273 | functions are allowed in atomic context. | 273 | atomic context. |
274 | |||
275 | For clk_is_enabled() API, it is also designed to be allowed to be used in | ||
276 | atomic context. However, it doesn't really make any sense to hold the enable | ||
277 | lock in core, unless you want to do something else with the information of | ||
278 | the enable state with that lock held. Otherwise, seeing if a clk is enabled is | ||
279 | a one-shot read of the enabled state, which could just as easily change after | ||
280 | the function returns because the lock is released. Thus the user of this API | ||
281 | needs to handle synchronizing the read of the state with whatever they're | ||
282 | using it for to make sure that the enable state doesn't change during that | ||
283 | time. | ||
274 | 284 | ||
275 | The prepare lock is a mutex and is held across calls to all other operations. | 285 | The prepare lock is a mutex and is held across calls to all other operations. |
276 | All those operations are allowed to sleep, and calls to the corresponding API | 286 | All 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 @@ | |||
1 | STMicroelectronics STM32 Peripheral Reset Clock Controller | ||
2 | ========================================================== | ||
3 | |||
4 | The RCC IP is both a reset and a clock controller. | ||
5 | |||
6 | RCC makes also power management (resume/supend and wakeup interrupt). | ||
7 | |||
8 | Please also refer to reset.txt for common reset controller binding usage. | ||
9 | |||
10 | Please also refer to clock-bindings.txt for common clock controller | ||
11 | binding usage. | ||
12 | |||
13 | |||
14 | Required 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 | |||
24 | Example: | ||
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 | |||
34 | Specifying clocks | ||
35 | ================= | ||
36 | |||
37 | All available clocks are defined as preprocessor macros in | ||
38 | dt-bindings/clock/stm32mp1-clks.h header and can be used in device | ||
39 | tree sources. | ||
40 | |||
41 | Specifying softreset control of devices | ||
42 | ======================================= | ||
43 | |||
44 | Device nodes should specify the reset channel required in their "resets" | ||
45 | property, containing a phandle to the reset device node and an index specifying | ||
46 | which channel to use. | ||
47 | The index is the bit number within the RCC registers bank, starting from RCC | ||
48 | base address. | ||
49 | It is calculated as: index = register_offset / 4 * 32 + bit_offset. | ||
50 | Where bit_offset is the bit offset within the register. | ||
51 | |||
52 | For example on STM32MP1, for LTDC reset: | ||
53 | ltdc = APB4_RSTSETR_offset / 4 * 32 + LTDC_bit_offset | ||
54 | = 0x180 / 4 * 32 + 0 = 3072 | ||
55 | |||
56 | The list of valid indices for STM32MP1 is available in: | ||
57 | include/dt-bindings/reset-controller/stm32mp1-resets.h | ||
58 | |||
59 | This 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 | ||
79 | Examples: | 82 | Examples: |
80 | dpll_usb_m2_ck: dpll_usb_m2_ck@4a008190 { | 83 | dpll_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 | ||
52 | Examples: | 55 | Examples: |
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> | |||
12189 | M: Chanwoo Choi <cw00.choi@samsung.com> | 12189 | M: Chanwoo Choi <cw00.choi@samsung.com> |
12190 | S: Supported | 12190 | S: Supported |
12191 | L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers) | 12191 | L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers) |
12192 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/snawrocki/clk.git | ||
12192 | F: drivers/clk/samsung/ | 12193 | F: drivers/clk/samsung/ |
12193 | F: include/dt-bindings/clock/exynos*.h | 12194 | F: include/dt-bindings/clock/exynos*.h |
12194 | F: Documentation/devicetree/bindings/clock/exynos*.txt | 12195 | F: 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 | ||
57 | config COMMON_CLK_HI655X | 57 | config 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 | ||
243 | config COMMON_CLK_STM32MP157 | ||
244 | def_bool COMMON_CLK && MACH_STM32MP157 | ||
245 | help | ||
246 | ---help--- | ||
247 | Support for stm32mp157 SoC family clocks | ||
248 | |||
249 | config 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 | |||
256 | config 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 | |||
241 | source "drivers/clk/bcm/Kconfig" | 263 | source "drivers/clk/bcm/Kconfig" |
242 | source "drivers/clk/hisilicon/Kconfig" | 264 | source "drivers/clk/hisilicon/Kconfig" |
243 | source "drivers/clk/imgtec/Kconfig" | 265 | source "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 | |||
45 | obj-$(CONFIG_COMMON_CLK_SI5351) += clk-si5351.o | 45 | obj-$(CONFIG_COMMON_CLK_SI5351) += clk-si5351.o |
46 | obj-$(CONFIG_COMMON_CLK_SI514) += clk-si514.o | 46 | obj-$(CONFIG_COMMON_CLK_SI514) += clk-si514.o |
47 | obj-$(CONFIG_COMMON_CLK_SI570) += clk-si570.o | 47 | obj-$(CONFIG_COMMON_CLK_SI570) += clk-si570.o |
48 | obj-$(CONFIG_ARCH_STM32) += clk-stm32f4.o | 48 | obj-$(CONFIG_COMMON_CLK_STM32F) += clk-stm32f4.o |
49 | obj-$(CONFIG_ARCH_STM32) += clk-stm32h7.o | 49 | obj-$(CONFIG_COMMON_CLK_STM32H7) += clk-stm32h7.o |
50 | obj-$(CONFIG_COMMON_CLK_STM32MP157) += clk-stm32mp1.o | ||
50 | obj-$(CONFIG_ARCH_TANGO) += clk-tango4.o | 51 | obj-$(CONFIG_ARCH_TANGO) += clk-tango4.o |
51 | obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o | 52 | obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o |
52 | obj-$(CONFIG_ARCH_U300) += clk-u300.o | 53 | obj-$(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 | |||
33 | static unsigned int _get_table_maxdiv(const struct clk_div_table *table, | 31 | static 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 | ||
68 | static unsigned int _get_table_div(const struct clk_div_table *table, | 66 | static 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 | } |
345 | EXPORT_SYMBOL_GPL(divider_round_rate_parent); | 343 | EXPORT_SYMBOL_GPL(divider_round_rate_parent); |
346 | 344 | ||
345 | long 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 | } | ||
364 | EXPORT_SYMBOL_GPL(divider_ro_round_rate_parent); | ||
365 | |||
366 | |||
347 | static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate, | 367 | static 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 | } |
381 | EXPORT_SYMBOL_GPL(divider_get_val); | 403 | EXPORT_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 | ||
79 | static int clk_gpio_mux_set_parent(struct clk_hw *hw, u8 index) | 79 | static 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 | ||
29 | static u8 clk_mux_get_parent(struct clk_hw *hw) | 29 | int 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 | } |
54 | EXPORT_SYMBOL_GPL(clk_mux_val_to_index); | ||
65 | 55 | ||
66 | static int clk_mux_set_parent(struct clk_hw *hw, u8 index) | 56 | unsigned 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 | } | ||
72 | EXPORT_SYMBOL_GPL(clk_mux_index_to_val); | ||
73 | |||
74 | static 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 | |||
85 | static 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 | ||
316 | static const u64 stm32f746_gate_map[MAX_GATE_MAP] = { 0x000000f17ef417ffull, | 317 | static const u64 stm32f746_gate_map[MAX_GATE_MAP] = { 0x000000f17ef417ffull, |
317 | 0x0000000000000003ull, | 318 | 0x0000000000000003ull, |
318 | 0x04f77f033e01c9ffull }; | 319 | 0x04f77f833e01c9ffull }; |
319 | 320 | ||
320 | static const u64 *stm32f4_gate_map; | 321 | static 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 | ||
523 | static const struct stm32f4_pll_data stm32f469_pll[MAX_PLL_DIV] = { | 524 | static 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 | ||
1051 | static const char *dsi_parent[2] = { NULL, "pll-r" }; | ||
1052 | |||
1050 | static const char *lcd_parent[1] = { "pllsai-r-div" }; | 1053 | static const char *lcd_parent[1] = { "pllsai-r-div" }; |
1051 | 1054 | ||
1052 | static const char *i2s_parents[2] = { "plli2s-r", NULL }; | 1055 | static 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 | ||
1161 | static const struct stm32_aux_clk stm32f746_aux_clk[] = { | 1170 | static 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 | |||
20 | static 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 | |||
107 | static const char * const ref12_parents[] = { | ||
108 | "ck_hsi", "ck_hse" | ||
109 | }; | ||
110 | |||
111 | static const char * const ref3_parents[] = { | ||
112 | "ck_hsi", "ck_hse", "ck_csi" | ||
113 | }; | ||
114 | |||
115 | static const char * const ref4_parents[] = { | ||
116 | "ck_hsi", "ck_hse", "ck_csi" | ||
117 | }; | ||
118 | |||
119 | static const char * const cpu_src[] = { | ||
120 | "ck_hsi", "ck_hse", "pll1_p" | ||
121 | }; | ||
122 | |||
123 | static const char * const axi_src[] = { | ||
124 | "ck_hsi", "ck_hse", "pll2_p", "pll3_p" | ||
125 | }; | ||
126 | |||
127 | static const char * const per_src[] = { | ||
128 | "ck_hsi", "ck_csi", "ck_hse" | ||
129 | }; | ||
130 | |||
131 | static const char * const mcu_src[] = { | ||
132 | "ck_hsi", "ck_hse", "ck_csi", "pll3_p" | ||
133 | }; | ||
134 | |||
135 | static const char * const sdmmc12_src[] = { | ||
136 | "ck_axi", "pll3_r", "pll4_p", "ck_hsi" | ||
137 | }; | ||
138 | |||
139 | static const char * const sdmmc3_src[] = { | ||
140 | "ck_mcu", "pll3_r", "pll4_p", "ck_hsi" | ||
141 | }; | ||
142 | |||
143 | static const char * const fmc_src[] = { | ||
144 | "ck_axi", "pll3_r", "pll4_p", "ck_per" | ||
145 | }; | ||
146 | |||
147 | static const char * const qspi_src[] = { | ||
148 | "ck_axi", "pll3_r", "pll4_p", "ck_per" | ||
149 | }; | ||
150 | |||
151 | static const char * const eth_src[] = { | ||
152 | "pll4_p", "pll3_q" | ||
153 | }; | ||
154 | |||
155 | static const char * const rng_src[] = { | ||
156 | "ck_csi", "pll4_r", "ck_lse", "ck_lsi" | ||
157 | }; | ||
158 | |||
159 | static const char * const usbphy_src[] = { | ||
160 | "ck_hse", "pll4_r", "clk-hse-div2" | ||
161 | }; | ||
162 | |||
163 | static const char * const usbo_src[] = { | ||
164 | "pll4_r", "ck_usbo_48m" | ||
165 | }; | ||
166 | |||
167 | static const char * const stgen_src[] = { | ||
168 | "ck_hsi", "ck_hse" | ||
169 | }; | ||
170 | |||
171 | static const char * const spdif_src[] = { | ||
172 | "pll4_p", "pll3_q", "ck_hsi" | ||
173 | }; | ||
174 | |||
175 | static const char * const spi123_src[] = { | ||
176 | "pll4_p", "pll3_q", "i2s_ckin", "ck_per", "pll3_r" | ||
177 | }; | ||
178 | |||
179 | static const char * const spi45_src[] = { | ||
180 | "pclk2", "pll4_q", "ck_hsi", "ck_csi", "ck_hse" | ||
181 | }; | ||
182 | |||
183 | static const char * const spi6_src[] = { | ||
184 | "pclk5", "pll4_q", "ck_hsi", "ck_csi", "ck_hse", "pll3_q" | ||
185 | }; | ||
186 | |||
187 | static const char * const cec_src[] = { | ||
188 | "ck_lse", "ck_lsi", "ck_csi" | ||
189 | }; | ||
190 | |||
191 | static const char * const i2c12_src[] = { | ||
192 | "pclk1", "pll4_r", "ck_hsi", "ck_csi" | ||
193 | }; | ||
194 | |||
195 | static const char * const i2c35_src[] = { | ||
196 | "pclk1", "pll4_r", "ck_hsi", "ck_csi" | ||
197 | }; | ||
198 | |||
199 | static const char * const i2c46_src[] = { | ||
200 | "pclk5", "pll3_q", "ck_hsi", "ck_csi" | ||
201 | }; | ||
202 | |||
203 | static const char * const lptim1_src[] = { | ||
204 | "pclk1", "pll4_p", "pll3_q", "ck_lse", "ck_lsi", "ck_per" | ||
205 | }; | ||
206 | |||
207 | static const char * const lptim23_src[] = { | ||
208 | "pclk3", "pll4_q", "ck_per", "ck_lse", "ck_lsi" | ||
209 | }; | ||
210 | |||
211 | static const char * const lptim45_src[] = { | ||
212 | "pclk3", "pll4_p", "pll3_q", "ck_lse", "ck_lsi", "ck_per" | ||
213 | }; | ||
214 | |||
215 | static const char * const usart1_src[] = { | ||
216 | "pclk5", "pll3_q", "ck_hsi", "ck_csi", "pll4_q", "ck_hse" | ||
217 | }; | ||
218 | |||
219 | const char * const usart234578_src[] = { | ||
220 | "pclk1", "pll4_q", "ck_hsi", "ck_csi", "ck_hse" | ||
221 | }; | ||
222 | |||
223 | static const char * const usart6_src[] = { | ||
224 | "pclk2", "pll4_q", "ck_hsi", "ck_csi", "ck_hse" | ||
225 | }; | ||
226 | |||
227 | static const char * const dfsdm_src[] = { | ||
228 | "pclk2", "ck_mcu" | ||
229 | }; | ||
230 | |||
231 | static const char * const fdcan_src[] = { | ||
232 | "ck_hse", "pll3_q", "pll4_q" | ||
233 | }; | ||
234 | |||
235 | static const char * const sai_src[] = { | ||
236 | "pll4_q", "pll3_q", "i2s_ckin", "ck_per" | ||
237 | }; | ||
238 | |||
239 | static const char * const sai2_src[] = { | ||
240 | "pll4_q", "pll3_q", "i2s_ckin", "ck_per", "spdif_ck_symb" | ||
241 | }; | ||
242 | |||
243 | static const char * const adc12_src[] = { | ||
244 | "pll4_q", "ck_per" | ||
245 | }; | ||
246 | |||
247 | static const char * const dsi_src[] = { | ||
248 | "ck_dsi_phy", "pll4_p" | ||
249 | }; | ||
250 | |||
251 | static const char * const rtc_src[] = { | ||
252 | "off", "ck_lse", "ck_lsi", "ck_hse_rtc" | ||
253 | }; | ||
254 | |||
255 | static const char * const mco1_src[] = { | ||
256 | "ck_hsi", "ck_hse", "ck_csi", "ck_lsi", "ck_lse" | ||
257 | }; | ||
258 | |||
259 | static const char * const mco2_src[] = { | ||
260 | "ck_mpu", "ck_axi", "ck_mcu", "pll4_p", "ck_hse", "ck_hsi" | ||
261 | }; | ||
262 | |||
263 | static const char * const ck_trace_src[] = { | ||
264 | "ck_axi" | ||
265 | }; | ||
266 | |||
267 | static 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 | |||
273 | static 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 | |||
281 | static 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 | |||
287 | static 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 | |||
295 | struct stm32_mmux { | ||
296 | u8 nbr_clk; | ||
297 | struct clk_hw *hws[MAX_MUX_CLK]; | ||
298 | }; | ||
299 | |||
300 | struct stm32_clk_mmux { | ||
301 | struct clk_mux mux; | ||
302 | struct stm32_mmux *mmux; | ||
303 | }; | ||
304 | |||
305 | struct stm32_mgate { | ||
306 | u8 nbr_clk; | ||
307 | u32 flag; | ||
308 | }; | ||
309 | |||
310 | struct stm32_clk_mgate { | ||
311 | struct clk_gate gate; | ||
312 | struct stm32_mgate *mgate; | ||
313 | u32 mask; | ||
314 | }; | ||
315 | |||
316 | struct 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 | |||
334 | struct gate_cfg { | ||
335 | u32 reg_off; | ||
336 | u8 bit_idx; | ||
337 | u8 gate_flags; | ||
338 | }; | ||
339 | |||
340 | struct fixed_factor_cfg { | ||
341 | unsigned int mult; | ||
342 | unsigned int div; | ||
343 | }; | ||
344 | |||
345 | struct 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 | |||
353 | struct mux_cfg { | ||
354 | u32 reg_off; | ||
355 | u8 shift; | ||
356 | u8 width; | ||
357 | u8 mux_flags; | ||
358 | u32 *table; | ||
359 | }; | ||
360 | |||
361 | struct stm32_gate_cfg { | ||
362 | struct gate_cfg *gate; | ||
363 | struct stm32_mgate *mgate; | ||
364 | const struct clk_ops *ops; | ||
365 | }; | ||
366 | |||
367 | struct stm32_div_cfg { | ||
368 | struct div_cfg *div; | ||
369 | const struct clk_ops *ops; | ||
370 | }; | ||
371 | |||
372 | struct 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 */ | ||
379 | struct 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 | |||
385 | static 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 | |||
403 | static 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 | |||
416 | static 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 | |||
436 | static 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 | |||
452 | static 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 | |||
460 | static 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 | |||
472 | const 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 | |||
478 | static 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 | |||
518 | static 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 | |||
539 | static 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 | |||
578 | static struct clk_hw * | ||
579 | clk_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 | |||
621 | static struct clk_hw * | ||
622 | clk_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 | |||
678 | static 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 | |||
690 | static 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 | |||
701 | const 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 | |||
710 | static u8 clk_mmux_get_parent(struct clk_hw *hw) | ||
711 | { | ||
712 | return clk_mux_ops.get_parent(hw); | ||
713 | } | ||
714 | |||
715 | static 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 | |||
735 | const 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 */ | ||
742 | struct 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 | |||
762 | static 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 | |||
771 | static 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 | |||
801 | unlock: | ||
802 | spin_unlock_irqrestore(clk_elem->lock, flags); | ||
803 | |||
804 | return bit_status; | ||
805 | } | ||
806 | |||
807 | static 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 | |||
822 | static 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 | |||
834 | static 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 | |||
859 | static 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 | |||
872 | static 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 | |||
879 | static 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 */ | ||
916 | struct 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 | |||
929 | static 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 | |||
948 | static 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 | |||
956 | static 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 | |||
983 | static 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 | |||
1002 | static 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 | |||
1009 | static 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 | |||
1047 | struct stm32_pll_cfg { | ||
1048 | u32 offset; | ||
1049 | }; | ||
1050 | |||
1051 | struct 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 | |||
1062 | struct stm32_cktim_cfg { | ||
1063 | u32 offset_apbdiv; | ||
1064 | u32 offset_timpre; | ||
1065 | }; | ||
1066 | |||
1067 | static 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 | |||
1079 | static 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 | |||
1094 | static 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 | |||
1307 | enum { | ||
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 | |||
1420 | struct 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 */ | ||
1443 | struct 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 | |||
1564 | enum { | ||
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 | |||
1603 | struct 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 | |||
1626 | const 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 | |||
1667 | static 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 | |||
2007 | struct stm32_clock_match_data { | ||
2008 | const struct clock_config *cfg; | ||
2009 | unsigned int num; | ||
2010 | unsigned int maxbinding; | ||
2011 | }; | ||
2012 | |||
2013 | static 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 | |||
2019 | static const struct of_device_id stm32mp1_match_data[] = { | ||
2020 | { | ||
2021 | .compatible = "st,stm32mp1-rcc", | ||
2022 | .data = &stm32mp1_data, | ||
2023 | }, | ||
2024 | { } | ||
2025 | }; | ||
2026 | |||
2027 | static 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 | |||
2051 | static 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 | |||
2100 | static 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 | |||
2117 | CLK_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 | 2497 | DEFINE_SHOW_ATTRIBUTE(clk_summary); | |
2490 | |||
2491 | static int clk_summary_open(struct inode *inode, struct file *file) | ||
2492 | { | ||
2493 | return single_open(file, clk_summary_show, inode->i_private); | ||
2494 | } | ||
2495 | |||
2496 | static 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 | ||
2503 | static void clk_dump_one(struct seq_file *s, struct clk_core *c, int level) | 2499 | static 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 | ||
2535 | static int clk_dump(struct seq_file *s, void *data) | 2531 | static 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 | 2554 | DEFINE_SHOW_ATTRIBUTE(clk_dump); | |
2559 | |||
2560 | static int clk_dump_open(struct inode *inode, struct file *file) | ||
2561 | { | ||
2562 | return single_open(file, clk_dump, inode->i_private); | ||
2563 | } | ||
2564 | |||
2565 | static 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 | ||
2572 | static const struct { | 2556 | static 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 | ||
2592 | static int clk_flags_dump(struct seq_file *s, void *data) | 2576 | static 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 | } |
2595 | DEFINE_SHOW_ATTRIBUTE(clk_flags); | ||
2611 | 2596 | ||
2612 | static int clk_flags_open(struct inode *inode, struct file *file) | 2597 | static int possible_parents_show(struct seq_file *s, void *data) |
2613 | { | ||
2614 | return single_open(file, clk_flags_dump, inode->i_private); | ||
2615 | } | ||
2616 | |||
2617 | static 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 | |||
2624 | static 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 | 2609 | DEFINE_SHOW_ATTRIBUTE(possible_parents); | |
2637 | static int possible_parents_open(struct inode *inode, struct file *file) | ||
2638 | { | ||
2639 | return single_open(file, possible_parents_dump, inode->i_private); | ||
2640 | } | ||
2641 | |||
2642 | static 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 | ||
2649 | static int clk_debug_create_one(struct clk_core *core, struct dentry *pdentry) | 2611 | static 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); |
3014 | out: | 2981 | out: |
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 | */ | ||
36 | struct 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 | */ |
285 | static struct clk_hw *_sci_clk_build(struct sci_clk_provider *provider, | 274 | static 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 | ||
355 | err: | 330 | err: |
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 | ||
371 | static int _cmp_sci_clk(const void *a, const void *b) | 343 | static 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 | ||
415 | static int ti_sci_init_clocks(struct sci_clk_provider *p) | 387 | static 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 | ||
458 | static 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 | |||
662 | static const struct of_device_id ti_sci_clk_of_match[] = { | 401 | static 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 | }; |
666 | MODULE_DEVICE_TABLE(of, ti_sci_clk_of_match); | 405 | MODULE_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 | ||
226 | static const char * const axi_parents[] = { | 228 | static const char * const axi_parents[] = { |
@@ -625,7 +627,7 @@ static const char * const ether_125m_parents[] = { | |||
625 | static const char * const ether_50m_parents[] = { | 627 | static 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 | ||
687 | static const char * const msdc0p_aes_parents[] = { | 689 | static 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 | ||
724 | static 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 | |||
722 | static const char * const audull_vtx_parents[] = { | 735 | static 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 | ||
891 | static const char * const mcu_mp0_parents[] = { | 908 | static 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 | ||
935 | static const struct mtk_gate_regs top_cg_regs = { | 952 | static 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) { \ | 958 | static 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 | |||
950 | static const struct mtk_gate top_clks[] = { | 982 | static 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 | ||
961 | static const struct mtk_gate_regs infra_cg_regs = { | 998 | static 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 | ||
6 | config COMMON_CLK_REGMAP_MESON | ||
7 | bool | ||
8 | select REGMAP | ||
9 | |||
6 | config COMMON_CLK_MESON8B | 10 | config 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 | ||
5 | obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-cpu.o clk-mpll.o clk-audio-divider.o | 5 | obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-mpll.o clk-audio-divider.o |
6 | obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o | 6 | obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o |
7 | obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o gxbb-aoclk-regmap.o gxbb-aoclk-32k.o | 7 | obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o gxbb-aoclk-32k.o |
8 | obj-$(CONFIG_COMMON_CLK_AXG) += axg.o | 8 | obj-$(CONFIG_COMMON_CLK_AXG) += axg.o |
9 | obj-$(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 | ||
22 | static DEFINE_SPINLOCK(meson_clk_lock); | 24 | static DEFINE_SPINLOCK(meson_clk_lock); |
23 | 25 | ||
24 | static const struct pll_rate_table sys_pll_rate_table[] = { | 26 | static 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 | |||
116 | static 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 | ||
141 | static struct meson_clk_pll axg_sys_pll = { | 67 | static 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 | ||
260 | static struct pll_params_table axg_gp0_params_table[] = { | 195 | static 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 | ||
269 | static struct meson_clk_pll axg_gp0_pll = { | 204 | static 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 | ||
248 | static 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 | |||
257 | static 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 | ||
303 | static struct clk_fixed_factor axg_fclk_div2 = { | 302 | static 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 | ||
314 | static struct clk_fixed_factor axg_fclk_div3 = { | 313 | static 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 | |||
326 | static 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 | ||
325 | static struct clk_fixed_factor axg_fclk_div4 = { | 337 | static 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 | |||
350 | static 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 | ||
336 | static struct clk_fixed_factor axg_fclk_div5 = { | 361 | static 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 | |||
374 | static 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 | ||
347 | static struct clk_fixed_factor axg_fclk_div7 = { | 385 | static 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 | |||
398 | static 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 | ||
358 | static struct meson_clk_mpll axg_mpll0 = { | 409 | static 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, | 422 | static 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, | 436 | static 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 | ||
393 | static struct meson_clk_mpll axg_mpll1 = { | 473 | static 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, | 487 | static 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 | ||
423 | static struct meson_clk_mpll axg_mpll2 = { | 519 | static 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, | 533 | static 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 | ||
453 | static struct meson_clk_mpll axg_mpll3 = { | 565 | static 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 | |||
579 | static 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, | 611 | static 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 | */ | ||
488 | static u32 mux_table_clk81[] = { 0, 2, 3, 4, 5, 6, 7 }; | 625 | static u32 mux_table_clk81[] = { 0, 2, 3, 4, 5, 6, 7 }; |
489 | static const char * const clk81_parent_names[] = { | 626 | static 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 | ||
494 | static struct clk_mux axg_mpeg_clk_sel = { | 631 | static 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 | ||
509 | static struct clk_divider axg_mpeg_clk_div = { | 646 | static 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 | ||
523 | static struct clk_gate axg_clk81 = { | 661 | static 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 */ |
548 | static struct clk_mux axg_sd_emmc_b_clk0_sel = { | 687 | static 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 | ||
562 | static struct clk_divider axg_sd_emmc_b_clk0_div = { | 702 | static 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 | ||
577 | static struct clk_gate axg_sd_emmc_b_clk0 = { | 718 | static 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 */ |
591 | static struct clk_mux axg_sd_emmc_c_clk0_sel = { | 733 | static 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 | ||
605 | static struct clk_divider axg_sd_emmc_c_clk0_div = { | 748 | static 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 | ||
620 | static struct clk_gate axg_sd_emmc_c_clk0 = { | 764 | static 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 | 915 | static struct clk_regmap *const axg_clk_regmaps[] = { | |
760 | static struct meson_clk_pll *const axg_clk_plls[] = { | ||
761 | &axg_fixed_pll, | ||
762 | &axg_sys_pll, | ||
763 | &axg_gp0_pll, | ||
764 | }; | ||
765 | |||
766 | static struct meson_clk_mpll *const axg_clk_mplls[] = { | ||
767 | &axg_mpll0, | ||
768 | &axg_mpll1, | ||
769 | &axg_mpll2, | ||
770 | &axg_mpll3, | ||
771 | }; | ||
772 | |||
773 | static 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 | |||
823 | static 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 | |||
829 | static 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, | |
835 | struct 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, | |
849 | static 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 | ||
863 | static const struct of_device_id clkc_match_table[] = { | 989 | static 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 | ||
994 | static const struct regmap_config clkc_regmap_config = { | ||
995 | .reg_bits = 32, | ||
996 | .val_bits = 32, | ||
997 | .reg_stride = 4, | ||
998 | }; | ||
999 | |||
868 | static int axg_clkc_probe(struct platform_device *pdev) | 1000 | static 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 | ||
930 | static struct platform_driver axg_driver = { | 1059 | static 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, \ | 31 | static inline struct meson_clk_audio_div_data * |
32 | struct meson_clk_audio_divider, hw) | 32 | meson_clk_audio_div_data(struct clk_regmap *clk) |
33 | { | ||
34 | return (struct meson_clk_audio_div_data *)clk->data; | ||
35 | } | ||
33 | 36 | ||
34 | static int _div_round(unsigned long parent_rate, unsigned long rate, | 37 | static 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 | ||
48 | static int _valid_divider(struct clk_hw *hw, int divider) | 51 | static 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) | |||
61 | static unsigned long audio_divider_recalc_rate(struct clk_hw *hw, | 58 | static 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 | |||
57 | static 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 | |||
66 | static 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 | |||
93 | static 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 */ | ||
116 | static 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 */ | ||
138 | static 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 | */ | ||
159 | int 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 | |||
174 | const 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) | 71 | static inline struct meson_clk_mpll_data * |
72 | meson_clk_mpll_data(struct clk_regmap *clk) | ||
73 | { | ||
74 | return (struct meson_clk_mpll_data *)clk->data; | ||
75 | } | ||
72 | 76 | ||
73 | static long rate_from_params(unsigned long parent_rate, | 77 | static 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 | ||
85 | static void params_from_rate(unsigned long requested_rate, | 89 | static 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, | |||
105 | static unsigned long mpll_recalc_rate(struct clk_hw *hw, | 109 | static 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 | ||
128 | static long mpll_round_rate(struct clk_hw *hw, | 124 | static 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 | ||
184 | static 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 | |||
208 | static 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 | ||
215 | static void mpll_disable(struct clk_hw *hw) | ||
216 | { | ||
217 | mpll_enable_core(hw, 0); | ||
218 | } | ||
219 | |||
220 | static 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 | |||
234 | const struct clk_ops meson_clk_mpll_ro_ops = { | 173 | const 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 | ||
240 | const struct clk_ops meson_clk_mpll_ops = { | 178 | const 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) | 48 | static inline struct meson_clk_pll_data * |
45 | #define MESON_PLL_LOCK BIT(31) | 49 | meson_clk_pll_data(struct clk_regmap *clk) |
46 | |||
47 | #define to_meson_clk_pll(_hw) container_of(_hw, struct meson_clk_pll, hw) | ||
48 | |||
49 | static 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 | ||
90 | static long meson_clk_pll_round_rate(struct clk_hw *hw, unsigned long rate, | 54 | static 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 | ||
106 | static const struct pll_rate_table *meson_clk_get_pll_settings(struct meson_clk_pll *pll, | 72 | static 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 */ | 99 | static u16 __pll_params_with_frac(unsigned long rate, |
120 | static 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 | |||
119 | static const struct pll_rate_table * | ||
120 | meson_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 | ||
143 | static int meson_clk_pll_wait_lock(struct meson_clk_pll *pll, | 144 | static 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) { | 169 | static 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 | ||
159 | static void meson_clk_pll_init_params(struct meson_clk_pll *pll) | 186 | static 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 | ||
168 | static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, | 199 | static 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 | ||
246 | const struct clk_ops meson_clk_pll_ops = { | 253 | const 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 | |||
7 | static 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 | |||
19 | static int clk_regmap_gate_enable(struct clk_hw *hw) | ||
20 | { | ||
21 | return clk_regmap_gate_endisable(hw, 1); | ||
22 | } | ||
23 | |||
24 | static void clk_regmap_gate_disable(struct clk_hw *hw) | ||
25 | { | ||
26 | clk_regmap_gate_endisable(hw, 0); | ||
27 | } | ||
28 | |||
29 | static 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 | |||
44 | const 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 | }; | ||
49 | EXPORT_SYMBOL_GPL(clk_regmap_gate_ops); | ||
50 | |||
51 | static 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 | |||
70 | static 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 | |||
96 | static 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 | |||
116 | const 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 | }; | ||
121 | EXPORT_SYMBOL_GPL(clk_regmap_divider_ops); | ||
122 | |||
123 | const 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 | }; | ||
127 | EXPORT_SYMBOL_GPL(clk_regmap_divider_ro_ops); | ||
128 | |||
129 | static 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 | |||
145 | static 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 | |||
156 | const 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 | }; | ||
161 | EXPORT_SYMBOL_GPL(clk_regmap_mux_ops); | ||
162 | |||
163 | const struct clk_ops clk_regmap_mux_ro_ops = { | ||
164 | .get_parent = clk_regmap_mux_get_parent, | ||
165 | }; | ||
166 | EXPORT_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 | */ | ||
21 | struct 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 | */ | ||
39 | struct clk_regmap_gate_data { | ||
40 | unsigned int offset; | ||
41 | u8 bit_idx; | ||
42 | u8 flags; | ||
43 | }; | ||
44 | |||
45 | static inline struct clk_regmap_gate_data * | ||
46 | clk_get_regmap_gate_data(struct clk_regmap *clk) | ||
47 | { | ||
48 | return (struct clk_regmap_gate_data *)clk->data; | ||
49 | } | ||
50 | |||
51 | extern 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 | */ | ||
64 | struct 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 | |||
72 | static inline struct clk_regmap_div_data * | ||
73 | clk_get_regmap_div_data(struct clk_regmap *clk) | ||
74 | { | ||
75 | return (struct clk_regmap_div_data *)clk->data; | ||
76 | } | ||
77 | |||
78 | extern const struct clk_ops clk_regmap_divider_ops; | ||
79 | extern 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 | */ | ||
94 | struct clk_regmap_mux_data { | ||
95 | unsigned int offset; | ||
96 | u32 *table; | ||
97 | u32 mask; | ||
98 | u8 shift; | ||
99 | u8 flags; | ||
100 | }; | ||
101 | |||
102 | static inline struct clk_regmap_mux_data * | ||
103 | clk_get_regmap_mux_data(struct clk_regmap *clk) | ||
104 | { | ||
105 | return (struct clk_regmap_mux_data *)clk->data; | ||
106 | } | ||
107 | |||
108 | extern const struct clk_ops clk_regmap_mux_ops; | ||
109 | extern 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 | ||
41 | static 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 | |||
49 | static 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 | |||
38 | struct pll_rate_table { | 57 | struct 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 | |||
65 | struct 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 | ||
76 | struct 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 | ||
87 | struct meson_clk_pll { | 76 | struct 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 | ||
103 | struct meson_clk_cpu { | 93 | struct 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 | |||
111 | int meson_clk_cpu_notifier_cb(struct notifier_block *nb, unsigned long event, | ||
112 | void *data); | ||
113 | |||
114 | struct 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 | ||
125 | struct meson_clk_audio_divider { | 102 | struct 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) \ |
134 | struct clk_gate _name = { \ | 108 | struct 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 | |||
13 | static 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 | |||
21 | static 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 | |||
29 | static 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 | |||
42 | const 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 | ||
67 | static DEFINE_SPINLOCK(gxbb_aoclk_lock); | ||
68 | |||
69 | struct gxbb_aoclk_reset_controller { | 68 | struct 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) \ |
90 | static struct aoclk_gate_regmap _name##_ao = { \ | 89 | static 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); | |||
107 | GXBB_AO_GATE(ir_blaster, 6); | 108 | GXBB_AO_GATE(ir_blaster, 6); |
108 | 109 | ||
109 | static struct aoclk_cec_32k cec_32k_ao = { | 110 | static 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 | ||
129 | static struct aoclk_gate_regmap *gxbb_aoclk_gate[] = { | 129 | static 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 | ||
20 | struct 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 | |||
30 | extern const struct clk_ops meson_aoclk_gate_regmap_ops; | 20 | extern const struct clk_ops meson_aoclk_gate_regmap_ops; |
31 | 21 | ||
32 | struct aoclk_cec_32k { | 22 | struct 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 | ||
30 | static DEFINE_SPINLOCK(meson_clk_lock); | 33 | static DEFINE_SPINLOCK(meson_clk_lock); |
31 | 34 | ||
32 | static 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 | |||
124 | static const struct pll_rate_table gxbb_gp0_pll_rate_table[] = { | 35 | static 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 | ||
281 | static struct meson_clk_pll gxbb_fixed_pll = { | 192 | static 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 | ||
307 | static struct meson_clk_pll gxbb_hdmi_pll = { | 234 | static 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, | 245 | static 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, | 297 | static 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 | ||
343 | static struct meson_clk_pll gxbb_sys_pll = { | 355 | static 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 | ||
371 | struct pll_params_table gxbb_gp0_params_table[] = { | 392 | static 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 | ||
378 | static struct meson_clk_pll gxbb_gp0_pll = { | 399 | static 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 | ||
412 | struct pll_params_table gxl_gp0_params_table[] = { | 439 | static 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 | ||
421 | static struct meson_clk_pll gxl_gp0_pll = { | 448 | static 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 | ||
455 | static struct clk_fixed_factor gxbb_fclk_div2 = { | 493 | static 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 | ||
466 | static struct clk_fixed_factor gxbb_fclk_div3 = { | 504 | static 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 | |||
517 | static 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 | ||
477 | static struct clk_fixed_factor gxbb_fclk_div4 = { | 528 | static 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 | |||
541 | static 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 | ||
488 | static struct clk_fixed_factor gxbb_fclk_div5 = { | 552 | static 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 | |||
565 | static 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 | ||
499 | static struct clk_fixed_factor gxbb_fclk_div7 = { | 576 | static 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 | |||
589 | static 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 | ||
510 | static struct meson_clk_mpll gxbb_mpll0 = { | 600 | static 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, | 613 | static 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, | 627 | static 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 | ||
545 | static struct meson_clk_mpll gxbb_mpll1 = { | 659 | static 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, | 673 | static 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 | ||
575 | static struct meson_clk_mpll gxbb_mpll2 = { | 700 | static 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, | 714 | static 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 | /* | 741 | static 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 | ||
611 | static u32 mux_table_clk81[] = { 0, 2, 3, 4, 5, 6, 7 }; | 755 | static u32 mux_table_clk81[] = { 0, 2, 3, 4, 5, 6, 7 }; |
612 | static const char * const clk81_parent_names[] = { | 756 | static 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 | ||
617 | static struct clk_mux gxbb_mpeg_clk_sel = { | 761 | static 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 | ||
638 | static struct clk_divider gxbb_mpeg_clk_div = { | 781 | static 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 */ |
653 | static struct clk_gate gxbb_clk81 = { | 796 | static 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 | ||
666 | static struct clk_mux gxbb_sar_adc_clk_sel = { | 810 | static 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 | ||
680 | static struct clk_divider gxbb_sar_adc_clk_div = { | 825 | static 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 | ||
693 | static struct clk_gate gxbb_sar_adc_clk = { | 839 | static 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 | ||
711 | static u32 mux_table_mali_0_1[] = {0, 1, 2, 3, 4, 5, 6, 7}; | ||
712 | static const char * const gxbb_mali_0_1_parent_names[] = { | 858 | static 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 | ||
717 | static struct clk_mux gxbb_mali_0_sel = { | 863 | static 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 | ||
737 | static struct clk_divider gxbb_mali_0_div = { | 883 | static 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 | ||
751 | static struct clk_gate gxbb_mali_0 = { | 898 | static 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 | ||
764 | static struct clk_mux gxbb_mali_1_sel = { | 912 | static 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 | ||
784 | static struct clk_divider gxbb_mali_1_div = { | 932 | static 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 | ||
798 | static struct clk_gate gxbb_mali_1 = { | 947 | static 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 | ||
811 | static u32 mux_table_mali[] = {0, 1}; | ||
812 | static const char * const gxbb_mali_parent_names[] = { | 961 | static const char * const gxbb_mali_parent_names[] = { |
813 | "mali_0", "mali_1" | 962 | "mali_0", "mali_1" |
814 | }; | 963 | }; |
815 | 964 | ||
816 | static struct clk_mux gxbb_mali = { | 965 | static 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 | ||
831 | static struct clk_mux gxbb_cts_amclk_sel = { | 980 | static 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 | ||
847 | static struct meson_clk_audio_divider gxbb_cts_amclk_div = { | 996 | static 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 | ||
864 | static struct clk_gate gxbb_cts_amclk = { | 1014 | static 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 | ||
877 | static struct clk_mux gxbb_cts_mclk_i958_sel = { | 1028 | static 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 | ||
893 | static struct clk_divider gxbb_cts_mclk_i958_div = { | 1044 | static 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 | ||
908 | static struct clk_gate gxbb_cts_mclk_i958 = { | 1060 | static 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 | ||
921 | static struct clk_mux gxbb_cts_i958 = { | 1074 | static 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 | ||
939 | static struct clk_divider gxbb_32k_clk_div = { | 1093 | static 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 | ||
953 | static struct clk_gate gxbb_32k_clk = { | 1108 | static 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 | ||
970 | static struct clk_mux gxbb_32k_clk_sel = { | 1126 | static 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 */ |
996 | static struct clk_mux gxbb_sd_emmc_a_clk0_sel = { | 1153 | static 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 | ||
1010 | static struct clk_divider gxbb_sd_emmc_a_clk0_div = { | 1168 | static 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 | ||
1025 | static struct clk_gate gxbb_sd_emmc_a_clk0 = { | 1184 | static 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 */ |
1039 | static struct clk_mux gxbb_sd_emmc_b_clk0_sel = { | 1199 | static 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 | ||
1053 | static struct clk_divider gxbb_sd_emmc_b_clk0_div = { | 1214 | static 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 | ||
1068 | static struct clk_gate gxbb_sd_emmc_b_clk0 = { | 1230 | static 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 */ |
1082 | static struct clk_mux gxbb_sd_emmc_c_clk0_sel = { | 1245 | static 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 | ||
1096 | static struct clk_divider gxbb_sd_emmc_c_clk0_div = { | 1260 | static 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 | ||
1111 | static struct clk_gate gxbb_sd_emmc_c_clk0 = { | 1276 | static 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 | ||
1126 | static u32 mux_table_vpu[] = {0, 1, 2, 3}; | ||
1127 | static const char * const gxbb_vpu_parent_names[] = { | 1292 | static 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 | ||
1131 | static struct clk_mux gxbb_vpu_0_sel = { | 1296 | static 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 | ||
1150 | static struct clk_divider gxbb_vpu_0_div = { | 1315 | static 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 | ||
1164 | static struct clk_gate gxbb_vpu_0 = { | 1330 | static 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 | ||
1177 | static struct clk_mux gxbb_vpu_1_sel = { | 1344 | static 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 | ||
1196 | static struct clk_divider gxbb_vpu_1_div = { | 1363 | static 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 | ||
1210 | static struct clk_gate gxbb_vpu_1 = { | 1378 | static 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 | ||
1223 | static struct clk_mux gxbb_vpu = { | 1392 | static 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 | ||
1243 | static u32 mux_table_vapb[] = {0, 1, 2, 3}; | ||
1244 | static const char * const gxbb_vapb_parent_names[] = { | 1413 | static 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 | ||
1248 | static struct clk_mux gxbb_vapb_0_sel = { | 1417 | static 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 | ||
1267 | static struct clk_divider gxbb_vapb_0_div = { | 1436 | static 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 | ||
1281 | static struct clk_gate gxbb_vapb_0 = { | 1451 | static 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 | ||
1294 | static struct clk_mux gxbb_vapb_1_sel = { | 1465 | static 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 | ||
1313 | static struct clk_divider gxbb_vapb_1_div = { | 1484 | static 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 | ||
1327 | static struct clk_gate gxbb_vapb_1 = { | 1499 | static 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 | ||
1340 | static struct clk_mux gxbb_vapb_sel = { | 1513 | static 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 | ||
1358 | static struct clk_gate gxbb_vapb = { | 1532 | static 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 = { | |||
1609 | static struct clk_hw_onecell_data gxl_hw_onecell_data = { | 1794 | static 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 */ | 1950 | static struct clk_regmap *const gxbb_clk_regmaps[] = { |
1757 | |||
1758 | static 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 | |||
1765 | static 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 | ||
1772 | static struct meson_clk_mpll *const gxbb_clk_mplls[] = { | 1955 | static 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 | ||
1778 | static struct clk_gate *const gxbb_clk_gates[] = { | 1960 | static 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, | |
1877 | static 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, | |
1898 | static 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 | |||
1914 | static 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 | ||
1918 | struct clkc_data { | 2105 | struct 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 | ||
1934 | static const struct clkc_data gxbb_clkc_data = { | 2111 | static 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 | ||
1950 | static const struct clkc_data gxl_clkc_data = { | 2117 | static 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 | ||
2129 | static const struct regmap_config clkc_regmap_config = { | ||
2130 | .reg_bits = 32, | ||
2131 | .val_bits = 32, | ||
2132 | .reg_stride = 4, | ||
2133 | }; | ||
2134 | |||
1972 | static int gxbb_clkc_probe(struct platform_device *pdev) | 2135 | static 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 | |||
2034 | iounmap: | ||
2035 | iounmap(clk_base); | ||
2036 | return ret; | ||
2037 | } | 2202 | } |
2038 | 2203 | ||
2039 | static struct platform_driver gxbb_driver = { | 2204 | static 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 | ||
35 | static DEFINE_SPINLOCK(meson_clk_lock); | 37 | static 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 | ||
100 | static 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 | |||
114 | static struct clk_fixed_rate meson8b_xtal = { | 102 | static 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 | ||
123 | static struct meson_clk_pll meson8b_fixed_pll = { | 111 | static 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 | ||
149 | static struct meson_clk_pll meson8b_vid_pll = { | 153 | static 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 | ||
175 | static struct meson_clk_pll meson8b_sys_pll = { | 190 | static 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 | ||
203 | static struct clk_fixed_factor meson8b_fclk_div2 = { | 228 | static 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 | ||
214 | static struct clk_fixed_factor meson8b_fclk_div3 = { | 239 | static 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 | |||
252 | static 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 | ||
225 | static struct clk_fixed_factor meson8b_fclk_div4 = { | 263 | static 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 | |||
276 | static 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 | ||
236 | static struct clk_fixed_factor meson8b_fclk_div5 = { | 287 | static 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 | |||
300 | static 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 | ||
247 | static struct clk_fixed_factor meson8b_fclk_div7 = { | 311 | static 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 | |||
324 | static 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 | ||
258 | static struct meson_clk_mpll meson8b_mpll0 = { | 335 | static 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, | 348 | static 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, | 362 | static 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 | ||
293 | static struct meson_clk_mpll meson8b_mpll1 = { | 394 | static 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, | 408 | static 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 | ||
323 | static struct meson_clk_mpll meson8b_mpll2 = { | 435 | static 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, | 449 | static 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 | /* | 476 | static 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 | }, |
358 | static 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 | ||
370 | static u32 mux_table_clk81[] = { 6, 5, 7 }; | 490 | static u32 mux_table_clk81[] = { 6, 5, 7 }; |
371 | 491 | static struct clk_regmap meson8b_mpeg_clk_sel = { | |
372 | struct 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 | ||
394 | struct clk_divider meson8b_mpeg_clk_div = { | 512 | static 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 | ||
408 | struct clk_gate meson8b_clk81 = { | 526 | static 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 | |||
540 | static 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 | |||
556 | static 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 | |||
568 | static 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 | |||
580 | static 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 | |||
591 | static 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 | |||
608 | static 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 | |||
626 | static 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 | ||
607 | static struct meson_clk_pll *const meson8b_clk_plls[] = { | 842 | static struct clk_regmap *const meson8b_clk_regmaps[] = { |
608 | &meson8b_fixed_pll, | ||
609 | &meson8b_vid_pll, | ||
610 | &meson8b_sys_pll, | ||
611 | }; | ||
612 | |||
613 | static struct meson_clk_mpll *const meson8b_clk_mplls[] = { | ||
614 | &meson8b_mpll0, | ||
615 | &meson8b_mpll1, | ||
616 | &meson8b_mpll2, | ||
617 | }; | ||
618 | |||
619 | static 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 | |||
700 | static struct clk_mux *const meson8b_clk_muxes[] = { | ||
701 | &meson8b_mpeg_clk_sel, | ||
702 | }; | ||
703 | |||
704 | static 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 | ||
708 | static const struct meson8b_clk_reset_line { | 944 | static 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 | ||
1043 | static const struct regmap_config clkc_regmap_config = { | ||
1044 | .reg_bits = 32, | ||
1045 | .val_bits = 32, | ||
1046 | .reg_stride = 4, | ||
1047 | }; | ||
1048 | |||
807 | static int meson8b_clkc_probe(struct platform_device *pdev) | 1049 | static 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 | ||
885 | static const struct of_device_id meson8b_clkc_match_table[] = { | 1084 | static 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 | ||
69 | static struct regmap_config lpc32xx_scb_regmap_config = { | 69 | static 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 = ÷r->clkr; | 30 | struct clk_regmap *clkr = ÷r->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 | ||
49 | static long div_round_rate(struct clk_hw *hw, unsigned long rate, | 41 | static 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 | ||
142 | struct rpm_cc; | ||
143 | |||
129 | struct clk_rpm { | 144 | struct 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 | ||
140 | struct rpm_cc { | 157 | struct 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 | ||
146 | struct rpm_clk_desc { | 165 | struct 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 | ||
311 | static 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 | |||
332 | static 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 | |||
291 | static int clk_rpm_fixed_prepare(struct clk_hw *hw) | 351 | static 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 | ||
441 | static const struct clk_ops clk_rpm_xo_ops = { | ||
442 | .prepare = clk_rpm_xo_prepare, | ||
443 | .unprepare = clk_rpm_xo_unprepare, | ||
444 | }; | ||
445 | |||
381 | static const struct clk_ops clk_rpm_fixed_ops = { | 446 | static 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); | |||
449 | DEFINE_CLK_RPM(apq8064, sfab_clk, sfab_a_clk, QCOM_RPM_SYS_FABRIC_CLK); | 514 | DEFINE_CLK_RPM(apq8064, sfab_clk, sfab_a_clk, QCOM_RPM_SYS_FABRIC_CLK); |
450 | DEFINE_CLK_RPM(apq8064, sfpb_clk, sfpb_a_clk, QCOM_RPM_SFPB_CLK); | 515 | DEFINE_CLK_RPM(apq8064, sfpb_clk, sfpb_a_clk, QCOM_RPM_SFPB_CLK); |
451 | DEFINE_CLK_RPM(apq8064, qdss_clk, qdss_a_clk, QCOM_RPM_QDSS_CLK); | 516 | DEFINE_CLK_RPM(apq8064, qdss_clk, qdss_a_clk, QCOM_RPM_QDSS_CLK); |
517 | DEFINE_CLK_RPM_XO_BUFFER(apq8064, xo_d0_clk, xo_d0_a_clk, 0); | ||
518 | DEFINE_CLK_RPM_XO_BUFFER(apq8064, xo_d1_clk, xo_d1_a_clk, 8); | ||
519 | DEFINE_CLK_RPM_XO_BUFFER(apq8064, xo_a0_clk, xo_a0_a_clk, 16); | ||
520 | DEFINE_CLK_RPM_XO_BUFFER(apq8064, xo_a1_clk, xo_a1_a_clk, 24); | ||
521 | DEFINE_CLK_RPM_XO_BUFFER(apq8064, xo_a2_clk, xo_a2_a_clk, 28); | ||
452 | 522 | ||
453 | static struct clk_rpm *apq8064_clks[] = { | 523 | static 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 | ||
474 | static const struct rpm_clk_desc rpm_clk_apq8064 = { | 549 | static 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 | ||
700 | static int rpm_smd_clk_remove(struct platform_device *pdev) | ||
701 | { | ||
702 | of_clk_del_provider(pdev->dev.of_node); | ||
703 | return 0; | ||
704 | } | ||
705 | |||
706 | static struct platform_driver rpm_smd_clk_driver = { | 700 | static 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 | ||
715 | static int __init rpm_smd_clk_init(void) | 708 | static 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 | |||
8 | obj-$(CONFIG_ARCH_EXYNOS4) += clk-exynos4.o | 8 | obj-$(CONFIG_ARCH_EXYNOS4) += clk-exynos4.o |
9 | obj-$(CONFIG_ARCH_EXYNOS4) += clk-exynos4412-isp.o | 9 | obj-$(CONFIG_ARCH_EXYNOS4) += clk-exynos4412-isp.o |
10 | obj-$(CONFIG_SOC_EXYNOS5250) += clk-exynos5250.o | 10 | obj-$(CONFIG_SOC_EXYNOS5250) += clk-exynos5250.o |
11 | obj-$(CONFIG_SOC_EXYNOS5250) += clk-exynos5-subcmu.o | ||
11 | obj-$(CONFIG_SOC_EXYNOS5260) += clk-exynos5260.o | 12 | obj-$(CONFIG_SOC_EXYNOS5260) += clk-exynos5260.o |
12 | obj-$(CONFIG_SOC_EXYNOS5410) += clk-exynos5410.o | 13 | obj-$(CONFIG_SOC_EXYNOS5410) += clk-exynos5410.o |
13 | obj-$(CONFIG_SOC_EXYNOS5420) += clk-exynos5420.o | 14 | obj-$(CONFIG_SOC_EXYNOS5420) += clk-exynos5420.o |
15 | obj-$(CONFIG_SOC_EXYNOS5420) += clk-exynos5-subcmu.o | ||
14 | obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynos5433.o | 16 | obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynos5433.o |
15 | obj-$(CONFIG_SOC_EXYNOS5440) += clk-exynos5440.o | 17 | obj-$(CONFIG_SOC_EXYNOS5440) += clk-exynos5440.o |
16 | obj-$(CONFIG_EXYNOS_AUDSS_CLK_CON) += clk-exynos-audss.o | 18 | obj-$(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 */ |
672 | static const struct samsung_pll_rate_table exynos3250_pll_rates[] __initconst = { | 672 | static 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 */ |
694 | static const struct samsung_pll_rate_table exynos3250_epll_rates[] __initconst = { | 694 | static 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 */ |
713 | static const struct samsung_pll_rate_table exynos3250_vpll_rates[] __initconst = { | 713 | static 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 */ |
1268 | static const struct samsung_pll_rate_table exynos4210_apll_rates[] __initconst = { | 1268 | static 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 | ||
1281 | static const struct samsung_pll_rate_table exynos4210_epll_rates[] __initconst = { | 1281 | static 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 | ||
1292 | static const struct samsung_pll_rate_table exynos4210_vpll_rates[] __initconst = { | 1292 | static 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 | ||
1301 | static const struct samsung_pll_rate_table exynos4x12_apll_rates[] __initconst = { | 1301 | static 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 | ||
1321 | static const struct samsung_pll_rate_table exynos4x12_epll_rates[] __initconst = { | 1321 | static 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 | ||
1332 | static const struct samsung_pll_rate_table exynos4x12_vpll_rates[] __initconst = { | 1333 | static 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 | |||
15 | static struct samsung_clk_provider *ctx; | ||
16 | static const struct exynos5_subcmu_info *cmu; | ||
17 | static int nr_cmus; | ||
18 | |||
19 | static 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 | |||
30 | static 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 | |||
39 | static 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 | */ | ||
57 | void 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 | |||
72 | static 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 | |||
85 | static 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 | |||
98 | static 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 | |||
117 | static 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 | |||
124 | static 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 | |||
133 | static 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 | |||
150 | static 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 | |||
167 | static 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 | |||
174 | static 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 | |||
183 | static 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 | } | ||
189 | core_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 | |||
6 | struct exynos5_subcmu_reg_dump { | ||
7 | u32 offset; | ||
8 | u32 value; | ||
9 | u32 mask; | ||
10 | u32 save; | ||
11 | }; | ||
12 | |||
13 | struct 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 | |||
23 | void 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 | ||
693 | static 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 | |||
711 | static 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 | |||
717 | static 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 | |||
701 | static const struct samsung_pll_rate_table vpll_24mhz_tbl[] __initconst = { | 725 | static 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 | ||
710 | static const struct samsung_pll_rate_table epll_24mhz_tbl[] __initconst = { | 734 | static 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 | ||
724 | static const struct samsung_pll_rate_table apll_24mhz_tbl[] __initconst = { | 748 | static 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 | ||
745 | static struct samsung_pll_clock exynos5250_plls[nr_plls] __initdata = { | 769 | static 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 | } |
868 | CLK_OF_DECLARE(exynos5250_clk, "samsung,exynos5250-clock", exynos5250_clk_init); | 893 | CLK_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 | */ |
25 | static const struct samsung_pll_rate_table pll2550_24mhz_tbl[] __initconst = { | 25 | static 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 | */ |
58 | static const struct samsung_pll_rate_table pll2650_24mhz_tbl[] __initconst = { | 58 | static 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 | ||
228 | static const struct samsung_pll_rate_table exynos5410_pll2550x_24mhz_tbl[] __initconst = { | 228 | static 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 | ||
241 | static struct samsung_pll_clock exynos5410_plls[nr_plls] __initdata = { | 241 | static 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 | |||
1240 | static const struct samsung_div_clock exynos5x_disp_div_clks[] __initconst = { | ||
1241 | DIV(0, "dout_disp1_blk", "aclk200_disp1", DIV2_RATIO0, 16, 2), | ||
1242 | }; | ||
1243 | |||
1244 | static 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 | |||
1258 | static 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 | |||
1266 | static 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 | |||
1271 | static 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 | |||
1280 | static 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 | |||
1287 | static 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 | |||
1291 | static 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), | 1297 | static 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 | |||
1303 | static 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 | ||
1265 | static const struct samsung_pll_rate_table exynos5420_pll2550x_24mhz_tbl[] __initconst = { | 1331 | static 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 | ||
1287 | static const struct samsung_pll_rate_table exynos5420_epll_24mhz_tbl[] = { | 1353 | static 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 | ||
1302 | static struct samsung_pll_clock exynos5x_plls[nr_plls] __initdata = { | 1371 | static 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 | } |
1483 | CLK_OF_DECLARE(exynos5420_clk, "samsung,exynos5420-clock", exynos5420_clk_init); | 1554 | CLK_OF_DECLARE_DRIVER(exynos5420_clk, "samsung,exynos5420-clock", |
1555 | exynos5420_clk_init); | ||
1484 | 1556 | ||
1485 | static void __init exynos5800_clk_init(struct device_node *np) | 1557 | static 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 | } |
1489 | CLK_OF_DECLARE(exynos5800_clk, "samsung,exynos5800-clock", exynos5800_clk_init); | 1561 | CLK_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 | */ |
705 | static const struct samsung_pll_rate_table exynos5433_pll_rates[] __initconst = { | 705 | static 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 */ |
758 | static const struct samsung_pll_rate_table exynos5433_aud_pll_rates[] __initconst = { | 758 | static 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 | ||
142 | static const struct samsung_pll_rate_table pll1460x_24mhz_tbl[] __initconst = { | 142 | static 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 | ||
96 | PNAME(fclk_p) = { "mpll", "div_slow" }; | 96 | PNAME(fclk_p) = { "mpll", "div_slow" }; |
97 | 97 | ||
98 | struct samsung_mux_clock s3c2410_common_muxes[] __initdata = { | 98 | static 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 | ||
114 | struct samsung_div_clock s3c2410_common_dividers[] __initdata = { | 114 | static 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 | ||
119 | struct samsung_gate_clock s3c2410_common_gates[] __initdata = { | 119 | static 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 */ |
138 | struct samsung_clock_alias s3c2410_common_aliases[] __initdata = { | 138 | static 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 = { | |||
162 | static struct samsung_pll_rate_table pll_s3c2410_12mhz_tbl[] __initdata = { | 162 | static 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 | ||
203 | struct samsung_div_clock s3c2410_dividers[] __initdata = { | 203 | static 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 | ||
207 | struct samsung_fixed_factor_clock s3c2410_ffactor[] __initdata = { | 207 | static 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 | ||
218 | struct samsung_clock_alias s3c2410_aliases[] __initdata = { | 218 | static 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 | ||
230 | static struct samsung_pll_rate_table pll_s3c244x_12mhz_tbl[] __initdata = { | 230 | static 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 = { | |||
269 | PNAME(hclk_p) = { "fclk", "div_hclk_2", "div_hclk_4", "div_hclk_3" }; | 269 | PNAME(hclk_p) = { "fclk", "div_hclk_2", "div_hclk_4", "div_hclk_3" }; |
270 | PNAME(armclk_p) = { "fclk", "hclk" }; | 270 | PNAME(armclk_p) = { "fclk", "hclk" }; |
271 | 271 | ||
272 | struct samsung_mux_clock s3c244x_common_muxes[] __initdata = { | 272 | static 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 | ||
277 | struct samsung_fixed_factor_clock s3c244x_common_ffactor[] __initdata = { | 277 | static 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 | ||
294 | struct samsung_div_clock s3c244x_common_dividers[] __initdata = { | 294 | static 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 | ||
302 | struct samsung_gate_clock s3c244x_common_gates[] __initdata = { | 302 | static 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 | ||
306 | struct samsung_clock_alias s3c244x_common_aliases[] __initdata = { | 306 | static 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 | ||
319 | PNAME(s3c2440_camif_p) = { "upll", "ff_cam" }; | 319 | PNAME(s3c2440_camif_p) = { "upll", "ff_cam" }; |
320 | 320 | ||
321 | struct samsung_mux_clock s3c2440_muxes[] __initdata = { | 321 | static 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 | ||
325 | struct samsung_gate_clock s3c2440_gates[] __initdata = { | 325 | static 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 | ||
331 | struct samsung_fixed_factor_clock s3c2442_ffactor[] __initdata = { | 331 | static 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 | ||
335 | PNAME(s3c2442_camif_p) = { "upll", "ff_cam", "upll", "upll_3" }; | 335 | PNAME(s3c2442_camif_p) = { "upll", "ff_cam", "upll", "upll_3" }; |
336 | 336 | ||
337 | struct samsung_mux_clock s3c2442_muxes[] __initdata = { | 337 | static 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 |
346 | struct samsung_fixed_rate_clock s3c2410_common_frate_clks[] __initdata = { | 346 | static 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 | ||
469 | static void __init s3c2410_clk_init(struct device_node *np) | 469 | static 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 | } |
473 | CLK_OF_DECLARE(s3c2410_clk, "samsung,s3c2410-clock", s3c2410_clk_init); | 473 | CLK_OF_DECLARE(s3c2410_clk, "samsung,s3c2410-clock", s3c2410_clk_init); |
474 | 474 | ||
475 | static void __init s3c2440_clk_init(struct device_node *np) | 475 | static 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 | } |
479 | CLK_OF_DECLARE(s3c2440_clk, "samsung,s3c2440-clock", s3c2440_clk_init); | 479 | CLK_OF_DECLARE(s3c2440_clk, "samsung,s3c2440-clock", s3c2440_clk_init); |
480 | 480 | ||
481 | static void __init s3c2442_clk_init(struct device_node *np) | 481 | static 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 | } |
485 | CLK_OF_DECLARE(s3c2442_clk, "samsung,s3c2442-clock", s3c2442_clk_init); | 485 | CLK_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 */ | ||
31 | enum s3c2412_plls { | ||
32 | mpll, upll, | ||
33 | }; | ||
34 | |||
35 | static void __iomem *reg_base; | 30 | static 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 | ||
101 | struct samsung_div_clock s3c2412_dividers[] __initdata = { | 96 | static 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 | ||
113 | struct samsung_fixed_factor_clock s3c2412_ffactor[] __initdata = { | 108 | static 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" }; | |||
130 | PNAME(mdivclk_p) = { "xti", "div_xti" }; | 125 | PNAME(mdivclk_p) = { "xti", "div_xti" }; |
131 | PNAME(armclk_p) = { "armdiv", "hclk" }; | 126 | PNAME(armclk_p) = { "armdiv", "hclk" }; |
132 | 127 | ||
133 | struct samsung_mux_clock s3c2412_muxes[] __initdata = { | 128 | static 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 | ||
146 | static struct samsung_pll_clock s3c2412_plls[] __initdata = { | 141 | static 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 | ||
153 | struct samsung_gate_clock s3c2412_gates[] __initdata = { | 146 | static 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 | ||
184 | struct samsung_clock_alias s3c2412_aliases[] __initdata = { | 177 | static 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 |
234 | struct samsung_fixed_rate_clock s3c2412_common_frate_clks[] __initdata = { | 227 | static 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 | ||
297 | static void __init s3c2412_clk_init(struct device_node *np) | 290 | static 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 | } |
301 | CLK_OF_DECLARE(s3c2412_clk, "samsung,s3c2412-clock", s3c2412_clk_init); | 294 | CLK_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 */ | ||
45 | enum s3c2443_plls { | ||
46 | mpll, epll, | ||
47 | }; | ||
48 | |||
49 | static void __iomem *reg_base; | 44 | static 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" }; | |||
113 | PNAME(armclk_p) = { "armdiv" , "hclk" }; | 108 | PNAME(armclk_p) = { "armdiv" , "hclk" }; |
114 | PNAME(i2s0_p) = { "div_i2s0", "ext_i2s", "epllref", "epllref" }; | 109 | PNAME(i2s0_p) = { "div_i2s0", "ext_i2s", "epllref", "epllref" }; |
115 | 110 | ||
116 | struct samsung_mux_clock s3c2443_common_muxes[] __initdata = { | 111 | static 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 | ||
144 | struct samsung_div_clock s3c2443_common_dividers[] __initdata = { | 139 | static 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 | ||
157 | struct samsung_gate_clock s3c2443_common_gates[] __initdata = { | 152 | static 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 | ||
191 | struct samsung_clock_alias s3c2443_common_aliases[] __initdata = { | 186 | static 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 | ||
227 | static struct samsung_pll_clock s3c2416_pll_clks[] __initdata = { | 222 | static 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 | ||
234 | PNAME(s3c2416_hsmmc0_p) = { "sclk_hsmmc0", "sclk_hsmmcext" }; | 227 | PNAME(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 | ||
248 | struct samsung_div_clock s3c2416_dividers[] __initdata = { | 241 | static 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 | ||
254 | struct samsung_mux_clock s3c2416_muxes[] __initdata = { | 247 | static 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 | ||
260 | struct samsung_gate_clock s3c2416_gates[] __initdata = { | 253 | static 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 | ||
270 | struct samsung_clock_alias s3c2416_aliases[] __initdata = { | 263 | static 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 | ||
281 | static struct samsung_pll_clock s3c2443_pll_clks[] __initdata = { | 274 | static 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 | ||
288 | static struct clk_div_table armdiv_s3c2443_d[] = { | 279 | static 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 | ||
300 | struct samsung_div_clock s3c2443_dividers[] __initdata = { | 291 | static 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 | ||
305 | struct samsung_gate_clock s3c2443_gates[] __initdata = { | 296 | static 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 | ||
314 | struct samsung_clock_alias s3c2443_aliases[] __initdata = { | 305 | static 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" }; | |||
327 | PNAME(s3c2450_hsspi1_p) = { "hsspi1_epll", "hsspi1_mpll" }; | 318 | PNAME(s3c2450_hsspi1_p) = { "hsspi1_epll", "hsspi1_mpll" }; |
328 | PNAME(i2s1_p) = { "div_i2s1", "ext_i2s", "epllref", "epllref" }; | 319 | PNAME(i2s1_p) = { "div_i2s1", "ext_i2s", "epllref", "epllref" }; |
329 | 320 | ||
330 | struct samsung_div_clock s3c2450_dividers[] __initdata = { | 321 | static 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 | ||
337 | struct samsung_mux_clock s3c2450_muxes[] __initdata = { | 328 | static 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 | ||
343 | struct samsung_gate_clock s3c2450_gates[] __initdata = { | 334 | static 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 | ||
354 | struct samsung_clock_alias s3c2450_aliases[] __initdata = { | 345 | static 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 | */ |
377 | struct samsung_fixed_rate_clock s3c2443_common_frate_clks[] __initdata = { | 368 | static 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 | ||
471 | static void __init s3c2416_clk_init(struct device_node *np) | 462 | static 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 | } |
475 | CLK_OF_DECLARE(s3c2416_clk, "samsung,s3c2416-clock", s3c2416_clk_init); | 466 | CLK_OF_DECLARE(s3c2416_clk, "samsung,s3c2416-clock", s3c2416_clk_init); |
476 | 467 | ||
477 | static void __init s3c2443_clk_init(struct device_node *np) | 468 | static 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 | } |
481 | CLK_OF_DECLARE(s3c2443_clk, "samsung,s3c2443-clock", s3c2443_clk_init); | 472 | CLK_OF_DECLARE(s3c2443_clk, "samsung,s3c2443-clock", s3c2443_clk_init); |
482 | 473 | ||
483 | static void __init s3c2450_clk_init(struct device_node *np) | 474 | static 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 | } |
487 | CLK_OF_DECLARE(s3c2450_clk, "samsung,s3c2450-clock", s3c2450_clk_init); | 478 | CLK_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 */ | ||
60 | enum s3c64xx_plls { | ||
61 | apll, mpll, epll, | ||
62 | }; | ||
63 | |||
64 | static void __iomem *reg_base; | 59 | static void __iomem *reg_base; |
65 | static bool is_s3c6400; | 60 | static 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. */ |
366 | static struct samsung_pll_clock s3c64xx_pll_clks[] __initdata = { | 361 | static 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); |
960 | static SPRD_SC_GATE_CLK(emmc_2x_en, "emmc-2x-en", "aon-apb", 0x13c, | 960 | static 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); |
962 | static SPRD_SC_GATE_CLK(arch_rtc_eb, "arch-rtc-eb", "aon-apb", 0x10, | ||
963 | 0x1000, BIT(0), CLK_IGNORE_UNUSED, 0); | ||
964 | static SPRD_SC_GATE_CLK(kpb_rtc_eb, "kpb-rtc-eb", "aon-apb", 0x10, | ||
965 | 0x1000, BIT(1), CLK_IGNORE_UNUSED, 0); | ||
966 | static SPRD_SC_GATE_CLK(aon_syst_rtc_eb, "aon-syst-rtc-eb", "aon-apb", 0x10, | ||
967 | 0x1000, BIT(2), CLK_IGNORE_UNUSED, 0); | ||
968 | static SPRD_SC_GATE_CLK(ap_syst_rtc_eb, "ap-syst-rtc-eb", "aon-apb", 0x10, | ||
969 | 0x1000, BIT(3), CLK_IGNORE_UNUSED, 0); | ||
970 | static SPRD_SC_GATE_CLK(aon_tmr_rtc_eb, "aon-tmr-rtc-eb", "aon-apb", 0x10, | ||
971 | 0x1000, BIT(4), CLK_IGNORE_UNUSED, 0); | ||
972 | static SPRD_SC_GATE_CLK(ap_tmr0_rtc_eb, "ap-tmr0-rtc-eb", "aon-apb", 0x10, | ||
973 | 0x1000, BIT(5), CLK_IGNORE_UNUSED, 0); | ||
974 | static SPRD_SC_GATE_CLK(eic_rtc_eb, "eic-rtc-eb", "aon-apb", 0x10, | ||
975 | 0x1000, BIT(6), CLK_IGNORE_UNUSED, 0); | ||
976 | static SPRD_SC_GATE_CLK(eic_rtcdv5_eb, "eic-rtcdv5-eb", "aon-apb", 0x10, | ||
977 | 0x1000, BIT(7), CLK_IGNORE_UNUSED, 0); | ||
978 | static SPRD_SC_GATE_CLK(ap_wdg_rtc_eb, "ap-wdg-rtc-eb", "aon-apb", 0x10, | ||
979 | 0x1000, BIT(9), CLK_IGNORE_UNUSED, 0); | ||
980 | static SPRD_SC_GATE_CLK(ap_tmr1_rtc_eb, "ap-tmr1-rtc-eb", "aon-apb", 0x10, | ||
981 | 0x1000, BIT(15), CLK_IGNORE_UNUSED, 0); | ||
982 | static SPRD_SC_GATE_CLK(ap_tmr2_rtc_eb, "ap-tmr2-rtc-eb", "aon-apb", 0x10, | ||
983 | 0x1000, BIT(16), CLK_IGNORE_UNUSED, 0); | ||
984 | static SPRD_SC_GATE_CLK(dcxo_tmr_rtc_eb, "dcxo-tmr-rtc-eb", "aon-apb", 0x10, | ||
985 | 0x1000, BIT(17), CLK_IGNORE_UNUSED, 0); | ||
986 | static SPRD_SC_GATE_CLK(bb_cal_rtc_eb, "bb-cal-rtc-eb", "aon-apb", 0x10, | ||
987 | 0x1000, BIT(18), CLK_IGNORE_UNUSED, 0); | ||
988 | static SPRD_SC_GATE_CLK(avs_big_rtc_eb, "avs-big-rtc-eb", "aon-apb", 0x10, | ||
989 | 0x1000, BIT(20), CLK_IGNORE_UNUSED, 0); | ||
990 | static SPRD_SC_GATE_CLK(avs_lit_rtc_eb, "avs-lit-rtc-eb", "aon-apb", 0x10, | ||
991 | 0x1000, BIT(21), CLK_IGNORE_UNUSED, 0); | ||
992 | static SPRD_SC_GATE_CLK(avs_gpu0_rtc_eb, "avs-gpu0-rtc-eb", "aon-apb", 0x10, | ||
993 | 0x1000, BIT(22), CLK_IGNORE_UNUSED, 0); | ||
994 | static SPRD_SC_GATE_CLK(avs_gpu1_rtc_eb, "avs-gpu1-rtc-eb", "aon-apb", 0x10, | ||
995 | 0x1000, BIT(23), CLK_IGNORE_UNUSED, 0); | ||
996 | static SPRD_SC_GATE_CLK(gpu_ts_eb, "gpu-ts-eb", "aon-apb", 0x10, | ||
997 | 0x1000, BIT(24), CLK_IGNORE_UNUSED, 0); | ||
998 | static SPRD_SC_GATE_CLK(rtcdv10_eb, "rtcdv10-eb", "aon-apb", 0x10, | ||
999 | 0x1000, BIT(27), CLK_IGNORE_UNUSED, 0); | ||
962 | 1000 | ||
963 | static struct sprd_clk_common *sc9860_aon_gate[] = { | 1001 | static 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 | ||
1035 | static struct clk_hw_onecell_data sc9860_aon_gate_hws = { | 1092 | static 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 | ||
1156 | static int _pll_fixed_mdiv(struct tegra_clk_pll_params *pll_params, | 1158 | static 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 | ||
581 | static unsigned long tegra20_clk_measure_input_freq(void) | 582 | static 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 | ||
285 | struct 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 | |||
294 | static struct clk **clks; | ||
295 | |||
258 | static void __iomem *clk_base; | 296 | static void __iomem *clk_base; |
259 | static void __iomem *pmc_base; | 297 | static void __iomem *pmc_base; |
298 | static void __iomem *ahub_base; | ||
299 | static void __iomem *dispa_base; | ||
300 | static void __iomem *vic_base; | ||
260 | 301 | ||
261 | static unsigned long osc_freq; | 302 | static unsigned long osc_freq; |
262 | static unsigned long pll_ref_freq; | 303 | static unsigned long pll_ref_freq; |
@@ -267,6 +308,7 @@ static DEFINE_SPINLOCK(pll_re_lock); | |||
267 | static DEFINE_SPINLOCK(pll_u_lock); | 308 | static DEFINE_SPINLOCK(pll_u_lock); |
268 | static DEFINE_SPINLOCK(sor1_lock); | 309 | static DEFINE_SPINLOCK(sor1_lock); |
269 | static DEFINE_SPINLOCK(emc_lock); | 310 | static DEFINE_SPINLOCK(emc_lock); |
311 | static DEFINE_MUTEX(lvl2_ovr_lock); | ||
270 | 312 | ||
271 | /* possible OSC frequencies in Hz */ | 313 | /* possible OSC frequencies in Hz */ |
272 | static unsigned long tegra210_input_freq[] = { | 314 | static 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 | } |
514 | EXPORT_SYMBOL_GPL(tegra210_set_sata_pll_seq_sw); | 558 | EXPORT_SYMBOL_GPL(tegra210_set_sata_pll_seq_sw); |
515 | 559 | ||
560 | static 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 | |||
571 | static 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 | |||
596 | static 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 | |||
614 | static 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 | |||
634 | static 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 | |||
516 | static inline void _pll_misc_chk_default(void __iomem *base, | 669 | static 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 | ||
2414 | static struct clk **clks; | ||
2415 | |||
2416 | static const char * const aclk_parents[] = { | 2567 | static 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 | ||
2572 | static const unsigned int nvjpg_slcg_clkids[] = { TEGRA210_CLK_NVDEC }; | ||
2573 | static const unsigned int nvdec_slcg_clkids[] = { TEGRA210_CLK_NVJPG }; | ||
2574 | static const unsigned int sor_slcg_clkids[] = { TEGRA210_CLK_HDA2CODEC_2X, | ||
2575 | TEGRA210_CLK_HDA2HDMI, TEGRA210_CLK_DISP1, TEGRA210_CLK_DISP2 }; | ||
2576 | static const unsigned int disp_slcg_clkids[] = { TEGRA210_CLK_LA, | ||
2577 | TEGRA210_CLK_HOST1X}; | ||
2578 | static const unsigned int xusba_slcg_clkids[] = { TEGRA210_CLK_XUSB_HOST, | ||
2579 | TEGRA210_CLK_XUSB_DEV }; | ||
2580 | static const unsigned int xusbb_slcg_clkids[] = { TEGRA210_CLK_XUSB_HOST, | ||
2581 | TEGRA210_CLK_XUSB_SS }; | ||
2582 | static const unsigned int xusbc_slcg_clkids[] = { TEGRA210_CLK_XUSB_DEV, | ||
2583 | TEGRA210_CLK_XUSB_SS }; | ||
2584 | static const unsigned int venc_slcg_clkids[] = { TEGRA210_CLK_HOST1X, | ||
2585 | TEGRA210_CLK_PLL_D }; | ||
2586 | static 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 }; | ||
2590 | static const unsigned int vic_slcg_clkids[] = { TEGRA210_CLK_HOST1X }; | ||
2591 | |||
2592 | static 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 | |||
2679 | int 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 | |||
2421 | void tegra210_put_utmipll_in_iddq(void) | 2711 | void 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 | ||
2947 | static 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 | |||
2951 | static 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 | |||
2657 | static __init void tegra210_periph_clk_init(void __iomem *clk_base, | 2954 | static __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 | ||
3454 | static 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 | } |
3224 | CLK_OF_DECLARE(tegra210, "nvidia,tegra210-car", tegra210_clock_init); | 3577 | CLK_OF_DECLARE(tegra210, "nvidia,tegra210-car", tegra210_clock_init); |
diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c index 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 | ||
824 | static const char *pll_e_parents[] = { "pll_ref", "pll_p" }; | 825 | static 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); | |||
812 | u16 tegra_pll_get_fixed_mdiv(struct clk_hw *hw, unsigned long input_rate); | 812 | u16 tegra_pll_get_fixed_mdiv(struct clk_hw *hw, unsigned long input_rate); |
813 | int tegra_pll_p_div_to_hw(struct tegra_clk_pll *pll, u8 p_div); | 813 | int 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 | ||
58 | static 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 | |||
68 | static 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 | |||
58 | static u32 clk_memmap_readl(const struct clk_omap_reg *reg) | 81 | static 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 | ||
278 | void 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, | |||
194 | int ti_clk_add_alias(struct device *dev, struct clk *clk, const char *con); | 196 | int ti_clk_add_alias(struct device *dev, struct clk *clk, const char *con); |
195 | void ti_clk_add_aliases(void); | 197 | void ti_clk_add_aliases(void); |
196 | 198 | ||
199 | void ti_clk_latch(struct clk_omap_reg *reg, s8 shift); | ||
200 | |||
197 | struct clk_hw *ti_clk_build_component_mux(struct ti_clk_mux *setup); | 201 | struct clk_hw *ti_clk_build_component_mux(struct ti_clk_mux *setup); |
198 | 202 | ||
199 | int ti_clk_parse_divider_data(int *div_table, int num_dividers, int max_div, | 203 | int 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, ÷r->reg); | 264 | ti_clk_ll_ops->clk_writel(val, ÷r->reg); |
265 | 265 | ||
266 | ti_clk_latch(÷r->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, ®, div->bit_shift, | 459 | flags, ®, 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 | ||
557 | static int __init ti_clk_divider_populate(struct device_node *node, | 562 | static 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, ®, &table, &flags, | 627 | if (ti_clk_divider_populate(node, ®, &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, ®, | 631 | clk = _register_divider(NULL, node->name, parent_name, flags, ®, |
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, ®, mux->bit_shift, mask, | 165 | flags, ®, 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, ®, shift, mask, clk_mux_flags, NULL); | 219 | flags, ®, 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 | ||
150 | static const char *soc_force_no_clk[] = { | ||
151 | "samsung,exynos5250-clock", | ||
152 | "samsung,exynos5420-clock", | ||
153 | "samsung,exynos5800-clock", | ||
154 | }; | ||
155 | |||
150 | static __init int exynos4_pm_init_power_domain(void) | 156 | static __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); |
423 | long 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); | ||
422 | int divider_get_val(unsigned long rate, unsigned long parent_rate, | 427 | int 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 | ||
519 | int clk_mux_val_to_index(struct clk_hw *hw, u32 *table, unsigned int flags, | ||
520 | unsigned int val); | ||
521 | unsigned int clk_mux_index_to_val(u32 *table, unsigned int flags, u8 index); | ||
522 | |||
513 | void clk_unregister_mux(struct clk *clk); | 523 | void clk_unregister_mux(struct clk *clk); |
514 | void clk_hw_unregister_mux(struct clk_hw *hw); | 524 | void 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 | ||
787 | static 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 | ||
212 | static inline int clk_bulk_prepare(int num_clks, struct clk_bulk_data *clks) | 212 | static 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 | ||
606 | static inline int clk_bulk_get(struct device *dev, int num_clks, | 606 | static 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 | ||
617 | static inline int devm_clk_bulk_get(struct device *dev, int num_clks, | 617 | static 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 | ||
648 | static inline int clk_bulk_enable(int num_clks, struct clk_bulk_data *clks) | 648 | static 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 | ||
722 | static inline int clk_bulk_prepare_enable(int num_clks, | 722 | static 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); | |||
128 | extern void tegra210_set_sata_pll_seq_sw(bool state); | 128 | extern void tegra210_set_sata_pll_seq_sw(bool state); |
129 | extern void tegra210_put_utmipll_in_iddq(void); | 129 | extern void tegra210_put_utmipll_in_iddq(void); |
130 | extern void tegra210_put_utmipll_out_iddq(void); | 130 | extern void tegra210_put_utmipll_out_iddq(void); |
131 | extern 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 { | |||
226 | struct ti_clk_ll_ops { | 227 | struct 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); |