diff options
-rw-r--r-- | Documentation/devicetree/bindings/clock/actions,owl-cmu.txt | 7 | ||||
-rw-r--r-- | drivers/clk/actions/Kconfig | 5 | ||||
-rw-r--r-- | drivers/clk/actions/Makefile | 1 | ||||
-rw-r--r-- | drivers/clk/actions/owl-pll.c | 2 | ||||
-rw-r--r-- | drivers/clk/actions/owl-pll.h | 30 | ||||
-rw-r--r-- | drivers/clk/actions/owl-s500.c | 525 | ||||
-rw-r--r-- | drivers/clk/clk-gpio.c | 39 | ||||
-rw-r--r-- | drivers/clk/clk-stm32mp1.c | 37 | ||||
-rw-r--r-- | drivers/clk/qcom/clk-rcg.h | 5 | ||||
-rw-r--r-- | drivers/clk/qcom/clk-rcg2.c | 24 | ||||
-rw-r--r-- | drivers/clk/qcom/clk-rpmh.c | 146 | ||||
-rw-r--r-- | drivers/clk/qcom/gcc-qcs404.c | 1 | ||||
-rw-r--r-- | include/dt-bindings/clock/actions,s500-cmu.h | 78 | ||||
-rw-r--r-- | include/dt-bindings/clock/qcom,rpmh.h | 1 | ||||
-rw-r--r-- | include/dt-bindings/clock/stm32mp1-clks.h | 3 |
15 files changed, 859 insertions, 45 deletions
diff --git a/Documentation/devicetree/bindings/clock/actions,owl-cmu.txt b/Documentation/devicetree/bindings/clock/actions,owl-cmu.txt index 2ef86ae96df8..d19885b7c73f 100644 --- a/Documentation/devicetree/bindings/clock/actions,owl-cmu.txt +++ b/Documentation/devicetree/bindings/clock/actions,owl-cmu.txt | |||
@@ -2,13 +2,14 @@ | |||
2 | 2 | ||
3 | The Actions Semi Owl Clock Management Unit generates and supplies clock | 3 | The Actions Semi Owl Clock Management Unit generates and supplies clock |
4 | to various controllers within the SoC. The clock binding described here is | 4 | to various controllers within the SoC. The clock binding described here is |
5 | applicable to S900 and S700 SoC's. | 5 | applicable to S900, S700 and S500 SoC's. |
6 | 6 | ||
7 | Required Properties: | 7 | Required Properties: |
8 | 8 | ||
9 | - compatible: should be one of the following, | 9 | - compatible: should be one of the following, |
10 | "actions,s900-cmu" | 10 | "actions,s900-cmu" |
11 | "actions,s700-cmu" | 11 | "actions,s700-cmu" |
12 | "actions,s500-cmu" | ||
12 | - reg: physical base address of the controller and length of memory mapped | 13 | - reg: physical base address of the controller and length of memory mapped |
13 | region. | 14 | region. |
14 | - clocks: Reference to the parent clocks ("hosc", "losc") | 15 | - clocks: Reference to the parent clocks ("hosc", "losc") |
@@ -19,8 +20,8 @@ Each clock is assigned an identifier, and client nodes can use this identifier | |||
19 | to specify the clock which they consume. | 20 | to specify the clock which they consume. |
20 | 21 | ||
21 | All available clocks are defined as preprocessor macros in corresponding | 22 | All available clocks are defined as preprocessor macros in corresponding |
22 | dt-bindings/clock/actions,s900-cmu.h or actions,s700-cmu.h header and can be | 23 | dt-bindings/clock/actions,s900-cmu.h or actions,s700-cmu.h or |
23 | used in device tree sources. | 24 | actions,s500-cmu.h header and can be used in device tree sources. |
24 | 25 | ||
25 | External clocks: | 26 | External clocks: |
26 | 27 | ||
diff --git a/drivers/clk/actions/Kconfig b/drivers/clk/actions/Kconfig index 04f0a6355726..5b45ca35757e 100644 --- a/drivers/clk/actions/Kconfig +++ b/drivers/clk/actions/Kconfig | |||
@@ -9,6 +9,11 @@ if CLK_ACTIONS | |||
9 | 9 | ||
10 | # SoC Drivers | 10 | # SoC Drivers |
11 | 11 | ||
12 | config CLK_OWL_S500 | ||
13 | bool "Support for the Actions Semi OWL S500 clocks" | ||
14 | depends on ARCH_ACTIONS || COMPILE_TEST | ||
15 | default ARCH_ACTIONS | ||
16 | |||
12 | config CLK_OWL_S700 | 17 | config CLK_OWL_S700 |
13 | bool "Support for the Actions Semi OWL S700 clocks" | 18 | bool "Support for the Actions Semi OWL S700 clocks" |
14 | depends on (ARM64 && ARCH_ACTIONS) || COMPILE_TEST | 19 | depends on (ARM64 && ARCH_ACTIONS) || COMPILE_TEST |
diff --git a/drivers/clk/actions/Makefile b/drivers/clk/actions/Makefile index ccfdf9781cef..a2588e55c790 100644 --- a/drivers/clk/actions/Makefile +++ b/drivers/clk/actions/Makefile | |||
@@ -10,5 +10,6 @@ clk-owl-y += owl-pll.o | |||
10 | clk-owl-y += owl-reset.o | 10 | clk-owl-y += owl-reset.o |
11 | 11 | ||
12 | # SoC support | 12 | # SoC support |
13 | obj-$(CONFIG_CLK_OWL_S500) += owl-s500.o | ||
13 | obj-$(CONFIG_CLK_OWL_S700) += owl-s700.o | 14 | obj-$(CONFIG_CLK_OWL_S700) += owl-s700.o |
14 | obj-$(CONFIG_CLK_OWL_S900) += owl-s900.o | 15 | obj-$(CONFIG_CLK_OWL_S900) += owl-s900.o |
diff --git a/drivers/clk/actions/owl-pll.c b/drivers/clk/actions/owl-pll.c index 058e06d7099f..02437bdedf4d 100644 --- a/drivers/clk/actions/owl-pll.c +++ b/drivers/clk/actions/owl-pll.c | |||
@@ -179,7 +179,7 @@ static int owl_pll_set_rate(struct clk_hw *hw, unsigned long rate, | |||
179 | 179 | ||
180 | regmap_write(common->regmap, pll_hw->reg, reg); | 180 | regmap_write(common->regmap, pll_hw->reg, reg); |
181 | 181 | ||
182 | udelay(PLL_STABILITY_WAIT_US); | 182 | udelay(pll_hw->delay); |
183 | 183 | ||
184 | return 0; | 184 | return 0; |
185 | } | 185 | } |
diff --git a/drivers/clk/actions/owl-pll.h b/drivers/clk/actions/owl-pll.h index 0aae30abd5dc..6fb0d45bb088 100644 --- a/drivers/clk/actions/owl-pll.h +++ b/drivers/clk/actions/owl-pll.h | |||
@@ -13,6 +13,8 @@ | |||
13 | 13 | ||
14 | #include "owl-common.h" | 14 | #include "owl-common.h" |
15 | 15 | ||
16 | #define OWL_PLL_DEF_DELAY 50 | ||
17 | |||
16 | /* last entry should have rate = 0 */ | 18 | /* last entry should have rate = 0 */ |
17 | struct clk_pll_table { | 19 | struct clk_pll_table { |
18 | unsigned int val; | 20 | unsigned int val; |
@@ -27,6 +29,7 @@ struct owl_pll_hw { | |||
27 | u8 width; | 29 | u8 width; |
28 | u8 min_mul; | 30 | u8 min_mul; |
29 | u8 max_mul; | 31 | u8 max_mul; |
32 | u8 delay; | ||
30 | const struct clk_pll_table *table; | 33 | const struct clk_pll_table *table; |
31 | }; | 34 | }; |
32 | 35 | ||
@@ -36,7 +39,7 @@ struct owl_pll { | |||
36 | }; | 39 | }; |
37 | 40 | ||
38 | #define OWL_PLL_HW(_reg, _bfreq, _bit_idx, _shift, \ | 41 | #define OWL_PLL_HW(_reg, _bfreq, _bit_idx, _shift, \ |
39 | _width, _min_mul, _max_mul, _table) \ | 42 | _width, _min_mul, _max_mul, _delay, _table) \ |
40 | { \ | 43 | { \ |
41 | .reg = _reg, \ | 44 | .reg = _reg, \ |
42 | .bfreq = _bfreq, \ | 45 | .bfreq = _bfreq, \ |
@@ -45,6 +48,7 @@ struct owl_pll { | |||
45 | .width = _width, \ | 48 | .width = _width, \ |
46 | .min_mul = _min_mul, \ | 49 | .min_mul = _min_mul, \ |
47 | .max_mul = _max_mul, \ | 50 | .max_mul = _max_mul, \ |
51 | .delay = _delay, \ | ||
48 | .table = _table, \ | 52 | .table = _table, \ |
49 | } | 53 | } |
50 | 54 | ||
@@ -52,8 +56,8 @@ struct owl_pll { | |||
52 | _shift, _width, _min_mul, _max_mul, _table, _flags) \ | 56 | _shift, _width, _min_mul, _max_mul, _table, _flags) \ |
53 | struct owl_pll _struct = { \ | 57 | struct owl_pll _struct = { \ |
54 | .pll_hw = OWL_PLL_HW(_reg, _bfreq, _bit_idx, _shift, \ | 58 | .pll_hw = OWL_PLL_HW(_reg, _bfreq, _bit_idx, _shift, \ |
55 | _width, _min_mul, \ | 59 | _width, _min_mul, _max_mul, \ |
56 | _max_mul, _table), \ | 60 | OWL_PLL_DEF_DELAY, _table), \ |
57 | .common = { \ | 61 | .common = { \ |
58 | .regmap = NULL, \ | 62 | .regmap = NULL, \ |
59 | .hw.init = CLK_HW_INIT(_name, \ | 63 | .hw.init = CLK_HW_INIT(_name, \ |
@@ -67,8 +71,23 @@ struct owl_pll { | |||
67 | _shift, _width, _min_mul, _max_mul, _table, _flags) \ | 71 | _shift, _width, _min_mul, _max_mul, _table, _flags) \ |
68 | struct owl_pll _struct = { \ | 72 | struct owl_pll _struct = { \ |
69 | .pll_hw = OWL_PLL_HW(_reg, _bfreq, _bit_idx, _shift, \ | 73 | .pll_hw = OWL_PLL_HW(_reg, _bfreq, _bit_idx, _shift, \ |
70 | _width, _min_mul, \ | 74 | _width, _min_mul, _max_mul, \ |
71 | _max_mul, _table), \ | 75 | OWL_PLL_DEF_DELAY, _table), \ |
76 | .common = { \ | ||
77 | .regmap = NULL, \ | ||
78 | .hw.init = CLK_HW_INIT_NO_PARENT(_name, \ | ||
79 | &owl_pll_ops, \ | ||
80 | _flags), \ | ||
81 | }, \ | ||
82 | } | ||
83 | |||
84 | #define OWL_PLL_NO_PARENT_DELAY(_struct, _name, _reg, _bfreq, _bit_idx, \ | ||
85 | _shift, _width, _min_mul, _max_mul, _delay, _table, \ | ||
86 | _flags) \ | ||
87 | struct owl_pll _struct = { \ | ||
88 | .pll_hw = OWL_PLL_HW(_reg, _bfreq, _bit_idx, _shift, \ | ||
89 | _width, _min_mul, _max_mul, \ | ||
90 | _delay, _table), \ | ||
72 | .common = { \ | 91 | .common = { \ |
73 | .regmap = NULL, \ | 92 | .regmap = NULL, \ |
74 | .hw.init = CLK_HW_INIT_NO_PARENT(_name, \ | 93 | .hw.init = CLK_HW_INIT_NO_PARENT(_name, \ |
@@ -78,7 +97,6 @@ struct owl_pll { | |||
78 | } | 97 | } |
79 | 98 | ||
80 | #define mul_mask(m) ((1 << ((m)->width)) - 1) | 99 | #define mul_mask(m) ((1 << ((m)->width)) - 1) |
81 | #define PLL_STABILITY_WAIT_US (50) | ||
82 | 100 | ||
83 | static inline struct owl_pll *hw_to_owl_pll(const struct clk_hw *hw) | 101 | static inline struct owl_pll *hw_to_owl_pll(const struct clk_hw *hw) |
84 | { | 102 | { |
diff --git a/drivers/clk/actions/owl-s500.c b/drivers/clk/actions/owl-s500.c new file mode 100644 index 000000000000..e2007ac4d235 --- /dev/null +++ b/drivers/clk/actions/owl-s500.c | |||
@@ -0,0 +1,525 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0+ | ||
2 | /* | ||
3 | * Actions Semi Owl S500 SoC clock driver | ||
4 | * | ||
5 | * Copyright (c) 2014 Actions Semi Inc. | ||
6 | * Author: David Liu <liuwei@actions-semi.com> | ||
7 | * | ||
8 | * Copyright (c) 2018 Linaro Ltd. | ||
9 | * Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> | ||
10 | * | ||
11 | * Copyright (c) 2018 LSI-TEC - Caninos Loucos | ||
12 | * Author: Edgar Bernardi Righi <edgar.righi@lsitec.org.br> | ||
13 | */ | ||
14 | |||
15 | #include <linux/clk-provider.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | |||
18 | #include "owl-common.h" | ||
19 | #include "owl-composite.h" | ||
20 | #include "owl-divider.h" | ||
21 | #include "owl-factor.h" | ||
22 | #include "owl-fixed-factor.h" | ||
23 | #include "owl-gate.h" | ||
24 | #include "owl-mux.h" | ||
25 | #include "owl-pll.h" | ||
26 | |||
27 | #include <dt-bindings/clock/actions,s500-cmu.h> | ||
28 | |||
29 | #define CMU_COREPLL (0x0000) | ||
30 | #define CMU_DEVPLL (0x0004) | ||
31 | #define CMU_DDRPLL (0x0008) | ||
32 | #define CMU_NANDPLL (0x000C) | ||
33 | #define CMU_DISPLAYPLL (0x0010) | ||
34 | #define CMU_AUDIOPLL (0x0014) | ||
35 | #define CMU_TVOUTPLL (0x0018) | ||
36 | #define CMU_BUSCLK (0x001C) | ||
37 | #define CMU_SENSORCLK (0x0020) | ||
38 | #define CMU_LCDCLK (0x0024) | ||
39 | #define CMU_DSICLK (0x0028) | ||
40 | #define CMU_CSICLK (0x002C) | ||
41 | #define CMU_DECLK (0x0030) | ||
42 | #define CMU_BISPCLK (0x0034) | ||
43 | #define CMU_BUSCLK1 (0x0038) | ||
44 | #define CMU_VDECLK (0x0040) | ||
45 | #define CMU_VCECLK (0x0044) | ||
46 | #define CMU_NANDCCLK (0x004C) | ||
47 | #define CMU_SD0CLK (0x0050) | ||
48 | #define CMU_SD1CLK (0x0054) | ||
49 | #define CMU_SD2CLK (0x0058) | ||
50 | #define CMU_UART0CLK (0x005C) | ||
51 | #define CMU_UART1CLK (0x0060) | ||
52 | #define CMU_UART2CLK (0x0064) | ||
53 | #define CMU_PWM4CLK (0x0068) | ||
54 | #define CMU_PWM5CLK (0x006C) | ||
55 | #define CMU_PWM0CLK (0x0070) | ||
56 | #define CMU_PWM1CLK (0x0074) | ||
57 | #define CMU_PWM2CLK (0x0078) | ||
58 | #define CMU_PWM3CLK (0x007C) | ||
59 | #define CMU_USBPLL (0x0080) | ||
60 | #define CMU_ETHERNETPLL (0x0084) | ||
61 | #define CMU_CVBSPLL (0x0088) | ||
62 | #define CMU_LENSCLK (0x008C) | ||
63 | #define CMU_GPU3DCLK (0x0090) | ||
64 | #define CMU_CORECTL (0x009C) | ||
65 | #define CMU_DEVCLKEN0 (0x00A0) | ||
66 | #define CMU_DEVCLKEN1 (0x00A4) | ||
67 | #define CMU_DEVRST0 (0x00A8) | ||
68 | #define CMU_DEVRST1 (0x00AC) | ||
69 | #define CMU_UART3CLK (0x00B0) | ||
70 | #define CMU_UART4CLK (0x00B4) | ||
71 | #define CMU_UART5CLK (0x00B8) | ||
72 | #define CMU_UART6CLK (0x00BC) | ||
73 | #define CMU_SSCLK (0x00C0) | ||
74 | #define CMU_DIGITALDEBUG (0x00D0) | ||
75 | #define CMU_ANALOGDEBUG (0x00D4) | ||
76 | #define CMU_COREPLLDEBUG (0x00D8) | ||
77 | #define CMU_DEVPLLDEBUG (0x00DC) | ||
78 | #define CMU_DDRPLLDEBUG (0x00E0) | ||
79 | #define CMU_NANDPLLDEBUG (0x00E4) | ||
80 | #define CMU_DISPLAYPLLDEBUG (0x00E8) | ||
81 | #define CMU_TVOUTPLLDEBUG (0x00EC) | ||
82 | #define CMU_DEEPCOLORPLLDEBUG (0x00F4) | ||
83 | #define CMU_AUDIOPLL_ETHPLLDEBUG (0x00F8) | ||
84 | #define CMU_CVBSPLLDEBUG (0x00FC) | ||
85 | |||
86 | #define OWL_S500_COREPLL_DELAY (150) | ||
87 | #define OWL_S500_DDRPLL_DELAY (63) | ||
88 | #define OWL_S500_DEVPLL_DELAY (28) | ||
89 | #define OWL_S500_NANDPLL_DELAY (44) | ||
90 | #define OWL_S500_DISPLAYPLL_DELAY (57) | ||
91 | #define OWL_S500_ETHERNETPLL_DELAY (25) | ||
92 | #define OWL_S500_AUDIOPLL_DELAY (100) | ||
93 | |||
94 | static const struct clk_pll_table clk_audio_pll_table[] = { | ||
95 | { 0, 45158400 }, { 1, 49152000 }, | ||
96 | { 0, 0 }, | ||
97 | }; | ||
98 | |||
99 | /* pll clocks */ | ||
100 | static OWL_PLL_NO_PARENT_DELAY(ethernet_pll_clk, "ethernet_pll_clk", CMU_ETHERNETPLL, 500000000, 0, 0, 0, 0, 0, OWL_S500_ETHERNETPLL_DELAY, NULL, CLK_IGNORE_UNUSED); | ||
101 | static OWL_PLL_NO_PARENT_DELAY(core_pll_clk, "core_pll_clk", CMU_COREPLL, 12000000, 9, 0, 8, 4, 134, OWL_S500_COREPLL_DELAY, NULL, CLK_IGNORE_UNUSED); | ||
102 | static OWL_PLL_NO_PARENT_DELAY(ddr_pll_clk, "ddr_pll_clk", CMU_DDRPLL, 12000000, 8, 0, 8, 1, 67, OWL_S500_DDRPLL_DELAY, NULL, CLK_IGNORE_UNUSED); | ||
103 | static OWL_PLL_NO_PARENT_DELAY(nand_pll_clk, "nand_pll_clk", CMU_NANDPLL, 6000000, 8, 0, 7, 2, 86, OWL_S500_NANDPLL_DELAY, NULL, CLK_IGNORE_UNUSED); | ||
104 | static OWL_PLL_NO_PARENT_DELAY(display_pll_clk, "display_pll_clk", CMU_DISPLAYPLL, 6000000, 8, 0, 8, 2, 126, OWL_S500_DISPLAYPLL_DELAY, NULL, CLK_IGNORE_UNUSED); | ||
105 | static OWL_PLL_NO_PARENT_DELAY(dev_pll_clk, "dev_pll_clk", CMU_DEVPLL, 6000000, 8, 0, 7, 8, 126, OWL_S500_DEVPLL_DELAY, NULL, CLK_IGNORE_UNUSED); | ||
106 | static OWL_PLL_NO_PARENT_DELAY(audio_pll_clk, "audio_pll_clk", CMU_AUDIOPLL, 0, 4, 0, 1, 0, 0, OWL_S500_AUDIOPLL_DELAY, clk_audio_pll_table, CLK_IGNORE_UNUSED); | ||
107 | |||
108 | static const char * const dev_clk_mux_p[] = { "hosc", "dev_pll_clk" }; | ||
109 | static const char * const bisp_clk_mux_p[] = { "display_pll_clk", "dev_clk" }; | ||
110 | static const char * const sensor_clk_mux_p[] = { "hosc", "bisp_clk" }; | ||
111 | static const char * const sd_clk_mux_p[] = { "dev_clk", "nand_pll_clk" }; | ||
112 | static const char * const pwm_clk_mux_p[] = { "losc", "hosc" }; | ||
113 | static const char * const ahbprediv_clk_mux_p[] = { "dev_clk", "display_pll_clk", "nand_pll_clk", "ddr_pll_clk" }; | ||
114 | static const char * const uart_clk_mux_p[] = { "hosc", "dev_pll_clk" }; | ||
115 | static const char * const de_clk_mux_p[] = { "display_pll_clk", "dev_clk" }; | ||
116 | static const char * const i2s_clk_mux_p[] = { "audio_pll_clk" }; | ||
117 | static const char * const hde_clk_mux_p[] = { "dev_clk", "display_pll_clk", "nand_pll_clk", "ddr_pll_clk" }; | ||
118 | static const char * const nand_clk_mux_p[] = { "nand_pll_clk", "display_pll_clk", "dev_clk", "ddr_pll_clk" }; | ||
119 | |||
120 | static struct clk_factor_table sd_factor_table[] = { | ||
121 | /* bit0 ~ 4 */ | ||
122 | { 0, 1, 1 }, { 1, 1, 2 }, { 2, 1, 3 }, { 3, 1, 4 }, | ||
123 | { 4, 1, 5 }, { 5, 1, 6 }, { 6, 1, 7 }, { 7, 1, 8 }, | ||
124 | { 8, 1, 9 }, { 9, 1, 10 }, { 10, 1, 11 }, { 11, 1, 12 }, | ||
125 | { 12, 1, 13 }, { 13, 1, 14 }, { 14, 1, 15 }, { 15, 1, 16 }, | ||
126 | { 16, 1, 17 }, { 17, 1, 18 }, { 18, 1, 19 }, { 19, 1, 20 }, | ||
127 | { 20, 1, 21 }, { 21, 1, 22 }, { 22, 1, 23 }, { 23, 1, 24 }, | ||
128 | { 24, 1, 25 }, { 25, 1, 26 }, { 26, 1, 27 }, { 27, 1, 28 }, | ||
129 | { 28, 1, 29 }, { 29, 1, 30 }, { 30, 1, 31 }, { 31, 1, 32 }, | ||
130 | |||
131 | /* bit8: /128 */ | ||
132 | { 256, 1, 1 * 128 }, { 257, 1, 2 * 128 }, { 258, 1, 3 * 128 }, { 259, 1, 4 * 128 }, | ||
133 | { 260, 1, 5 * 128 }, { 261, 1, 6 * 128 }, { 262, 1, 7 * 128 }, { 263, 1, 8 * 128 }, | ||
134 | { 264, 1, 9 * 128 }, { 265, 1, 10 * 128 }, { 266, 1, 11 * 128 }, { 267, 1, 12 * 128 }, | ||
135 | { 268, 1, 13 * 128 }, { 269, 1, 14 * 128 }, { 270, 1, 15 * 128 }, { 271, 1, 16 * 128 }, | ||
136 | { 272, 1, 17 * 128 }, { 273, 1, 18 * 128 }, { 274, 1, 19 * 128 }, { 275, 1, 20 * 128 }, | ||
137 | { 276, 1, 21 * 128 }, { 277, 1, 22 * 128 }, { 278, 1, 23 * 128 }, { 279, 1, 24 * 128 }, | ||
138 | { 280, 1, 25 * 128 }, { 281, 1, 26 * 128 }, { 282, 1, 27 * 128 }, { 283, 1, 28 * 128 }, | ||
139 | { 284, 1, 29 * 128 }, { 285, 1, 30 * 128 }, { 286, 1, 31 * 128 }, { 287, 1, 32 * 128 }, | ||
140 | { 0, 0, 0 }, | ||
141 | }; | ||
142 | |||
143 | static struct clk_factor_table bisp_factor_table[] = { | ||
144 | { 0, 1, 1 }, { 1, 1, 2 }, { 2, 1, 3 }, { 3, 1, 4 }, | ||
145 | { 4, 1, 5 }, { 5, 1, 6 }, { 6, 1, 7 }, { 7, 1, 8 }, | ||
146 | { 0, 0, 0 }, | ||
147 | }; | ||
148 | |||
149 | static struct clk_factor_table ahb_factor_table[] = { | ||
150 | { 1, 1, 2 }, { 2, 1, 3 }, | ||
151 | { 0, 0, 0 }, | ||
152 | }; | ||
153 | |||
154 | static struct clk_div_table rmii_ref_div_table[] = { | ||
155 | { 0, 4 }, { 1, 10 }, | ||
156 | { 0, 0 }, | ||
157 | }; | ||
158 | |||
159 | static struct clk_div_table i2s_div_table[] = { | ||
160 | { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 }, | ||
161 | { 4, 6 }, { 5, 8 }, { 6, 12 }, { 7, 16 }, | ||
162 | { 8, 24 }, | ||
163 | { 0, 0 }, | ||
164 | }; | ||
165 | |||
166 | static struct clk_div_table nand_div_table[] = { | ||
167 | { 0, 1 }, { 1, 2 }, { 2, 4 }, { 3, 6 }, | ||
168 | { 4, 8 }, { 5, 10 }, { 6, 12 }, { 7, 14 }, | ||
169 | { 8, 16 }, { 9, 18 }, { 10, 20 }, { 11, 22 }, | ||
170 | { 0, 0 }, | ||
171 | }; | ||
172 | |||
173 | /* mux clock */ | ||
174 | static OWL_MUX(dev_clk, "dev_clk", dev_clk_mux_p, CMU_DEVPLL, 12, 1, CLK_SET_RATE_PARENT); | ||
175 | static OWL_MUX(ahbprediv_clk, "ahbprediv_clk", ahbprediv_clk_mux_p, CMU_BUSCLK1, 8, 3, CLK_SET_RATE_PARENT); | ||
176 | |||
177 | /* gate clocks */ | ||
178 | static OWL_GATE(spi0_clk, "spi0_clk", "ahb_clk", CMU_DEVCLKEN1, 10, 0, CLK_IGNORE_UNUSED); | ||
179 | static OWL_GATE(spi1_clk, "spi1_clk", "ahb_clk", CMU_DEVCLKEN1, 11, 0, CLK_IGNORE_UNUSED); | ||
180 | static OWL_GATE(spi2_clk, "spi2_clk", "ahb_clk", CMU_DEVCLKEN1, 12, 0, CLK_IGNORE_UNUSED); | ||
181 | static OWL_GATE(spi3_clk, "spi3_clk", "ahb_clk", CMU_DEVCLKEN1, 13, 0, CLK_IGNORE_UNUSED); | ||
182 | static OWL_GATE(timer_clk, "timer_clk", "hosc", CMU_DEVCLKEN1, 27, 0, 0); | ||
183 | static OWL_GATE(hdmi_clk, "hdmi_clk", "hosc", CMU_DEVCLKEN1, 3, 0, 0); | ||
184 | |||
185 | /* divider clocks */ | ||
186 | static OWL_DIVIDER(h_clk, "h_clk", "ahbprevdiv_clk", CMU_BUSCLK1, 12, 2, NULL, 0, 0); | ||
187 | static OWL_DIVIDER(rmii_ref_clk, "rmii_ref_clk", "ethernet_pll_clk", CMU_ETHERNETPLL, 1, 1, rmii_ref_div_table, 0, 0); | ||
188 | |||
189 | /* factor clocks */ | ||
190 | static OWL_FACTOR(ahb_clk, "ahb_clk", "h_clk", CMU_BUSCLK1, 2, 2, ahb_factor_table, 0, 0); | ||
191 | static OWL_FACTOR(de1_clk, "de_clk1", "de_clk", CMU_DECLK, 0, 3, bisp_factor_table, 0, 0); | ||
192 | static OWL_FACTOR(de2_clk, "de_clk2", "de_clk", CMU_DECLK, 4, 3, bisp_factor_table, 0, 0); | ||
193 | |||
194 | /* composite clocks */ | ||
195 | static OWL_COMP_FACTOR(vce_clk, "vce_clk", hde_clk_mux_p, | ||
196 | OWL_MUX_HW(CMU_VCECLK, 4, 2), | ||
197 | OWL_GATE_HW(CMU_DEVCLKEN0, 26, 0), | ||
198 | OWL_FACTOR_HW(CMU_VCECLK, 0, 3, 0, bisp_factor_table), | ||
199 | 0); | ||
200 | |||
201 | static OWL_COMP_FACTOR(vde_clk, "vde_clk", hde_clk_mux_p, | ||
202 | OWL_MUX_HW(CMU_VDECLK, 4, 2), | ||
203 | OWL_GATE_HW(CMU_DEVCLKEN0, 25, 0), | ||
204 | OWL_FACTOR_HW(CMU_VDECLK, 0, 3, 0, bisp_factor_table), | ||
205 | 0); | ||
206 | |||
207 | static OWL_COMP_FACTOR(bisp_clk, "bisp_clk", bisp_clk_mux_p, | ||
208 | OWL_MUX_HW(CMU_BISPCLK, 4, 1), | ||
209 | OWL_GATE_HW(CMU_DEVCLKEN0, 14, 0), | ||
210 | OWL_FACTOR_HW(CMU_BISPCLK, 0, 3, 0, bisp_factor_table), | ||
211 | 0); | ||
212 | |||
213 | static OWL_COMP_FACTOR(sensor0_clk, "sensor0_clk", sensor_clk_mux_p, | ||
214 | OWL_MUX_HW(CMU_SENSORCLK, 4, 1), | ||
215 | OWL_GATE_HW(CMU_DEVCLKEN0, 14, 0), | ||
216 | OWL_FACTOR_HW(CMU_SENSORCLK, 0, 3, 0, bisp_factor_table), | ||
217 | CLK_IGNORE_UNUSED); | ||
218 | |||
219 | static OWL_COMP_FACTOR(sensor1_clk, "sensor1_clk", sensor_clk_mux_p, | ||
220 | OWL_MUX_HW(CMU_SENSORCLK, 4, 1), | ||
221 | OWL_GATE_HW(CMU_DEVCLKEN0, 14, 0), | ||
222 | OWL_FACTOR_HW(CMU_SENSORCLK, 8, 3, 0, bisp_factor_table), | ||
223 | CLK_IGNORE_UNUSED); | ||
224 | |||
225 | static OWL_COMP_FACTOR(sd0_clk, "sd0_clk", sd_clk_mux_p, | ||
226 | OWL_MUX_HW(CMU_SD0CLK, 9, 1), | ||
227 | OWL_GATE_HW(CMU_DEVCLKEN0, 5, 0), | ||
228 | OWL_FACTOR_HW(CMU_SD0CLK, 0, 9, 0, sd_factor_table), | ||
229 | 0); | ||
230 | |||
231 | static OWL_COMP_FACTOR(sd1_clk, "sd1_clk", sd_clk_mux_p, | ||
232 | OWL_MUX_HW(CMU_SD1CLK, 9, 1), | ||
233 | OWL_GATE_HW(CMU_DEVCLKEN0, 6, 0), | ||
234 | OWL_FACTOR_HW(CMU_SD1CLK, 0, 9, 0, sd_factor_table), | ||
235 | 0); | ||
236 | |||
237 | static OWL_COMP_FACTOR(sd2_clk, "sd2_clk", sd_clk_mux_p, | ||
238 | OWL_MUX_HW(CMU_SD2CLK, 9, 1), | ||
239 | OWL_GATE_HW(CMU_DEVCLKEN0, 7, 0), | ||
240 | OWL_FACTOR_HW(CMU_SD2CLK, 0, 9, 0, sd_factor_table), | ||
241 | 0); | ||
242 | |||
243 | static OWL_COMP_DIV(pwm0_clk, "pwm0_clk", pwm_clk_mux_p, | ||
244 | OWL_MUX_HW(CMU_PWM0CLK, 12, 1), | ||
245 | OWL_GATE_HW(CMU_DEVCLKEN1, 23, 0), | ||
246 | OWL_DIVIDER_HW(CMU_PWM0CLK, 0, 10, 0, NULL), | ||
247 | 0); | ||
248 | |||
249 | static OWL_COMP_DIV(pwm1_clk, "pwm1_clk", pwm_clk_mux_p, | ||
250 | OWL_MUX_HW(CMU_PWM1CLK, 12, 1), | ||
251 | OWL_GATE_HW(CMU_DEVCLKEN1, 24, 0), | ||
252 | OWL_DIVIDER_HW(CMU_PWM1CLK, 0, 10, 0, NULL), | ||
253 | 0); | ||
254 | |||
255 | static OWL_COMP_DIV(pwm2_clk, "pwm2_clk", pwm_clk_mux_p, | ||
256 | OWL_MUX_HW(CMU_PWM2CLK, 12, 1), | ||
257 | OWL_GATE_HW(CMU_DEVCLKEN1, 25, 0), | ||
258 | OWL_DIVIDER_HW(CMU_PWM2CLK, 0, 10, 0, NULL), | ||
259 | 0); | ||
260 | |||
261 | static OWL_COMP_DIV(pwm3_clk, "pwm3_clk", pwm_clk_mux_p, | ||
262 | OWL_MUX_HW(CMU_PWM3CLK, 12, 1), | ||
263 | OWL_GATE_HW(CMU_DEVCLKEN1, 26, 0), | ||
264 | OWL_DIVIDER_HW(CMU_PWM3CLK, 0, 10, 0, NULL), | ||
265 | 0); | ||
266 | |||
267 | static OWL_COMP_DIV(pwm4_clk, "pwm4_clk", pwm_clk_mux_p, | ||
268 | OWL_MUX_HW(CMU_PWM4CLK, 12, 1), | ||
269 | OWL_GATE_HW(CMU_DEVCLKEN0, 11, 0), | ||
270 | OWL_DIVIDER_HW(CMU_PWM4CLK, 0, 10, 0, NULL), | ||
271 | 0); | ||
272 | |||
273 | static OWL_COMP_DIV(pwm5_clk, "pwm5_clk", pwm_clk_mux_p, | ||
274 | OWL_MUX_HW(CMU_PWM5CLK, 12, 1), | ||
275 | OWL_GATE_HW(CMU_DEVCLKEN0, 0, 0), | ||
276 | OWL_DIVIDER_HW(CMU_PWM5CLK, 0, 10, 0, NULL), | ||
277 | 0); | ||
278 | |||
279 | static OWL_COMP_PASS(de_clk, "de_clk", de_clk_mux_p, | ||
280 | OWL_MUX_HW(CMU_DECLK, 12, 1), | ||
281 | OWL_GATE_HW(CMU_DEVCLKEN0, 8, 0), | ||
282 | 0); | ||
283 | |||
284 | static OWL_COMP_FIXED_FACTOR(i2c0_clk, "i2c0_clk", "ethernet_pll_clk", | ||
285 | OWL_GATE_HW(CMU_DEVCLKEN1, 14, 0), | ||
286 | 1, 5, 0); | ||
287 | |||
288 | static OWL_COMP_FIXED_FACTOR(i2c1_clk, "i2c1_clk", "ethernet_pll_clk", | ||
289 | OWL_GATE_HW(CMU_DEVCLKEN1, 15, 0), | ||
290 | 1, 5, 0); | ||
291 | |||
292 | static OWL_COMP_FIXED_FACTOR(i2c2_clk, "i2c2_clk", "ethernet_pll_clk", | ||
293 | OWL_GATE_HW(CMU_DEVCLKEN1, 30, 0), | ||
294 | 1, 5, 0); | ||
295 | |||
296 | static OWL_COMP_FIXED_FACTOR(i2c3_clk, "i2c3_clk", "ethernet_pll_clk", | ||
297 | OWL_GATE_HW(CMU_DEVCLKEN1, 31, 0), | ||
298 | 1, 5, 0); | ||
299 | |||
300 | static OWL_COMP_DIV(uart0_clk, "uart0_clk", uart_clk_mux_p, | ||
301 | OWL_MUX_HW(CMU_UART0CLK, 16, 1), | ||
302 | OWL_GATE_HW(CMU_DEVCLKEN1, 6, 0), | ||
303 | OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), | ||
304 | CLK_IGNORE_UNUSED); | ||
305 | |||
306 | static OWL_COMP_DIV(uart1_clk, "uart1_clk", uart_clk_mux_p, | ||
307 | OWL_MUX_HW(CMU_UART1CLK, 16, 1), | ||
308 | OWL_GATE_HW(CMU_DEVCLKEN1, 7, 0), | ||
309 | OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), | ||
310 | CLK_IGNORE_UNUSED); | ||
311 | |||
312 | static OWL_COMP_DIV(uart2_clk, "uart2_clk", uart_clk_mux_p, | ||
313 | OWL_MUX_HW(CMU_UART2CLK, 16, 1), | ||
314 | OWL_GATE_HW(CMU_DEVCLKEN1, 8, 0), | ||
315 | OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), | ||
316 | CLK_IGNORE_UNUSED); | ||
317 | |||
318 | static OWL_COMP_DIV(uart3_clk, "uart3_clk", uart_clk_mux_p, | ||
319 | OWL_MUX_HW(CMU_UART3CLK, 16, 1), | ||
320 | OWL_GATE_HW(CMU_DEVCLKEN1, 19, 0), | ||
321 | OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), | ||
322 | CLK_IGNORE_UNUSED); | ||
323 | |||
324 | static OWL_COMP_DIV(uart4_clk, "uart4_clk", uart_clk_mux_p, | ||
325 | OWL_MUX_HW(CMU_UART4CLK, 16, 1), | ||
326 | OWL_GATE_HW(CMU_DEVCLKEN1, 20, 0), | ||
327 | OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), | ||
328 | CLK_IGNORE_UNUSED); | ||
329 | |||
330 | static OWL_COMP_DIV(uart5_clk, "uart5_clk", uart_clk_mux_p, | ||
331 | OWL_MUX_HW(CMU_UART5CLK, 16, 1), | ||
332 | OWL_GATE_HW(CMU_DEVCLKEN1, 21, 0), | ||
333 | OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), | ||
334 | CLK_IGNORE_UNUSED); | ||
335 | |||
336 | static OWL_COMP_DIV(uart6_clk, "uart6_clk", uart_clk_mux_p, | ||
337 | OWL_MUX_HW(CMU_UART6CLK, 16, 1), | ||
338 | OWL_GATE_HW(CMU_DEVCLKEN1, 18, 0), | ||
339 | OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), | ||
340 | CLK_IGNORE_UNUSED); | ||
341 | |||
342 | static OWL_COMP_DIV(i2srx_clk, "i2srx_clk", i2s_clk_mux_p, | ||
343 | OWL_MUX_HW(CMU_AUDIOPLL, 24, 1), | ||
344 | OWL_GATE_HW(CMU_DEVCLKEN0, 21, 0), | ||
345 | OWL_DIVIDER_HW(CMU_AUDIOPLL, 20, 4, 0, i2s_div_table), | ||
346 | 0); | ||
347 | |||
348 | static OWL_COMP_DIV(i2stx_clk, "i2stx_clk", i2s_clk_mux_p, | ||
349 | OWL_MUX_HW(CMU_AUDIOPLL, 24, 1), | ||
350 | OWL_GATE_HW(CMU_DEVCLKEN0, 20, 0), | ||
351 | OWL_DIVIDER_HW(CMU_AUDIOPLL, 16, 4, 0, i2s_div_table), | ||
352 | 0); | ||
353 | |||
354 | static OWL_COMP_DIV(hdmia_clk, "hdmia_clk", i2s_clk_mux_p, | ||
355 | OWL_MUX_HW(CMU_AUDIOPLL, 24, 1), | ||
356 | OWL_GATE_HW(CMU_DEVCLKEN0, 22, 0), | ||
357 | OWL_DIVIDER_HW(CMU_AUDIOPLL, 24, 4, 0, i2s_div_table), | ||
358 | 0); | ||
359 | |||
360 | static OWL_COMP_DIV(spdif_clk, "spdif_clk", i2s_clk_mux_p, | ||
361 | OWL_MUX_HW(CMU_AUDIOPLL, 24, 1), | ||
362 | OWL_GATE_HW(CMU_DEVCLKEN0, 23, 0), | ||
363 | OWL_DIVIDER_HW(CMU_AUDIOPLL, 28, 4, 0, i2s_div_table), | ||
364 | 0); | ||
365 | |||
366 | static OWL_COMP_DIV(nand_clk, "nand_clk", nand_clk_mux_p, | ||
367 | OWL_MUX_HW(CMU_NANDCCLK, 8, 2), | ||
368 | OWL_GATE_HW(CMU_DEVCLKEN0, 4, 0), | ||
369 | OWL_DIVIDER_HW(CMU_NANDCCLK, 0, 3, 0, nand_div_table), | ||
370 | CLK_SET_RATE_PARENT); | ||
371 | |||
372 | static OWL_COMP_DIV(ecc_clk, "ecc_clk", nand_clk_mux_p, | ||
373 | OWL_MUX_HW(CMU_NANDCCLK, 8, 2), | ||
374 | OWL_GATE_HW(CMU_DEVCLKEN0, 4, 0), | ||
375 | OWL_DIVIDER_HW(CMU_NANDCCLK, 4, 3, 0, nand_div_table), | ||
376 | CLK_SET_RATE_PARENT); | ||
377 | |||
378 | static struct owl_clk_common *s500_clks[] = { | ||
379 | ðernet_pll_clk.common, | ||
380 | &core_pll_clk.common, | ||
381 | &ddr_pll_clk.common, | ||
382 | &dev_pll_clk.common, | ||
383 | &nand_pll_clk.common, | ||
384 | &audio_pll_clk.common, | ||
385 | &display_pll_clk.common, | ||
386 | &dev_clk.common, | ||
387 | &timer_clk.common, | ||
388 | &i2c0_clk.common, | ||
389 | &i2c1_clk.common, | ||
390 | &i2c2_clk.common, | ||
391 | &i2c3_clk.common, | ||
392 | &uart0_clk.common, | ||
393 | &uart1_clk.common, | ||
394 | &uart2_clk.common, | ||
395 | &uart3_clk.common, | ||
396 | &uart4_clk.common, | ||
397 | &uart5_clk.common, | ||
398 | &uart6_clk.common, | ||
399 | &pwm0_clk.common, | ||
400 | &pwm1_clk.common, | ||
401 | &pwm2_clk.common, | ||
402 | &pwm3_clk.common, | ||
403 | &pwm4_clk.common, | ||
404 | &pwm5_clk.common, | ||
405 | &sensor0_clk.common, | ||
406 | &sensor1_clk.common, | ||
407 | &sd0_clk.common, | ||
408 | &sd1_clk.common, | ||
409 | &sd2_clk.common, | ||
410 | &bisp_clk.common, | ||
411 | &ahb_clk.common, | ||
412 | &ahbprediv_clk.common, | ||
413 | &h_clk.common, | ||
414 | &spi0_clk.common, | ||
415 | &spi1_clk.common, | ||
416 | &spi2_clk.common, | ||
417 | &spi3_clk.common, | ||
418 | &rmii_ref_clk.common, | ||
419 | &de_clk.common, | ||
420 | &de1_clk.common, | ||
421 | &de2_clk.common, | ||
422 | &i2srx_clk.common, | ||
423 | &i2stx_clk.common, | ||
424 | &hdmia_clk.common, | ||
425 | &hdmi_clk.common, | ||
426 | &vce_clk.common, | ||
427 | &vde_clk.common, | ||
428 | &spdif_clk.common, | ||
429 | &nand_clk.common, | ||
430 | &ecc_clk.common, | ||
431 | }; | ||
432 | |||
433 | static struct clk_hw_onecell_data s500_hw_clks = { | ||
434 | .hws = { | ||
435 | [CLK_ETHERNET_PLL] = ðernet_pll_clk.common.hw, | ||
436 | [CLK_CORE_PLL] = &core_pll_clk.common.hw, | ||
437 | [CLK_DDR_PLL] = &ddr_pll_clk.common.hw, | ||
438 | [CLK_NAND_PLL] = &nand_pll_clk.common.hw, | ||
439 | [CLK_DISPLAY_PLL] = &display_pll_clk.common.hw, | ||
440 | [CLK_DEV_PLL] = &dev_pll_clk.common.hw, | ||
441 | [CLK_AUDIO_PLL] = &audio_pll_clk.common.hw, | ||
442 | [CLK_TIMER] = &timer_clk.common.hw, | ||
443 | [CLK_DEV] = &dev_clk.common.hw, | ||
444 | [CLK_DE] = &de_clk.common.hw, | ||
445 | [CLK_DE1] = &de1_clk.common.hw, | ||
446 | [CLK_DE2] = &de2_clk.common.hw, | ||
447 | [CLK_I2C0] = &i2c0_clk.common.hw, | ||
448 | [CLK_I2C1] = &i2c1_clk.common.hw, | ||
449 | [CLK_I2C2] = &i2c2_clk.common.hw, | ||
450 | [CLK_I2C3] = &i2c3_clk.common.hw, | ||
451 | [CLK_I2SRX] = &i2srx_clk.common.hw, | ||
452 | [CLK_I2STX] = &i2stx_clk.common.hw, | ||
453 | [CLK_UART0] = &uart0_clk.common.hw, | ||
454 | [CLK_UART1] = &uart1_clk.common.hw, | ||
455 | [CLK_UART2] = &uart2_clk.common.hw, | ||
456 | [CLK_UART3] = &uart3_clk.common.hw, | ||
457 | [CLK_UART4] = &uart4_clk.common.hw, | ||
458 | [CLK_UART5] = &uart5_clk.common.hw, | ||
459 | [CLK_UART6] = &uart6_clk.common.hw, | ||
460 | [CLK_PWM0] = &pwm0_clk.common.hw, | ||
461 | [CLK_PWM1] = &pwm1_clk.common.hw, | ||
462 | [CLK_PWM2] = &pwm2_clk.common.hw, | ||
463 | [CLK_PWM3] = &pwm3_clk.common.hw, | ||
464 | [CLK_PWM4] = &pwm4_clk.common.hw, | ||
465 | [CLK_PWM5] = &pwm5_clk.common.hw, | ||
466 | [CLK_SENSOR0] = &sensor0_clk.common.hw, | ||
467 | [CLK_SENSOR1] = &sensor1_clk.common.hw, | ||
468 | [CLK_SD0] = &sd0_clk.common.hw, | ||
469 | [CLK_SD1] = &sd1_clk.common.hw, | ||
470 | [CLK_SD2] = &sd2_clk.common.hw, | ||
471 | [CLK_BISP] = &bisp_clk.common.hw, | ||
472 | [CLK_SPI0] = &spi0_clk.common.hw, | ||
473 | [CLK_SPI1] = &spi1_clk.common.hw, | ||
474 | [CLK_SPI2] = &spi2_clk.common.hw, | ||
475 | [CLK_SPI3] = &spi3_clk.common.hw, | ||
476 | [CLK_AHB] = &ahb_clk.common.hw, | ||
477 | [CLK_H] = &h_clk.common.hw, | ||
478 | [CLK_AHBPREDIV] = &ahbprediv_clk.common.hw, | ||
479 | [CLK_RMII_REF] = &rmii_ref_clk.common.hw, | ||
480 | [CLK_HDMI_AUDIO] = &hdmia_clk.common.hw, | ||
481 | [CLK_HDMI] = &hdmi_clk.common.hw, | ||
482 | [CLK_VDE] = &vde_clk.common.hw, | ||
483 | [CLK_VCE] = &vce_clk.common.hw, | ||
484 | [CLK_SPDIF] = &spdif_clk.common.hw, | ||
485 | [CLK_NAND] = &nand_clk.common.hw, | ||
486 | [CLK_ECC] = &ecc_clk.common.hw, | ||
487 | }, | ||
488 | .num = CLK_NR_CLKS, | ||
489 | }; | ||
490 | |||
491 | static struct owl_clk_desc s500_clk_desc = { | ||
492 | .clks = s500_clks, | ||
493 | .num_clks = ARRAY_SIZE(s500_clks), | ||
494 | |||
495 | .hw_clks = &s500_hw_clks, | ||
496 | }; | ||
497 | |||
498 | static int s500_clk_probe(struct platform_device *pdev) | ||
499 | { | ||
500 | struct owl_clk_desc *desc; | ||
501 | |||
502 | desc = &s500_clk_desc; | ||
503 | owl_clk_regmap_init(pdev, desc); | ||
504 | |||
505 | return owl_clk_probe(&pdev->dev, desc->hw_clks); | ||
506 | } | ||
507 | |||
508 | static const struct of_device_id s500_clk_of_match[] = { | ||
509 | { .compatible = "actions,s500-cmu", }, | ||
510 | { /* sentinel */ } | ||
511 | }; | ||
512 | |||
513 | static struct platform_driver s500_clk_driver = { | ||
514 | .probe = s500_clk_probe, | ||
515 | .driver = { | ||
516 | .name = "s500-cmu", | ||
517 | .of_match_table = s500_clk_of_match, | ||
518 | }, | ||
519 | }; | ||
520 | |||
521 | static int __init s500_clk_init(void) | ||
522 | { | ||
523 | return platform_driver_register(&s500_clk_driver); | ||
524 | } | ||
525 | core_initcall(s500_clk_init); | ||
diff --git a/drivers/clk/clk-gpio.c b/drivers/clk/clk-gpio.c index 25eed3e0251f..c2f07f0d077c 100644 --- a/drivers/clk/clk-gpio.c +++ b/drivers/clk/clk-gpio.c | |||
@@ -58,6 +58,35 @@ const struct clk_ops clk_gpio_gate_ops = { | |||
58 | }; | 58 | }; |
59 | EXPORT_SYMBOL_GPL(clk_gpio_gate_ops); | 59 | EXPORT_SYMBOL_GPL(clk_gpio_gate_ops); |
60 | 60 | ||
61 | static int clk_sleeping_gpio_gate_prepare(struct clk_hw *hw) | ||
62 | { | ||
63 | struct clk_gpio *clk = to_clk_gpio(hw); | ||
64 | |||
65 | gpiod_set_value_cansleep(clk->gpiod, 1); | ||
66 | |||
67 | return 0; | ||
68 | } | ||
69 | |||
70 | static void clk_sleeping_gpio_gate_unprepare(struct clk_hw *hw) | ||
71 | { | ||
72 | struct clk_gpio *clk = to_clk_gpio(hw); | ||
73 | |||
74 | gpiod_set_value_cansleep(clk->gpiod, 0); | ||
75 | } | ||
76 | |||
77 | static int clk_sleeping_gpio_gate_is_prepared(struct clk_hw *hw) | ||
78 | { | ||
79 | struct clk_gpio *clk = to_clk_gpio(hw); | ||
80 | |||
81 | return gpiod_get_value_cansleep(clk->gpiod); | ||
82 | } | ||
83 | |||
84 | static const struct clk_ops clk_sleeping_gpio_gate_ops = { | ||
85 | .prepare = clk_sleeping_gpio_gate_prepare, | ||
86 | .unprepare = clk_sleeping_gpio_gate_unprepare, | ||
87 | .is_prepared = clk_sleeping_gpio_gate_is_prepared, | ||
88 | }; | ||
89 | |||
61 | /** | 90 | /** |
62 | * DOC: basic clock multiplexer which can be controlled with a gpio output | 91 | * DOC: basic clock multiplexer which can be controlled with a gpio output |
63 | * Traits of this clock: | 92 | * Traits of this clock: |
@@ -144,10 +173,16 @@ struct clk_hw *clk_hw_register_gpio_gate(struct device *dev, const char *name, | |||
144 | const char *parent_name, struct gpio_desc *gpiod, | 173 | const char *parent_name, struct gpio_desc *gpiod, |
145 | unsigned long flags) | 174 | unsigned long flags) |
146 | { | 175 | { |
176 | const struct clk_ops *ops; | ||
177 | |||
178 | if (gpiod_cansleep(gpiod)) | ||
179 | ops = &clk_sleeping_gpio_gate_ops; | ||
180 | else | ||
181 | ops = &clk_gpio_gate_ops; | ||
182 | |||
147 | return clk_register_gpio(dev, name, | 183 | return clk_register_gpio(dev, name, |
148 | (parent_name ? &parent_name : NULL), | 184 | (parent_name ? &parent_name : NULL), |
149 | (parent_name ? 1 : 0), gpiod, flags, | 185 | (parent_name ? 1 : 0), gpiod, flags, ops); |
150 | &clk_gpio_gate_ops); | ||
151 | } | 186 | } |
152 | EXPORT_SYMBOL_GPL(clk_hw_register_gpio_gate); | 187 | EXPORT_SYMBOL_GPL(clk_hw_register_gpio_gate); |
153 | 188 | ||
diff --git a/drivers/clk/clk-stm32mp1.c b/drivers/clk/clk-stm32mp1.c index 6a31f7f434ce..a0ae8dc16909 100644 --- a/drivers/clk/clk-stm32mp1.c +++ b/drivers/clk/clk-stm32mp1.c | |||
@@ -121,7 +121,7 @@ static const char * const cpu_src[] = { | |||
121 | }; | 121 | }; |
122 | 122 | ||
123 | static const char * const axi_src[] = { | 123 | static const char * const axi_src[] = { |
124 | "ck_hsi", "ck_hse", "pll2_p", "pll3_p" | 124 | "ck_hsi", "ck_hse", "pll2_p" |
125 | }; | 125 | }; |
126 | 126 | ||
127 | static const char * const per_src[] = { | 127 | static const char * const per_src[] = { |
@@ -225,19 +225,19 @@ static const char * const usart6_src[] = { | |||
225 | }; | 225 | }; |
226 | 226 | ||
227 | static const char * const fdcan_src[] = { | 227 | static const char * const fdcan_src[] = { |
228 | "ck_hse", "pll3_q", "pll4_q" | 228 | "ck_hse", "pll3_q", "pll4_q", "pll4_r" |
229 | }; | 229 | }; |
230 | 230 | ||
231 | static const char * const sai_src[] = { | 231 | static const char * const sai_src[] = { |
232 | "pll4_q", "pll3_q", "i2s_ckin", "ck_per" | 232 | "pll4_q", "pll3_q", "i2s_ckin", "ck_per", "pll3_r" |
233 | }; | 233 | }; |
234 | 234 | ||
235 | static const char * const sai2_src[] = { | 235 | static const char * const sai2_src[] = { |
236 | "pll4_q", "pll3_q", "i2s_ckin", "ck_per", "spdif_ck_symb" | 236 | "pll4_q", "pll3_q", "i2s_ckin", "ck_per", "spdif_ck_symb", "pll3_r" |
237 | }; | 237 | }; |
238 | 238 | ||
239 | static const char * const adc12_src[] = { | 239 | static const char * const adc12_src[] = { |
240 | "pll4_q", "ck_per" | 240 | "pll4_r", "ck_per", "pll3_q" |
241 | }; | 241 | }; |
242 | 242 | ||
243 | static const char * const dsi_src[] = { | 243 | static const char * const dsi_src[] = { |
@@ -269,7 +269,7 @@ static const struct clk_div_table axi_div_table[] = { | |||
269 | static const struct clk_div_table mcu_div_table[] = { | 269 | static const struct clk_div_table mcu_div_table[] = { |
270 | { 0, 1 }, { 1, 2 }, { 2, 4 }, { 3, 8 }, | 270 | { 0, 1 }, { 1, 2 }, { 2, 4 }, { 3, 8 }, |
271 | { 4, 16 }, { 5, 32 }, { 6, 64 }, { 7, 128 }, | 271 | { 4, 16 }, { 5, 32 }, { 6, 64 }, { 7, 128 }, |
272 | { 8, 512 }, { 9, 512 }, { 10, 512}, { 11, 512 }, | 272 | { 8, 256 }, { 9, 512 }, { 10, 512}, { 11, 512 }, |
273 | { 12, 512 }, { 13, 512 }, { 14, 512}, { 15, 512 }, | 273 | { 12, 512 }, { 13, 512 }, { 14, 512}, { 15, 512 }, |
274 | { 0 }, | 274 | { 0 }, |
275 | }; | 275 | }; |
@@ -1286,10 +1286,11 @@ _clk_stm32_register_composite(struct device *dev, | |||
1286 | MGATE_MP1(_id, _name, _parent, _flags, _mgate) | 1286 | MGATE_MP1(_id, _name, _parent, _flags, _mgate) |
1287 | 1287 | ||
1288 | #define KCLK(_id, _name, _parents, _flags, _mgate, _mmux)\ | 1288 | #define KCLK(_id, _name, _parents, _flags, _mgate, _mmux)\ |
1289 | COMPOSITE(_id, _name, _parents, CLK_OPS_PARENT_ENABLE | _flags,\ | 1289 | COMPOSITE(_id, _name, _parents, CLK_OPS_PARENT_ENABLE |\ |
1290 | _MGATE_MP1(_mgate),\ | 1290 | CLK_SET_RATE_NO_REPARENT | _flags,\ |
1291 | _MMUX(_mmux),\ | 1291 | _MGATE_MP1(_mgate),\ |
1292 | _NO_DIV) | 1292 | _MMUX(_mmux),\ |
1293 | _NO_DIV) | ||
1293 | 1294 | ||
1294 | enum { | 1295 | enum { |
1295 | G_SAI1, | 1296 | G_SAI1, |
@@ -1655,12 +1656,14 @@ static const struct stm32_mux_cfg ker_mux_cfg[M_LAST] = { | |||
1655 | 1656 | ||
1656 | static const struct clock_config stm32mp1_clock_cfg[] = { | 1657 | static const struct clock_config stm32mp1_clock_cfg[] = { |
1657 | /* Oscillator divider */ | 1658 | /* Oscillator divider */ |
1658 | DIV(NO_ID, "clk-hsi-div", "clk-hsi", 0, RCC_HSICFGR, 0, 2, | 1659 | DIV(NO_ID, "clk-hsi-div", "clk-hsi", CLK_DIVIDER_POWER_OF_TWO, |
1659 | CLK_DIVIDER_READ_ONLY), | 1660 | RCC_HSICFGR, 0, 2, CLK_DIVIDER_READ_ONLY), |
1660 | 1661 | ||
1661 | /* External / Internal Oscillators */ | 1662 | /* External / Internal Oscillators */ |
1662 | GATE_MP1(CK_HSE, "ck_hse", "clk-hse", 0, RCC_OCENSETR, 8, 0), | 1663 | GATE_MP1(CK_HSE, "ck_hse", "clk-hse", 0, RCC_OCENSETR, 8, 0), |
1663 | GATE_MP1(CK_CSI, "ck_csi", "clk-csi", 0, RCC_OCENSETR, 4, 0), | 1664 | /* ck_csi is used by IO compensation and should be critical */ |
1665 | GATE_MP1(CK_CSI, "ck_csi", "clk-csi", CLK_IS_CRITICAL, | ||
1666 | RCC_OCENSETR, 4, 0), | ||
1664 | GATE_MP1(CK_HSI, "ck_hsi", "clk-hsi-div", 0, RCC_OCENSETR, 0, 0), | 1667 | GATE_MP1(CK_HSI, "ck_hsi", "clk-hsi-div", 0, RCC_OCENSETR, 0, 0), |
1665 | GATE(CK_LSI, "ck_lsi", "clk-lsi", 0, RCC_RDLSICR, 0, 0), | 1668 | GATE(CK_LSI, "ck_lsi", "clk-lsi", 0, RCC_RDLSICR, 0, 0), |
1666 | GATE(CK_LSE, "ck_lse", "clk-lse", 0, RCC_BDCR, 0, 0), | 1669 | GATE(CK_LSE, "ck_lse", "clk-lse", 0, RCC_BDCR, 0, 0), |
@@ -1952,14 +1955,14 @@ static const struct clock_config stm32mp1_clock_cfg[] = { | |||
1952 | MGATE_MP1(GPU_K, "gpu_k", "pll2_q", 0, G_GPU), | 1955 | MGATE_MP1(GPU_K, "gpu_k", "pll2_q", 0, G_GPU), |
1953 | MGATE_MP1(DAC12_K, "dac12_k", "ck_lsi", 0, G_DAC12), | 1956 | MGATE_MP1(DAC12_K, "dac12_k", "ck_lsi", 0, G_DAC12), |
1954 | 1957 | ||
1955 | COMPOSITE(ETHPTP_K, "ethptp_k", eth_src, CLK_OPS_PARENT_ENABLE, | 1958 | COMPOSITE(ETHPTP_K, "ethptp_k", eth_src, CLK_OPS_PARENT_ENABLE | |
1959 | CLK_SET_RATE_NO_REPARENT, | ||
1956 | _NO_GATE, | 1960 | _NO_GATE, |
1957 | _MMUX(M_ETHCK), | 1961 | _MMUX(M_ETHCK), |
1958 | _DIV(RCC_ETHCKSELR, 4, 4, CLK_DIVIDER_ALLOW_ZERO, NULL)), | 1962 | _DIV(RCC_ETHCKSELR, 4, 4, 0, NULL)), |
1959 | 1963 | ||
1960 | /* RTC clock */ | 1964 | /* RTC clock */ |
1961 | DIV(NO_ID, "ck_hse_rtc", "ck_hse", 0, RCC_RTCDIVR, 0, 7, | 1965 | DIV(NO_ID, "ck_hse_rtc", "ck_hse", 0, RCC_RTCDIVR, 0, 6, 0), |
1962 | CLK_DIVIDER_ALLOW_ZERO), | ||
1963 | 1966 | ||
1964 | COMPOSITE(RTC, "ck_rtc", rtc_src, CLK_OPS_PARENT_ENABLE | | 1967 | COMPOSITE(RTC, "ck_rtc", rtc_src, CLK_OPS_PARENT_ENABLE | |
1965 | CLK_SET_RATE_PARENT, | 1968 | CLK_SET_RATE_PARENT, |
diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h index e5eca8a1abe4..c25b57c3cbc8 100644 --- a/drivers/clk/qcom/clk-rcg.h +++ b/drivers/clk/qcom/clk-rcg.h | |||
@@ -71,7 +71,6 @@ struct src_sel { | |||
71 | * @freq_tbl: frequency table | 71 | * @freq_tbl: frequency table |
72 | * @clkr: regmap clock handle | 72 | * @clkr: regmap clock handle |
73 | * @lock: register lock | 73 | * @lock: register lock |
74 | * | ||
75 | */ | 74 | */ |
76 | struct clk_rcg { | 75 | struct clk_rcg { |
77 | u32 ns_reg; | 76 | u32 ns_reg; |
@@ -107,7 +106,6 @@ extern const struct clk_ops clk_rcg_lcc_ops; | |||
107 | * @freq_tbl: frequency table | 106 | * @freq_tbl: frequency table |
108 | * @clkr: regmap clock handle | 107 | * @clkr: regmap clock handle |
109 | * @lock: register lock | 108 | * @lock: register lock |
110 | * | ||
111 | */ | 109 | */ |
112 | struct clk_dyn_rcg { | 110 | struct clk_dyn_rcg { |
113 | u32 ns_reg[2]; | 111 | u32 ns_reg[2]; |
@@ -140,7 +138,7 @@ extern const struct clk_ops clk_dyn_rcg_ops; | |||
140 | * @parent_map: map from software's parent index to hardware's src_sel field | 138 | * @parent_map: map from software's parent index to hardware's src_sel field |
141 | * @freq_tbl: frequency table | 139 | * @freq_tbl: frequency table |
142 | * @clkr: regmap clock handle | 140 | * @clkr: regmap clock handle |
143 | * | 141 | * @cfg_off: defines the cfg register offset from the CMD_RCGR + CFG_REG |
144 | */ | 142 | */ |
145 | struct clk_rcg2 { | 143 | struct clk_rcg2 { |
146 | u32 cmd_rcgr; | 144 | u32 cmd_rcgr; |
@@ -150,6 +148,7 @@ struct clk_rcg2 { | |||
150 | const struct parent_map *parent_map; | 148 | const struct parent_map *parent_map; |
151 | const struct freq_tbl *freq_tbl; | 149 | const struct freq_tbl *freq_tbl; |
152 | struct clk_regmap clkr; | 150 | struct clk_regmap clkr; |
151 | u8 cfg_off; | ||
153 | }; | 152 | }; |
154 | 153 | ||
155 | #define to_clk_rcg2(_hw) container_of(to_clk_regmap(_hw), struct clk_rcg2, clkr) | 154 | #define to_clk_rcg2(_hw) container_of(to_clk_regmap(_hw), struct clk_rcg2, clkr) |
diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index 6e3bd195d012..8c02bffe50df 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c | |||
@@ -41,6 +41,11 @@ | |||
41 | #define N_REG 0xc | 41 | #define N_REG 0xc |
42 | #define D_REG 0x10 | 42 | #define D_REG 0x10 |
43 | 43 | ||
44 | #define RCG_CFG_OFFSET(rcg) ((rcg)->cmd_rcgr + (rcg)->cfg_off + CFG_REG) | ||
45 | #define RCG_M_OFFSET(rcg) ((rcg)->cmd_rcgr + (rcg)->cfg_off + M_REG) | ||
46 | #define RCG_N_OFFSET(rcg) ((rcg)->cmd_rcgr + (rcg)->cfg_off + N_REG) | ||
47 | #define RCG_D_OFFSET(rcg) ((rcg)->cmd_rcgr + (rcg)->cfg_off + D_REG) | ||
48 | |||
44 | /* Dynamic Frequency Scaling */ | 49 | /* Dynamic Frequency Scaling */ |
45 | #define MAX_PERF_LEVEL 8 | 50 | #define MAX_PERF_LEVEL 8 |
46 | #define SE_CMD_DFSR_OFFSET 0x14 | 51 | #define SE_CMD_DFSR_OFFSET 0x14 |
@@ -74,7 +79,7 @@ static u8 clk_rcg2_get_parent(struct clk_hw *hw) | |||
74 | u32 cfg; | 79 | u32 cfg; |
75 | int i, ret; | 80 | int i, ret; |
76 | 81 | ||
77 | ret = regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, &cfg); | 82 | ret = regmap_read(rcg->clkr.regmap, RCG_CFG_OFFSET(rcg), &cfg); |
78 | if (ret) | 83 | if (ret) |
79 | goto err; | 84 | goto err; |
80 | 85 | ||
@@ -123,7 +128,7 @@ static int clk_rcg2_set_parent(struct clk_hw *hw, u8 index) | |||
123 | int ret; | 128 | int ret; |
124 | u32 cfg = rcg->parent_map[index].cfg << CFG_SRC_SEL_SHIFT; | 129 | u32 cfg = rcg->parent_map[index].cfg << CFG_SRC_SEL_SHIFT; |
125 | 130 | ||
126 | ret = regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, | 131 | ret = regmap_update_bits(rcg->clkr.regmap, RCG_CFG_OFFSET(rcg), |
127 | CFG_SRC_SEL_MASK, cfg); | 132 | CFG_SRC_SEL_MASK, cfg); |
128 | if (ret) | 133 | if (ret) |
129 | return ret; | 134 | return ret; |
@@ -162,13 +167,13 @@ clk_rcg2_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) | |||
162 | struct clk_rcg2 *rcg = to_clk_rcg2(hw); | 167 | struct clk_rcg2 *rcg = to_clk_rcg2(hw); |
163 | u32 cfg, hid_div, m = 0, n = 0, mode = 0, mask; | 168 | u32 cfg, hid_div, m = 0, n = 0, mode = 0, mask; |
164 | 169 | ||
165 | regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, &cfg); | 170 | regmap_read(rcg->clkr.regmap, RCG_CFG_OFFSET(rcg), &cfg); |
166 | 171 | ||
167 | if (rcg->mnd_width) { | 172 | if (rcg->mnd_width) { |
168 | mask = BIT(rcg->mnd_width) - 1; | 173 | mask = BIT(rcg->mnd_width) - 1; |
169 | regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + M_REG, &m); | 174 | regmap_read(rcg->clkr.regmap, RCG_M_OFFSET(rcg), &m); |
170 | m &= mask; | 175 | m &= mask; |
171 | regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + N_REG, &n); | 176 | regmap_read(rcg->clkr.regmap, RCG_N_OFFSET(rcg), &n); |
172 | n = ~n; | 177 | n = ~n; |
173 | n &= mask; | 178 | n &= mask; |
174 | n += m; | 179 | n += m; |
@@ -263,17 +268,17 @@ static int __clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f) | |||
263 | if (rcg->mnd_width && f->n) { | 268 | if (rcg->mnd_width && f->n) { |
264 | mask = BIT(rcg->mnd_width) - 1; | 269 | mask = BIT(rcg->mnd_width) - 1; |
265 | ret = regmap_update_bits(rcg->clkr.regmap, | 270 | ret = regmap_update_bits(rcg->clkr.regmap, |
266 | rcg->cmd_rcgr + M_REG, mask, f->m); | 271 | RCG_M_OFFSET(rcg), mask, f->m); |
267 | if (ret) | 272 | if (ret) |
268 | return ret; | 273 | return ret; |
269 | 274 | ||
270 | ret = regmap_update_bits(rcg->clkr.regmap, | 275 | ret = regmap_update_bits(rcg->clkr.regmap, |
271 | rcg->cmd_rcgr + N_REG, mask, ~(f->n - f->m)); | 276 | RCG_N_OFFSET(rcg), mask, ~(f->n - f->m)); |
272 | if (ret) | 277 | if (ret) |
273 | return ret; | 278 | return ret; |
274 | 279 | ||
275 | ret = regmap_update_bits(rcg->clkr.regmap, | 280 | ret = regmap_update_bits(rcg->clkr.regmap, |
276 | rcg->cmd_rcgr + D_REG, mask, ~f->n); | 281 | RCG_D_OFFSET(rcg), mask, ~f->n); |
277 | if (ret) | 282 | if (ret) |
278 | return ret; | 283 | return ret; |
279 | } | 284 | } |
@@ -284,8 +289,7 @@ static int __clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f) | |||
284 | cfg |= rcg->parent_map[index].cfg << CFG_SRC_SEL_SHIFT; | 289 | cfg |= rcg->parent_map[index].cfg << CFG_SRC_SEL_SHIFT; |
285 | if (rcg->mnd_width && f->n && (f->m != f->n)) | 290 | if (rcg->mnd_width && f->n && (f->m != f->n)) |
286 | cfg |= CFG_MODE_DUAL_EDGE; | 291 | cfg |= CFG_MODE_DUAL_EDGE; |
287 | 292 | return regmap_update_bits(rcg->clkr.regmap, RCG_CFG_OFFSET(rcg), | |
288 | return regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, | ||
289 | mask, cfg); | 293 | mask, cfg); |
290 | } | 294 | } |
291 | 295 | ||
diff --git a/drivers/clk/qcom/clk-rpmh.c b/drivers/clk/qcom/clk-rpmh.c index 9f4fc7773fb2..c3fd632af119 100644 --- a/drivers/clk/qcom/clk-rpmh.c +++ b/drivers/clk/qcom/clk-rpmh.c | |||
@@ -18,6 +18,31 @@ | |||
18 | #define CLK_RPMH_ARC_EN_OFFSET 0 | 18 | #define CLK_RPMH_ARC_EN_OFFSET 0 |
19 | #define CLK_RPMH_VRM_EN_OFFSET 4 | 19 | #define CLK_RPMH_VRM_EN_OFFSET 4 |
20 | 20 | ||
21 | #define BCM_TCS_CMD_COMMIT_MASK 0x40000000 | ||
22 | #define BCM_TCS_CMD_VALID_SHIFT 29 | ||
23 | #define BCM_TCS_CMD_VOTE_MASK 0x3fff | ||
24 | #define BCM_TCS_CMD_VOTE_SHIFT 0 | ||
25 | |||
26 | #define BCM_TCS_CMD(valid, vote) \ | ||
27 | (BCM_TCS_CMD_COMMIT_MASK | \ | ||
28 | ((valid) << BCM_TCS_CMD_VALID_SHIFT) | \ | ||
29 | ((vote & BCM_TCS_CMD_VOTE_MASK) \ | ||
30 | << BCM_TCS_CMD_VOTE_SHIFT)) | ||
31 | |||
32 | /** | ||
33 | * struct bcm_db - Auxiliary data pertaining to each Bus Clock Manager(BCM) | ||
34 | * @unit: divisor used to convert Hz value to an RPMh msg | ||
35 | * @width: multiplier used to convert Hz value to an RPMh msg | ||
36 | * @vcd: virtual clock domain that this bcm belongs to | ||
37 | * @reserved: reserved to pad the struct | ||
38 | */ | ||
39 | struct bcm_db { | ||
40 | __le32 unit; | ||
41 | __le16 width; | ||
42 | u8 vcd; | ||
43 | u8 reserved; | ||
44 | }; | ||
45 | |||
21 | /** | 46 | /** |
22 | * struct clk_rpmh - individual rpmh clock data structure | 47 | * struct clk_rpmh - individual rpmh clock data structure |
23 | * @hw: handle between common and hardware-specific interfaces | 48 | * @hw: handle between common and hardware-specific interfaces |
@@ -29,6 +54,7 @@ | |||
29 | * @aggr_state: rpmh clock aggregated state | 54 | * @aggr_state: rpmh clock aggregated state |
30 | * @last_sent_aggr_state: rpmh clock last aggr state sent to RPMh | 55 | * @last_sent_aggr_state: rpmh clock last aggr state sent to RPMh |
31 | * @valid_state_mask: mask to determine the state of the rpmh clock | 56 | * @valid_state_mask: mask to determine the state of the rpmh clock |
57 | * @unit: divisor to convert rate to rpmh msg in magnitudes of Khz | ||
32 | * @dev: device to which it is attached | 58 | * @dev: device to which it is attached |
33 | * @peer: pointer to the clock rpmh sibling | 59 | * @peer: pointer to the clock rpmh sibling |
34 | */ | 60 | */ |
@@ -42,6 +68,7 @@ struct clk_rpmh { | |||
42 | u32 aggr_state; | 68 | u32 aggr_state; |
43 | u32 last_sent_aggr_state; | 69 | u32 last_sent_aggr_state; |
44 | u32 valid_state_mask; | 70 | u32 valid_state_mask; |
71 | u32 unit; | ||
45 | struct device *dev; | 72 | struct device *dev; |
46 | struct clk_rpmh *peer; | 73 | struct clk_rpmh *peer; |
47 | }; | 74 | }; |
@@ -98,6 +125,17 @@ static DEFINE_MUTEX(rpmh_clk_lock); | |||
98 | __DEFINE_CLK_RPMH(_platform, _name, _name_active, _res_name, \ | 125 | __DEFINE_CLK_RPMH(_platform, _name, _name_active, _res_name, \ |
99 | CLK_RPMH_VRM_EN_OFFSET, 1, _div) | 126 | CLK_RPMH_VRM_EN_OFFSET, 1, _div) |
100 | 127 | ||
128 | #define DEFINE_CLK_RPMH_BCM(_platform, _name, _res_name) \ | ||
129 | static struct clk_rpmh _platform##_##_name = { \ | ||
130 | .res_name = _res_name, \ | ||
131 | .valid_state_mask = BIT(RPMH_ACTIVE_ONLY_STATE), \ | ||
132 | .div = 1, \ | ||
133 | .hw.init = &(struct clk_init_data){ \ | ||
134 | .ops = &clk_rpmh_bcm_ops, \ | ||
135 | .name = #_name, \ | ||
136 | }, \ | ||
137 | } | ||
138 | |||
101 | static inline struct clk_rpmh *to_clk_rpmh(struct clk_hw *_hw) | 139 | static inline struct clk_rpmh *to_clk_rpmh(struct clk_hw *_hw) |
102 | { | 140 | { |
103 | return container_of(_hw, struct clk_rpmh, hw); | 141 | return container_of(_hw, struct clk_rpmh, hw); |
@@ -210,6 +248,96 @@ static const struct clk_ops clk_rpmh_ops = { | |||
210 | .recalc_rate = clk_rpmh_recalc_rate, | 248 | .recalc_rate = clk_rpmh_recalc_rate, |
211 | }; | 249 | }; |
212 | 250 | ||
251 | static int clk_rpmh_bcm_send_cmd(struct clk_rpmh *c, bool enable) | ||
252 | { | ||
253 | struct tcs_cmd cmd = { 0 }; | ||
254 | u32 cmd_state; | ||
255 | int ret; | ||
256 | |||
257 | mutex_lock(&rpmh_clk_lock); | ||
258 | |||
259 | cmd_state = 0; | ||
260 | if (enable) { | ||
261 | cmd_state = 1; | ||
262 | if (c->aggr_state) | ||
263 | cmd_state = c->aggr_state; | ||
264 | } | ||
265 | |||
266 | if (c->last_sent_aggr_state == cmd_state) { | ||
267 | mutex_unlock(&rpmh_clk_lock); | ||
268 | return 0; | ||
269 | } | ||
270 | |||
271 | cmd.addr = c->res_addr; | ||
272 | cmd.data = BCM_TCS_CMD(enable, cmd_state); | ||
273 | |||
274 | ret = rpmh_write_async(c->dev, RPMH_ACTIVE_ONLY_STATE, &cmd, 1); | ||
275 | if (ret) { | ||
276 | dev_err(c->dev, "set active state of %s failed: (%d)\n", | ||
277 | c->res_name, ret); | ||
278 | mutex_unlock(&rpmh_clk_lock); | ||
279 | return ret; | ||
280 | } | ||
281 | |||
282 | c->last_sent_aggr_state = cmd_state; | ||
283 | |||
284 | mutex_unlock(&rpmh_clk_lock); | ||
285 | |||
286 | return 0; | ||
287 | } | ||
288 | |||
289 | static int clk_rpmh_bcm_prepare(struct clk_hw *hw) | ||
290 | { | ||
291 | struct clk_rpmh *c = to_clk_rpmh(hw); | ||
292 | |||
293 | return clk_rpmh_bcm_send_cmd(c, true); | ||
294 | }; | ||
295 | |||
296 | static void clk_rpmh_bcm_unprepare(struct clk_hw *hw) | ||
297 | { | ||
298 | struct clk_rpmh *c = to_clk_rpmh(hw); | ||
299 | |||
300 | clk_rpmh_bcm_send_cmd(c, false); | ||
301 | }; | ||
302 | |||
303 | static int clk_rpmh_bcm_set_rate(struct clk_hw *hw, unsigned long rate, | ||
304 | unsigned long parent_rate) | ||
305 | { | ||
306 | struct clk_rpmh *c = to_clk_rpmh(hw); | ||
307 | |||
308 | c->aggr_state = rate / c->unit; | ||
309 | /* | ||
310 | * Since any non-zero value sent to hw would result in enabling the | ||
311 | * clock, only send the value if the clock has already been prepared. | ||
312 | */ | ||
313 | if (clk_hw_is_prepared(hw)) | ||
314 | clk_rpmh_bcm_send_cmd(c, true); | ||
315 | |||
316 | return 0; | ||
317 | }; | ||
318 | |||
319 | static long clk_rpmh_round_rate(struct clk_hw *hw, unsigned long rate, | ||
320 | unsigned long *parent_rate) | ||
321 | { | ||
322 | return rate; | ||
323 | } | ||
324 | |||
325 | static unsigned long clk_rpmh_bcm_recalc_rate(struct clk_hw *hw, | ||
326 | unsigned long prate) | ||
327 | { | ||
328 | struct clk_rpmh *c = to_clk_rpmh(hw); | ||
329 | |||
330 | return c->aggr_state * c->unit; | ||
331 | } | ||
332 | |||
333 | static const struct clk_ops clk_rpmh_bcm_ops = { | ||
334 | .prepare = clk_rpmh_bcm_prepare, | ||
335 | .unprepare = clk_rpmh_bcm_unprepare, | ||
336 | .set_rate = clk_rpmh_bcm_set_rate, | ||
337 | .round_rate = clk_rpmh_round_rate, | ||
338 | .recalc_rate = clk_rpmh_bcm_recalc_rate, | ||
339 | }; | ||
340 | |||
213 | /* Resource name must match resource id present in cmd-db. */ | 341 | /* Resource name must match resource id present in cmd-db. */ |
214 | DEFINE_CLK_RPMH_ARC(sdm845, bi_tcxo, bi_tcxo_ao, "xo.lvl", 0x3, 2); | 342 | DEFINE_CLK_RPMH_ARC(sdm845, bi_tcxo, bi_tcxo_ao, "xo.lvl", 0x3, 2); |
215 | DEFINE_CLK_RPMH_VRM(sdm845, ln_bb_clk2, ln_bb_clk2_ao, "lnbclka2", 2); | 343 | DEFINE_CLK_RPMH_VRM(sdm845, ln_bb_clk2, ln_bb_clk2_ao, "lnbclka2", 2); |
@@ -217,6 +345,7 @@ DEFINE_CLK_RPMH_VRM(sdm845, ln_bb_clk3, ln_bb_clk3_ao, "lnbclka3", 2); | |||
217 | DEFINE_CLK_RPMH_VRM(sdm845, rf_clk1, rf_clk1_ao, "rfclka1", 1); | 345 | DEFINE_CLK_RPMH_VRM(sdm845, rf_clk1, rf_clk1_ao, "rfclka1", 1); |
218 | DEFINE_CLK_RPMH_VRM(sdm845, rf_clk2, rf_clk2_ao, "rfclka2", 1); | 346 | DEFINE_CLK_RPMH_VRM(sdm845, rf_clk2, rf_clk2_ao, "rfclka2", 1); |
219 | DEFINE_CLK_RPMH_VRM(sdm845, rf_clk3, rf_clk3_ao, "rfclka3", 1); | 347 | DEFINE_CLK_RPMH_VRM(sdm845, rf_clk3, rf_clk3_ao, "rfclka3", 1); |
348 | DEFINE_CLK_RPMH_BCM(sdm845, ipa, "IP0"); | ||
220 | 349 | ||
221 | static struct clk_hw *sdm845_rpmh_clocks[] = { | 350 | static struct clk_hw *sdm845_rpmh_clocks[] = { |
222 | [RPMH_CXO_CLK] = &sdm845_bi_tcxo.hw, | 351 | [RPMH_CXO_CLK] = &sdm845_bi_tcxo.hw, |
@@ -231,6 +360,7 @@ static struct clk_hw *sdm845_rpmh_clocks[] = { | |||
231 | [RPMH_RF_CLK2_A] = &sdm845_rf_clk2_ao.hw, | 360 | [RPMH_RF_CLK2_A] = &sdm845_rf_clk2_ao.hw, |
232 | [RPMH_RF_CLK3] = &sdm845_rf_clk3.hw, | 361 | [RPMH_RF_CLK3] = &sdm845_rf_clk3.hw, |
233 | [RPMH_RF_CLK3_A] = &sdm845_rf_clk3_ao.hw, | 362 | [RPMH_RF_CLK3_A] = &sdm845_rf_clk3_ao.hw, |
363 | [RPMH_IPA_CLK] = &sdm845_ipa.hw, | ||
234 | }; | 364 | }; |
235 | 365 | ||
236 | static const struct clk_rpmh_desc clk_rpmh_sdm845 = { | 366 | static const struct clk_rpmh_desc clk_rpmh_sdm845 = { |
@@ -267,6 +397,8 @@ static int clk_rpmh_probe(struct platform_device *pdev) | |||
267 | 397 | ||
268 | for (i = 0; i < desc->num_clks; i++) { | 398 | for (i = 0; i < desc->num_clks; i++) { |
269 | u32 res_addr; | 399 | u32 res_addr; |
400 | size_t aux_data_len; | ||
401 | const struct bcm_db *data; | ||
270 | 402 | ||
271 | rpmh_clk = to_clk_rpmh(hw_clks[i]); | 403 | rpmh_clk = to_clk_rpmh(hw_clks[i]); |
272 | res_addr = cmd_db_read_addr(rpmh_clk->res_name); | 404 | res_addr = cmd_db_read_addr(rpmh_clk->res_name); |
@@ -275,6 +407,20 @@ static int clk_rpmh_probe(struct platform_device *pdev) | |||
275 | rpmh_clk->res_name); | 407 | rpmh_clk->res_name); |
276 | return -ENODEV; | 408 | return -ENODEV; |
277 | } | 409 | } |
410 | |||
411 | data = cmd_db_read_aux_data(rpmh_clk->res_name, &aux_data_len); | ||
412 | if (IS_ERR(data)) { | ||
413 | ret = PTR_ERR(data); | ||
414 | dev_err(&pdev->dev, | ||
415 | "error reading RPMh aux data for %s (%d)\n", | ||
416 | rpmh_clk->res_name, ret); | ||
417 | return ret; | ||
418 | } | ||
419 | |||
420 | /* Convert unit from Khz to Hz */ | ||
421 | if (aux_data_len == sizeof(*data)) | ||
422 | rpmh_clk->unit = le32_to_cpu(data->unit) * 1000ULL; | ||
423 | |||
278 | rpmh_clk->res_addr += res_addr; | 424 | rpmh_clk->res_addr += res_addr; |
279 | rpmh_clk->dev = &pdev->dev; | 425 | rpmh_clk->dev = &pdev->dev; |
280 | 426 | ||
diff --git a/drivers/clk/qcom/gcc-qcs404.c b/drivers/clk/qcom/gcc-qcs404.c index 64da032bb9ed..493e055299b4 100644 --- a/drivers/clk/qcom/gcc-qcs404.c +++ b/drivers/clk/qcom/gcc-qcs404.c | |||
@@ -678,6 +678,7 @@ static struct clk_rcg2 blsp1_uart3_apps_clk_src = { | |||
678 | .cmd_rcgr = 0x4014, | 678 | .cmd_rcgr = 0x4014, |
679 | .mnd_width = 16, | 679 | .mnd_width = 16, |
680 | .hid_width = 5, | 680 | .hid_width = 5, |
681 | .cfg_off = 0x20, | ||
681 | .parent_map = gcc_parent_map_0, | 682 | .parent_map = gcc_parent_map_0, |
682 | .freq_tbl = ftbl_blsp1_uart0_apps_clk_src, | 683 | .freq_tbl = ftbl_blsp1_uart0_apps_clk_src, |
683 | .clkr.hw.init = &(struct clk_init_data){ | 684 | .clkr.hw.init = &(struct clk_init_data){ |
diff --git a/include/dt-bindings/clock/actions,s500-cmu.h b/include/dt-bindings/clock/actions,s500-cmu.h new file mode 100644 index 000000000000..030981cd2d56 --- /dev/null +++ b/include/dt-bindings/clock/actions,s500-cmu.h | |||
@@ -0,0 +1,78 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0+ */ | ||
2 | /* | ||
3 | * Device Tree binding constants for Actions Semi S500 Clock Management Unit | ||
4 | * | ||
5 | * Copyright (c) 2014 Actions Semi Inc. | ||
6 | * Copyright (c) 2018 LSI-TEC - Caninos Loucos | ||
7 | */ | ||
8 | |||
9 | #ifndef __DT_BINDINGS_CLOCK_S500_CMU_H | ||
10 | #define __DT_BINDINGS_CLOCK_S500_CMU_H | ||
11 | |||
12 | #define CLK_NONE 0 | ||
13 | |||
14 | /* fixed rate clocks */ | ||
15 | #define CLK_LOSC 1 | ||
16 | #define CLK_HOSC 2 | ||
17 | |||
18 | /* pll clocks */ | ||
19 | #define CLK_CORE_PLL 3 | ||
20 | #define CLK_DEV_PLL 4 | ||
21 | #define CLK_DDR_PLL 5 | ||
22 | #define CLK_NAND_PLL 6 | ||
23 | #define CLK_DISPLAY_PLL 7 | ||
24 | #define CLK_ETHERNET_PLL 8 | ||
25 | #define CLK_AUDIO_PLL 9 | ||
26 | |||
27 | /* system clock */ | ||
28 | #define CLK_DEV 10 | ||
29 | #define CLK_H 11 | ||
30 | #define CLK_AHBPREDIV 12 | ||
31 | #define CLK_AHB 13 | ||
32 | #define CLK_DE 14 | ||
33 | #define CLK_BISP 15 | ||
34 | #define CLK_VCE 16 | ||
35 | #define CLK_VDE 17 | ||
36 | |||
37 | /* peripheral device clock */ | ||
38 | #define CLK_TIMER 18 | ||
39 | #define CLK_I2C0 19 | ||
40 | #define CLK_I2C1 20 | ||
41 | #define CLK_I2C2 21 | ||
42 | #define CLK_I2C3 22 | ||
43 | #define CLK_PWM0 23 | ||
44 | #define CLK_PWM1 24 | ||
45 | #define CLK_PWM2 25 | ||
46 | #define CLK_PWM3 26 | ||
47 | #define CLK_PWM4 27 | ||
48 | #define CLK_PWM5 28 | ||
49 | #define CLK_SD0 29 | ||
50 | #define CLK_SD1 30 | ||
51 | #define CLK_SD2 31 | ||
52 | #define CLK_SENSOR0 32 | ||
53 | #define CLK_SENSOR1 33 | ||
54 | #define CLK_SPI0 34 | ||
55 | #define CLK_SPI1 35 | ||
56 | #define CLK_SPI2 36 | ||
57 | #define CLK_SPI3 37 | ||
58 | #define CLK_UART0 38 | ||
59 | #define CLK_UART1 39 | ||
60 | #define CLK_UART2 40 | ||
61 | #define CLK_UART3 41 | ||
62 | #define CLK_UART4 42 | ||
63 | #define CLK_UART5 43 | ||
64 | #define CLK_UART6 44 | ||
65 | #define CLK_DE1 45 | ||
66 | #define CLK_DE2 46 | ||
67 | #define CLK_I2SRX 47 | ||
68 | #define CLK_I2STX 48 | ||
69 | #define CLK_HDMI_AUDIO 49 | ||
70 | #define CLK_HDMI 50 | ||
71 | #define CLK_SPDIF 51 | ||
72 | #define CLK_NAND 52 | ||
73 | #define CLK_ECC 53 | ||
74 | #define CLK_RMII_REF 54 | ||
75 | |||
76 | #define CLK_NR_CLKS (CLK_RMII_REF + 1) | ||
77 | |||
78 | #endif /* __DT_BINDINGS_CLOCK_S500_CMU_H */ | ||
diff --git a/include/dt-bindings/clock/qcom,rpmh.h b/include/dt-bindings/clock/qcom,rpmh.h index f48fbd6f2095..edcab3f7b7d3 100644 --- a/include/dt-bindings/clock/qcom,rpmh.h +++ b/include/dt-bindings/clock/qcom,rpmh.h | |||
@@ -18,5 +18,6 @@ | |||
18 | #define RPMH_RF_CLK2_A 9 | 18 | #define RPMH_RF_CLK2_A 9 |
19 | #define RPMH_RF_CLK3 10 | 19 | #define RPMH_RF_CLK3 10 |
20 | #define RPMH_RF_CLK3_A 11 | 20 | #define RPMH_RF_CLK3_A 11 |
21 | #define RPMH_IPA_CLK 12 | ||
21 | 22 | ||
22 | #endif | 23 | #endif |
diff --git a/include/dt-bindings/clock/stm32mp1-clks.h b/include/dt-bindings/clock/stm32mp1-clks.h index 90ec780bfc68..4cdaf135829c 100644 --- a/include/dt-bindings/clock/stm32mp1-clks.h +++ b/include/dt-bindings/clock/stm32mp1-clks.h | |||
@@ -248,7 +248,4 @@ | |||
248 | 248 | ||
249 | #define STM32MP1_LAST_CLK 232 | 249 | #define STM32MP1_LAST_CLK 232 |
250 | 250 | ||
251 | #define LTDC_K LTDC_PX | ||
252 | #define ETHMAC_K ETHCK_K | ||
253 | |||
254 | #endif /* _DT_BINDINGS_STM32MP1_CLKS_H_ */ | 251 | #endif /* _DT_BINDINGS_STM32MP1_CLKS_H_ */ |