Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/clk/clk-bm1880.c
26278 views
1
// SPDX-License-Identifier: GPL-2.0+
2
/*
3
* Bitmain BM1880 SoC clock driver
4
*
5
* Copyright (c) 2019 Linaro Ltd.
6
* Author: Manivannan Sadhasivam <[email protected]>
7
*/
8
9
#include <linux/clk-provider.h>
10
#include <linux/io.h>
11
#include <linux/kernel.h>
12
#include <linux/mod_devicetable.h>
13
#include <linux/module.h>
14
#include <linux/platform_device.h>
15
#include <linux/slab.h>
16
17
#include <dt-bindings/clock/bm1880-clock.h>
18
19
#define BM1880_CLK_MPLL_CTL 0x00
20
#define BM1880_CLK_SPLL_CTL 0x04
21
#define BM1880_CLK_FPLL_CTL 0x08
22
#define BM1880_CLK_DDRPLL_CTL 0x0c
23
24
#define BM1880_CLK_ENABLE0 0x00
25
#define BM1880_CLK_ENABLE1 0x04
26
#define BM1880_CLK_SELECT 0x20
27
#define BM1880_CLK_DIV0 0x40
28
#define BM1880_CLK_DIV1 0x44
29
#define BM1880_CLK_DIV2 0x48
30
#define BM1880_CLK_DIV3 0x4c
31
#define BM1880_CLK_DIV4 0x50
32
#define BM1880_CLK_DIV5 0x54
33
#define BM1880_CLK_DIV6 0x58
34
#define BM1880_CLK_DIV7 0x5c
35
#define BM1880_CLK_DIV8 0x60
36
#define BM1880_CLK_DIV9 0x64
37
#define BM1880_CLK_DIV10 0x68
38
#define BM1880_CLK_DIV11 0x6c
39
#define BM1880_CLK_DIV12 0x70
40
#define BM1880_CLK_DIV13 0x74
41
#define BM1880_CLK_DIV14 0x78
42
#define BM1880_CLK_DIV15 0x7c
43
#define BM1880_CLK_DIV16 0x80
44
#define BM1880_CLK_DIV17 0x84
45
#define BM1880_CLK_DIV18 0x88
46
#define BM1880_CLK_DIV19 0x8c
47
#define BM1880_CLK_DIV20 0x90
48
#define BM1880_CLK_DIV21 0x94
49
#define BM1880_CLK_DIV22 0x98
50
#define BM1880_CLK_DIV23 0x9c
51
#define BM1880_CLK_DIV24 0xa0
52
#define BM1880_CLK_DIV25 0xa4
53
#define BM1880_CLK_DIV26 0xa8
54
#define BM1880_CLK_DIV27 0xac
55
#define BM1880_CLK_DIV28 0xb0
56
57
#define to_bm1880_pll_clk(_hw) container_of(_hw, struct bm1880_pll_hw_clock, hw)
58
#define to_bm1880_div_clk(_hw) container_of(_hw, struct bm1880_div_hw_clock, hw)
59
60
static DEFINE_SPINLOCK(bm1880_clk_lock);
61
62
struct bm1880_clock_data {
63
void __iomem *pll_base;
64
void __iomem *sys_base;
65
struct clk_hw_onecell_data hw_data;
66
};
67
68
struct bm1880_gate_clock {
69
unsigned int id;
70
const char *name;
71
const char *parent;
72
u32 gate_reg;
73
s8 gate_shift;
74
unsigned long flags;
75
};
76
77
struct bm1880_mux_clock {
78
unsigned int id;
79
const char *name;
80
const char * const *parents;
81
s8 num_parents;
82
u32 reg;
83
s8 shift;
84
unsigned long flags;
85
};
86
87
struct bm1880_div_clock {
88
unsigned int id;
89
const char *name;
90
u32 reg;
91
u8 shift;
92
u8 width;
93
u32 initval;
94
const struct clk_div_table *table;
95
unsigned long flags;
96
};
97
98
struct bm1880_div_hw_clock {
99
struct bm1880_div_clock div;
100
void __iomem *base;
101
spinlock_t *lock;
102
struct clk_hw hw;
103
struct clk_init_data init;
104
};
105
106
struct bm1880_composite_clock {
107
unsigned int id;
108
const char *name;
109
const char *parent;
110
const char * const *parents;
111
unsigned int num_parents;
112
unsigned long flags;
113
114
u32 gate_reg;
115
u32 mux_reg;
116
u32 div_reg;
117
118
s8 gate_shift;
119
s8 mux_shift;
120
s8 div_shift;
121
s8 div_width;
122
s16 div_initval;
123
const struct clk_div_table *table;
124
};
125
126
struct bm1880_pll_clock {
127
unsigned int id;
128
const char *name;
129
u32 reg;
130
unsigned long flags;
131
};
132
133
struct bm1880_pll_hw_clock {
134
struct bm1880_pll_clock pll;
135
void __iomem *base;
136
struct clk_hw hw;
137
struct clk_init_data init;
138
};
139
140
static const struct clk_ops bm1880_pll_ops;
141
static const struct clk_ops bm1880_clk_div_ops;
142
143
#define GATE_DIV(_id, _name, _parent, _gate_reg, _gate_shift, _div_reg, \
144
_div_shift, _div_width, _div_initval, _table, \
145
_flags) { \
146
.id = _id, \
147
.parent = _parent, \
148
.name = _name, \
149
.gate_reg = _gate_reg, \
150
.gate_shift = _gate_shift, \
151
.div_reg = _div_reg, \
152
.div_shift = _div_shift, \
153
.div_width = _div_width, \
154
.div_initval = _div_initval, \
155
.table = _table, \
156
.mux_shift = -1, \
157
.flags = _flags, \
158
}
159
160
#define GATE_MUX(_id, _name, _parents, _gate_reg, _gate_shift, \
161
_mux_reg, _mux_shift, _flags) { \
162
.id = _id, \
163
.parents = _parents, \
164
.num_parents = ARRAY_SIZE(_parents), \
165
.name = _name, \
166
.gate_reg = _gate_reg, \
167
.gate_shift = _gate_shift, \
168
.div_shift = -1, \
169
.mux_reg = _mux_reg, \
170
.mux_shift = _mux_shift, \
171
.flags = _flags, \
172
}
173
174
#define CLK_PLL(_id, _name, _parent, _reg, _flags) { \
175
.pll.id = _id, \
176
.pll.name = _name, \
177
.pll.reg = _reg, \
178
.hw.init = CLK_HW_INIT_PARENTS_DATA(_name, _parent, \
179
&bm1880_pll_ops, \
180
_flags), \
181
}
182
183
#define CLK_DIV(_id, _name, _parent, _reg, _shift, _width, _initval, \
184
_table, _flags) { \
185
.div.id = _id, \
186
.div.name = _name, \
187
.div.reg = _reg, \
188
.div.shift = _shift, \
189
.div.width = _width, \
190
.div.initval = _initval, \
191
.div.table = _table, \
192
.hw.init = CLK_HW_INIT_HW(_name, _parent, \
193
&bm1880_clk_div_ops, \
194
_flags), \
195
}
196
197
static struct clk_parent_data bm1880_pll_parent[] = {
198
{ .fw_name = "osc", .name = "osc" },
199
};
200
201
/*
202
* All PLL clocks are marked as CRITICAL, hence they are very crucial
203
* for the functioning of the SoC
204
*/
205
static struct bm1880_pll_hw_clock bm1880_pll_clks[] = {
206
CLK_PLL(BM1880_CLK_MPLL, "clk_mpll", bm1880_pll_parent,
207
BM1880_CLK_MPLL_CTL, 0),
208
CLK_PLL(BM1880_CLK_SPLL, "clk_spll", bm1880_pll_parent,
209
BM1880_CLK_SPLL_CTL, 0),
210
CLK_PLL(BM1880_CLK_FPLL, "clk_fpll", bm1880_pll_parent,
211
BM1880_CLK_FPLL_CTL, 0),
212
CLK_PLL(BM1880_CLK_DDRPLL, "clk_ddrpll", bm1880_pll_parent,
213
BM1880_CLK_DDRPLL_CTL, 0),
214
};
215
216
/*
217
* Clocks marked as CRITICAL are needed for the proper functioning
218
* of the SoC.
219
*/
220
static const struct bm1880_gate_clock bm1880_gate_clks[] = {
221
{ BM1880_CLK_AHB_ROM, "clk_ahb_rom", "clk_mux_axi6",
222
BM1880_CLK_ENABLE0, 2, 0 },
223
{ BM1880_CLK_AXI_SRAM, "clk_axi_sram", "clk_axi1",
224
BM1880_CLK_ENABLE0, 3, 0 },
225
/*
226
* Since this clock is sourcing the DDR memory, let's mark it as
227
* critical to avoid gating.
228
*/
229
{ BM1880_CLK_DDR_AXI, "clk_ddr_axi", "clk_mux_axi6",
230
BM1880_CLK_ENABLE0, 4, CLK_IS_CRITICAL },
231
{ BM1880_CLK_APB_EFUSE, "clk_apb_efuse", "clk_mux_axi6",
232
BM1880_CLK_ENABLE0, 6, 0 },
233
{ BM1880_CLK_AXI5_EMMC, "clk_axi5_emmc", "clk_axi5",
234
BM1880_CLK_ENABLE0, 7, 0 },
235
{ BM1880_CLK_AXI5_SD, "clk_axi5_sd", "clk_axi5",
236
BM1880_CLK_ENABLE0, 10, 0 },
237
{ BM1880_CLK_AXI4_ETH0, "clk_axi4_eth0", "clk_axi4",
238
BM1880_CLK_ENABLE0, 14, 0 },
239
{ BM1880_CLK_AXI4_ETH1, "clk_axi4_eth1", "clk_axi4",
240
BM1880_CLK_ENABLE0, 16, 0 },
241
{ BM1880_CLK_AXI1_GDMA, "clk_axi1_gdma", "clk_axi1",
242
BM1880_CLK_ENABLE0, 17, 0 },
243
/* Don't gate GPIO clocks as it is not owned by the GPIO driver */
244
{ BM1880_CLK_APB_GPIO, "clk_apb_gpio", "clk_mux_axi6",
245
BM1880_CLK_ENABLE0, 18, CLK_IGNORE_UNUSED },
246
{ BM1880_CLK_APB_GPIO_INTR, "clk_apb_gpio_intr", "clk_mux_axi6",
247
BM1880_CLK_ENABLE0, 19, CLK_IGNORE_UNUSED },
248
{ BM1880_CLK_AXI1_MINER, "clk_axi1_miner", "clk_axi1",
249
BM1880_CLK_ENABLE0, 21, 0 },
250
{ BM1880_CLK_AHB_SF, "clk_ahb_sf", "clk_mux_axi6",
251
BM1880_CLK_ENABLE0, 22, 0 },
252
/*
253
* Not sure which module this clock is sourcing but gating this clock
254
* prevents the system from booting. So, let's mark it as critical.
255
*/
256
{ BM1880_CLK_SDMA_AXI, "clk_sdma_axi", "clk_axi5",
257
BM1880_CLK_ENABLE0, 23, CLK_IS_CRITICAL },
258
{ BM1880_CLK_APB_I2C, "clk_apb_i2c", "clk_mux_axi6",
259
BM1880_CLK_ENABLE0, 25, 0 },
260
{ BM1880_CLK_APB_WDT, "clk_apb_wdt", "clk_mux_axi6",
261
BM1880_CLK_ENABLE0, 26, 0 },
262
{ BM1880_CLK_APB_JPEG, "clk_apb_jpeg", "clk_axi6",
263
BM1880_CLK_ENABLE0, 27, 0 },
264
{ BM1880_CLK_AXI5_NF, "clk_axi5_nf", "clk_axi5",
265
BM1880_CLK_ENABLE0, 29, 0 },
266
{ BM1880_CLK_APB_NF, "clk_apb_nf", "clk_axi6",
267
BM1880_CLK_ENABLE0, 30, 0 },
268
{ BM1880_CLK_APB_PWM, "clk_apb_pwm", "clk_mux_axi6",
269
BM1880_CLK_ENABLE1, 0, 0 },
270
{ BM1880_CLK_RV, "clk_rv", "clk_mux_rv",
271
BM1880_CLK_ENABLE1, 1, 0 },
272
{ BM1880_CLK_APB_SPI, "clk_apb_spi", "clk_mux_axi6",
273
BM1880_CLK_ENABLE1, 2, 0 },
274
{ BM1880_CLK_UART_500M, "clk_uart_500m", "clk_div_uart_500m",
275
BM1880_CLK_ENABLE1, 4, 0 },
276
{ BM1880_CLK_APB_UART, "clk_apb_uart", "clk_axi6",
277
BM1880_CLK_ENABLE1, 5, 0 },
278
{ BM1880_CLK_APB_I2S, "clk_apb_i2s", "clk_axi6",
279
BM1880_CLK_ENABLE1, 6, 0 },
280
{ BM1880_CLK_AXI4_USB, "clk_axi4_usb", "clk_axi4",
281
BM1880_CLK_ENABLE1, 7, 0 },
282
{ BM1880_CLK_APB_USB, "clk_apb_usb", "clk_axi6",
283
BM1880_CLK_ENABLE1, 8, 0 },
284
{ BM1880_CLK_12M_USB, "clk_12m_usb", "clk_div_12m_usb",
285
BM1880_CLK_ENABLE1, 11, 0 },
286
{ BM1880_CLK_APB_VIDEO, "clk_apb_video", "clk_axi6",
287
BM1880_CLK_ENABLE1, 12, 0 },
288
{ BM1880_CLK_APB_VPP, "clk_apb_vpp", "clk_axi6",
289
BM1880_CLK_ENABLE1, 15, 0 },
290
{ BM1880_CLK_AXI6, "clk_axi6", "clk_mux_axi6",
291
BM1880_CLK_ENABLE1, 21, 0 },
292
};
293
294
static const char * const clk_a53_parents[] = { "clk_spll", "clk_mpll" };
295
static const char * const clk_rv_parents[] = { "clk_div_1_rv", "clk_div_0_rv" };
296
static const char * const clk_axi1_parents[] = { "clk_div_1_axi1", "clk_div_0_axi1" };
297
static const char * const clk_axi6_parents[] = { "clk_div_1_axi6", "clk_div_0_axi6" };
298
299
static const struct bm1880_mux_clock bm1880_mux_clks[] = {
300
{ BM1880_CLK_MUX_RV, "clk_mux_rv", clk_rv_parents, 2,
301
BM1880_CLK_SELECT, 1, 0 },
302
{ BM1880_CLK_MUX_AXI6, "clk_mux_axi6", clk_axi6_parents, 2,
303
BM1880_CLK_SELECT, 3, 0 },
304
};
305
306
static const struct clk_div_table bm1880_div_table_0[] = {
307
{ 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 },
308
{ 4, 5 }, { 5, 6 }, { 6, 7 }, { 7, 8 },
309
{ 8, 9 }, { 9, 10 }, { 10, 11 }, { 11, 12 },
310
{ 12, 13 }, { 13, 14 }, { 14, 15 }, { 15, 16 },
311
{ 16, 17 }, { 17, 18 }, { 18, 19 }, { 19, 20 },
312
{ 20, 21 }, { 21, 22 }, { 22, 23 }, { 23, 24 },
313
{ 24, 25 }, { 25, 26 }, { 26, 27 }, { 27, 28 },
314
{ 28, 29 }, { 29, 30 }, { 30, 31 }, { 31, 32 },
315
{ 0, 0 }
316
};
317
318
static const struct clk_div_table bm1880_div_table_1[] = {
319
{ 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 },
320
{ 4, 5 }, { 5, 6 }, { 6, 7 }, { 7, 8 },
321
{ 8, 9 }, { 9, 10 }, { 10, 11 }, { 11, 12 },
322
{ 12, 13 }, { 13, 14 }, { 14, 15 }, { 15, 16 },
323
{ 16, 17 }, { 17, 18 }, { 18, 19 }, { 19, 20 },
324
{ 20, 21 }, { 21, 22 }, { 22, 23 }, { 23, 24 },
325
{ 24, 25 }, { 25, 26 }, { 26, 27 }, { 27, 28 },
326
{ 28, 29 }, { 29, 30 }, { 30, 31 }, { 31, 32 },
327
{ 127, 128 }, { 0, 0 }
328
};
329
330
static const struct clk_div_table bm1880_div_table_2[] = {
331
{ 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 },
332
{ 4, 5 }, { 5, 6 }, { 6, 7 }, { 7, 8 },
333
{ 8, 9 }, { 9, 10 }, { 10, 11 }, { 11, 12 },
334
{ 12, 13 }, { 13, 14 }, { 14, 15 }, { 15, 16 },
335
{ 16, 17 }, { 17, 18 }, { 18, 19 }, { 19, 20 },
336
{ 20, 21 }, { 21, 22 }, { 22, 23 }, { 23, 24 },
337
{ 24, 25 }, { 25, 26 }, { 26, 27 }, { 27, 28 },
338
{ 28, 29 }, { 29, 30 }, { 30, 31 }, { 31, 32 },
339
{ 127, 128 }, { 255, 256 }, { 0, 0 }
340
};
341
342
static const struct clk_div_table bm1880_div_table_3[] = {
343
{ 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 },
344
{ 4, 5 }, { 5, 6 }, { 6, 7 }, { 7, 8 },
345
{ 8, 9 }, { 9, 10 }, { 10, 11 }, { 11, 12 },
346
{ 12, 13 }, { 13, 14 }, { 14, 15 }, { 15, 16 },
347
{ 16, 17 }, { 17, 18 }, { 18, 19 }, { 19, 20 },
348
{ 20, 21 }, { 21, 22 }, { 22, 23 }, { 23, 24 },
349
{ 24, 25 }, { 25, 26 }, { 26, 27 }, { 27, 28 },
350
{ 28, 29 }, { 29, 30 }, { 30, 31 }, { 31, 32 },
351
{ 127, 128 }, { 255, 256 }, { 511, 512 }, { 0, 0 }
352
};
353
354
static const struct clk_div_table bm1880_div_table_4[] = {
355
{ 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 },
356
{ 4, 5 }, { 5, 6 }, { 6, 7 }, { 7, 8 },
357
{ 8, 9 }, { 9, 10 }, { 10, 11 }, { 11, 12 },
358
{ 12, 13 }, { 13, 14 }, { 14, 15 }, { 15, 16 },
359
{ 16, 17 }, { 17, 18 }, { 18, 19 }, { 19, 20 },
360
{ 20, 21 }, { 21, 22 }, { 22, 23 }, { 23, 24 },
361
{ 24, 25 }, { 25, 26 }, { 26, 27 }, { 27, 28 },
362
{ 28, 29 }, { 29, 30 }, { 30, 31 }, { 31, 32 },
363
{ 127, 128 }, { 255, 256 }, { 511, 512 }, { 65535, 65536 },
364
{ 0, 0 }
365
};
366
367
/*
368
* Clocks marked as CRITICAL are needed for the proper functioning
369
* of the SoC.
370
*/
371
static struct bm1880_div_hw_clock bm1880_div_clks[] = {
372
CLK_DIV(BM1880_CLK_DIV_0_RV, "clk_div_0_rv", &bm1880_pll_clks[1].hw,
373
BM1880_CLK_DIV12, 16, 5, 1, bm1880_div_table_0, 0),
374
CLK_DIV(BM1880_CLK_DIV_1_RV, "clk_div_1_rv", &bm1880_pll_clks[2].hw,
375
BM1880_CLK_DIV13, 16, 5, 1, bm1880_div_table_0, 0),
376
CLK_DIV(BM1880_CLK_DIV_UART_500M, "clk_div_uart_500m", &bm1880_pll_clks[2].hw,
377
BM1880_CLK_DIV15, 16, 7, 3, bm1880_div_table_1, 0),
378
CLK_DIV(BM1880_CLK_DIV_0_AXI1, "clk_div_0_axi1", &bm1880_pll_clks[0].hw,
379
BM1880_CLK_DIV21, 16, 5, 2, bm1880_div_table_0,
380
0),
381
CLK_DIV(BM1880_CLK_DIV_1_AXI1, "clk_div_1_axi1", &bm1880_pll_clks[2].hw,
382
BM1880_CLK_DIV22, 16, 5, 3, bm1880_div_table_0,
383
0),
384
CLK_DIV(BM1880_CLK_DIV_0_AXI6, "clk_div_0_axi6", &bm1880_pll_clks[2].hw,
385
BM1880_CLK_DIV27, 16, 5, 15, bm1880_div_table_0,
386
0),
387
CLK_DIV(BM1880_CLK_DIV_1_AXI6, "clk_div_1_axi6", &bm1880_pll_clks[0].hw,
388
BM1880_CLK_DIV28, 16, 5, 11, bm1880_div_table_0,
389
0),
390
CLK_DIV(BM1880_CLK_DIV_12M_USB, "clk_div_12m_usb", &bm1880_pll_clks[2].hw,
391
BM1880_CLK_DIV18, 16, 7, 125, bm1880_div_table_1, 0),
392
};
393
394
/*
395
* Clocks marked as CRITICAL are all needed for the proper functioning
396
* of the SoC.
397
*/
398
static struct bm1880_composite_clock bm1880_composite_clks[] = {
399
/*
400
* Since clk_a53 and clk_50m_a53 clocks are sourcing the CPU core,
401
* let's mark them as critical to avoid gating.
402
*/
403
GATE_MUX(BM1880_CLK_A53, "clk_a53", clk_a53_parents,
404
BM1880_CLK_ENABLE0, 0, BM1880_CLK_SELECT, 0,
405
CLK_IS_CRITICAL),
406
GATE_DIV(BM1880_CLK_50M_A53, "clk_50m_a53", "clk_fpll",
407
BM1880_CLK_ENABLE0, 1, BM1880_CLK_DIV0, 16, 5, 30,
408
bm1880_div_table_0, CLK_IS_CRITICAL),
409
GATE_DIV(BM1880_CLK_EFUSE, "clk_efuse", "clk_fpll",
410
BM1880_CLK_ENABLE0, 5, BM1880_CLK_DIV1, 16, 7, 60,
411
bm1880_div_table_1, 0),
412
GATE_DIV(BM1880_CLK_EMMC, "clk_emmc", "clk_fpll",
413
BM1880_CLK_ENABLE0, 8, BM1880_CLK_DIV2, 16, 5, 15,
414
bm1880_div_table_0, 0),
415
GATE_DIV(BM1880_CLK_100K_EMMC, "clk_100k_emmc", "clk_div_12m_usb",
416
BM1880_CLK_ENABLE0, 9, BM1880_CLK_DIV3, 16, 8, 120,
417
bm1880_div_table_2, 0),
418
GATE_DIV(BM1880_CLK_SD, "clk_sd", "clk_fpll",
419
BM1880_CLK_ENABLE0, 11, BM1880_CLK_DIV4, 16, 5, 15,
420
bm1880_div_table_0, 0),
421
GATE_DIV(BM1880_CLK_100K_SD, "clk_100k_sd", "clk_div_12m_usb",
422
BM1880_CLK_ENABLE0, 12, BM1880_CLK_DIV5, 16, 8, 120,
423
bm1880_div_table_2, 0),
424
GATE_DIV(BM1880_CLK_500M_ETH0, "clk_500m_eth0", "clk_fpll",
425
BM1880_CLK_ENABLE0, 13, BM1880_CLK_DIV6, 16, 5, 3,
426
bm1880_div_table_0, 0),
427
GATE_DIV(BM1880_CLK_500M_ETH1, "clk_500m_eth1", "clk_fpll",
428
BM1880_CLK_ENABLE0, 15, BM1880_CLK_DIV7, 16, 5, 3,
429
bm1880_div_table_0, 0),
430
/* Don't gate GPIO clocks as it is not owned by the GPIO driver */
431
GATE_DIV(BM1880_CLK_GPIO_DB, "clk_gpio_db", "clk_div_12m_usb",
432
BM1880_CLK_ENABLE0, 20, BM1880_CLK_DIV8, 16, 16, 120,
433
bm1880_div_table_4, CLK_IGNORE_UNUSED),
434
GATE_DIV(BM1880_CLK_SDMA_AUD, "clk_sdma_aud", "clk_fpll",
435
BM1880_CLK_ENABLE0, 24, BM1880_CLK_DIV9, 16, 7, 61,
436
bm1880_div_table_1, 0),
437
GATE_DIV(BM1880_CLK_JPEG_AXI, "clk_jpeg_axi", "clk_fpll",
438
BM1880_CLK_ENABLE0, 28, BM1880_CLK_DIV10, 16, 5, 4,
439
bm1880_div_table_0, 0),
440
GATE_DIV(BM1880_CLK_NF, "clk_nf", "clk_fpll",
441
BM1880_CLK_ENABLE0, 31, BM1880_CLK_DIV11, 16, 5, 30,
442
bm1880_div_table_0, 0),
443
GATE_DIV(BM1880_CLK_TPU_AXI, "clk_tpu_axi", "clk_spll",
444
BM1880_CLK_ENABLE1, 3, BM1880_CLK_DIV14, 16, 5, 1,
445
bm1880_div_table_0, 0),
446
GATE_DIV(BM1880_CLK_125M_USB, "clk_125m_usb", "clk_fpll",
447
BM1880_CLK_ENABLE1, 9, BM1880_CLK_DIV16, 16, 5, 12,
448
bm1880_div_table_0, 0),
449
GATE_DIV(BM1880_CLK_33K_USB, "clk_33k_usb", "clk_div_12m_usb",
450
BM1880_CLK_ENABLE1, 10, BM1880_CLK_DIV17, 16, 9, 363,
451
bm1880_div_table_3, 0),
452
GATE_DIV(BM1880_CLK_VIDEO_AXI, "clk_video_axi", "clk_fpll",
453
BM1880_CLK_ENABLE1, 13, BM1880_CLK_DIV19, 16, 5, 4,
454
bm1880_div_table_0, 0),
455
GATE_DIV(BM1880_CLK_VPP_AXI, "clk_vpp_axi", "clk_fpll",
456
BM1880_CLK_ENABLE1, 14, BM1880_CLK_DIV20, 16, 5, 4,
457
bm1880_div_table_0, 0),
458
GATE_MUX(BM1880_CLK_AXI1, "clk_axi1", clk_axi1_parents,
459
BM1880_CLK_ENABLE1, 15, BM1880_CLK_SELECT, 2, 0),
460
GATE_DIV(BM1880_CLK_AXI2, "clk_axi2", "clk_fpll",
461
BM1880_CLK_ENABLE1, 17, BM1880_CLK_DIV23, 16, 5, 3,
462
bm1880_div_table_0, 0),
463
GATE_DIV(BM1880_CLK_AXI3, "clk_axi3", "clk_mux_rv",
464
BM1880_CLK_ENABLE1, 18, BM1880_CLK_DIV24, 16, 5, 2,
465
bm1880_div_table_0, 0),
466
GATE_DIV(BM1880_CLK_AXI4, "clk_axi4", "clk_fpll",
467
BM1880_CLK_ENABLE1, 19, BM1880_CLK_DIV25, 16, 5, 6,
468
bm1880_div_table_0, 0),
469
GATE_DIV(BM1880_CLK_AXI5, "clk_axi5", "clk_fpll",
470
BM1880_CLK_ENABLE1, 20, BM1880_CLK_DIV26, 16, 5, 15,
471
bm1880_div_table_0, 0),
472
};
473
474
static unsigned long bm1880_pll_rate_calc(u32 regval, unsigned long parent_rate)
475
{
476
u64 numerator;
477
u32 fbdiv, refdiv;
478
u32 postdiv1, postdiv2, denominator;
479
480
fbdiv = (regval >> 16) & 0xfff;
481
refdiv = regval & 0x1f;
482
postdiv1 = (regval >> 8) & 0x7;
483
postdiv2 = (regval >> 12) & 0x7;
484
485
numerator = parent_rate * fbdiv;
486
denominator = refdiv * postdiv1 * postdiv2;
487
do_div(numerator, denominator);
488
489
return (unsigned long)numerator;
490
}
491
492
static unsigned long bm1880_pll_recalc_rate(struct clk_hw *hw,
493
unsigned long parent_rate)
494
{
495
struct bm1880_pll_hw_clock *pll_hw = to_bm1880_pll_clk(hw);
496
unsigned long rate;
497
u32 regval;
498
499
regval = readl(pll_hw->base + pll_hw->pll.reg);
500
rate = bm1880_pll_rate_calc(regval, parent_rate);
501
502
return rate;
503
}
504
505
static const struct clk_ops bm1880_pll_ops = {
506
.recalc_rate = bm1880_pll_recalc_rate,
507
};
508
509
static struct clk_hw *bm1880_clk_register_pll(struct bm1880_pll_hw_clock *pll_clk,
510
void __iomem *sys_base)
511
{
512
struct clk_hw *hw;
513
int err;
514
515
pll_clk->base = sys_base;
516
hw = &pll_clk->hw;
517
518
err = clk_hw_register(NULL, hw);
519
if (err)
520
return ERR_PTR(err);
521
522
return hw;
523
}
524
525
static int bm1880_clk_register_plls(struct bm1880_pll_hw_clock *clks,
526
int num_clks,
527
struct bm1880_clock_data *data)
528
{
529
struct clk_hw *hw;
530
void __iomem *pll_base = data->pll_base;
531
int i;
532
533
for (i = 0; i < num_clks; i++) {
534
struct bm1880_pll_hw_clock *bm1880_clk = &clks[i];
535
536
hw = bm1880_clk_register_pll(bm1880_clk, pll_base);
537
if (IS_ERR(hw)) {
538
pr_err("%s: failed to register clock %s\n",
539
__func__, bm1880_clk->pll.name);
540
goto err_clk;
541
}
542
543
data->hw_data.hws[clks[i].pll.id] = hw;
544
}
545
546
return 0;
547
548
err_clk:
549
while (i--)
550
clk_hw_unregister(data->hw_data.hws[clks[i].pll.id]);
551
552
return PTR_ERR(hw);
553
}
554
555
static int bm1880_clk_register_mux(const struct bm1880_mux_clock *clks,
556
int num_clks,
557
struct bm1880_clock_data *data)
558
{
559
struct clk_hw *hw;
560
void __iomem *sys_base = data->sys_base;
561
int i;
562
563
for (i = 0; i < num_clks; i++) {
564
hw = clk_hw_register_mux(NULL, clks[i].name,
565
clks[i].parents,
566
clks[i].num_parents,
567
clks[i].flags,
568
sys_base + clks[i].reg,
569
clks[i].shift, 1, 0,
570
&bm1880_clk_lock);
571
if (IS_ERR(hw)) {
572
pr_err("%s: failed to register clock %s\n",
573
__func__, clks[i].name);
574
goto err_clk;
575
}
576
577
data->hw_data.hws[clks[i].id] = hw;
578
}
579
580
return 0;
581
582
err_clk:
583
while (i--)
584
clk_hw_unregister_mux(data->hw_data.hws[clks[i].id]);
585
586
return PTR_ERR(hw);
587
}
588
589
static unsigned long bm1880_clk_div_recalc_rate(struct clk_hw *hw,
590
unsigned long parent_rate)
591
{
592
struct bm1880_div_hw_clock *div_hw = to_bm1880_div_clk(hw);
593
struct bm1880_div_clock *div = &div_hw->div;
594
void __iomem *reg_addr = div_hw->base + div->reg;
595
unsigned int val;
596
unsigned long rate;
597
598
if (!(readl(reg_addr) & BIT(3))) {
599
val = div->initval;
600
} else {
601
val = readl(reg_addr) >> div->shift;
602
val &= clk_div_mask(div->width);
603
}
604
605
rate = divider_recalc_rate(hw, parent_rate, val, div->table,
606
div->flags, div->width);
607
608
return rate;
609
}
610
611
static long bm1880_clk_div_round_rate(struct clk_hw *hw, unsigned long rate,
612
unsigned long *prate)
613
{
614
struct bm1880_div_hw_clock *div_hw = to_bm1880_div_clk(hw);
615
struct bm1880_div_clock *div = &div_hw->div;
616
void __iomem *reg_addr = div_hw->base + div->reg;
617
618
if (div->flags & CLK_DIVIDER_READ_ONLY) {
619
u32 val;
620
621
val = readl(reg_addr) >> div->shift;
622
val &= clk_div_mask(div->width);
623
624
return divider_ro_round_rate(hw, rate, prate, div->table,
625
div->width, div->flags,
626
val);
627
}
628
629
return divider_round_rate(hw, rate, prate, div->table,
630
div->width, div->flags);
631
}
632
633
static int bm1880_clk_div_set_rate(struct clk_hw *hw, unsigned long rate,
634
unsigned long parent_rate)
635
{
636
struct bm1880_div_hw_clock *div_hw = to_bm1880_div_clk(hw);
637
struct bm1880_div_clock *div = &div_hw->div;
638
void __iomem *reg_addr = div_hw->base + div->reg;
639
unsigned long flags = 0;
640
int value;
641
u32 val;
642
643
value = divider_get_val(rate, parent_rate, div->table,
644
div->width, div_hw->div.flags);
645
if (value < 0)
646
return value;
647
648
if (div_hw->lock)
649
spin_lock_irqsave(div_hw->lock, flags);
650
else
651
__acquire(div_hw->lock);
652
653
val = readl(reg_addr);
654
val &= ~(clk_div_mask(div->width) << div_hw->div.shift);
655
val |= (u32)value << div->shift;
656
writel(val, reg_addr);
657
658
if (div_hw->lock)
659
spin_unlock_irqrestore(div_hw->lock, flags);
660
else
661
__release(div_hw->lock);
662
663
return 0;
664
}
665
666
static const struct clk_ops bm1880_clk_div_ops = {
667
.recalc_rate = bm1880_clk_div_recalc_rate,
668
.round_rate = bm1880_clk_div_round_rate,
669
.set_rate = bm1880_clk_div_set_rate,
670
};
671
672
static struct clk_hw *bm1880_clk_register_div(struct bm1880_div_hw_clock *div_clk,
673
void __iomem *sys_base)
674
{
675
struct clk_hw *hw;
676
int err;
677
678
div_clk->div.flags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO;
679
div_clk->base = sys_base;
680
div_clk->lock = &bm1880_clk_lock;
681
682
hw = &div_clk->hw;
683
err = clk_hw_register(NULL, hw);
684
if (err)
685
return ERR_PTR(err);
686
687
return hw;
688
}
689
690
static int bm1880_clk_register_divs(struct bm1880_div_hw_clock *clks,
691
int num_clks,
692
struct bm1880_clock_data *data)
693
{
694
struct clk_hw *hw;
695
void __iomem *sys_base = data->sys_base;
696
unsigned int i, id;
697
698
for (i = 0; i < num_clks; i++) {
699
struct bm1880_div_hw_clock *bm1880_clk = &clks[i];
700
701
hw = bm1880_clk_register_div(bm1880_clk, sys_base);
702
if (IS_ERR(hw)) {
703
pr_err("%s: failed to register clock %s\n",
704
__func__, bm1880_clk->div.name);
705
goto err_clk;
706
}
707
708
id = clks[i].div.id;
709
data->hw_data.hws[id] = hw;
710
}
711
712
return 0;
713
714
err_clk:
715
while (i--)
716
clk_hw_unregister(data->hw_data.hws[clks[i].div.id]);
717
718
return PTR_ERR(hw);
719
}
720
721
static int bm1880_clk_register_gate(const struct bm1880_gate_clock *clks,
722
int num_clks,
723
struct bm1880_clock_data *data)
724
{
725
struct clk_hw *hw;
726
void __iomem *sys_base = data->sys_base;
727
int i;
728
729
for (i = 0; i < num_clks; i++) {
730
hw = clk_hw_register_gate(NULL, clks[i].name,
731
clks[i].parent,
732
clks[i].flags,
733
sys_base + clks[i].gate_reg,
734
clks[i].gate_shift, 0,
735
&bm1880_clk_lock);
736
if (IS_ERR(hw)) {
737
pr_err("%s: failed to register clock %s\n",
738
__func__, clks[i].name);
739
goto err_clk;
740
}
741
742
data->hw_data.hws[clks[i].id] = hw;
743
}
744
745
return 0;
746
747
err_clk:
748
while (i--)
749
clk_hw_unregister_gate(data->hw_data.hws[clks[i].id]);
750
751
return PTR_ERR(hw);
752
}
753
754
static struct clk_hw *bm1880_clk_register_composite(struct bm1880_composite_clock *clks,
755
void __iomem *sys_base)
756
{
757
struct clk_hw *hw;
758
struct clk_mux *mux = NULL;
759
struct clk_gate *gate = NULL;
760
struct bm1880_div_hw_clock *div_hws = NULL;
761
struct clk_hw *mux_hw = NULL, *gate_hw = NULL, *div_hw = NULL;
762
const struct clk_ops *mux_ops = NULL, *gate_ops = NULL, *div_ops = NULL;
763
const char * const *parent_names;
764
const char *parent;
765
int num_parents;
766
int ret;
767
768
if (clks->mux_shift >= 0) {
769
mux = kzalloc(sizeof(*mux), GFP_KERNEL);
770
if (!mux)
771
return ERR_PTR(-ENOMEM);
772
773
mux->reg = sys_base + clks->mux_reg;
774
mux->mask = 1;
775
mux->shift = clks->mux_shift;
776
mux_hw = &mux->hw;
777
mux_ops = &clk_mux_ops;
778
mux->lock = &bm1880_clk_lock;
779
780
parent_names = clks->parents;
781
num_parents = clks->num_parents;
782
} else {
783
parent = clks->parent;
784
parent_names = &parent;
785
num_parents = 1;
786
}
787
788
if (clks->gate_shift >= 0) {
789
gate = kzalloc(sizeof(*gate), GFP_KERNEL);
790
if (!gate) {
791
ret = -ENOMEM;
792
goto err_out;
793
}
794
795
gate->reg = sys_base + clks->gate_reg;
796
gate->bit_idx = clks->gate_shift;
797
gate->lock = &bm1880_clk_lock;
798
799
gate_hw = &gate->hw;
800
gate_ops = &clk_gate_ops;
801
}
802
803
if (clks->div_shift >= 0) {
804
div_hws = kzalloc(sizeof(*div_hws), GFP_KERNEL);
805
if (!div_hws) {
806
ret = -ENOMEM;
807
goto err_out;
808
}
809
810
div_hws->base = sys_base;
811
div_hws->div.reg = clks->div_reg;
812
div_hws->div.shift = clks->div_shift;
813
div_hws->div.width = clks->div_width;
814
div_hws->div.table = clks->table;
815
div_hws->div.initval = clks->div_initval;
816
div_hws->lock = &bm1880_clk_lock;
817
div_hws->div.flags = CLK_DIVIDER_ONE_BASED |
818
CLK_DIVIDER_ALLOW_ZERO;
819
820
div_hw = &div_hws->hw;
821
div_ops = &bm1880_clk_div_ops;
822
}
823
824
hw = clk_hw_register_composite(NULL, clks->name, parent_names,
825
num_parents, mux_hw, mux_ops, div_hw,
826
div_ops, gate_hw, gate_ops,
827
clks->flags);
828
829
if (IS_ERR(hw)) {
830
ret = PTR_ERR(hw);
831
goto err_out;
832
}
833
834
return hw;
835
836
err_out:
837
kfree(div_hws);
838
kfree(gate);
839
kfree(mux);
840
841
return ERR_PTR(ret);
842
}
843
844
static int bm1880_clk_register_composites(struct bm1880_composite_clock *clks,
845
int num_clks,
846
struct bm1880_clock_data *data)
847
{
848
struct clk_hw *hw;
849
void __iomem *sys_base = data->sys_base;
850
int i;
851
852
for (i = 0; i < num_clks; i++) {
853
struct bm1880_composite_clock *bm1880_clk = &clks[i];
854
855
hw = bm1880_clk_register_composite(bm1880_clk, sys_base);
856
if (IS_ERR(hw)) {
857
pr_err("%s: failed to register clock %s\n",
858
__func__, bm1880_clk->name);
859
goto err_clk;
860
}
861
862
data->hw_data.hws[clks[i].id] = hw;
863
}
864
865
return 0;
866
867
err_clk:
868
while (i--)
869
clk_hw_unregister_composite(data->hw_data.hws[clks[i].id]);
870
871
return PTR_ERR(hw);
872
}
873
874
static int bm1880_clk_probe(struct platform_device *pdev)
875
{
876
struct bm1880_clock_data *clk_data;
877
void __iomem *pll_base, *sys_base;
878
struct device *dev = &pdev->dev;
879
int num_clks, i;
880
881
pll_base = devm_platform_ioremap_resource(pdev, 0);
882
if (IS_ERR(pll_base))
883
return PTR_ERR(pll_base);
884
885
sys_base = devm_platform_ioremap_resource(pdev, 1);
886
if (IS_ERR(sys_base))
887
return PTR_ERR(sys_base);
888
889
num_clks = ARRAY_SIZE(bm1880_pll_clks) +
890
ARRAY_SIZE(bm1880_div_clks) +
891
ARRAY_SIZE(bm1880_mux_clks) +
892
ARRAY_SIZE(bm1880_composite_clks) +
893
ARRAY_SIZE(bm1880_gate_clks);
894
895
clk_data = devm_kzalloc(dev, struct_size(clk_data, hw_data.hws,
896
num_clks), GFP_KERNEL);
897
if (!clk_data)
898
return -ENOMEM;
899
900
clk_data->pll_base = pll_base;
901
clk_data->sys_base = sys_base;
902
903
for (i = 0; i < num_clks; i++)
904
clk_data->hw_data.hws[i] = ERR_PTR(-ENOENT);
905
906
clk_data->hw_data.num = num_clks;
907
908
bm1880_clk_register_plls(bm1880_pll_clks,
909
ARRAY_SIZE(bm1880_pll_clks),
910
clk_data);
911
912
bm1880_clk_register_divs(bm1880_div_clks,
913
ARRAY_SIZE(bm1880_div_clks),
914
clk_data);
915
916
bm1880_clk_register_mux(bm1880_mux_clks,
917
ARRAY_SIZE(bm1880_mux_clks),
918
clk_data);
919
920
bm1880_clk_register_composites(bm1880_composite_clks,
921
ARRAY_SIZE(bm1880_composite_clks),
922
clk_data);
923
924
bm1880_clk_register_gate(bm1880_gate_clks,
925
ARRAY_SIZE(bm1880_gate_clks),
926
clk_data);
927
928
return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
929
&clk_data->hw_data);
930
}
931
932
static const struct of_device_id bm1880_of_match[] = {
933
{ .compatible = "bitmain,bm1880-clk", },
934
{}
935
};
936
MODULE_DEVICE_TABLE(of, bm1880_of_match);
937
938
static struct platform_driver bm1880_clk_driver = {
939
.driver = {
940
.name = "bm1880-clk",
941
.of_match_table = bm1880_of_match,
942
},
943
.probe = bm1880_clk_probe,
944
};
945
module_platform_driver(bm1880_clk_driver);
946
947
MODULE_AUTHOR("Manivannan Sadhasivam <[email protected]>");
948
MODULE_DESCRIPTION("Clock driver for Bitmain BM1880 SoC");
949
950