aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGabriel Fernandez <gabriel.fernandez@st.com>2018-03-08 11:53:55 -0500
committerMichael Turquette <mturquette@baylibre.com>2018-03-11 18:40:32 -0400
commit9bee94e7b7dac0bb049c488b8eaa9a48854ddb8f (patch)
tree4ec7e1f4a034219f130d3178a6d3d66dcbaf3a1b
parent605add0c7bbf5ecb9eeef02c605e47dfd2980acb (diff)
clk: stm32mp1: Introduce STM32MP1 clock driver
This patch introduces the mechanism to probe stm32mp1 driver. It also defines registers definition. This patch also introduces the generic mechanism to register a clock (a simple gate, divider and fixed factor). All clocks will be defined in one table. Signed-off-by: Gabriel Fernandez <gabriel.fernandez@st.com> Signed-off-by: Michael Turquette <mturquette@baylibre.com>
-rw-r--r--drivers/clk/Kconfig6
-rw-r--r--drivers/clk/Makefile1
-rw-r--r--drivers/clk/clk-stm32mp1.c364
-rw-r--r--include/dt-bindings/clock/stm32mp1-clks.h254
4 files changed, 625 insertions, 0 deletions
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 98ce9fc6e6c0..cbb9b0c05442 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -238,6 +238,12 @@ config COMMON_CLK_VC5
238 This driver supports the IDT VersaClock 5 and VersaClock 6 238 This driver supports the IDT VersaClock 5 and VersaClock 6
239 programmable clock generators. 239 programmable clock generators.
240 240
241config COMMON_CLK_STM32MP157
242 def_bool COMMON_CLK && MACH_STM32MP157
243 help
244 ---help---
245 Support for stm32mp157 SoC family clocks
246
241source "drivers/clk/bcm/Kconfig" 247source "drivers/clk/bcm/Kconfig"
242source "drivers/clk/hisilicon/Kconfig" 248source "drivers/clk/hisilicon/Kconfig"
243source "drivers/clk/imgtec/Kconfig" 249source "drivers/clk/imgtec/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 71ec41e6364f..8d812c701aa6 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -47,6 +47,7 @@ obj-$(CONFIG_COMMON_CLK_SI514) += clk-si514.o
47obj-$(CONFIG_COMMON_CLK_SI570) += clk-si570.o 47obj-$(CONFIG_COMMON_CLK_SI570) += clk-si570.o
48obj-$(CONFIG_ARCH_STM32) += clk-stm32f4.o 48obj-$(CONFIG_ARCH_STM32) += clk-stm32f4.o
49obj-$(CONFIG_ARCH_STM32) += clk-stm32h7.o 49obj-$(CONFIG_ARCH_STM32) += clk-stm32h7.o
50obj-$(CONFIG_COMMON_CLK_STM32MP157) += clk-stm32mp1.o
50obj-$(CONFIG_ARCH_TANGO) += clk-tango4.o 51obj-$(CONFIG_ARCH_TANGO) += clk-tango4.o
51obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o 52obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o
52obj-$(CONFIG_ARCH_U300) += clk-u300.o 53obj-$(CONFIG_ARCH_U300) += clk-u300.o
diff --git a/drivers/clk/clk-stm32mp1.c b/drivers/clk/clk-stm32mp1.c
new file mode 100644
index 000000000000..6261a92bbdc0
--- /dev/null
+++ b/drivers/clk/clk-stm32mp1.c
@@ -0,0 +1,364 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (C) STMicroelectronics 2018 - All Rights Reserved
4 * Author: Olivier Bideau <olivier.bideau@st.com> for STMicroelectronics.
5 * Author: Gabriel Fernandez <gabriel.fernandez@st.com> for STMicroelectronics.
6 */
7
8#include <linux/clk.h>
9#include <linux/clk-provider.h>
10#include <linux/err.h>
11#include <linux/io.h>
12#include <linux/of.h>
13#include <linux/of_address.h>
14#include <linux/slab.h>
15#include <linux/spinlock.h>
16
17#include <dt-bindings/clock/stm32mp1-clks.h>
18
19static DEFINE_SPINLOCK(rlock);
20
21#define RCC_OCENSETR 0x0C
22#define RCC_HSICFGR 0x18
23#define RCC_RDLSICR 0x144
24#define RCC_PLL1CR 0x80
25#define RCC_PLL1CFGR1 0x84
26#define RCC_PLL1CFGR2 0x88
27#define RCC_PLL2CR 0x94
28#define RCC_PLL2CFGR1 0x98
29#define RCC_PLL2CFGR2 0x9C
30#define RCC_PLL3CR 0x880
31#define RCC_PLL3CFGR1 0x884
32#define RCC_PLL3CFGR2 0x888
33#define RCC_PLL4CR 0x894
34#define RCC_PLL4CFGR1 0x898
35#define RCC_PLL4CFGR2 0x89C
36#define RCC_APB1ENSETR 0xA00
37#define RCC_APB2ENSETR 0xA08
38#define RCC_APB3ENSETR 0xA10
39#define RCC_APB4ENSETR 0x200
40#define RCC_APB5ENSETR 0x208
41#define RCC_AHB2ENSETR 0xA18
42#define RCC_AHB3ENSETR 0xA20
43#define RCC_AHB4ENSETR 0xA28
44#define RCC_AHB5ENSETR 0x210
45#define RCC_AHB6ENSETR 0x218
46#define RCC_AHB6LPENSETR 0x318
47#define RCC_RCK12SELR 0x28
48#define RCC_RCK3SELR 0x820
49#define RCC_RCK4SELR 0x824
50#define RCC_MPCKSELR 0x20
51#define RCC_ASSCKSELR 0x24
52#define RCC_MSSCKSELR 0x48
53#define RCC_SPI6CKSELR 0xC4
54#define RCC_SDMMC12CKSELR 0x8F4
55#define RCC_SDMMC3CKSELR 0x8F8
56#define RCC_FMCCKSELR 0x904
57#define RCC_I2C46CKSELR 0xC0
58#define RCC_I2C12CKSELR 0x8C0
59#define RCC_I2C35CKSELR 0x8C4
60#define RCC_UART1CKSELR 0xC8
61#define RCC_QSPICKSELR 0x900
62#define RCC_ETHCKSELR 0x8FC
63#define RCC_RNG1CKSELR 0xCC
64#define RCC_RNG2CKSELR 0x920
65#define RCC_GPUCKSELR 0x938
66#define RCC_USBCKSELR 0x91C
67#define RCC_STGENCKSELR 0xD4
68#define RCC_SPDIFCKSELR 0x914
69#define RCC_SPI2S1CKSELR 0x8D8
70#define RCC_SPI2S23CKSELR 0x8DC
71#define RCC_SPI2S45CKSELR 0x8E0
72#define RCC_CECCKSELR 0x918
73#define RCC_LPTIM1CKSELR 0x934
74#define RCC_LPTIM23CKSELR 0x930
75#define RCC_LPTIM45CKSELR 0x92C
76#define RCC_UART24CKSELR 0x8E8
77#define RCC_UART35CKSELR 0x8EC
78#define RCC_UART6CKSELR 0x8E4
79#define RCC_UART78CKSELR 0x8F0
80#define RCC_FDCANCKSELR 0x90C
81#define RCC_SAI1CKSELR 0x8C8
82#define RCC_SAI2CKSELR 0x8CC
83#define RCC_SAI3CKSELR 0x8D0
84#define RCC_SAI4CKSELR 0x8D4
85#define RCC_ADCCKSELR 0x928
86#define RCC_MPCKDIVR 0x2C
87#define RCC_DSICKSELR 0x924
88#define RCC_CPERCKSELR 0xD0
89#define RCC_MCO1CFGR 0x800
90#define RCC_MCO2CFGR 0x804
91#define RCC_BDCR 0x140
92#define RCC_AXIDIVR 0x30
93#define RCC_MCUDIVR 0x830
94#define RCC_APB1DIVR 0x834
95#define RCC_APB2DIVR 0x838
96#define RCC_APB3DIVR 0x83C
97#define RCC_APB4DIVR 0x3C
98#define RCC_APB5DIVR 0x40
99#define RCC_TIMG1PRER 0x828
100#define RCC_TIMG2PRER 0x82C
101#define RCC_RTCDIVR 0x44
102#define RCC_DBGCFGR 0x80C
103
104#define RCC_CLR 0x4
105
106struct clock_config {
107 u32 id;
108 const char *name;
109 union {
110 const char *parent_name;
111 const char * const *parent_names;
112 };
113 int num_parents;
114 unsigned long flags;
115 void *cfg;
116 struct clk_hw * (*func)(struct device *dev,
117 struct clk_hw_onecell_data *clk_data,
118 void __iomem *base, spinlock_t *lock,
119 const struct clock_config *cfg);
120};
121
122#define NO_ID ~0
123
124struct gate_cfg {
125 u32 reg_off;
126 u8 bit_idx;
127 u8 gate_flags;
128};
129
130struct fixed_factor_cfg {
131 unsigned int mult;
132 unsigned int div;
133};
134
135struct div_cfg {
136 u32 reg_off;
137 u8 shift;
138 u8 width;
139 u8 div_flags;
140 const struct clk_div_table *table;
141};
142
143static struct clk_hw *
144_clk_hw_register_gate(struct device *dev,
145 struct clk_hw_onecell_data *clk_data,
146 void __iomem *base, spinlock_t *lock,
147 const struct clock_config *cfg)
148{
149 struct gate_cfg *gate_cfg = cfg->cfg;
150
151 return clk_hw_register_gate(dev,
152 cfg->name,
153 cfg->parent_name,
154 cfg->flags,
155 gate_cfg->reg_off + base,
156 gate_cfg->bit_idx,
157 gate_cfg->gate_flags,
158 lock);
159}
160
161static struct clk_hw *
162_clk_hw_register_fixed_factor(struct device *dev,
163 struct clk_hw_onecell_data *clk_data,
164 void __iomem *base, spinlock_t *lock,
165 const struct clock_config *cfg)
166{
167 struct fixed_factor_cfg *ff_cfg = cfg->cfg;
168
169 return clk_hw_register_fixed_factor(dev, cfg->name, cfg->parent_name,
170 cfg->flags, ff_cfg->mult,
171 ff_cfg->div);
172}
173
174static struct clk_hw *
175_clk_hw_register_divider_table(struct device *dev,
176 struct clk_hw_onecell_data *clk_data,
177 void __iomem *base, spinlock_t *lock,
178 const struct clock_config *cfg)
179{
180 struct div_cfg *div_cfg = cfg->cfg;
181
182 return clk_hw_register_divider_table(dev,
183 cfg->name,
184 cfg->parent_name,
185 cfg->flags,
186 div_cfg->reg_off + base,
187 div_cfg->shift,
188 div_cfg->width,
189 div_cfg->div_flags,
190 div_cfg->table,
191 lock);
192}
193
194#define GATE(_id, _name, _parent, _flags, _offset, _bit_idx, _gate_flags)\
195{\
196 .id = _id,\
197 .name = _name,\
198 .parent_name = _parent,\
199 .flags = _flags,\
200 .cfg = &(struct gate_cfg) {\
201 .reg_off = _offset,\
202 .bit_idx = _bit_idx,\
203 .gate_flags = _gate_flags,\
204 },\
205 .func = _clk_hw_register_gate,\
206}
207
208#define FIXED_FACTOR(_id, _name, _parent, _flags, _mult, _div)\
209{\
210 .id = _id,\
211 .name = _name,\
212 .parent_name = _parent,\
213 .flags = _flags,\
214 .cfg = &(struct fixed_factor_cfg) {\
215 .mult = _mult,\
216 .div = _div,\
217 },\
218 .func = _clk_hw_register_fixed_factor,\
219}
220
221#define DIV_TABLE(_id, _name, _parent, _flags, _offset, _shift, _width,\
222 _div_flags, _div_table)\
223{\
224 .id = _id,\
225 .name = _name,\
226 .parent_name = _parent,\
227 .flags = _flags,\
228 .cfg = &(struct div_cfg) {\
229 .reg_off = _offset,\
230 .shift = _shift,\
231 .width = _width,\
232 .div_flags = _div_flags,\
233 .table = _div_table,\
234 },\
235 .func = _clk_hw_register_divider_table,\
236}
237
238#define DIV(_id, _name, _parent, _flags, _offset, _shift, _width, _div_flags)\
239 DIV_TABLE(_id, _name, _parent, _flags, _offset, _shift, _width,\
240 _div_flags, NULL)
241
242static const struct clock_config stm32mp1_clock_cfg[] = {
243 /* Oscillator divider */
244 DIV(NO_ID, "clk-hsi-div", "clk-hsi", 0, RCC_HSICFGR, 0, 2,
245 CLK_DIVIDER_READ_ONLY),
246
247 /* External / Internal Oscillators */
248 GATE(CK_LSI, "ck_lsi", "clk-lsi", 0, RCC_RDLSICR, 0, 0),
249 GATE(CK_LSE, "ck_lse", "clk-lse", 0, RCC_BDCR, 0, 0),
250
251 FIXED_FACTOR(CK_HSE_DIV2, "clk-hse-div2", "ck_hse", 0, 1, 2),
252};
253
254struct stm32_clock_match_data {
255 const struct clock_config *cfg;
256 unsigned int num;
257 unsigned int maxbinding;
258};
259
260static struct stm32_clock_match_data stm32mp1_data = {
261 .cfg = stm32mp1_clock_cfg,
262 .num = ARRAY_SIZE(stm32mp1_clock_cfg),
263 .maxbinding = STM32MP1_LAST_CLK,
264};
265
266static const struct of_device_id stm32mp1_match_data[] = {
267 {
268 .compatible = "st,stm32mp1-rcc",
269 .data = &stm32mp1_data,
270 },
271 { }
272};
273
274static int stm32_register_hw_clk(struct device *dev,
275 struct clk_hw_onecell_data *clk_data,
276 void __iomem *base, spinlock_t *lock,
277 const struct clock_config *cfg)
278{
279 static struct clk_hw **hws;
280 struct clk_hw *hw = ERR_PTR(-ENOENT);
281
282 hws = clk_data->hws;
283
284 if (cfg->func)
285 hw = (*cfg->func)(dev, clk_data, base, lock, cfg);
286
287 if (IS_ERR(hw)) {
288 pr_err("Unable to register %s\n", cfg->name);
289 return PTR_ERR(hw);
290 }
291
292 if (cfg->id != NO_ID)
293 hws[cfg->id] = hw;
294
295 return 0;
296}
297
298static int stm32_rcc_init(struct device_node *np,
299 void __iomem *base,
300 const struct of_device_id *match_data)
301{
302 struct clk_hw_onecell_data *clk_data;
303 struct clk_hw **hws;
304 const struct of_device_id *match;
305 const struct stm32_clock_match_data *data;
306 int err, n, max_binding;
307
308 match = of_match_node(match_data, np);
309 if (!match) {
310 pr_err("%s: match data not found\n", __func__);
311 return -ENODEV;
312 }
313
314 data = match->data;
315
316 max_binding = data->maxbinding;
317
318 clk_data = kzalloc(sizeof(*clk_data) +
319 sizeof(*clk_data->hws) * max_binding,
320 GFP_KERNEL);
321 if (!clk_data)
322 return -ENOMEM;
323
324 clk_data->num = max_binding;
325
326 hws = clk_data->hws;
327
328 for (n = 0; n < max_binding; n++)
329 hws[n] = ERR_PTR(-ENOENT);
330
331 for (n = 0; n < data->num; n++) {
332 err = stm32_register_hw_clk(NULL, clk_data, base, &rlock,
333 &data->cfg[n]);
334 if (err) {
335 pr_err("%s: can't register %s\n", __func__,
336 data->cfg[n].name);
337
338 kfree(clk_data);
339
340 return err;
341 }
342 }
343
344 return of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data);
345}
346
347static void stm32mp1_rcc_init(struct device_node *np)
348{
349 void __iomem *base;
350
351 base = of_iomap(np, 0);
352 if (!base) {
353 pr_err("%s: unable to map resource", np->name);
354 of_node_put(np);
355 return;
356 }
357
358 if (stm32_rcc_init(np, base, stm32mp1_match_data)) {
359 iounmap(base);
360 of_node_put(np);
361 }
362}
363
364CLK_OF_DECLARE_DRIVER(stm32mp1_rcc, "st,stm32mp1-rcc", stm32mp1_rcc_init);
diff --git a/include/dt-bindings/clock/stm32mp1-clks.h b/include/dt-bindings/clock/stm32mp1-clks.h
new file mode 100644
index 000000000000..86e3ec662ef4
--- /dev/null
+++ b/include/dt-bindings/clock/stm32mp1-clks.h
@@ -0,0 +1,254 @@
1/* SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause */
2/*
3 * Copyright (C) STMicroelectronics 2018 - All Rights Reserved
4 * Author: Gabriel Fernandez <gabriel.fernandez@st.com> for STMicroelectronics.
5 */
6
7#ifndef _DT_BINDINGS_STM32MP1_CLKS_H_
8#define _DT_BINDINGS_STM32MP1_CLKS_H_
9
10/* OSCILLATOR clocks */
11#define CK_HSE 0
12#define CK_CSI 1
13#define CK_LSI 2
14#define CK_LSE 3
15#define CK_HSI 4
16#define CK_HSE_DIV2 5
17
18/* Bus clocks */
19#define TIM2 6
20#define TIM3 7
21#define TIM4 8
22#define TIM5 9
23#define TIM6 10
24#define TIM7 11
25#define TIM12 12
26#define TIM13 13
27#define TIM14 14
28#define LPTIM1 15
29#define SPI2 16
30#define SPI3 17
31#define USART2 18
32#define USART3 19
33#define UART4 20
34#define UART5 21
35#define UART7 22
36#define UART8 23
37#define I2C1 24
38#define I2C2 25
39#define I2C3 26
40#define I2C5 27
41#define SPDIF 28
42#define CEC 29
43#define DAC12 30
44#define MDIO 31
45#define TIM1 32
46#define TIM8 33
47#define TIM15 34
48#define TIM16 35
49#define TIM17 36
50#define SPI1 37
51#define SPI4 38
52#define SPI5 39
53#define USART6 40
54#define SAI1 41
55#define SAI2 42
56#define SAI3 43
57#define DFSDM 44
58#define FDCAN 45
59#define LPTIM2 46
60#define LPTIM3 47
61#define LPTIM4 48
62#define LPTIM5 49
63#define SAI4 50
64#define SYSCFG 51
65#define VREF 52
66#define TMPSENS 53
67#define PMBCTRL 54
68#define HDP 55
69#define LTDC 56
70#define DSI 57
71#define IWDG2 58
72#define USBPHY 59
73#define STGENRO 60
74#define SPI6 61
75#define I2C4 62
76#define I2C6 63
77#define USART1 64
78#define RTCAPB 65
79#define TZC 66
80#define TZPC 67
81#define IWDG1 68
82#define BSEC 69
83#define STGEN 70
84#define DMA1 71
85#define DMA2 72
86#define DMAMUX 73
87#define ADC12 74
88#define USBO 75
89#define SDMMC3 76
90#define DCMI 77
91#define CRYP2 78
92#define HASH2 79
93#define RNG2 80
94#define CRC2 81
95#define HSEM 82
96#define IPCC 83
97#define GPIOA 84
98#define GPIOB 85
99#define GPIOC 86
100#define GPIOD 87
101#define GPIOE 88
102#define GPIOF 89
103#define GPIOG 90
104#define GPIOH 91
105#define GPIOI 92
106#define GPIOJ 93
107#define GPIOK 94
108#define GPIOZ 95
109#define CRYP1 96
110#define HASH1 97
111#define RNG1 98
112#define BKPSRAM 99
113#define MDMA 100
114#define GPU 101
115#define ETHCK 102
116#define ETHTX 103
117#define ETHRX 104
118#define ETHMAC 105
119#define FMC 106
120#define QSPI 107
121#define SDMMC1 108
122#define SDMMC2 109
123#define CRC1 110
124#define USBH 111
125#define ETHSTP 112
126
127/* Kernel clocks */
128#define SDMMC1_K 118
129#define SDMMC2_K 119
130#define SDMMC3_K 120
131#define FMC_K 121
132#define QSPI_K 122
133#define ETHCK_K 123
134#define RNG1_K 124
135#define RNG2_K 125
136#define GPU_K 126
137#define USBPHY_K 127
138#define STGEN_K 128
139#define SPDIF_K 129
140#define SPI1_K 130
141#define SPI2_K 131
142#define SPI3_K 132
143#define SPI4_K 133
144#define SPI5_K 134
145#define SPI6_K 135
146#define CEC_K 136
147#define I2C1_K 137
148#define I2C2_K 138
149#define I2C3_K 139
150#define I2C4_K 140
151#define I2C5_K 141
152#define I2C6_K 142
153#define LPTIM1_K 143
154#define LPTIM2_K 144
155#define LPTIM3_K 145
156#define LPTIM4_K 146
157#define LPTIM5_K 147
158#define USART1_K 148
159#define USART2_K 149
160#define USART3_K 150
161#define UART4_K 151
162#define UART5_K 152
163#define USART6_K 153
164#define UART7_K 154
165#define UART8_K 155
166#define DFSDM_K 156
167#define FDCAN_K 157
168#define SAI1_K 158
169#define SAI2_K 159
170#define SAI3_K 160
171#define SAI4_K 161
172#define ADC12_K 162
173#define DSI_K 163
174#define DSI_PX 164
175#define ADFSDM_K 165
176#define USBO_K 166
177#define LTDC_PX 167
178#define DAC12_K 168
179#define ETHPTP_K 169
180
181/* PLL */
182#define PLL1 176
183#define PLL2 177
184#define PLL3 178
185#define PLL4 179
186
187/* ODF */
188#define PLL1_P 180
189#define PLL1_Q 181
190#define PLL1_R 182
191#define PLL2_P 183
192#define PLL2_Q 184
193#define PLL2_R 185
194#define PLL3_P 186
195#define PLL3_Q 187
196#define PLL3_R 188
197#define PLL4_P 189
198#define PLL4_Q 190
199#define PLL4_R 191
200
201/* AUX */
202#define RTC 192
203
204/* MCLK */
205#define CK_PER 193
206#define CK_MPU 194
207#define CK_AXI 195
208#define CK_MCU 196
209
210/* Time base */
211#define TIM2_K 197
212#define TIM3_K 198
213#define TIM4_K 199
214#define TIM5_K 200
215#define TIM6_K 201
216#define TIM7_K 202
217#define TIM12_K 203
218#define TIM13_K 204
219#define TIM14_K 205
220#define TIM1_K 206
221#define TIM8_K 207
222#define TIM15_K 208
223#define TIM16_K 209
224#define TIM17_K 210
225
226/* MCO clocks */
227#define CK_MCO1 211
228#define CK_MCO2 212
229
230/* TRACE & DEBUG clocks */
231#define DBG 213
232#define CK_DBG 214
233#define CK_TRACE 215
234
235/* DDR */
236#define DDRC1 220
237#define DDRC1LP 221
238#define DDRC2 222
239#define DDRC2LP 223
240#define DDRPHYC 224
241#define DDRPHYCLP 225
242#define DDRCAPB 226
243#define DDRCAPBLP 227
244#define AXIDCG 228
245#define DDRPHYCAPB 229
246#define DDRPHYCAPBLP 230
247#define DDRPERFM 231
248
249#define STM32MP1_LAST_CLK 232
250
251#define LTDC_K LTDC_PX
252#define ETHMAC_K ETHCK_K
253
254#endif /* _DT_BINDINGS_STM32MP1_CLKS_H_ */