diff options
author | Vladimir Zapolskiy <vz@mleia.com> | 2015-12-06 05:45:57 -0500 |
---|---|---|
committer | Michael Turquette <mturquette@baylibre.com> | 2015-12-24 15:31:26 -0500 |
commit | f7c82a60ba26c2f003662bcb2cff131021c1e828 (patch) | |
tree | 5f86b73f7381c0fe34f426f0e03da5f8021e8602 | |
parent | 8a896310a7ea5fa99fc89690bde7be404c7e1113 (diff) |
clk: lpc32xx: add common clock framework driver
Add support for all configurable clocks found on NXP LPC32xx SoC.
The list contains several heterogenous groups of clocks:
* system clocks including multiple dividers and muxes,
* x397 PLL, HCLK PLL and USB PLL,
* peripheral clocks inherited from rtc, hclk and pclk,
* USB controller clocks: AHB slave, I2C, OTG, OHCI and device.
Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
Signed-off-by: Michael Turquette <mturquette@baylibre.com>
-rw-r--r-- | drivers/clk/Kconfig | 6 | ||||
-rw-r--r-- | drivers/clk/nxp/Makefile | 1 | ||||
-rw-r--r-- | drivers/clk/nxp/clk-lpc32xx.c | 1569 |
3 files changed, 1576 insertions, 0 deletions
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 7fc1eb90ca2b..bd2b504df603 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig | |||
@@ -161,6 +161,12 @@ config COMMON_CLK_KEYSTONE | |||
161 | Supports clock drivers for Keystone based SOCs. These SOCs have local | 161 | Supports clock drivers for Keystone based SOCs. These SOCs have local |
162 | a power sleep control module that gate the clock to the IPs and PLLs. | 162 | a power sleep control module that gate the clock to the IPs and PLLs. |
163 | 163 | ||
164 | config COMMON_CLK_NXP | ||
165 | def_bool COMMON_CLK && (ARCH_LPC18XX || ARCH_LPC32XX) | ||
166 | select REGMAP_MMIO if ARCH_LPC32XX | ||
167 | ---help--- | ||
168 | Support for clock providers on NXP platforms. | ||
169 | |||
164 | config COMMON_CLK_PALMAS | 170 | config COMMON_CLK_PALMAS |
165 | tristate "Clock driver for TI Palmas devices" | 171 | tristate "Clock driver for TI Palmas devices" |
166 | depends on MFD_PALMAS | 172 | depends on MFD_PALMAS |
diff --git a/drivers/clk/nxp/Makefile b/drivers/clk/nxp/Makefile index 7f608b0ad7b4..607bd48c6563 100644 --- a/drivers/clk/nxp/Makefile +++ b/drivers/clk/nxp/Makefile | |||
@@ -1,2 +1,3 @@ | |||
1 | obj-$(CONFIG_ARCH_LPC18XX) += clk-lpc18xx-cgu.o | 1 | obj-$(CONFIG_ARCH_LPC18XX) += clk-lpc18xx-cgu.o |
2 | obj-$(CONFIG_ARCH_LPC18XX) += clk-lpc18xx-ccu.o | 2 | obj-$(CONFIG_ARCH_LPC18XX) += clk-lpc18xx-ccu.o |
3 | obj-$(CONFIG_ARCH_LPC32XX) += clk-lpc32xx.o | ||
diff --git a/drivers/clk/nxp/clk-lpc32xx.c b/drivers/clk/nxp/clk-lpc32xx.c new file mode 100644 index 000000000000..10dd0fdaa474 --- /dev/null +++ b/drivers/clk/nxp/clk-lpc32xx.c | |||
@@ -0,0 +1,1569 @@ | |||
1 | /* | ||
2 | * Copyright 2015 Vladimir Zapolskiy <vz@mleia.com> | ||
3 | * | ||
4 | * The code contained herein is licensed under the GNU General Public | ||
5 | * License. You may obtain a copy of the GNU General Public License | ||
6 | * Version 2 or later at the following locations: | ||
7 | * | ||
8 | * http://www.opensource.org/licenses/gpl-license.html | ||
9 | * http://www.gnu.org/copyleft/gpl.html | ||
10 | */ | ||
11 | |||
12 | #include <linux/clk.h> | ||
13 | #include <linux/clk-provider.h> | ||
14 | #include <linux/of_address.h> | ||
15 | #include <linux/regmap.h> | ||
16 | |||
17 | #include <dt-bindings/clock/lpc32xx-clock.h> | ||
18 | |||
19 | #undef pr_fmt | ||
20 | #define pr_fmt(fmt) "%s: " fmt, __func__ | ||
21 | |||
22 | /* Common bitfield definitions for x397 PLL (lock), USB PLL and HCLK PLL */ | ||
23 | #define PLL_CTRL_ENABLE BIT(16) | ||
24 | #define PLL_CTRL_BYPASS BIT(15) | ||
25 | #define PLL_CTRL_DIRECT BIT(14) | ||
26 | #define PLL_CTRL_FEEDBACK BIT(13) | ||
27 | #define PLL_CTRL_POSTDIV (BIT(12)|BIT(11)) | ||
28 | #define PLL_CTRL_PREDIV (BIT(10)|BIT(9)) | ||
29 | #define PLL_CTRL_FEEDDIV (0xFF << 1) | ||
30 | #define PLL_CTRL_LOCK BIT(0) | ||
31 | |||
32 | /* Clock registers on System Control Block */ | ||
33 | #define LPC32XX_CLKPWR_DEBUG_CTRL 0x00 | ||
34 | #define LPC32XX_CLKPWR_USB_DIV 0x1C | ||
35 | #define LPC32XX_CLKPWR_HCLKDIV_CTRL 0x40 | ||
36 | #define LPC32XX_CLKPWR_PWR_CTRL 0x44 | ||
37 | #define LPC32XX_CLKPWR_PLL397_CTRL 0x48 | ||
38 | #define LPC32XX_CLKPWR_OSC_CTRL 0x4C | ||
39 | #define LPC32XX_CLKPWR_SYSCLK_CTRL 0x50 | ||
40 | #define LPC32XX_CLKPWR_LCDCLK_CTRL 0x54 | ||
41 | #define LPC32XX_CLKPWR_HCLKPLL_CTRL 0x58 | ||
42 | #define LPC32XX_CLKPWR_ADCCLK_CTRL1 0x60 | ||
43 | #define LPC32XX_CLKPWR_USB_CTRL 0x64 | ||
44 | #define LPC32XX_CLKPWR_SSP_CTRL 0x78 | ||
45 | #define LPC32XX_CLKPWR_I2S_CTRL 0x7C | ||
46 | #define LPC32XX_CLKPWR_MS_CTRL 0x80 | ||
47 | #define LPC32XX_CLKPWR_MACCLK_CTRL 0x90 | ||
48 | #define LPC32XX_CLKPWR_TEST_CLK_CTRL 0xA4 | ||
49 | #define LPC32XX_CLKPWR_I2CCLK_CTRL 0xAC | ||
50 | #define LPC32XX_CLKPWR_KEYCLK_CTRL 0xB0 | ||
51 | #define LPC32XX_CLKPWR_ADCCLK_CTRL 0xB4 | ||
52 | #define LPC32XX_CLKPWR_PWMCLK_CTRL 0xB8 | ||
53 | #define LPC32XX_CLKPWR_TIMCLK_CTRL 0xBC | ||
54 | #define LPC32XX_CLKPWR_TIMCLK_CTRL1 0xC0 | ||
55 | #define LPC32XX_CLKPWR_SPI_CTRL 0xC4 | ||
56 | #define LPC32XX_CLKPWR_FLASHCLK_CTRL 0xC8 | ||
57 | #define LPC32XX_CLKPWR_UART3_CLK_CTRL 0xD0 | ||
58 | #define LPC32XX_CLKPWR_UART4_CLK_CTRL 0xD4 | ||
59 | #define LPC32XX_CLKPWR_UART5_CLK_CTRL 0xD8 | ||
60 | #define LPC32XX_CLKPWR_UART6_CLK_CTRL 0xDC | ||
61 | #define LPC32XX_CLKPWR_IRDA_CLK_CTRL 0xE0 | ||
62 | #define LPC32XX_CLKPWR_UART_CLK_CTRL 0xE4 | ||
63 | #define LPC32XX_CLKPWR_DMA_CLK_CTRL 0xE8 | ||
64 | |||
65 | /* Clock registers on USB controller */ | ||
66 | #define LPC32XX_USB_CLK_CTRL 0xF4 | ||
67 | #define LPC32XX_USB_CLK_STS 0xF8 | ||
68 | |||
69 | static struct regmap_config lpc32xx_scb_regmap_config = { | ||
70 | .reg_bits = 32, | ||
71 | .val_bits = 32, | ||
72 | .reg_stride = 4, | ||
73 | .val_format_endian = REGMAP_ENDIAN_LITTLE, | ||
74 | .max_register = 0x114, | ||
75 | .fast_io = true, | ||
76 | }; | ||
77 | |||
78 | static struct regmap *clk_regmap; | ||
79 | static void __iomem *usb_clk_vbase; | ||
80 | |||
81 | enum { | ||
82 | LPC32XX_USB_CLK_OTG = LPC32XX_USB_CLK_HOST + 1, | ||
83 | LPC32XX_USB_CLK_AHB, | ||
84 | |||
85 | LPC32XX_USB_CLK_MAX = LPC32XX_USB_CLK_AHB + 1, | ||
86 | }; | ||
87 | |||
88 | enum { | ||
89 | /* Start from the last defined clock in dt bindings */ | ||
90 | LPC32XX_CLK_ADC_DIV = LPC32XX_CLK_ADC + 1, | ||
91 | LPC32XX_CLK_ADC_RTC, | ||
92 | LPC32XX_CLK_TEST1, | ||
93 | LPC32XX_CLK_TEST2, | ||
94 | |||
95 | /* System clocks, PLL 397x and HCLK PLL clocks */ | ||
96 | LPC32XX_CLK_OSC, | ||
97 | LPC32XX_CLK_SYS, | ||
98 | LPC32XX_CLK_PLL397X, | ||
99 | LPC32XX_CLK_HCLK_PLL, | ||
100 | LPC32XX_CLK_HCLK_DIV_PERIPH, | ||
101 | LPC32XX_CLK_HCLK_DIV, | ||
102 | LPC32XX_CLK_HCLK, | ||
103 | LPC32XX_CLK_PERIPH, | ||
104 | LPC32XX_CLK_ARM, | ||
105 | LPC32XX_CLK_ARM_VFP, | ||
106 | |||
107 | /* USB clocks */ | ||
108 | LPC32XX_CLK_USB_PLL, | ||
109 | LPC32XX_CLK_USB_DIV, | ||
110 | LPC32XX_CLK_USB, | ||
111 | |||
112 | /* Only one control PWR_CTRL[10] for both muxes */ | ||
113 | LPC32XX_CLK_PERIPH_HCLK_MUX, | ||
114 | LPC32XX_CLK_PERIPH_ARM_MUX, | ||
115 | |||
116 | /* Only one control PWR_CTRL[2] for all three muxes */ | ||
117 | LPC32XX_CLK_SYSCLK_PERIPH_MUX, | ||
118 | LPC32XX_CLK_SYSCLK_HCLK_MUX, | ||
119 | LPC32XX_CLK_SYSCLK_ARM_MUX, | ||
120 | |||
121 | /* Two clock sources external to the driver */ | ||
122 | LPC32XX_CLK_XTAL_32K, | ||
123 | LPC32XX_CLK_XTAL, | ||
124 | |||
125 | /* Renumbered USB clocks, may have a parent from SCB table */ | ||
126 | LPC32XX_CLK_USB_OFFSET, | ||
127 | LPC32XX_CLK_USB_I2C = LPC32XX_USB_CLK_I2C + LPC32XX_CLK_USB_OFFSET, | ||
128 | LPC32XX_CLK_USB_DEV = LPC32XX_USB_CLK_DEVICE + LPC32XX_CLK_USB_OFFSET, | ||
129 | LPC32XX_CLK_USB_HOST = LPC32XX_USB_CLK_HOST + LPC32XX_CLK_USB_OFFSET, | ||
130 | LPC32XX_CLK_USB_OTG = LPC32XX_USB_CLK_OTG + LPC32XX_CLK_USB_OFFSET, | ||
131 | LPC32XX_CLK_USB_AHB = LPC32XX_USB_CLK_AHB + LPC32XX_CLK_USB_OFFSET, | ||
132 | |||
133 | /* Stub for composite clocks */ | ||
134 | LPC32XX_CLK__NULL, | ||
135 | |||
136 | /* Subclocks of composite clocks, clocks above are for CCF */ | ||
137 | LPC32XX_CLK_PWM1_MUX, | ||
138 | LPC32XX_CLK_PWM1_DIV, | ||
139 | LPC32XX_CLK_PWM1_GATE, | ||
140 | LPC32XX_CLK_PWM2_MUX, | ||
141 | LPC32XX_CLK_PWM2_DIV, | ||
142 | LPC32XX_CLK_PWM2_GATE, | ||
143 | LPC32XX_CLK_UART3_MUX, | ||
144 | LPC32XX_CLK_UART3_DIV, | ||
145 | LPC32XX_CLK_UART3_GATE, | ||
146 | LPC32XX_CLK_UART4_MUX, | ||
147 | LPC32XX_CLK_UART4_DIV, | ||
148 | LPC32XX_CLK_UART4_GATE, | ||
149 | LPC32XX_CLK_UART5_MUX, | ||
150 | LPC32XX_CLK_UART5_DIV, | ||
151 | LPC32XX_CLK_UART5_GATE, | ||
152 | LPC32XX_CLK_UART6_MUX, | ||
153 | LPC32XX_CLK_UART6_DIV, | ||
154 | LPC32XX_CLK_UART6_GATE, | ||
155 | LPC32XX_CLK_TEST1_MUX, | ||
156 | LPC32XX_CLK_TEST1_GATE, | ||
157 | LPC32XX_CLK_TEST2_MUX, | ||
158 | LPC32XX_CLK_TEST2_GATE, | ||
159 | LPC32XX_CLK_USB_DIV_DIV, | ||
160 | LPC32XX_CLK_USB_DIV_GATE, | ||
161 | LPC32XX_CLK_SD_DIV, | ||
162 | LPC32XX_CLK_SD_GATE, | ||
163 | LPC32XX_CLK_LCD_DIV, | ||
164 | LPC32XX_CLK_LCD_GATE, | ||
165 | |||
166 | LPC32XX_CLK_HW_MAX, | ||
167 | LPC32XX_CLK_MAX = LPC32XX_CLK_SYSCLK_ARM_MUX + 1, | ||
168 | LPC32XX_CLK_CCF_MAX = LPC32XX_CLK_USB_AHB + 1, | ||
169 | }; | ||
170 | |||
171 | static struct clk *clk[LPC32XX_CLK_MAX]; | ||
172 | static struct clk_onecell_data clk_data = { | ||
173 | .clks = clk, | ||
174 | .clk_num = LPC32XX_CLK_MAX, | ||
175 | }; | ||
176 | |||
177 | static struct clk *usb_clk[LPC32XX_USB_CLK_MAX]; | ||
178 | static struct clk_onecell_data usb_clk_data = { | ||
179 | .clks = usb_clk, | ||
180 | .clk_num = LPC32XX_USB_CLK_MAX, | ||
181 | }; | ||
182 | |||
183 | #define LPC32XX_CLK_PARENTS_MAX 5 | ||
184 | |||
185 | struct clk_proto_t { | ||
186 | const char *name; | ||
187 | const u8 parents[LPC32XX_CLK_PARENTS_MAX]; | ||
188 | u8 num_parents; | ||
189 | unsigned long flags; | ||
190 | }; | ||
191 | |||
192 | #define CLK_PREFIX(LITERAL) LPC32XX_CLK_ ## LITERAL | ||
193 | #define NUMARGS(...) (sizeof((int[]){__VA_ARGS__})/sizeof(int)) | ||
194 | |||
195 | #define LPC32XX_CLK_DEFINE(_idx, _name, _flags, ...) \ | ||
196 | [CLK_PREFIX(_idx)] = { \ | ||
197 | .name = _name, \ | ||
198 | .flags = _flags, \ | ||
199 | .parents = { __VA_ARGS__ }, \ | ||
200 | .num_parents = NUMARGS(__VA_ARGS__), \ | ||
201 | } | ||
202 | |||
203 | static const struct clk_proto_t clk_proto[LPC32XX_CLK_CCF_MAX] __initconst = { | ||
204 | LPC32XX_CLK_DEFINE(XTAL, "xtal", 0x0), | ||
205 | LPC32XX_CLK_DEFINE(XTAL_32K, "xtal_32k", 0x0), | ||
206 | |||
207 | LPC32XX_CLK_DEFINE(RTC, "rtc", 0x0, LPC32XX_CLK_XTAL_32K), | ||
208 | LPC32XX_CLK_DEFINE(OSC, "osc", CLK_IGNORE_UNUSED, LPC32XX_CLK_XTAL), | ||
209 | LPC32XX_CLK_DEFINE(SYS, "sys", CLK_IGNORE_UNUSED, | ||
210 | LPC32XX_CLK_OSC, LPC32XX_CLK_PLL397X), | ||
211 | LPC32XX_CLK_DEFINE(PLL397X, "pll_397x", CLK_IGNORE_UNUSED, | ||
212 | LPC32XX_CLK_RTC), | ||
213 | LPC32XX_CLK_DEFINE(HCLK_PLL, "hclk_pll", CLK_IGNORE_UNUSED, | ||
214 | LPC32XX_CLK_SYS), | ||
215 | LPC32XX_CLK_DEFINE(HCLK_DIV_PERIPH, "hclk_div_periph", | ||
216 | CLK_IGNORE_UNUSED, LPC32XX_CLK_HCLK_PLL), | ||
217 | LPC32XX_CLK_DEFINE(HCLK_DIV, "hclk_div", CLK_IGNORE_UNUSED, | ||
218 | LPC32XX_CLK_HCLK_PLL), | ||
219 | LPC32XX_CLK_DEFINE(HCLK, "hclk", CLK_IGNORE_UNUSED, | ||
220 | LPC32XX_CLK_PERIPH_HCLK_MUX), | ||
221 | LPC32XX_CLK_DEFINE(PERIPH, "pclk", CLK_IGNORE_UNUSED, | ||
222 | LPC32XX_CLK_SYSCLK_PERIPH_MUX), | ||
223 | LPC32XX_CLK_DEFINE(ARM, "arm", CLK_IGNORE_UNUSED, | ||
224 | LPC32XX_CLK_PERIPH_ARM_MUX), | ||
225 | |||
226 | LPC32XX_CLK_DEFINE(PERIPH_HCLK_MUX, "periph_hclk_mux", | ||
227 | CLK_IGNORE_UNUSED, | ||
228 | LPC32XX_CLK_SYSCLK_HCLK_MUX, LPC32XX_CLK_SYSCLK_PERIPH_MUX), | ||
229 | LPC32XX_CLK_DEFINE(PERIPH_ARM_MUX, "periph_arm_mux", CLK_IGNORE_UNUSED, | ||
230 | LPC32XX_CLK_SYSCLK_ARM_MUX, LPC32XX_CLK_SYSCLK_PERIPH_MUX), | ||
231 | LPC32XX_CLK_DEFINE(SYSCLK_PERIPH_MUX, "sysclk_periph_mux", | ||
232 | CLK_IGNORE_UNUSED, | ||
233 | LPC32XX_CLK_SYS, LPC32XX_CLK_HCLK_DIV_PERIPH), | ||
234 | LPC32XX_CLK_DEFINE(SYSCLK_HCLK_MUX, "sysclk_hclk_mux", | ||
235 | CLK_IGNORE_UNUSED, | ||
236 | LPC32XX_CLK_SYS, LPC32XX_CLK_HCLK_DIV), | ||
237 | LPC32XX_CLK_DEFINE(SYSCLK_ARM_MUX, "sysclk_arm_mux", CLK_IGNORE_UNUSED, | ||
238 | LPC32XX_CLK_SYS, LPC32XX_CLK_HCLK_PLL), | ||
239 | |||
240 | LPC32XX_CLK_DEFINE(ARM_VFP, "vfp9", CLK_IGNORE_UNUSED, | ||
241 | LPC32XX_CLK_ARM), | ||
242 | LPC32XX_CLK_DEFINE(USB_PLL, "usb_pll", | ||
243 | CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT, LPC32XX_CLK_USB_DIV), | ||
244 | LPC32XX_CLK_DEFINE(USB_DIV, "usb_div", 0x0, LPC32XX_CLK_OSC), | ||
245 | LPC32XX_CLK_DEFINE(USB, "usb", 0x0, LPC32XX_CLK_USB_PLL), | ||
246 | LPC32XX_CLK_DEFINE(DMA, "dma", 0x0, LPC32XX_CLK_HCLK), | ||
247 | LPC32XX_CLK_DEFINE(MLC, "mlc", 0x0, LPC32XX_CLK_HCLK), | ||
248 | LPC32XX_CLK_DEFINE(SLC, "slc", 0x0, LPC32XX_CLK_HCLK), | ||
249 | LPC32XX_CLK_DEFINE(LCD, "lcd", 0x0, LPC32XX_CLK_HCLK), | ||
250 | LPC32XX_CLK_DEFINE(MAC, "mac", 0x0, LPC32XX_CLK_HCLK), | ||
251 | LPC32XX_CLK_DEFINE(SD, "sd", 0x0, LPC32XX_CLK_ARM), | ||
252 | LPC32XX_CLK_DEFINE(DDRAM, "ddram", CLK_GET_RATE_NOCACHE, | ||
253 | LPC32XX_CLK_SYSCLK_ARM_MUX), | ||
254 | LPC32XX_CLK_DEFINE(SSP0, "ssp0", 0x0, LPC32XX_CLK_HCLK), | ||
255 | LPC32XX_CLK_DEFINE(SSP1, "ssp1", 0x0, LPC32XX_CLK_HCLK), | ||
256 | |||
257 | /* | ||
258 | * CLK_GET_RATE_NOCACHE is needed, if UART clock is disabled, its | ||
259 | * divider register does not contain information about selected rate. | ||
260 | */ | ||
261 | LPC32XX_CLK_DEFINE(UART3, "uart3", CLK_GET_RATE_NOCACHE, | ||
262 | LPC32XX_CLK_PERIPH, LPC32XX_CLK_HCLK), | ||
263 | LPC32XX_CLK_DEFINE(UART4, "uart4", CLK_GET_RATE_NOCACHE, | ||
264 | LPC32XX_CLK_PERIPH, LPC32XX_CLK_HCLK), | ||
265 | LPC32XX_CLK_DEFINE(UART5, "uart5", CLK_GET_RATE_NOCACHE, | ||
266 | LPC32XX_CLK_PERIPH, LPC32XX_CLK_HCLK), | ||
267 | LPC32XX_CLK_DEFINE(UART6, "uart6", CLK_GET_RATE_NOCACHE, | ||
268 | LPC32XX_CLK_PERIPH, LPC32XX_CLK_HCLK), | ||
269 | LPC32XX_CLK_DEFINE(IRDA, "irda", 0x0, LPC32XX_CLK_PERIPH), | ||
270 | LPC32XX_CLK_DEFINE(I2C1, "i2c1", 0x0, LPC32XX_CLK_HCLK), | ||
271 | LPC32XX_CLK_DEFINE(I2C2, "i2c2", 0x0, LPC32XX_CLK_HCLK), | ||
272 | LPC32XX_CLK_DEFINE(TIMER0, "timer0", 0x0, LPC32XX_CLK_PERIPH), | ||
273 | LPC32XX_CLK_DEFINE(TIMER1, "timer1", 0x0, LPC32XX_CLK_PERIPH), | ||
274 | LPC32XX_CLK_DEFINE(TIMER2, "timer2", 0x0, LPC32XX_CLK_PERIPH), | ||
275 | LPC32XX_CLK_DEFINE(TIMER3, "timer3", 0x0, LPC32XX_CLK_PERIPH), | ||
276 | LPC32XX_CLK_DEFINE(TIMER4, "timer4", 0x0, LPC32XX_CLK_PERIPH), | ||
277 | LPC32XX_CLK_DEFINE(TIMER5, "timer5", 0x0, LPC32XX_CLK_PERIPH), | ||
278 | LPC32XX_CLK_DEFINE(WDOG, "watchdog", 0x0, LPC32XX_CLK_PERIPH), | ||
279 | LPC32XX_CLK_DEFINE(I2S0, "i2s0", 0x0, LPC32XX_CLK_HCLK), | ||
280 | LPC32XX_CLK_DEFINE(I2S1, "i2s1", 0x0, LPC32XX_CLK_HCLK), | ||
281 | LPC32XX_CLK_DEFINE(SPI1, "spi1", 0x0, LPC32XX_CLK_HCLK), | ||
282 | LPC32XX_CLK_DEFINE(SPI2, "spi2", 0x0, LPC32XX_CLK_HCLK), | ||
283 | LPC32XX_CLK_DEFINE(MCPWM, "mcpwm", 0x0, LPC32XX_CLK_HCLK), | ||
284 | LPC32XX_CLK_DEFINE(HSTIMER, "hstimer", 0x0, LPC32XX_CLK_PERIPH), | ||
285 | LPC32XX_CLK_DEFINE(KEY, "key", 0x0, LPC32XX_CLK_RTC), | ||
286 | LPC32XX_CLK_DEFINE(PWM1, "pwm1", 0x0, | ||
287 | LPC32XX_CLK_RTC, LPC32XX_CLK_PERIPH), | ||
288 | LPC32XX_CLK_DEFINE(PWM2, "pwm2", 0x0, | ||
289 | LPC32XX_CLK_RTC, LPC32XX_CLK_PERIPH), | ||
290 | LPC32XX_CLK_DEFINE(ADC, "adc", 0x0, | ||
291 | LPC32XX_CLK_ADC_RTC, LPC32XX_CLK_ADC_DIV), | ||
292 | LPC32XX_CLK_DEFINE(ADC_DIV, "adc_div", 0x0, LPC32XX_CLK_PERIPH), | ||
293 | LPC32XX_CLK_DEFINE(ADC_RTC, "adc_rtc", 0x0, LPC32XX_CLK_RTC), | ||
294 | LPC32XX_CLK_DEFINE(TEST1, "test1", 0x0, | ||
295 | LPC32XX_CLK_PERIPH, LPC32XX_CLK_RTC, LPC32XX_CLK_OSC), | ||
296 | LPC32XX_CLK_DEFINE(TEST2, "test2", 0x0, | ||
297 | LPC32XX_CLK_HCLK, LPC32XX_CLK_PERIPH, LPC32XX_CLK_USB, | ||
298 | LPC32XX_CLK_OSC, LPC32XX_CLK_PLL397X), | ||
299 | |||
300 | /* USB controller clocks */ | ||
301 | LPC32XX_CLK_DEFINE(USB_AHB, "usb_ahb", 0x0, LPC32XX_CLK_USB), | ||
302 | LPC32XX_CLK_DEFINE(USB_OTG, "usb_otg", 0x0, LPC32XX_CLK_USB_AHB), | ||
303 | LPC32XX_CLK_DEFINE(USB_I2C, "usb_i2c", 0x0, LPC32XX_CLK_USB_AHB), | ||
304 | LPC32XX_CLK_DEFINE(USB_DEV, "usb_dev", 0x0, LPC32XX_CLK_USB_OTG), | ||
305 | LPC32XX_CLK_DEFINE(USB_HOST, "usb_host", 0x0, LPC32XX_CLK_USB_OTG), | ||
306 | }; | ||
307 | |||
308 | struct lpc32xx_clk { | ||
309 | struct clk_hw hw; | ||
310 | u32 reg; | ||
311 | u32 enable; | ||
312 | u32 enable_mask; | ||
313 | u32 disable; | ||
314 | u32 disable_mask; | ||
315 | u32 busy; | ||
316 | u32 busy_mask; | ||
317 | }; | ||
318 | |||
319 | enum clk_pll_mode { | ||
320 | PLL_UNKNOWN, | ||
321 | PLL_DIRECT, | ||
322 | PLL_BYPASS, | ||
323 | PLL_DIRECT_BYPASS, | ||
324 | PLL_INTEGER, | ||
325 | PLL_NON_INTEGER, | ||
326 | }; | ||
327 | |||
328 | struct lpc32xx_pll_clk { | ||
329 | struct clk_hw hw; | ||
330 | u32 reg; | ||
331 | u32 enable; | ||
332 | unsigned long m_div; | ||
333 | unsigned long n_div; | ||
334 | unsigned long p_div; | ||
335 | enum clk_pll_mode mode; | ||
336 | }; | ||
337 | |||
338 | struct lpc32xx_usb_clk { | ||
339 | struct clk_hw hw; | ||
340 | u32 ctrl_enable; | ||
341 | u32 ctrl_disable; | ||
342 | u32 ctrl_mask; | ||
343 | u32 enable; | ||
344 | u32 busy; | ||
345 | }; | ||
346 | |||
347 | struct lpc32xx_clk_mux { | ||
348 | struct clk_hw hw; | ||
349 | u32 reg; | ||
350 | u32 mask; | ||
351 | u8 shift; | ||
352 | u32 *table; | ||
353 | u8 flags; | ||
354 | }; | ||
355 | |||
356 | struct lpc32xx_clk_div { | ||
357 | struct clk_hw hw; | ||
358 | u32 reg; | ||
359 | u8 shift; | ||
360 | u8 width; | ||
361 | const struct clk_div_table *table; | ||
362 | u8 flags; | ||
363 | }; | ||
364 | |||
365 | struct lpc32xx_clk_gate { | ||
366 | struct clk_hw hw; | ||
367 | u32 reg; | ||
368 | u8 bit_idx; | ||
369 | u8 flags; | ||
370 | }; | ||
371 | |||
372 | #define to_lpc32xx_clk(_hw) container_of(_hw, struct lpc32xx_clk, hw) | ||
373 | #define to_lpc32xx_pll_clk(_hw) container_of(_hw, struct lpc32xx_pll_clk, hw) | ||
374 | #define to_lpc32xx_usb_clk(_hw) container_of(_hw, struct lpc32xx_usb_clk, hw) | ||
375 | #define to_lpc32xx_mux(_hw) container_of(_hw, struct lpc32xx_clk_mux, hw) | ||
376 | #define to_lpc32xx_div(_hw) container_of(_hw, struct lpc32xx_clk_div, hw) | ||
377 | #define to_lpc32xx_gate(_hw) container_of(_hw, struct lpc32xx_clk_gate, hw) | ||
378 | |||
379 | static inline bool pll_is_valid(u64 val0, u64 val1, u64 min, u64 max) | ||
380 | { | ||
381 | return (val0 >= (val1 * min) && val0 <= (val1 * max)); | ||
382 | } | ||
383 | |||
384 | static inline u32 lpc32xx_usb_clk_read(struct lpc32xx_usb_clk *clk) | ||
385 | { | ||
386 | return readl(usb_clk_vbase + LPC32XX_USB_CLK_STS); | ||
387 | } | ||
388 | |||
389 | static inline void lpc32xx_usb_clk_write(struct lpc32xx_usb_clk *clk, u32 val) | ||
390 | { | ||
391 | writel(val, usb_clk_vbase + LPC32XX_USB_CLK_CTRL); | ||
392 | } | ||
393 | |||
394 | static int clk_mask_enable(struct clk_hw *hw) | ||
395 | { | ||
396 | struct lpc32xx_clk *clk = to_lpc32xx_clk(hw); | ||
397 | u32 val; | ||
398 | |||
399 | regmap_read(clk_regmap, clk->reg, &val); | ||
400 | |||
401 | if (clk->busy_mask && (val & clk->busy_mask) == clk->busy) | ||
402 | return -EBUSY; | ||
403 | |||
404 | return regmap_update_bits(clk_regmap, clk->reg, | ||
405 | clk->enable_mask, clk->enable); | ||
406 | } | ||
407 | |||
408 | static void clk_mask_disable(struct clk_hw *hw) | ||
409 | { | ||
410 | struct lpc32xx_clk *clk = to_lpc32xx_clk(hw); | ||
411 | |||
412 | regmap_update_bits(clk_regmap, clk->reg, | ||
413 | clk->disable_mask, clk->disable); | ||
414 | } | ||
415 | |||
416 | static int clk_mask_is_enabled(struct clk_hw *hw) | ||
417 | { | ||
418 | struct lpc32xx_clk *clk = to_lpc32xx_clk(hw); | ||
419 | u32 val; | ||
420 | |||
421 | regmap_read(clk_regmap, clk->reg, &val); | ||
422 | |||
423 | return ((val & clk->enable_mask) == clk->enable); | ||
424 | } | ||
425 | |||
426 | static const struct clk_ops clk_mask_ops = { | ||
427 | .enable = clk_mask_enable, | ||
428 | .disable = clk_mask_disable, | ||
429 | .is_enabled = clk_mask_is_enabled, | ||
430 | }; | ||
431 | |||
432 | static int clk_pll_enable(struct clk_hw *hw) | ||
433 | { | ||
434 | struct lpc32xx_pll_clk *clk = to_lpc32xx_pll_clk(hw); | ||
435 | u32 val, count; | ||
436 | |||
437 | regmap_update_bits(clk_regmap, clk->reg, clk->enable, clk->enable); | ||
438 | |||
439 | for (count = 0; count < 1000; count++) { | ||
440 | regmap_read(clk_regmap, clk->reg, &val); | ||
441 | if (val & PLL_CTRL_LOCK) | ||
442 | break; | ||
443 | } | ||
444 | |||
445 | if (val & PLL_CTRL_LOCK) | ||
446 | return 0; | ||
447 | |||
448 | return -ETIMEDOUT; | ||
449 | } | ||
450 | |||
451 | static void clk_pll_disable(struct clk_hw *hw) | ||
452 | { | ||
453 | struct lpc32xx_pll_clk *clk = to_lpc32xx_pll_clk(hw); | ||
454 | |||
455 | regmap_update_bits(clk_regmap, clk->reg, clk->enable, 0x0); | ||
456 | } | ||
457 | |||
458 | static int clk_pll_is_enabled(struct clk_hw *hw) | ||
459 | { | ||
460 | struct lpc32xx_pll_clk *clk = to_lpc32xx_pll_clk(hw); | ||
461 | u32 val; | ||
462 | |||
463 | regmap_read(clk_regmap, clk->reg, &val); | ||
464 | |||
465 | val &= clk->enable | PLL_CTRL_LOCK; | ||
466 | if (val == (clk->enable | PLL_CTRL_LOCK)) | ||
467 | return 1; | ||
468 | |||
469 | return 0; | ||
470 | } | ||
471 | |||
472 | static unsigned long clk_pll_397x_recalc_rate(struct clk_hw *hw, | ||
473 | unsigned long parent_rate) | ||
474 | { | ||
475 | return parent_rate * 397; | ||
476 | } | ||
477 | |||
478 | static unsigned long clk_pll_recalc_rate(struct clk_hw *hw, | ||
479 | unsigned long parent_rate) | ||
480 | { | ||
481 | struct lpc32xx_pll_clk *clk = to_lpc32xx_pll_clk(hw); | ||
482 | bool is_direct, is_bypass, is_feedback; | ||
483 | unsigned long rate, cco_rate, ref_rate; | ||
484 | u32 val; | ||
485 | |||
486 | regmap_read(clk_regmap, clk->reg, &val); | ||
487 | is_direct = val & PLL_CTRL_DIRECT; | ||
488 | is_bypass = val & PLL_CTRL_BYPASS; | ||
489 | is_feedback = val & PLL_CTRL_FEEDBACK; | ||
490 | |||
491 | clk->m_div = ((val & PLL_CTRL_FEEDDIV) >> 1) + 1; | ||
492 | clk->n_div = ((val & PLL_CTRL_PREDIV) >> 9) + 1; | ||
493 | clk->p_div = ((val & PLL_CTRL_POSTDIV) >> 11) + 1; | ||
494 | |||
495 | if (is_direct && is_bypass) { | ||
496 | clk->p_div = 0; | ||
497 | clk->mode = PLL_DIRECT_BYPASS; | ||
498 | return parent_rate; | ||
499 | } | ||
500 | if (is_bypass) { | ||
501 | clk->mode = PLL_BYPASS; | ||
502 | return parent_rate / (1 << clk->p_div); | ||
503 | } | ||
504 | if (is_direct) { | ||
505 | clk->p_div = 0; | ||
506 | clk->mode = PLL_DIRECT; | ||
507 | } | ||
508 | |||
509 | ref_rate = parent_rate / clk->n_div; | ||
510 | rate = cco_rate = ref_rate * clk->m_div; | ||
511 | |||
512 | if (!is_direct) { | ||
513 | if (is_feedback) { | ||
514 | cco_rate *= (1 << clk->p_div); | ||
515 | clk->mode = PLL_INTEGER; | ||
516 | } else { | ||
517 | rate /= (1 << clk->p_div); | ||
518 | clk->mode = PLL_NON_INTEGER; | ||
519 | } | ||
520 | } | ||
521 | |||
522 | pr_debug("%s: %lu: 0x%x: %d/%d/%d, %lu/%lu/%d => %lu\n", | ||
523 | clk_hw_get_name(hw), | ||
524 | parent_rate, val, is_direct, is_bypass, is_feedback, | ||
525 | clk->n_div, clk->m_div, (1 << clk->p_div), rate); | ||
526 | |||
527 | if (clk_pll_is_enabled(hw) && | ||
528 | !(pll_is_valid(parent_rate, 1, 1000000, 20000000) | ||
529 | && pll_is_valid(cco_rate, 1, 156000000, 320000000) | ||
530 | && pll_is_valid(ref_rate, 1, 1000000, 27000000))) | ||
531 | pr_err("%s: PLL clocks are not in valid ranges: %lu/%lu/%lu", | ||
532 | clk_hw_get_name(hw), | ||
533 | parent_rate, cco_rate, ref_rate); | ||
534 | |||
535 | return rate; | ||
536 | } | ||
537 | |||
538 | static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, | ||
539 | unsigned long parent_rate) | ||
540 | { | ||
541 | struct lpc32xx_pll_clk *clk = to_lpc32xx_pll_clk(hw); | ||
542 | u32 val; | ||
543 | unsigned long new_rate; | ||
544 | |||
545 | /* Validate PLL clock parameters computed on round rate stage */ | ||
546 | switch (clk->mode) { | ||
547 | case PLL_DIRECT: | ||
548 | val = PLL_CTRL_DIRECT; | ||
549 | val |= (clk->m_div - 1) << 1; | ||
550 | val |= (clk->n_div - 1) << 9; | ||
551 | new_rate = (parent_rate * clk->m_div) / clk->n_div; | ||
552 | break; | ||
553 | case PLL_BYPASS: | ||
554 | val = PLL_CTRL_BYPASS; | ||
555 | val |= (clk->p_div - 1) << 11; | ||
556 | new_rate = parent_rate / (1 << (clk->p_div)); | ||
557 | break; | ||
558 | case PLL_DIRECT_BYPASS: | ||
559 | val = PLL_CTRL_DIRECT | PLL_CTRL_BYPASS; | ||
560 | new_rate = parent_rate; | ||
561 | break; | ||
562 | case PLL_INTEGER: | ||
563 | val = PLL_CTRL_FEEDBACK; | ||
564 | val |= (clk->m_div - 1) << 1; | ||
565 | val |= (clk->n_div - 1) << 9; | ||
566 | val |= (clk->p_div - 1) << 11; | ||
567 | new_rate = (parent_rate * clk->m_div) / clk->n_div; | ||
568 | break; | ||
569 | case PLL_NON_INTEGER: | ||
570 | val = 0x0; | ||
571 | val |= (clk->m_div - 1) << 1; | ||
572 | val |= (clk->n_div - 1) << 9; | ||
573 | val |= (clk->p_div - 1) << 11; | ||
574 | new_rate = (parent_rate * clk->m_div) / | ||
575 | (clk->n_div * (1 << clk->p_div)); | ||
576 | break; | ||
577 | default: | ||
578 | return -EINVAL; | ||
579 | } | ||
580 | |||
581 | /* Sanity check that round rate is equal to the requested one */ | ||
582 | if (new_rate != rate) | ||
583 | return -EINVAL; | ||
584 | |||
585 | return regmap_update_bits(clk_regmap, clk->reg, 0x1FFFF, val); | ||
586 | } | ||
587 | |||
588 | static long clk_hclk_pll_round_rate(struct clk_hw *hw, unsigned long rate, | ||
589 | unsigned long *parent_rate) | ||
590 | { | ||
591 | struct lpc32xx_pll_clk *clk = to_lpc32xx_pll_clk(hw); | ||
592 | u64 m_i, m, n, p, o = rate, i = *parent_rate, d = (u64)rate << 6; | ||
593 | int p_i, n_i; | ||
594 | |||
595 | pr_debug("%s: %lu/%lu\n", clk_hw_get_name(hw), *parent_rate, rate); | ||
596 | |||
597 | if (rate > 266500000) | ||
598 | return -EINVAL; | ||
599 | |||
600 | /* Have to check all 20 possibilities to find the minimal M */ | ||
601 | for (p_i = 4; p_i >= 0; p_i--) { | ||
602 | for (n_i = 4; n_i > 0; n_i--) { | ||
603 | m_i = div64_u64(o * n_i * (1 << p_i), i); | ||
604 | |||
605 | /* Check for valid PLL parameter constraints */ | ||
606 | if (!(m_i && m_i <= 256 | ||
607 | && pll_is_valid(i, n_i, 1000000, 27000000) | ||
608 | && pll_is_valid(i * m_i * (1 << p_i), n_i, | ||
609 | 156000000, 320000000))) | ||
610 | continue; | ||
611 | |||
612 | /* Store some intermediate valid parameters */ | ||
613 | if (o * n_i * (1 << p_i) - i * m_i <= d) { | ||
614 | m = m_i; | ||
615 | n = n_i; | ||
616 | p = p_i; | ||
617 | d = o * n_i * (1 << p_i) - i * m_i; | ||
618 | } | ||
619 | } | ||
620 | } | ||
621 | |||
622 | if (d == (u64)rate << 6) { | ||
623 | pr_err("%s: %lu: no valid PLL parameters are found\n", | ||
624 | clk_hw_get_name(hw), rate); | ||
625 | return -EINVAL; | ||
626 | } | ||
627 | |||
628 | clk->m_div = m; | ||
629 | clk->n_div = n; | ||
630 | clk->p_div = p; | ||
631 | |||
632 | /* Set only direct or non-integer mode of PLL */ | ||
633 | if (!p) | ||
634 | clk->mode = PLL_DIRECT; | ||
635 | else | ||
636 | clk->mode = PLL_NON_INTEGER; | ||
637 | |||
638 | o = div64_u64(i * m, n * (1 << p)); | ||
639 | |||
640 | if (!d) | ||
641 | pr_debug("%s: %lu: found exact match: %llu/%llu/%llu\n", | ||
642 | clk_hw_get_name(hw), rate, m, n, p); | ||
643 | else | ||
644 | pr_debug("%s: %lu: found closest: %llu/%llu/%llu - %llu\n", | ||
645 | clk_hw_get_name(hw), rate, m, n, p, o); | ||
646 | |||
647 | return o; | ||
648 | } | ||
649 | |||
650 | static long clk_usb_pll_round_rate(struct clk_hw *hw, unsigned long rate, | ||
651 | unsigned long *parent_rate) | ||
652 | { | ||
653 | struct lpc32xx_pll_clk *clk = to_lpc32xx_pll_clk(hw); | ||
654 | struct clk_hw *usb_div_hw, *osc_hw; | ||
655 | u64 d_i, n_i, m, o; | ||
656 | |||
657 | pr_debug("%s: %lu/%lu\n", clk_hw_get_name(hw), *parent_rate, rate); | ||
658 | |||
659 | /* | ||
660 | * The only supported USB clock is 48MHz, with PLL internal constraints | ||
661 | * on Fclkin, Fcco and Fref this implies that Fcco must be 192MHz | ||
662 | * and post-divider must be 4, this slightly simplifies calculation of | ||
663 | * USB divider, USB PLL N and M parameters. | ||
664 | */ | ||
665 | if (rate != 48000000) | ||
666 | return -EINVAL; | ||
667 | |||
668 | /* USB divider clock */ | ||
669 | usb_div_hw = clk_hw_get_parent_by_index(hw, 0); | ||
670 | if (!usb_div_hw) | ||
671 | return -EINVAL; | ||
672 | |||
673 | /* Main oscillator clock */ | ||
674 | osc_hw = clk_hw_get_parent_by_index(usb_div_hw, 0); | ||
675 | if (!osc_hw) | ||
676 | return -EINVAL; | ||
677 | o = clk_hw_get_rate(osc_hw); /* must be in range 1..20 MHz */ | ||
678 | |||
679 | /* Check if valid USB divider and USB PLL parameters exists */ | ||
680 | for (d_i = 16; d_i >= 1; d_i--) { | ||
681 | for (n_i = 1; n_i <= 4; n_i++) { | ||
682 | m = div64_u64(192000000 * d_i * n_i, o); | ||
683 | if (!(m && m <= 256 | ||
684 | && m * o == 192000000 * d_i * n_i | ||
685 | && pll_is_valid(o, d_i, 1000000, 20000000) | ||
686 | && pll_is_valid(o, d_i * n_i, 1000000, 27000000))) | ||
687 | continue; | ||
688 | |||
689 | clk->n_div = n_i; | ||
690 | clk->m_div = m; | ||
691 | clk->p_div = 2; | ||
692 | clk->mode = PLL_NON_INTEGER; | ||
693 | *parent_rate = div64_u64(o, d_i); | ||
694 | |||
695 | return rate; | ||
696 | } | ||
697 | } | ||
698 | |||
699 | return -EINVAL; | ||
700 | } | ||
701 | |||
702 | #define LPC32XX_DEFINE_PLL_OPS(_name, _rc, _sr, _rr) \ | ||
703 | static const struct clk_ops clk_ ##_name ## _ops = { \ | ||
704 | .enable = clk_pll_enable, \ | ||
705 | .disable = clk_pll_disable, \ | ||
706 | .is_enabled = clk_pll_is_enabled, \ | ||
707 | .recalc_rate = _rc, \ | ||
708 | .set_rate = _sr, \ | ||
709 | .round_rate = _rr, \ | ||
710 | } | ||
711 | |||
712 | LPC32XX_DEFINE_PLL_OPS(pll_397x, clk_pll_397x_recalc_rate, NULL, NULL); | ||
713 | LPC32XX_DEFINE_PLL_OPS(hclk_pll, clk_pll_recalc_rate, | ||
714 | clk_pll_set_rate, clk_hclk_pll_round_rate); | ||
715 | LPC32XX_DEFINE_PLL_OPS(usb_pll, clk_pll_recalc_rate, | ||
716 | clk_pll_set_rate, clk_usb_pll_round_rate); | ||
717 | |||
718 | static int clk_ddram_is_enabled(struct clk_hw *hw) | ||
719 | { | ||
720 | struct lpc32xx_clk *clk = to_lpc32xx_clk(hw); | ||
721 | u32 val; | ||
722 | |||
723 | regmap_read(clk_regmap, clk->reg, &val); | ||
724 | val &= clk->enable_mask | clk->busy_mask; | ||
725 | |||
726 | return (val == (BIT(7) | BIT(0)) || | ||
727 | val == (BIT(8) | BIT(1))); | ||
728 | } | ||
729 | |||
730 | static int clk_ddram_enable(struct clk_hw *hw) | ||
731 | { | ||
732 | struct lpc32xx_clk *clk = to_lpc32xx_clk(hw); | ||
733 | u32 val, hclk_div; | ||
734 | |||
735 | regmap_read(clk_regmap, clk->reg, &val); | ||
736 | hclk_div = val & clk->busy_mask; | ||
737 | |||
738 | /* | ||
739 | * DDRAM clock must be 2 times higher than HCLK, | ||
740 | * this implies DDRAM clock can not be enabled, | ||
741 | * if HCLK clock rate is equal to ARM clock rate | ||
742 | */ | ||
743 | if (hclk_div == 0x0 || hclk_div == (BIT(1) | BIT(0))) | ||
744 | return -EINVAL; | ||
745 | |||
746 | return regmap_update_bits(clk_regmap, clk->reg, | ||
747 | clk->enable_mask, hclk_div << 7); | ||
748 | } | ||
749 | |||
750 | static unsigned long clk_ddram_recalc_rate(struct clk_hw *hw, | ||
751 | unsigned long parent_rate) | ||
752 | { | ||
753 | struct lpc32xx_clk *clk = to_lpc32xx_clk(hw); | ||
754 | u32 val; | ||
755 | |||
756 | if (!clk_ddram_is_enabled(hw)) | ||
757 | return 0; | ||
758 | |||
759 | regmap_read(clk_regmap, clk->reg, &val); | ||
760 | val &= clk->enable_mask; | ||
761 | |||
762 | return parent_rate / (val >> 7); | ||
763 | } | ||
764 | |||
765 | static const struct clk_ops clk_ddram_ops = { | ||
766 | .enable = clk_ddram_enable, | ||
767 | .disable = clk_mask_disable, | ||
768 | .is_enabled = clk_ddram_is_enabled, | ||
769 | .recalc_rate = clk_ddram_recalc_rate, | ||
770 | }; | ||
771 | |||
772 | static unsigned long lpc32xx_clk_uart_recalc_rate(struct clk_hw *hw, | ||
773 | unsigned long parent_rate) | ||
774 | { | ||
775 | struct lpc32xx_clk *clk = to_lpc32xx_clk(hw); | ||
776 | u32 val, x, y; | ||
777 | |||
778 | regmap_read(clk_regmap, clk->reg, &val); | ||
779 | x = (val & 0xFF00) >> 8; | ||
780 | y = val & 0xFF; | ||
781 | |||
782 | if (x && y) | ||
783 | return (parent_rate * x) / y; | ||
784 | else | ||
785 | return 0; | ||
786 | } | ||
787 | |||
788 | static const struct clk_ops lpc32xx_uart_div_ops = { | ||
789 | .recalc_rate = lpc32xx_clk_uart_recalc_rate, | ||
790 | }; | ||
791 | |||
792 | static const struct clk_div_table clk_hclk_div_table[] = { | ||
793 | { .val = 0, .div = 1 }, | ||
794 | { .val = 1, .div = 2 }, | ||
795 | { .val = 2, .div = 4 }, | ||
796 | { }, | ||
797 | }; | ||
798 | |||
799 | static u32 test1_mux_table[] = { 0, 1, 2, }; | ||
800 | static u32 test2_mux_table[] = { 0, 1, 2, 5, 7, }; | ||
801 | |||
802 | static int clk_usb_enable(struct clk_hw *hw) | ||
803 | { | ||
804 | struct lpc32xx_usb_clk *clk = to_lpc32xx_usb_clk(hw); | ||
805 | u32 val, ctrl_val, count; | ||
806 | |||
807 | pr_debug("%s: 0x%x\n", clk_hw_get_name(hw), clk->enable); | ||
808 | |||
809 | if (clk->ctrl_mask) { | ||
810 | regmap_read(clk_regmap, LPC32XX_CLKPWR_USB_CTRL, &ctrl_val); | ||
811 | regmap_update_bits(clk_regmap, LPC32XX_CLKPWR_USB_CTRL, | ||
812 | clk->ctrl_mask, clk->ctrl_enable); | ||
813 | } | ||
814 | |||
815 | val = lpc32xx_usb_clk_read(clk); | ||
816 | if (clk->busy && (val & clk->busy) == clk->busy) { | ||
817 | if (clk->ctrl_mask) | ||
818 | regmap_write(clk_regmap, LPC32XX_CLKPWR_USB_CTRL, | ||
819 | ctrl_val); | ||
820 | return -EBUSY; | ||
821 | } | ||
822 | |||
823 | val |= clk->enable; | ||
824 | lpc32xx_usb_clk_write(clk, val); | ||
825 | |||
826 | for (count = 0; count < 1000; count++) { | ||
827 | val = lpc32xx_usb_clk_read(clk); | ||
828 | if ((val & clk->enable) == clk->enable) | ||
829 | break; | ||
830 | } | ||
831 | |||
832 | if ((val & clk->enable) == clk->enable) | ||
833 | return 0; | ||
834 | |||
835 | if (clk->ctrl_mask) | ||
836 | regmap_write(clk_regmap, LPC32XX_CLKPWR_USB_CTRL, ctrl_val); | ||
837 | |||
838 | return -ETIMEDOUT; | ||
839 | } | ||
840 | |||
841 | static void clk_usb_disable(struct clk_hw *hw) | ||
842 | { | ||
843 | struct lpc32xx_usb_clk *clk = to_lpc32xx_usb_clk(hw); | ||
844 | u32 val = lpc32xx_usb_clk_read(clk); | ||
845 | |||
846 | val &= ~clk->enable; | ||
847 | lpc32xx_usb_clk_write(clk, val); | ||
848 | |||
849 | if (clk->ctrl_mask) | ||
850 | regmap_update_bits(clk_regmap, LPC32XX_CLKPWR_USB_CTRL, | ||
851 | clk->ctrl_mask, clk->ctrl_disable); | ||
852 | } | ||
853 | |||
854 | static int clk_usb_is_enabled(struct clk_hw *hw) | ||
855 | { | ||
856 | struct lpc32xx_usb_clk *clk = to_lpc32xx_usb_clk(hw); | ||
857 | u32 ctrl_val, val; | ||
858 | |||
859 | if (clk->ctrl_mask) { | ||
860 | regmap_read(clk_regmap, LPC32XX_CLKPWR_USB_CTRL, &ctrl_val); | ||
861 | if ((ctrl_val & clk->ctrl_mask) != clk->ctrl_enable) | ||
862 | return 0; | ||
863 | } | ||
864 | |||
865 | val = lpc32xx_usb_clk_read(clk); | ||
866 | |||
867 | return ((val & clk->enable) == clk->enable); | ||
868 | } | ||
869 | |||
870 | static unsigned long clk_usb_i2c_recalc_rate(struct clk_hw *hw, | ||
871 | unsigned long parent_rate) | ||
872 | { | ||
873 | return clk_get_rate(clk[LPC32XX_CLK_PERIPH]); | ||
874 | } | ||
875 | |||
876 | static const struct clk_ops clk_usb_ops = { | ||
877 | .enable = clk_usb_enable, | ||
878 | .disable = clk_usb_disable, | ||
879 | .is_enabled = clk_usb_is_enabled, | ||
880 | }; | ||
881 | |||
882 | static const struct clk_ops clk_usb_i2c_ops = { | ||
883 | .enable = clk_usb_enable, | ||
884 | .disable = clk_usb_disable, | ||
885 | .is_enabled = clk_usb_is_enabled, | ||
886 | .recalc_rate = clk_usb_i2c_recalc_rate, | ||
887 | }; | ||
888 | |||
889 | static int clk_gate_enable(struct clk_hw *hw) | ||
890 | { | ||
891 | struct lpc32xx_clk_gate *clk = to_lpc32xx_gate(hw); | ||
892 | u32 mask = BIT(clk->bit_idx); | ||
893 | u32 val = (clk->flags & CLK_GATE_SET_TO_DISABLE ? 0x0 : mask); | ||
894 | |||
895 | return regmap_update_bits(clk_regmap, clk->reg, mask, val); | ||
896 | } | ||
897 | |||
898 | static void clk_gate_disable(struct clk_hw *hw) | ||
899 | { | ||
900 | struct lpc32xx_clk_gate *clk = to_lpc32xx_gate(hw); | ||
901 | u32 mask = BIT(clk->bit_idx); | ||
902 | u32 val = (clk->flags & CLK_GATE_SET_TO_DISABLE ? mask : 0x0); | ||
903 | |||
904 | regmap_update_bits(clk_regmap, clk->reg, mask, val); | ||
905 | } | ||
906 | |||
907 | static int clk_gate_is_enabled(struct clk_hw *hw) | ||
908 | { | ||
909 | struct lpc32xx_clk_gate *clk = to_lpc32xx_gate(hw); | ||
910 | u32 val; | ||
911 | bool is_set; | ||
912 | |||
913 | regmap_read(clk_regmap, clk->reg, &val); | ||
914 | is_set = val & BIT(clk->bit_idx); | ||
915 | |||
916 | return (clk->flags & CLK_GATE_SET_TO_DISABLE ? !is_set : is_set); | ||
917 | } | ||
918 | |||
919 | static const struct clk_ops lpc32xx_clk_gate_ops = { | ||
920 | .enable = clk_gate_enable, | ||
921 | .disable = clk_gate_disable, | ||
922 | .is_enabled = clk_gate_is_enabled, | ||
923 | }; | ||
924 | |||
925 | #define div_mask(width) ((1 << (width)) - 1) | ||
926 | |||
927 | static unsigned int _get_table_div(const struct clk_div_table *table, | ||
928 | unsigned int val) | ||
929 | { | ||
930 | const struct clk_div_table *clkt; | ||
931 | |||
932 | for (clkt = table; clkt->div; clkt++) | ||
933 | if (clkt->val == val) | ||
934 | return clkt->div; | ||
935 | return 0; | ||
936 | } | ||
937 | |||
938 | static unsigned int _get_div(const struct clk_div_table *table, | ||
939 | unsigned int val, unsigned long flags, u8 width) | ||
940 | { | ||
941 | if (flags & CLK_DIVIDER_ONE_BASED) | ||
942 | return val; | ||
943 | if (table) | ||
944 | return _get_table_div(table, val); | ||
945 | return val + 1; | ||
946 | } | ||
947 | |||
948 | static unsigned long clk_divider_recalc_rate(struct clk_hw *hw, | ||
949 | unsigned long parent_rate) | ||
950 | { | ||
951 | struct lpc32xx_clk_div *divider = to_lpc32xx_div(hw); | ||
952 | unsigned int val; | ||
953 | |||
954 | regmap_read(clk_regmap, divider->reg, &val); | ||
955 | |||
956 | val >>= divider->shift; | ||
957 | val &= div_mask(divider->width); | ||
958 | |||
959 | return divider_recalc_rate(hw, parent_rate, val, divider->table, | ||
960 | divider->flags); | ||
961 | } | ||
962 | |||
963 | static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate, | ||
964 | unsigned long *prate) | ||
965 | { | ||
966 | struct lpc32xx_clk_div *divider = to_lpc32xx_div(hw); | ||
967 | unsigned int bestdiv; | ||
968 | |||
969 | /* if read only, just return current value */ | ||
970 | if (divider->flags & CLK_DIVIDER_READ_ONLY) { | ||
971 | regmap_read(clk_regmap, divider->reg, &bestdiv); | ||
972 | bestdiv >>= divider->shift; | ||
973 | bestdiv &= div_mask(divider->width); | ||
974 | bestdiv = _get_div(divider->table, bestdiv, divider->flags, | ||
975 | divider->width); | ||
976 | return DIV_ROUND_UP(*prate, bestdiv); | ||
977 | } | ||
978 | |||
979 | return divider_round_rate(hw, rate, prate, divider->table, | ||
980 | divider->width, divider->flags); | ||
981 | } | ||
982 | |||
983 | static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate, | ||
984 | unsigned long parent_rate) | ||
985 | { | ||
986 | struct lpc32xx_clk_div *divider = to_lpc32xx_div(hw); | ||
987 | unsigned int value; | ||
988 | |||
989 | value = divider_get_val(rate, parent_rate, divider->table, | ||
990 | divider->width, divider->flags); | ||
991 | |||
992 | return regmap_update_bits(clk_regmap, divider->reg, | ||
993 | div_mask(divider->width) << divider->shift, | ||
994 | value << divider->shift); | ||
995 | } | ||
996 | |||
997 | static const struct clk_ops lpc32xx_clk_divider_ops = { | ||
998 | .recalc_rate = clk_divider_recalc_rate, | ||
999 | .round_rate = clk_divider_round_rate, | ||
1000 | .set_rate = clk_divider_set_rate, | ||
1001 | }; | ||
1002 | |||
1003 | static u8 clk_mux_get_parent(struct clk_hw *hw) | ||
1004 | { | ||
1005 | struct lpc32xx_clk_mux *mux = to_lpc32xx_mux(hw); | ||
1006 | u32 num_parents = clk_hw_get_num_parents(hw); | ||
1007 | u32 val; | ||
1008 | |||
1009 | regmap_read(clk_regmap, mux->reg, &val); | ||
1010 | val >>= mux->shift; | ||
1011 | val &= mux->mask; | ||
1012 | |||
1013 | if (mux->table) { | ||
1014 | u32 i; | ||
1015 | |||
1016 | for (i = 0; i < num_parents; i++) | ||
1017 | if (mux->table[i] == val) | ||
1018 | return i; | ||
1019 | return -EINVAL; | ||
1020 | } | ||
1021 | |||
1022 | if (val >= num_parents) | ||
1023 | return -EINVAL; | ||
1024 | |||
1025 | return val; | ||
1026 | } | ||
1027 | |||
1028 | static int clk_mux_set_parent(struct clk_hw *hw, u8 index) | ||
1029 | { | ||
1030 | struct lpc32xx_clk_mux *mux = to_lpc32xx_mux(hw); | ||
1031 | |||
1032 | if (mux->table) | ||
1033 | index = mux->table[index]; | ||
1034 | |||
1035 | return regmap_update_bits(clk_regmap, mux->reg, | ||
1036 | mux->mask << mux->shift, index << mux->shift); | ||
1037 | } | ||
1038 | |||
1039 | static const struct clk_ops lpc32xx_clk_mux_ro_ops = { | ||
1040 | .get_parent = clk_mux_get_parent, | ||
1041 | }; | ||
1042 | |||
1043 | static const struct clk_ops lpc32xx_clk_mux_ops = { | ||
1044 | .get_parent = clk_mux_get_parent, | ||
1045 | .set_parent = clk_mux_set_parent, | ||
1046 | .determine_rate = __clk_mux_determine_rate, | ||
1047 | }; | ||
1048 | |||
1049 | enum lpc32xx_clk_type { | ||
1050 | CLK_FIXED, | ||
1051 | CLK_MUX, | ||
1052 | CLK_DIV, | ||
1053 | CLK_GATE, | ||
1054 | CLK_COMPOSITE, | ||
1055 | CLK_LPC32XX, | ||
1056 | CLK_LPC32XX_PLL, | ||
1057 | CLK_LPC32XX_USB, | ||
1058 | }; | ||
1059 | |||
1060 | struct clk_hw_proto0 { | ||
1061 | const struct clk_ops *ops; | ||
1062 | union { | ||
1063 | struct lpc32xx_pll_clk pll; | ||
1064 | struct lpc32xx_clk clk; | ||
1065 | struct lpc32xx_usb_clk usb_clk; | ||
1066 | struct lpc32xx_clk_mux mux; | ||
1067 | struct lpc32xx_clk_div div; | ||
1068 | struct lpc32xx_clk_gate gate; | ||
1069 | }; | ||
1070 | }; | ||
1071 | |||
1072 | struct clk_hw_proto1 { | ||
1073 | struct clk_hw_proto0 *mux; | ||
1074 | struct clk_hw_proto0 *div; | ||
1075 | struct clk_hw_proto0 *gate; | ||
1076 | }; | ||
1077 | |||
1078 | struct clk_hw_proto { | ||
1079 | enum lpc32xx_clk_type type; | ||
1080 | |||
1081 | union { | ||
1082 | struct clk_fixed_rate f; | ||
1083 | struct clk_hw_proto0 hw0; | ||
1084 | struct clk_hw_proto1 hw1; | ||
1085 | }; | ||
1086 | }; | ||
1087 | |||
1088 | #define LPC32XX_DEFINE_FIXED(_idx, _rate, _flags) \ | ||
1089 | [CLK_PREFIX(_idx)] = { \ | ||
1090 | .type = CLK_FIXED, \ | ||
1091 | { \ | ||
1092 | .f = { \ | ||
1093 | .fixed_rate = (_rate), \ | ||
1094 | .flags = (_flags), \ | ||
1095 | }, \ | ||
1096 | }, \ | ||
1097 | } | ||
1098 | |||
1099 | #define LPC32XX_DEFINE_PLL(_idx, _name, _reg, _enable) \ | ||
1100 | [CLK_PREFIX(_idx)] = { \ | ||
1101 | .type = CLK_LPC32XX_PLL, \ | ||
1102 | { \ | ||
1103 | .hw0 = { \ | ||
1104 | .ops = &clk_ ##_name ## _ops, \ | ||
1105 | { \ | ||
1106 | .pll = { \ | ||
1107 | .reg = LPC32XX_CLKPWR_ ## _reg, \ | ||
1108 | .enable = (_enable), \ | ||
1109 | }, \ | ||
1110 | }, \ | ||
1111 | }, \ | ||
1112 | }, \ | ||
1113 | } | ||
1114 | |||
1115 | #define LPC32XX_DEFINE_MUX(_idx, _reg, _shift, _mask, _table, _flags) \ | ||
1116 | [CLK_PREFIX(_idx)] = { \ | ||
1117 | .type = CLK_MUX, \ | ||
1118 | { \ | ||
1119 | .hw0 = { \ | ||
1120 | .ops = (_flags & CLK_MUX_READ_ONLY ? \ | ||
1121 | &lpc32xx_clk_mux_ro_ops : \ | ||
1122 | &lpc32xx_clk_mux_ops), \ | ||
1123 | { \ | ||
1124 | .mux = { \ | ||
1125 | .reg = LPC32XX_CLKPWR_ ## _reg, \ | ||
1126 | .mask = (_mask), \ | ||
1127 | .shift = (_shift), \ | ||
1128 | .table = (_table), \ | ||
1129 | .flags = (_flags), \ | ||
1130 | }, \ | ||
1131 | }, \ | ||
1132 | }, \ | ||
1133 | }, \ | ||
1134 | } | ||
1135 | |||
1136 | #define LPC32XX_DEFINE_DIV(_idx, _reg, _shift, _width, _table, _flags) \ | ||
1137 | [CLK_PREFIX(_idx)] = { \ | ||
1138 | .type = CLK_DIV, \ | ||
1139 | { \ | ||
1140 | .hw0 = { \ | ||
1141 | .ops = &lpc32xx_clk_divider_ops, \ | ||
1142 | { \ | ||
1143 | .div = { \ | ||
1144 | .reg = LPC32XX_CLKPWR_ ## _reg, \ | ||
1145 | .shift = (_shift), \ | ||
1146 | .width = (_width), \ | ||
1147 | .table = (_table), \ | ||
1148 | .flags = (_flags), \ | ||
1149 | }, \ | ||
1150 | }, \ | ||
1151 | }, \ | ||
1152 | }, \ | ||
1153 | } | ||
1154 | |||
1155 | #define LPC32XX_DEFINE_GATE(_idx, _reg, _bit, _flags) \ | ||
1156 | [CLK_PREFIX(_idx)] = { \ | ||
1157 | .type = CLK_GATE, \ | ||
1158 | { \ | ||
1159 | .hw0 = { \ | ||
1160 | .ops = &lpc32xx_clk_gate_ops, \ | ||
1161 | { \ | ||
1162 | .gate = { \ | ||
1163 | .reg = LPC32XX_CLKPWR_ ## _reg, \ | ||
1164 | .bit_idx = (_bit), \ | ||
1165 | .flags = (_flags), \ | ||
1166 | }, \ | ||
1167 | }, \ | ||
1168 | }, \ | ||
1169 | }, \ | ||
1170 | } | ||
1171 | |||
1172 | #define LPC32XX_DEFINE_CLK(_idx, _reg, _e, _em, _d, _dm, _b, _bm, _ops) \ | ||
1173 | [CLK_PREFIX(_idx)] = { \ | ||
1174 | .type = CLK_LPC32XX, \ | ||
1175 | { \ | ||
1176 | .hw0 = { \ | ||
1177 | .ops = &(_ops), \ | ||
1178 | { \ | ||
1179 | .clk = { \ | ||
1180 | .reg = LPC32XX_CLKPWR_ ## _reg, \ | ||
1181 | .enable = (_e), \ | ||
1182 | .enable_mask = (_em), \ | ||
1183 | .disable = (_d), \ | ||
1184 | .disable_mask = (_dm), \ | ||
1185 | .busy = (_b), \ | ||
1186 | .busy_mask = (_bm), \ | ||
1187 | }, \ | ||
1188 | }, \ | ||
1189 | }, \ | ||
1190 | }, \ | ||
1191 | } | ||
1192 | |||
1193 | #define LPC32XX_DEFINE_USB(_idx, _ce, _cd, _cm, _e, _b, _ops) \ | ||
1194 | [CLK_PREFIX(_idx)] = { \ | ||
1195 | .type = CLK_LPC32XX_USB, \ | ||
1196 | { \ | ||
1197 | .hw0 = { \ | ||
1198 | .ops = &(_ops), \ | ||
1199 | { \ | ||
1200 | .usb_clk = { \ | ||
1201 | .ctrl_enable = (_ce), \ | ||
1202 | .ctrl_disable = (_cd), \ | ||
1203 | .ctrl_mask = (_cm), \ | ||
1204 | .enable = (_e), \ | ||
1205 | .busy = (_b), \ | ||
1206 | } \ | ||
1207 | }, \ | ||
1208 | } \ | ||
1209 | }, \ | ||
1210 | } | ||
1211 | |||
1212 | #define LPC32XX_DEFINE_COMPOSITE(_idx, _mux, _div, _gate) \ | ||
1213 | [CLK_PREFIX(_idx)] = { \ | ||
1214 | .type = CLK_COMPOSITE, \ | ||
1215 | { \ | ||
1216 | .hw1 = { \ | ||
1217 | .mux = (CLK_PREFIX(_mux) == LPC32XX_CLK__NULL ? NULL : \ | ||
1218 | &clk_hw_proto[CLK_PREFIX(_mux)].hw0), \ | ||
1219 | .div = (CLK_PREFIX(_div) == LPC32XX_CLK__NULL ? NULL : \ | ||
1220 | &clk_hw_proto[CLK_PREFIX(_div)].hw0), \ | ||
1221 | .gate = (CLK_PREFIX(_gate) == LPC32XX_CLK__NULL ? NULL :\ | ||
1222 | &clk_hw_proto[CLK_PREFIX(_gate)].hw0), \ | ||
1223 | }, \ | ||
1224 | }, \ | ||
1225 | } | ||
1226 | |||
1227 | static struct clk_hw_proto clk_hw_proto[LPC32XX_CLK_HW_MAX] = { | ||
1228 | LPC32XX_DEFINE_FIXED(RTC, 32768, 0), | ||
1229 | LPC32XX_DEFINE_PLL(PLL397X, pll_397x, HCLKPLL_CTRL, BIT(1)), | ||
1230 | LPC32XX_DEFINE_PLL(HCLK_PLL, hclk_pll, HCLKPLL_CTRL, PLL_CTRL_ENABLE), | ||
1231 | LPC32XX_DEFINE_PLL(USB_PLL, usb_pll, USB_CTRL, PLL_CTRL_ENABLE), | ||
1232 | LPC32XX_DEFINE_GATE(OSC, OSC_CTRL, 0, CLK_GATE_SET_TO_DISABLE), | ||
1233 | LPC32XX_DEFINE_GATE(USB, USB_CTRL, 18, 0), | ||
1234 | |||
1235 | LPC32XX_DEFINE_DIV(HCLK_DIV_PERIPH, HCLKDIV_CTRL, 2, 5, NULL, | ||
1236 | CLK_DIVIDER_READ_ONLY), | ||
1237 | LPC32XX_DEFINE_DIV(HCLK_DIV, HCLKDIV_CTRL, 0, 2, clk_hclk_div_table, | ||
1238 | CLK_DIVIDER_READ_ONLY), | ||
1239 | |||
1240 | /* Register 3 read-only muxes with a single control PWR_CTRL[2] */ | ||
1241 | LPC32XX_DEFINE_MUX(SYSCLK_PERIPH_MUX, PWR_CTRL, 2, 0x1, NULL, | ||
1242 | CLK_MUX_READ_ONLY), | ||
1243 | LPC32XX_DEFINE_MUX(SYSCLK_HCLK_MUX, PWR_CTRL, 2, 0x1, NULL, | ||
1244 | CLK_MUX_READ_ONLY), | ||
1245 | LPC32XX_DEFINE_MUX(SYSCLK_ARM_MUX, PWR_CTRL, 2, 0x1, NULL, | ||
1246 | CLK_MUX_READ_ONLY), | ||
1247 | /* Register 2 read-only muxes with a single control PWR_CTRL[10] */ | ||
1248 | LPC32XX_DEFINE_MUX(PERIPH_HCLK_MUX, PWR_CTRL, 10, 0x1, NULL, | ||
1249 | CLK_MUX_READ_ONLY), | ||
1250 | LPC32XX_DEFINE_MUX(PERIPH_ARM_MUX, PWR_CTRL, 10, 0x1, NULL, | ||
1251 | CLK_MUX_READ_ONLY), | ||
1252 | |||
1253 | /* 3 always on gates with a single control PWR_CTRL[0] same as OSC */ | ||
1254 | LPC32XX_DEFINE_GATE(PERIPH, PWR_CTRL, 0, CLK_GATE_SET_TO_DISABLE), | ||
1255 | LPC32XX_DEFINE_GATE(HCLK, PWR_CTRL, 0, CLK_GATE_SET_TO_DISABLE), | ||
1256 | LPC32XX_DEFINE_GATE(ARM, PWR_CTRL, 0, CLK_GATE_SET_TO_DISABLE), | ||
1257 | |||
1258 | LPC32XX_DEFINE_GATE(ARM_VFP, DEBUG_CTRL, 4, 0), | ||
1259 | LPC32XX_DEFINE_GATE(DMA, DMA_CLK_CTRL, 0, 0), | ||
1260 | LPC32XX_DEFINE_CLK(DDRAM, HCLKDIV_CTRL, 0x0, BIT(8) | BIT(7), | ||
1261 | 0x0, BIT(8) | BIT(7), 0x0, BIT(1) | BIT(0), clk_ddram_ops), | ||
1262 | |||
1263 | LPC32XX_DEFINE_GATE(TIMER0, TIMCLK_CTRL1, 2, 0), | ||
1264 | LPC32XX_DEFINE_GATE(TIMER1, TIMCLK_CTRL1, 3, 0), | ||
1265 | LPC32XX_DEFINE_GATE(TIMER2, TIMCLK_CTRL1, 4, 0), | ||
1266 | LPC32XX_DEFINE_GATE(TIMER3, TIMCLK_CTRL1, 5, 0), | ||
1267 | LPC32XX_DEFINE_GATE(TIMER4, TIMCLK_CTRL1, 0, 0), | ||
1268 | LPC32XX_DEFINE_GATE(TIMER5, TIMCLK_CTRL1, 1, 0), | ||
1269 | |||
1270 | LPC32XX_DEFINE_GATE(SSP0, SSP_CTRL, 0, 0), | ||
1271 | LPC32XX_DEFINE_GATE(SSP1, SSP_CTRL, 1, 0), | ||
1272 | LPC32XX_DEFINE_GATE(SPI1, SPI_CTRL, 0, 0), | ||
1273 | LPC32XX_DEFINE_GATE(SPI2, SPI_CTRL, 4, 0), | ||
1274 | LPC32XX_DEFINE_GATE(I2S0, I2S_CTRL, 0, 0), | ||
1275 | LPC32XX_DEFINE_GATE(I2S1, I2S_CTRL, 1, 0), | ||
1276 | LPC32XX_DEFINE_GATE(I2C1, I2CCLK_CTRL, 0, 0), | ||
1277 | LPC32XX_DEFINE_GATE(I2C2, I2CCLK_CTRL, 1, 0), | ||
1278 | LPC32XX_DEFINE_GATE(WDOG, TIMCLK_CTRL, 0, 0), | ||
1279 | LPC32XX_DEFINE_GATE(HSTIMER, TIMCLK_CTRL, 1, 0), | ||
1280 | |||
1281 | LPC32XX_DEFINE_GATE(KEY, KEYCLK_CTRL, 0, 0), | ||
1282 | LPC32XX_DEFINE_GATE(MCPWM, TIMCLK_CTRL1, 6, 0), | ||
1283 | |||
1284 | LPC32XX_DEFINE_MUX(PWM1_MUX, PWMCLK_CTRL, 1, 0x1, NULL, 0), | ||
1285 | LPC32XX_DEFINE_DIV(PWM1_DIV, PWMCLK_CTRL, 4, 4, NULL, | ||
1286 | CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO), | ||
1287 | LPC32XX_DEFINE_GATE(PWM1_GATE, PWMCLK_CTRL, 0, 0), | ||
1288 | LPC32XX_DEFINE_COMPOSITE(PWM1, PWM1_MUX, PWM1_DIV, PWM1_GATE), | ||
1289 | |||
1290 | LPC32XX_DEFINE_MUX(PWM2_MUX, PWMCLK_CTRL, 3, 0x1, NULL, 0), | ||
1291 | LPC32XX_DEFINE_DIV(PWM2_DIV, PWMCLK_CTRL, 8, 4, NULL, | ||
1292 | CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO), | ||
1293 | LPC32XX_DEFINE_GATE(PWM2_GATE, PWMCLK_CTRL, 2, 0), | ||
1294 | LPC32XX_DEFINE_COMPOSITE(PWM2, PWM2_MUX, PWM2_DIV, PWM2_GATE), | ||
1295 | |||
1296 | LPC32XX_DEFINE_MUX(UART3_MUX, UART3_CLK_CTRL, 16, 0x1, NULL, 0), | ||
1297 | LPC32XX_DEFINE_CLK(UART3_DIV, UART3_CLK_CTRL, | ||
1298 | 0, 0, 0, 0, 0, 0, lpc32xx_uart_div_ops), | ||
1299 | LPC32XX_DEFINE_GATE(UART3_GATE, UART_CLK_CTRL, 0, 0), | ||
1300 | LPC32XX_DEFINE_COMPOSITE(UART3, UART3_MUX, UART3_DIV, UART3_GATE), | ||
1301 | |||
1302 | LPC32XX_DEFINE_MUX(UART4_MUX, UART4_CLK_CTRL, 16, 0x1, NULL, 0), | ||
1303 | LPC32XX_DEFINE_CLK(UART4_DIV, UART4_CLK_CTRL, | ||
1304 | 0, 0, 0, 0, 0, 0, lpc32xx_uart_div_ops), | ||
1305 | LPC32XX_DEFINE_GATE(UART4_GATE, UART_CLK_CTRL, 1, 0), | ||
1306 | LPC32XX_DEFINE_COMPOSITE(UART4, UART4_MUX, UART4_DIV, UART4_GATE), | ||
1307 | |||
1308 | LPC32XX_DEFINE_MUX(UART5_MUX, UART5_CLK_CTRL, 16, 0x1, NULL, 0), | ||
1309 | LPC32XX_DEFINE_CLK(UART5_DIV, UART5_CLK_CTRL, | ||
1310 | 0, 0, 0, 0, 0, 0, lpc32xx_uart_div_ops), | ||
1311 | LPC32XX_DEFINE_GATE(UART5_GATE, UART_CLK_CTRL, 2, 0), | ||
1312 | LPC32XX_DEFINE_COMPOSITE(UART5, UART5_MUX, UART5_DIV, UART5_GATE), | ||
1313 | |||
1314 | LPC32XX_DEFINE_MUX(UART6_MUX, UART6_CLK_CTRL, 16, 0x1, NULL, 0), | ||
1315 | LPC32XX_DEFINE_CLK(UART6_DIV, UART6_CLK_CTRL, | ||
1316 | 0, 0, 0, 0, 0, 0, lpc32xx_uart_div_ops), | ||
1317 | LPC32XX_DEFINE_GATE(UART6_GATE, UART_CLK_CTRL, 3, 0), | ||
1318 | LPC32XX_DEFINE_COMPOSITE(UART6, UART6_MUX, UART6_DIV, UART6_GATE), | ||
1319 | |||
1320 | LPC32XX_DEFINE_CLK(IRDA, IRDA_CLK_CTRL, | ||
1321 | 0, 0, 0, 0, 0, 0, lpc32xx_uart_div_ops), | ||
1322 | |||
1323 | LPC32XX_DEFINE_MUX(TEST1_MUX, TEST_CLK_CTRL, 5, 0x3, | ||
1324 | test1_mux_table, 0), | ||
1325 | LPC32XX_DEFINE_GATE(TEST1_GATE, TEST_CLK_CTRL, 4, 0), | ||
1326 | LPC32XX_DEFINE_COMPOSITE(TEST1, TEST1_MUX, _NULL, TEST1_GATE), | ||
1327 | |||
1328 | LPC32XX_DEFINE_MUX(TEST2_MUX, TEST_CLK_CTRL, 1, 0x7, | ||
1329 | test2_mux_table, 0), | ||
1330 | LPC32XX_DEFINE_GATE(TEST2_GATE, TEST_CLK_CTRL, 0, 0), | ||
1331 | LPC32XX_DEFINE_COMPOSITE(TEST2, TEST2_MUX, _NULL, TEST2_GATE), | ||
1332 | |||
1333 | LPC32XX_DEFINE_MUX(SYS, SYSCLK_CTRL, 0, 0x1, NULL, CLK_MUX_READ_ONLY), | ||
1334 | |||
1335 | LPC32XX_DEFINE_DIV(USB_DIV_DIV, USB_DIV, 0, 4, NULL, 0), | ||
1336 | LPC32XX_DEFINE_GATE(USB_DIV_GATE, USB_CTRL, 17, 0), | ||
1337 | LPC32XX_DEFINE_COMPOSITE(USB_DIV, _NULL, USB_DIV_DIV, USB_DIV_GATE), | ||
1338 | |||
1339 | LPC32XX_DEFINE_DIV(SD_DIV, MS_CTRL, 0, 4, NULL, | ||
1340 | CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO), | ||
1341 | LPC32XX_DEFINE_CLK(SD_GATE, MS_CTRL, BIT(5) | BIT(9), BIT(5) | BIT(9), | ||
1342 | 0x0, BIT(5) | BIT(9), 0x0, 0x0, clk_mask_ops), | ||
1343 | LPC32XX_DEFINE_COMPOSITE(SD, _NULL, SD_DIV, SD_GATE), | ||
1344 | |||
1345 | LPC32XX_DEFINE_DIV(LCD_DIV, LCDCLK_CTRL, 0, 5, NULL, 0), | ||
1346 | LPC32XX_DEFINE_GATE(LCD_GATE, LCDCLK_CTRL, 5, 0), | ||
1347 | LPC32XX_DEFINE_COMPOSITE(LCD, _NULL, LCD_DIV, LCD_GATE), | ||
1348 | |||
1349 | LPC32XX_DEFINE_CLK(MAC, MACCLK_CTRL, | ||
1350 | BIT(2) | BIT(1) | BIT(0), BIT(2) | BIT(1) | BIT(0), | ||
1351 | BIT(2) | BIT(1) | BIT(0), BIT(2) | BIT(1) | BIT(0), | ||
1352 | 0x0, 0x0, clk_mask_ops), | ||
1353 | LPC32XX_DEFINE_CLK(SLC, FLASHCLK_CTRL, | ||
1354 | BIT(2) | BIT(0), BIT(2) | BIT(0), 0x0, | ||
1355 | BIT(0), BIT(1), BIT(2) | BIT(1), clk_mask_ops), | ||
1356 | LPC32XX_DEFINE_CLK(MLC, FLASHCLK_CTRL, | ||
1357 | BIT(1), BIT(2) | BIT(1), 0x0, BIT(1), | ||
1358 | BIT(2) | BIT(0), BIT(2) | BIT(0), clk_mask_ops), | ||
1359 | /* | ||
1360 | * ADC/TS clock unfortunately cannot be registered as a composite one | ||
1361 | * due to a different connection of gate, div and mux, e.g. gating it | ||
1362 | * won't mean that the clock is off, if peripheral clock is its parent: | ||
1363 | * | ||
1364 | * rtc-->[gate]-->| | | ||
1365 | * | mux |--> adc/ts | ||
1366 | * pclk-->[div]-->| | | ||
1367 | * | ||
1368 | * Constraints: | ||
1369 | * ADC --- resulting clock must be <= 4.5 MHz | ||
1370 | * TS --- resulting clock must be <= 400 KHz | ||
1371 | */ | ||
1372 | LPC32XX_DEFINE_DIV(ADC_DIV, ADCCLK_CTRL1, 0, 8, NULL, 0), | ||
1373 | LPC32XX_DEFINE_GATE(ADC_RTC, ADCCLK_CTRL, 0, 0), | ||
1374 | LPC32XX_DEFINE_MUX(ADC, ADCCLK_CTRL1, 8, 0x1, NULL, 0), | ||
1375 | |||
1376 | /* USB controller clocks */ | ||
1377 | LPC32XX_DEFINE_USB(USB_AHB, | ||
1378 | BIT(24), 0x0, BIT(24), BIT(4), 0, clk_usb_ops), | ||
1379 | LPC32XX_DEFINE_USB(USB_OTG, | ||
1380 | 0x0, 0x0, 0x0, BIT(3), 0, clk_usb_ops), | ||
1381 | LPC32XX_DEFINE_USB(USB_I2C, | ||
1382 | 0x0, BIT(23), BIT(23), BIT(2), 0, clk_usb_i2c_ops), | ||
1383 | LPC32XX_DEFINE_USB(USB_DEV, | ||
1384 | BIT(22), 0x0, BIT(22), BIT(1), BIT(0), clk_usb_ops), | ||
1385 | LPC32XX_DEFINE_USB(USB_HOST, | ||
1386 | BIT(21), 0x0, BIT(21), BIT(0), BIT(1), clk_usb_ops), | ||
1387 | }; | ||
1388 | |||
1389 | static struct clk * __init lpc32xx_clk_register(u32 id) | ||
1390 | { | ||
1391 | const struct clk_proto_t *lpc32xx_clk = &clk_proto[id]; | ||
1392 | struct clk_hw_proto *clk_hw = &clk_hw_proto[id]; | ||
1393 | const char *parents[LPC32XX_CLK_PARENTS_MAX]; | ||
1394 | struct clk *clk; | ||
1395 | unsigned int i; | ||
1396 | |||
1397 | for (i = 0; i < lpc32xx_clk->num_parents; i++) | ||
1398 | parents[i] = clk_proto[lpc32xx_clk->parents[i]].name; | ||
1399 | |||
1400 | pr_debug("%s: derived from '%s', clock type %d\n", lpc32xx_clk->name, | ||
1401 | parents[0], clk_hw->type); | ||
1402 | |||
1403 | switch (clk_hw->type) { | ||
1404 | case CLK_LPC32XX: | ||
1405 | case CLK_LPC32XX_PLL: | ||
1406 | case CLK_LPC32XX_USB: | ||
1407 | case CLK_MUX: | ||
1408 | case CLK_DIV: | ||
1409 | case CLK_GATE: | ||
1410 | { | ||
1411 | struct clk_init_data clk_init = { | ||
1412 | .name = lpc32xx_clk->name, | ||
1413 | .parent_names = parents, | ||
1414 | .num_parents = lpc32xx_clk->num_parents, | ||
1415 | .flags = lpc32xx_clk->flags, | ||
1416 | .ops = clk_hw->hw0.ops, | ||
1417 | }; | ||
1418 | struct clk_hw *hw; | ||
1419 | |||
1420 | if (clk_hw->type == CLK_LPC32XX) | ||
1421 | hw = &clk_hw->hw0.clk.hw; | ||
1422 | else if (clk_hw->type == CLK_LPC32XX_PLL) | ||
1423 | hw = &clk_hw->hw0.pll.hw; | ||
1424 | else if (clk_hw->type == CLK_LPC32XX_USB) | ||
1425 | hw = &clk_hw->hw0.usb_clk.hw; | ||
1426 | else if (clk_hw->type == CLK_MUX) | ||
1427 | hw = &clk_hw->hw0.mux.hw; | ||
1428 | else if (clk_hw->type == CLK_DIV) | ||
1429 | hw = &clk_hw->hw0.div.hw; | ||
1430 | else if (clk_hw->type == CLK_GATE) | ||
1431 | hw = &clk_hw->hw0.gate.hw; | ||
1432 | |||
1433 | hw->init = &clk_init; | ||
1434 | clk = clk_register(NULL, hw); | ||
1435 | break; | ||
1436 | } | ||
1437 | case CLK_COMPOSITE: | ||
1438 | { | ||
1439 | struct clk_hw *mux_hw = NULL, *div_hw = NULL, *gate_hw = NULL; | ||
1440 | const struct clk_ops *mops = NULL, *dops = NULL, *gops = NULL; | ||
1441 | struct clk_hw_proto0 *mux0, *div0, *gate0; | ||
1442 | |||
1443 | mux0 = clk_hw->hw1.mux; | ||
1444 | div0 = clk_hw->hw1.div; | ||
1445 | gate0 = clk_hw->hw1.gate; | ||
1446 | if (mux0) { | ||
1447 | mops = mux0->ops; | ||
1448 | mux_hw = &mux0->clk.hw; | ||
1449 | } | ||
1450 | if (div0) { | ||
1451 | dops = div0->ops; | ||
1452 | div_hw = &div0->clk.hw; | ||
1453 | } | ||
1454 | if (gate0) { | ||
1455 | gops = gate0->ops; | ||
1456 | gate_hw = &gate0->clk.hw; | ||
1457 | } | ||
1458 | |||
1459 | clk = clk_register_composite(NULL, lpc32xx_clk->name, | ||
1460 | parents, lpc32xx_clk->num_parents, | ||
1461 | mux_hw, mops, div_hw, dops, | ||
1462 | gate_hw, gops, lpc32xx_clk->flags); | ||
1463 | break; | ||
1464 | } | ||
1465 | case CLK_FIXED: | ||
1466 | { | ||
1467 | struct clk_fixed_rate *fixed = &clk_hw->f; | ||
1468 | |||
1469 | clk = clk_register_fixed_rate(NULL, lpc32xx_clk->name, | ||
1470 | parents[0], fixed->flags, fixed->fixed_rate); | ||
1471 | break; | ||
1472 | } | ||
1473 | default: | ||
1474 | clk = ERR_PTR(-EINVAL); | ||
1475 | } | ||
1476 | |||
1477 | return clk; | ||
1478 | } | ||
1479 | |||
1480 | static void __init lpc32xx_clk_init(struct device_node *np) | ||
1481 | { | ||
1482 | unsigned int i; | ||
1483 | struct clk *clk_osc, *clk_32k; | ||
1484 | void __iomem *base = NULL; | ||
1485 | |||
1486 | /* Ensure that parent clocks are available and valid */ | ||
1487 | clk_32k = of_clk_get_by_name(np, clk_proto[LPC32XX_CLK_XTAL_32K].name); | ||
1488 | if (IS_ERR(clk_32k)) { | ||
1489 | pr_err("failed to find external 32KHz clock: %ld\n", | ||
1490 | PTR_ERR(clk_32k)); | ||
1491 | return; | ||
1492 | } | ||
1493 | if (clk_get_rate(clk_32k) != 32768) { | ||
1494 | pr_err("invalid clock rate of external 32KHz oscillator"); | ||
1495 | return; | ||
1496 | } | ||
1497 | |||
1498 | clk_osc = of_clk_get_by_name(np, clk_proto[LPC32XX_CLK_XTAL].name); | ||
1499 | if (IS_ERR(clk_osc)) { | ||
1500 | pr_err("failed to find external main oscillator clock: %ld\n", | ||
1501 | PTR_ERR(clk_osc)); | ||
1502 | return; | ||
1503 | } | ||
1504 | |||
1505 | base = of_iomap(np, 0); | ||
1506 | if (!base) { | ||
1507 | pr_err("failed to map system control block registers\n"); | ||
1508 | return; | ||
1509 | } | ||
1510 | |||
1511 | clk_regmap = regmap_init_mmio(NULL, base, &lpc32xx_scb_regmap_config); | ||
1512 | if (IS_ERR(clk_regmap)) { | ||
1513 | pr_err("failed to regmap system control block: %ld\n", | ||
1514 | PTR_ERR(clk_regmap)); | ||
1515 | return; | ||
1516 | } | ||
1517 | |||
1518 | for (i = 0; i < LPC32XX_CLK_MAX; i++) { | ||
1519 | clk[i] = lpc32xx_clk_register(i); | ||
1520 | if (IS_ERR(clk[i])) { | ||
1521 | pr_err("failed to register %s clock: %ld\n", | ||
1522 | clk_proto[i].name, PTR_ERR(clk[i])); | ||
1523 | clk[i] = NULL; | ||
1524 | } | ||
1525 | } | ||
1526 | |||
1527 | of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); | ||
1528 | |||
1529 | /* For 13MHz osc valid output range of PLL is from 156MHz to 266.5MHz */ | ||
1530 | clk_set_rate(clk[LPC32XX_CLK_HCLK_PLL], 208000000); | ||
1531 | |||
1532 | /* Set 48MHz rate of USB PLL clock */ | ||
1533 | clk_set_rate(clk[LPC32XX_CLK_USB_PLL], 48000000); | ||
1534 | |||
1535 | /* These two clocks must be always on independently on consumers */ | ||
1536 | clk_prepare_enable(clk[LPC32XX_CLK_ARM]); | ||
1537 | clk_prepare_enable(clk[LPC32XX_CLK_HCLK]); | ||
1538 | |||
1539 | /* Enable ARM VFP by default */ | ||
1540 | clk_prepare_enable(clk[LPC32XX_CLK_ARM_VFP]); | ||
1541 | |||
1542 | /* Disable enabled by default clocks for NAND MLC and SLC */ | ||
1543 | clk_mask_disable(&clk_hw_proto[LPC32XX_CLK_SLC].hw0.clk.hw); | ||
1544 | clk_mask_disable(&clk_hw_proto[LPC32XX_CLK_MLC].hw0.clk.hw); | ||
1545 | } | ||
1546 | CLK_OF_DECLARE(lpc32xx_clk, "nxp,lpc3220-clk", lpc32xx_clk_init); | ||
1547 | |||
1548 | static void __init lpc32xx_usb_clk_init(struct device_node *np) | ||
1549 | { | ||
1550 | unsigned int i; | ||
1551 | |||
1552 | usb_clk_vbase = of_iomap(np, 0); | ||
1553 | if (!usb_clk_vbase) { | ||
1554 | pr_err("failed to map address range\n"); | ||
1555 | return; | ||
1556 | } | ||
1557 | |||
1558 | for (i = 0; i < LPC32XX_USB_CLK_MAX; i++) { | ||
1559 | usb_clk[i] = lpc32xx_clk_register(i + LPC32XX_CLK_USB_OFFSET); | ||
1560 | if (IS_ERR(usb_clk[i])) { | ||
1561 | pr_err("failed to register %s clock: %ld\n", | ||
1562 | clk_proto[i].name, PTR_ERR(usb_clk[i])); | ||
1563 | usb_clk[i] = NULL; | ||
1564 | } | ||
1565 | } | ||
1566 | |||
1567 | of_clk_add_provider(np, of_clk_src_onecell_get, &usb_clk_data); | ||
1568 | } | ||
1569 | CLK_OF_DECLARE(lpc32xx_usb_clk, "nxp,lpc3220-usb-clk", lpc32xx_usb_clk_init); | ||