1// SPDX-License-Identifier: GPL-2.0
2/*
3 * R9A06G032 clock driver
4 *
5 * Copyright (C) 2018 Renesas Electronics Europe Limited
6 *
7 * Michel Pollet <michel.pollet@bp.renesas.com>, <buserror@gmail.com>
8 */
9
10#include <clk-uclass.h>
11#include <dm.h>
12#include <dm/device_compat.h>
13#include <regmap.h>
14#include <syscon.h>
15#include <linux/bitops.h>
16#include <linux/clk-provider.h>
17#include <linux/delay.h>
18#include <asm/io.h>
19
20#include <dt-bindings/clock/r9a06g032-sysctrl.h>
21
22/**
23 * struct regbit - describe one bit in a register
24 * @reg: offset of register relative to base address,
25 *          expressed in units of 32-bit words (not bytes),
26 * @bit: which bit (0 to 31) in the register
27 *
28 * This structure is used to compactly encode the location
29 * of a single bit in a register. Five bits are needed to
30 * encode the bit number. With uint16_t data type, this
31 * leaves 11 bits to encode a register offset up to 2047.
32 *
33 * Since registers are aligned on 32-bit boundaries, the
34 * offset will be specified in 32-bit words rather than bytes.
35 * This allows encoding an offset up to 0x1FFC (8188) bytes.
36 *
37 * Helper macro RB() takes care of converting the register
38 * offset from bytes to 32-bit words.
39 */
40struct regbit {
41	u16 reg:11;
42	u16 bit:5;
43};
44
45#define RB(_reg, _bit) ((struct regbit) { \
46	.reg = (_reg) / 4, \
47	.bit = (_bit) \
48})
49
50/**
51 * struct r9a06g032_gate - clock-related control bits
52 * @gate:   clock enable/disable
53 * @reset:  clock module reset (active low)
54 * @ready:  enables NoC forwarding of read/write requests to device,
55 *          (eg. device is ready to handle read/write requests)
56 * @midle:  request to idle the NoC interconnect
57 *
58 * Each of these fields describes a single bit in a register,
59 * which controls some aspect of clock gating. The @gate field
60 * is mandatory, this one enables/disables the clock. The
61 * other fields are optional, with zero indicating "not used".
62 *
63 * In most cases there is a @reset bit which needs to be
64 * de-asserted to bring the module out of reset.
65 *
66 * Modules may also need to signal when the are @ready to
67 * handle requests (read/writes) from the NoC interconnect.
68 *
69 * Similarly, the @midle bit is used to idle the master.
70 */
71struct r9a06g032_gate {
72	struct regbit gate, reset, ready, midle;
73	/* Unused fields omitted to save space */
74	/* struct regbit scon, mirack, mistat */;
75};
76
77enum gate_type {
78	K_GATE = 0,	/* gate which enable/disable */
79	K_FFC,		/* fixed factor clock */
80	K_DIV,		/* divisor */
81	K_BITSEL,	/* special for UARTs */
82	K_DUALGATE	/* special for UARTs */
83};
84
85/**
86 * struct r9a06g032_clkdesc - describe a single clock
87 * @name:      string describing this clock
88 * @managed:   boolean indicating if this clock should be
89 *             started/stopped as part of power management
90 *             (not used in u-boot)
91 * @type:      see enum @gate_type
92 * @index:     the ID of this clock element
93 * @source:    the ID+1 of the parent clock element.
94 *             Root clock uses ID of ~0 (PARENT_ID);
95 * @gate:      clock enable/disable
96 * @div_min:   smallest permitted clock divider
97 * @div_max:   largest permitted clock divider
98 * @reg:       clock divider register offset, in 32-bit words
99 * @div_table: optional list of fixed clock divider values;
100 *             must be in ascending order, zero for unused
101 * @div:       divisor for fixed-factor clock
102 * @mul:       multiplier for fixed-factor clock
103 * @group:     UART group, 0=UART0/1/2, 1=UART3/4/5/6/7
104 * @sel:       select either g1/r1 or g2/r2 as clock source
105 * @g1:        1st source gate (clock enable/disable)
106 * @r1:        1st source reset (module reset)
107 * @g2:        2nd source gate (clock enable/disable)
108 * @r2:        2nd source reset (module reset)
109 *
110 * Describes a single element in the clock tree hierarchy.
111 * As there are quite a large number of clock elements, this
112 * structure is packed tightly to conserve space.
113 */
114struct r9a06g032_clkdesc {
115	const char *name;
116	uint32_t managed:1;
117	enum gate_type type:3;
118	uint32_t index:8;
119	uint32_t source:8; /* source index + 1 (0 == none) */
120	union {
121		/* type = K_GATE */
122		struct r9a06g032_gate gate;
123		/* type = K_DIV  */
124		struct {
125			unsigned int div_min:10, div_max:10, reg:10;
126			u16 div_table[4];
127		};
128		/* type = K_FFC */
129		struct {
130			u16 div, mul;
131		};
132		/* type = K_DUALGATE */
133		struct {
134			uint16_t group:1;
135			struct regbit sel, g1, r1, g2, r2;
136		} dual;
137	};
138};
139
140/*
141 * The last three arguments are not currently used,
142 * but are kept in the r9a06g032_clocks table below.
143 */
144#define I_GATE(_clk, _rst, _rdy, _midle, _scon, _mirack, _mistat) { \
145	.gate = _clk, \
146	.reset = _rst, \
147	.ready = _rdy, \
148	.midle = _midle, \
149	/* .scon = _scon, */ \
150	/* .mirack = _mirack, */ \
151	/* .mistat = _mistat */ \
152}
153#define D_GATE(_idx, _n, _src, ...) { \
154	.type = K_GATE, \
155	.index = R9A06G032_##_idx, \
156	.source = 1 + R9A06G032_##_src, \
157	.name = _n, \
158	.gate = I_GATE(__VA_ARGS__) \
159}
160#define D_MODULE(_idx, _n, _src, ...) { \
161	.type = K_GATE, \
162	.index = R9A06G032_##_idx, \
163	.source = 1 + R9A06G032_##_src, \
164	.name = _n, \
165	.managed = 1, \
166	.gate = I_GATE(__VA_ARGS__) \
167}
168#define D_ROOT(_idx, _n, _mul, _div) { \
169	.type = K_FFC, \
170	.index = R9A06G032_##_idx, \
171	.name = _n, \
172	.div = _div, \
173	.mul = _mul \
174}
175#define D_FFC(_idx, _n, _src, _div) { \
176	.type = K_FFC, \
177	.index = R9A06G032_##_idx, \
178	.source = 1 + R9A06G032_##_src, \
179	.name = _n, \
180	.div = _div, \
181	.mul = 1 \
182}
183#define D_DIV(_idx, _n, _src, _reg, _min, _max, ...) { \
184	.type = K_DIV, \
185	.index = R9A06G032_##_idx, \
186	.source = 1 + R9A06G032_##_src, \
187	.name = _n, \
188	.reg = _reg, \
189	.div_min = _min, \
190	.div_max = _max, \
191	.div_table = { __VA_ARGS__ } \
192}
193#define D_UGATE(_idx, _n, _src, _g, _g1, _r1, _g2, _r2) { \
194	.type = K_DUALGATE, \
195	.index = R9A06G032_##_idx, \
196	.source = 1 + R9A06G032_##_src, \
197	.name = _n, \
198	.dual = { \
199		.group = _g, \
200		.g1 = _g1, \
201		.r1 = _r1, \
202		.g2 = _g2, \
203		.r2 = _r2 \
204	}, \
205}
206
207/* Internal clock IDs */
208#define R9A06G032_CLKOUT		0
209#define R9A06G032_CLKOUT_D10		2
210#define R9A06G032_CLKOUT_D16		3
211#define R9A06G032_CLKOUT_D160		4
212#define R9A06G032_CLKOUT_D1OR2		5
213#define R9A06G032_CLKOUT_D20		6
214#define R9A06G032_CLKOUT_D40		7
215#define R9A06G032_CLKOUT_D5		8
216#define R9A06G032_CLKOUT_D8		9
217#define R9A06G032_DIV_ADC		10
218#define R9A06G032_DIV_I2C		11
219#define R9A06G032_DIV_NAND		12
220#define R9A06G032_DIV_P1_PG		13
221#define R9A06G032_DIV_P2_PG		14
222#define R9A06G032_DIV_P3_PG		15
223#define R9A06G032_DIV_P4_PG		16
224#define R9A06G032_DIV_P5_PG		17
225#define R9A06G032_DIV_P6_PG		18
226#define R9A06G032_DIV_QSPI0		19
227#define R9A06G032_DIV_QSPI1		20
228#define R9A06G032_DIV_REF_SYNC		21
229#define R9A06G032_DIV_SDIO0		22
230#define R9A06G032_DIV_SDIO1		23
231#define R9A06G032_DIV_SWITCH		24
232#define R9A06G032_DIV_UART		25
233#define R9A06G032_DIV_MOTOR		64
234#define R9A06G032_CLK_DDRPHY_PLLCLK_D4	78
235#define R9A06G032_CLK_ECAT100_D4	79
236#define R9A06G032_CLK_HSR100_D2		80
237#define R9A06G032_CLK_REF_SYNC_D4	81
238#define R9A06G032_CLK_REF_SYNC_D8	82
239#define R9A06G032_CLK_SERCOS100_D2	83
240#define R9A06G032_DIV_CA7		84
241
242#define R9A06G032_UART_GROUP_012	154
243#define R9A06G032_UART_GROUP_34567	155
244
245#define R9A06G032_CLOCK_COUNT		(R9A06G032_UART_GROUP_34567 + 1)
246
247static const struct r9a06g032_clkdesc r9a06g032_clocks[] = {
248	D_ROOT(CLKOUT, "clkout", 25, 1),
249	D_ROOT(CLK_PLL_USB, "clk_pll_usb", 12, 10),
250	D_FFC(CLKOUT_D10, "clkout_d10", CLKOUT, 10),
251	D_FFC(CLKOUT_D16, "clkout_d16", CLKOUT, 16),
252	D_FFC(CLKOUT_D160, "clkout_d160", CLKOUT, 160),
253	D_DIV(CLKOUT_D1OR2, "clkout_d1or2", CLKOUT, 0, 1, 2),
254	D_FFC(CLKOUT_D20, "clkout_d20", CLKOUT, 20),
255	D_FFC(CLKOUT_D40, "clkout_d40", CLKOUT, 40),
256	D_FFC(CLKOUT_D5, "clkout_d5", CLKOUT, 5),
257	D_FFC(CLKOUT_D8, "clkout_d8", CLKOUT, 8),
258	D_DIV(DIV_ADC, "div_adc", CLKOUT, 77, 50, 250),
259	D_DIV(DIV_I2C, "div_i2c", CLKOUT, 78, 12, 16),
260	D_DIV(DIV_NAND, "div_nand", CLKOUT, 82, 12, 32),
261	D_DIV(DIV_P1_PG, "div_p1_pg", CLKOUT, 68, 12, 200),
262	D_DIV(DIV_P2_PG, "div_p2_pg", CLKOUT, 62, 12, 128),
263	D_DIV(DIV_P3_PG, "div_p3_pg", CLKOUT, 64, 8, 128),
264	D_DIV(DIV_P4_PG, "div_p4_pg", CLKOUT, 66, 8, 128),
265	D_DIV(DIV_P5_PG, "div_p5_pg", CLKOUT, 71, 10, 40),
266	D_DIV(DIV_P6_PG, "div_p6_pg", CLKOUT, 18, 12, 64),
267	D_DIV(DIV_QSPI0, "div_qspi0", CLKOUT, 73, 3, 7),
268	D_DIV(DIV_QSPI1, "div_qspi1", CLKOUT, 25, 3, 7),
269	D_DIV(DIV_REF_SYNC, "div_ref_sync", CLKOUT, 56, 2, 16, 2, 4, 8, 16),
270	D_DIV(DIV_SDIO0, "div_sdio0", CLKOUT, 74, 20, 128),
271	D_DIV(DIV_SDIO1, "div_sdio1", CLKOUT, 75, 20, 128),
272	D_DIV(DIV_SWITCH, "div_switch", CLKOUT, 37, 5, 40),
273	D_DIV(DIV_UART, "div_uart", CLKOUT, 79, 12, 128),
274	D_GATE(CLK_25_PG4, "clk_25_pg4", CLKOUT_D40, RB(0xe8, 9),
275	       RB(0xe8, 10), RB(0xe8, 11), RB(0x00, 0),
276	       RB(0x15c, 3), RB(0x00, 0), RB(0x00, 0)),
277	D_GATE(CLK_25_PG5, "clk_25_pg5", CLKOUT_D40, RB(0xe8, 12),
278	       RB(0xe8, 13), RB(0xe8, 14), RB(0x00, 0),
279	       RB(0x15c, 4), RB(0x00, 0), RB(0x00, 0)),
280	D_GATE(CLK_25_PG6, "clk_25_pg6", CLKOUT_D40, RB(0xe8, 15),
281	       RB(0xe8, 16), RB(0xe8, 17), RB(0x00, 0),
282	       RB(0x15c, 5), RB(0x00, 0), RB(0x00, 0)),
283	D_GATE(CLK_25_PG7, "clk_25_pg7", CLKOUT_D40, RB(0xe8, 18),
284	       RB(0xe8, 19), RB(0xe8, 20), RB(0x00, 0),
285	       RB(0x15c, 6), RB(0x00, 0), RB(0x00, 0)),
286	D_GATE(CLK_25_PG8, "clk_25_pg8", CLKOUT_D40, RB(0xe8, 21),
287	       RB(0xe8, 22), RB(0xe8, 23), RB(0x00, 0),
288	       RB(0x15c, 7), RB(0x00, 0), RB(0x00, 0)),
289	D_GATE(CLK_ADC, "clk_adc", DIV_ADC, RB(0x3c, 10),
290	       RB(0x3c, 11), RB(0x00, 0), RB(0x00, 0),
291	       RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
292	D_GATE(CLK_ECAT100, "clk_ecat100", CLKOUT_D10, RB(0x80, 5),
293	       RB(0x00, 0), RB(0x00, 0), RB(0x00, 0),
294	       RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
295	D_GATE(CLK_HSR100, "clk_hsr100", CLKOUT_D10, RB(0x90, 3),
296	       RB(0x00, 0), RB(0x00, 0), RB(0x00, 0),
297	       RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
298	D_GATE(CLK_I2C0, "clk_i2c0", DIV_I2C, RB(0x3c, 6),
299	       RB(0x3c, 7), RB(0x00, 0), RB(0x00, 0),
300	       RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
301	D_GATE(CLK_I2C1, "clk_i2c1", DIV_I2C, RB(0x3c, 8),
302	       RB(0x3c, 9), RB(0x00, 0), RB(0x00, 0),
303	       RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
304	D_GATE(CLK_MII_REF, "clk_mii_ref", CLKOUT_D40, RB(0x68, 2),
305	       RB(0x00, 0), RB(0x00, 0), RB(0x00, 0),
306	       RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
307	D_GATE(CLK_NAND, "clk_nand", DIV_NAND, RB(0x50, 4),
308	       RB(0x50, 5), RB(0x00, 0), RB(0x00, 0),
309	       RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
310	D_GATE(CLK_NOUSBP2_PG6, "clk_nousbp2_pg6", DIV_P2_PG, RB(0xec, 20),
311	       RB(0xec, 21), RB(0x00, 0), RB(0x00, 0),
312	       RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
313	D_GATE(CLK_P1_PG2, "clk_p1_pg2", DIV_P1_PG, RB(0x10c, 2),
314	       RB(0x10c, 3), RB(0x00, 0), RB(0x00, 0),
315	       RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
316	D_GATE(CLK_P1_PG3, "clk_p1_pg3", DIV_P1_PG, RB(0x10c, 4),
317	       RB(0x10c, 5), RB(0x00, 0), RB(0x00, 0),
318	       RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
319	D_GATE(CLK_P1_PG4, "clk_p1_pg4", DIV_P1_PG, RB(0x10c, 6),
320	       RB(0x10c, 7), RB(0x00, 0), RB(0x00, 0),
321	       RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
322	D_GATE(CLK_P4_PG3, "clk_p4_pg3", DIV_P4_PG, RB(0x104, 4),
323	       RB(0x104, 5), RB(0x00, 0), RB(0x00, 0),
324	       RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
325	D_GATE(CLK_P4_PG4, "clk_p4_pg4", DIV_P4_PG, RB(0x104, 6),
326	       RB(0x104, 7), RB(0x00, 0), RB(0x00, 0),
327	       RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
328	D_GATE(CLK_P6_PG1, "clk_p6_pg1", DIV_P6_PG, RB(0x114, 0),
329	       RB(0x114, 1), RB(0x114, 2), RB(0x00, 0),
330	       RB(0x16c, 0), RB(0x00, 0), RB(0x00, 0)),
331	D_GATE(CLK_P6_PG2, "clk_p6_pg2", DIV_P6_PG, RB(0x114, 3),
332	       RB(0x114, 4), RB(0x114, 5), RB(0x00, 0),
333	       RB(0x16c, 1), RB(0x00, 0), RB(0x00, 0)),
334	D_GATE(CLK_P6_PG3, "clk_p6_pg3", DIV_P6_PG, RB(0x114, 6),
335	       RB(0x114, 7), RB(0x114, 8), RB(0x00, 0),
336	       RB(0x16c, 2), RB(0x00, 0), RB(0x00, 0)),
337	D_GATE(CLK_P6_PG4, "clk_p6_pg4", DIV_P6_PG, RB(0x114, 9),
338	       RB(0x114, 10), RB(0x114, 11), RB(0x00, 0),
339	       RB(0x16c, 3), RB(0x00, 0), RB(0x00, 0)),
340	D_MODULE(CLK_PCI_USB, "clk_pci_usb", CLKOUT_D40, RB(0x1c, 6),
341		 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0),
342		 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
343	D_GATE(CLK_QSPI0, "clk_qspi0", DIV_QSPI0, RB(0x54, 4),
344	       RB(0x54, 5), RB(0x00, 0), RB(0x00, 0),
345	       RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
346	D_GATE(CLK_QSPI1, "clk_qspi1", DIV_QSPI1, RB(0x90, 4),
347	       RB(0x90, 5), RB(0x00, 0), RB(0x00, 0),
348	       RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
349	D_GATE(CLK_RGMII_REF, "clk_rgmii_ref", CLKOUT_D8, RB(0x68, 0),
350	       RB(0x00, 0), RB(0x00, 0), RB(0x00, 0),
351	       RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
352	D_GATE(CLK_RMII_REF, "clk_rmii_ref", CLKOUT_D20, RB(0x68, 1),
353	       RB(0x00, 0), RB(0x00, 0), RB(0x00, 0),
354	       RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
355	D_GATE(CLK_SDIO0, "clk_sdio0", DIV_SDIO0, RB(0x0c, 4),
356	       RB(0x00, 0), RB(0x00, 0), RB(0x00, 0),
357	       RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
358	D_GATE(CLK_SDIO1, "clk_sdio1", DIV_SDIO1, RB(0xc8, 4),
359	       RB(0x00, 0), RB(0x00, 0), RB(0x00, 0),
360	       RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
361	D_GATE(CLK_SERCOS100, "clk_sercos100", CLKOUT_D10, RB(0x84, 5),
362	       RB(0x00, 0), RB(0x00, 0), RB(0x00, 0),
363	       RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
364	D_GATE(CLK_SLCD, "clk_slcd", DIV_P1_PG, RB(0x10c, 0),
365	       RB(0x10c, 1), RB(0x00, 0), RB(0x00, 0),
366	       RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
367	D_GATE(CLK_SPI0, "clk_spi0", DIV_P3_PG, RB(0xfc, 0),
368	       RB(0xfc, 1), RB(0x00, 0), RB(0x00, 0),
369	       RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
370	D_GATE(CLK_SPI1, "clk_spi1", DIV_P3_PG, RB(0xfc, 2),
371	       RB(0xfc, 3), RB(0x00, 0), RB(0x00, 0),
372	       RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
373	D_GATE(CLK_SPI2, "clk_spi2", DIV_P3_PG, RB(0xfc, 4),
374	       RB(0xfc, 5), RB(0x00, 0), RB(0x00, 0),
375	       RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
376	D_GATE(CLK_SPI3, "clk_spi3", DIV_P3_PG, RB(0xfc, 6),
377	       RB(0xfc, 7), RB(0x00, 0), RB(0x00, 0),
378	       RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
379	D_GATE(CLK_SPI4, "clk_spi4", DIV_P4_PG, RB(0x104, 0),
380	       RB(0x104, 1), RB(0x00, 0), RB(0x00, 0),
381	       RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
382	D_GATE(CLK_SPI5, "clk_spi5", DIV_P4_PG, RB(0x104, 2),
383	       RB(0x104, 3), RB(0x00, 0), RB(0x00, 0),
384	       RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
385	D_GATE(CLK_SWITCH, "clk_switch", DIV_SWITCH, RB(0x130, 2),
386	       RB(0x130, 3), RB(0x00, 0), RB(0x00, 0),
387	       RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
388	D_DIV(DIV_MOTOR, "div_motor", CLKOUT_D5, 84, 2, 8),
389	D_MODULE(HCLK_ECAT125, "hclk_ecat125", CLKOUT_D8, RB(0x80, 0),
390		 RB(0x80, 1), RB(0x00, 0), RB(0x80, 2),
391		 RB(0x00, 0), RB(0x88, 0), RB(0x88, 1)),
392	D_MODULE(HCLK_PINCONFIG, "hclk_pinconfig", CLKOUT_D40, RB(0xe8, 0),
393		 RB(0xe8, 1), RB(0xe8, 2), RB(0x00, 0),
394		 RB(0x15c, 0), RB(0x00, 0), RB(0x00, 0)),
395	D_MODULE(HCLK_SERCOS, "hclk_sercos", CLKOUT_D10, RB(0x84, 0),
396		 RB(0x84, 2), RB(0x00, 0), RB(0x84, 1),
397		 RB(0x00, 0), RB(0x8c, 0), RB(0x8c, 1)),
398	D_MODULE(HCLK_SGPIO2, "hclk_sgpio2", DIV_P5_PG, RB(0x118, 3),
399		 RB(0x118, 4), RB(0x118, 5), RB(0x00, 0),
400		 RB(0x168, 1), RB(0x00, 0), RB(0x00, 0)),
401	D_MODULE(HCLK_SGPIO3, "hclk_sgpio3", DIV_P5_PG, RB(0x118, 6),
402		 RB(0x118, 7), RB(0x118, 8), RB(0x00, 0),
403		 RB(0x168, 2), RB(0x00, 0), RB(0x00, 0)),
404	D_MODULE(HCLK_SGPIO4, "hclk_sgpio4", DIV_P5_PG, RB(0x118, 9),
405		 RB(0x118, 10), RB(0x118, 11), RB(0x00, 0),
406		 RB(0x168, 3), RB(0x00, 0), RB(0x00, 0)),
407	D_MODULE(HCLK_TIMER0, "hclk_timer0", CLKOUT_D40, RB(0xe8, 3),
408		 RB(0xe8, 4), RB(0xe8, 5), RB(0x00, 0),
409		 RB(0x15c, 1), RB(0x00, 0), RB(0x00, 0)),
410	D_MODULE(HCLK_TIMER1, "hclk_timer1", CLKOUT_D40, RB(0xe8, 6),
411		 RB(0xe8, 7), RB(0xe8, 8), RB(0x00, 0),
412		 RB(0x15c, 2), RB(0x00, 0), RB(0x00, 0)),
413	D_MODULE(HCLK_USBF, "hclk_usbf", CLKOUT_D8, RB(0x1c, 3),
414		 RB(0x00, 0), RB(0x00, 0), RB(0x1c, 4),
415		 RB(0x00, 0), RB(0x20, 2), RB(0x20, 3)),
416	D_MODULE(HCLK_USBH, "hclk_usbh", CLKOUT_D8, RB(0x1c, 0),
417		 RB(0x1c, 1), RB(0x00, 0), RB(0x1c, 2),
418		 RB(0x00, 0), RB(0x20, 0), RB(0x20, 1)),
419	D_MODULE(HCLK_USBPM, "hclk_usbpm", CLKOUT_D8, RB(0x1c, 5),
420		 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0),
421		 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
422	D_GATE(CLK_48_PG_F, "clk_48_pg_f", CLK_48, RB(0xf0, 12),
423	       RB(0xf0, 13), RB(0x00, 0), RB(0xf0, 14),
424	       RB(0x00, 0), RB(0x160, 4), RB(0x160, 5)),
425	D_GATE(CLK_48_PG4, "clk_48_pg4", CLK_48, RB(0xf0, 9),
426	       RB(0xf0, 10), RB(0xf0, 11), RB(0x00, 0),
427	       RB(0x160, 3), RB(0x00, 0), RB(0x00, 0)),
428	D_FFC(CLK_DDRPHY_PLLCLK_D4, "clk_ddrphy_pllclk_d4", CLK_DDRPHY_PLLCLK, 4),
429	D_FFC(CLK_ECAT100_D4, "clk_ecat100_d4", CLK_ECAT100, 4),
430	D_FFC(CLK_HSR100_D2, "clk_hsr100_d2", CLK_HSR100, 2),
431	D_FFC(CLK_REF_SYNC_D4, "clk_ref_sync_d4", CLK_REF_SYNC, 4),
432	D_FFC(CLK_REF_SYNC_D8, "clk_ref_sync_d8", CLK_REF_SYNC, 8),
433	D_FFC(CLK_SERCOS100_D2, "clk_sercos100_d2", CLK_SERCOS100, 2),
434	D_DIV(DIV_CA7, "div_ca7", CLK_REF_SYNC, 57, 1, 4, 1, 2, 4),
435	D_MODULE(HCLK_CAN0, "hclk_can0", CLK_48, RB(0xf0, 3),
436		 RB(0xf0, 4), RB(0xf0, 5), RB(0x00, 0),
437		 RB(0x160, 1), RB(0x00, 0), RB(0x00, 0)),
438	D_MODULE(HCLK_CAN1, "hclk_can1", CLK_48, RB(0xf0, 6),
439		 RB(0xf0, 7), RB(0xf0, 8), RB(0x00, 0),
440		 RB(0x160, 2), RB(0x00, 0), RB(0x00, 0)),
441	D_MODULE(HCLK_DELTASIGMA, "hclk_deltasigma", DIV_MOTOR, RB(0x3c, 15),
442		 RB(0x3c, 16), RB(0x3c, 17), RB(0x00, 0),
443		 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
444	D_MODULE(HCLK_PWMPTO, "hclk_pwmpto", DIV_MOTOR, RB(0x3c, 12),
445		 RB(0x3c, 13), RB(0x3c, 14), RB(0x00, 0),
446		 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
447	D_MODULE(HCLK_RSV, "hclk_rsv", CLK_48, RB(0xf0, 0),
448		 RB(0xf0, 1), RB(0xf0, 2), RB(0x00, 0),
449		 RB(0x160, 0), RB(0x00, 0), RB(0x00, 0)),
450	D_MODULE(HCLK_SGPIO0, "hclk_sgpio0", DIV_MOTOR, RB(0x3c, 0),
451		 RB(0x3c, 1), RB(0x3c, 2), RB(0x00, 0),
452		 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
453	D_MODULE(HCLK_SGPIO1, "hclk_sgpio1", DIV_MOTOR, RB(0x3c, 3),
454		 RB(0x3c, 4), RB(0x3c, 5), RB(0x00, 0),
455		 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
456	D_DIV(RTOS_MDC, "rtos_mdc", CLK_REF_SYNC, 100, 80, 640, 80, 160, 320, 640),
457	D_GATE(CLK_CM3, "clk_cm3", CLK_REF_SYNC_D4, RB(0x174, 0),
458	       RB(0x174, 1), RB(0x00, 0), RB(0x174, 2),
459	       RB(0x00, 0), RB(0x178, 0), RB(0x178, 1)),
460	D_GATE(CLK_DDRC, "clk_ddrc", CLK_DDRPHY_PLLCLK_D4, RB(0x64, 3),
461	       RB(0x64, 4), RB(0x00, 0), RB(0x00, 0),
462	       RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
463	D_GATE(CLK_ECAT25, "clk_ecat25", CLK_ECAT100_D4, RB(0x80, 3),
464	       RB(0x80, 4), RB(0x00, 0), RB(0x00, 0),
465	       RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
466	D_GATE(CLK_HSR50, "clk_hsr50", CLK_HSR100_D2, RB(0x90, 4),
467	       RB(0x90, 5), RB(0x00, 0), RB(0x00, 0),
468	       RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
469	D_GATE(CLK_HW_RTOS, "clk_hw_rtos", CLK_REF_SYNC_D4, RB(0x18c, 0),
470	       RB(0x18c, 1), RB(0x00, 0), RB(0x00, 0),
471	       RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
472	D_GATE(CLK_SERCOS50, "clk_sercos50", CLK_SERCOS100_D2, RB(0x84, 4),
473	       RB(0x84, 3), RB(0x00, 0), RB(0x00, 0),
474	       RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
475	D_MODULE(HCLK_ADC, "hclk_adc", CLK_REF_SYNC_D8, RB(0x34, 15),
476		 RB(0x34, 16), RB(0x34, 17), RB(0x00, 0),
477		 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
478	D_MODULE(HCLK_CM3, "hclk_cm3", CLK_REF_SYNC_D4, RB(0x184, 0),
479		 RB(0x184, 1), RB(0x184, 2), RB(0x00, 0),
480		 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
481	D_MODULE(HCLK_CRYPTO_EIP150, "hclk_crypto_eip150", CLK_REF_SYNC_D4, RB(0x24, 3),
482		 RB(0x24, 4), RB(0x24, 5), RB(0x00, 0),
483		 RB(0x28, 2), RB(0x00, 0), RB(0x00, 0)),
484	D_MODULE(HCLK_CRYPTO_EIP93, "hclk_crypto_eip93", CLK_REF_SYNC_D4, RB(0x24, 0),
485		 RB(0x24, 1), RB(0x00, 0), RB(0x24, 2),
486		 RB(0x00, 0), RB(0x28, 0), RB(0x28, 1)),
487	D_MODULE(HCLK_DDRC, "hclk_ddrc", CLK_REF_SYNC_D4, RB(0x64, 0),
488		 RB(0x64, 2), RB(0x00, 0), RB(0x64, 1),
489		 RB(0x00, 0), RB(0x74, 0), RB(0x74, 1)),
490	D_MODULE(HCLK_DMA0, "hclk_dma0", CLK_REF_SYNC_D4, RB(0x4c, 0),
491		 RB(0x4c, 1), RB(0x4c, 2), RB(0x4c, 3),
492		 RB(0x58, 0), RB(0x58, 1), RB(0x58, 2)),
493	D_MODULE(HCLK_DMA1, "hclk_dma1", CLK_REF_SYNC_D4, RB(0x4c, 4),
494		 RB(0x4c, 5), RB(0x4c, 6), RB(0x4c, 7),
495		 RB(0x58, 3), RB(0x58, 4), RB(0x58, 5)),
496	D_MODULE(HCLK_GMAC0, "hclk_gmac0", CLK_REF_SYNC_D4, RB(0x6c, 0),
497		 RB(0x6c, 1), RB(0x6c, 2), RB(0x6c, 3),
498		 RB(0x78, 0), RB(0x78, 1), RB(0x78, 2)),
499	D_MODULE(HCLK_GMAC1, "hclk_gmac1", CLK_REF_SYNC_D4, RB(0x70, 0),
500		 RB(0x70, 1), RB(0x70, 2), RB(0x70, 3),
501		 RB(0x7c, 0), RB(0x7c, 1), RB(0x7c, 2)),
502	D_MODULE(HCLK_GPIO0, "hclk_gpio0", CLK_REF_SYNC_D4, RB(0x40, 18),
503		 RB(0x40, 19), RB(0x40, 20), RB(0x00, 0),
504		 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
505	D_MODULE(HCLK_GPIO1, "hclk_gpio1", CLK_REF_SYNC_D4, RB(0x40, 21),
506		 RB(0x40, 22), RB(0x40, 23), RB(0x00, 0),
507		 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
508	D_MODULE(HCLK_GPIO2, "hclk_gpio2", CLK_REF_SYNC_D4, RB(0x44, 9),
509		 RB(0x44, 10), RB(0x44, 11), RB(0x00, 0),
510		 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
511	D_MODULE(HCLK_HSR, "hclk_hsr", CLK_HSR100_D2, RB(0x90, 0),
512		 RB(0x90, 2), RB(0x00, 0), RB(0x90, 1),
513		 RB(0x00, 0), RB(0x98, 0), RB(0x98, 1)),
514	D_MODULE(HCLK_I2C0, "hclk_i2c0", CLK_REF_SYNC_D8, RB(0x34, 9),
515		 RB(0x34, 10), RB(0x34, 11), RB(0x00, 0),
516		 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
517	D_MODULE(HCLK_I2C1, "hclk_i2c1", CLK_REF_SYNC_D8, RB(0x34, 12),
518		 RB(0x34, 13), RB(0x34, 14), RB(0x00, 0),
519		 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
520	D_MODULE(HCLK_LCD, "hclk_lcd", CLK_REF_SYNC_D4, RB(0xf4, 0),
521		 RB(0xf4, 1), RB(0xf4, 2), RB(0x00, 0),
522		 RB(0x164, 0), RB(0x00, 0), RB(0x00, 0)),
523	D_MODULE(HCLK_MSEBI_M, "hclk_msebi_m", CLK_REF_SYNC_D4, RB(0x2c, 4),
524		 RB(0x2c, 5), RB(0x2c, 6), RB(0x00, 0),
525		 RB(0x30, 3), RB(0x00, 0), RB(0x00, 0)),
526	D_MODULE(HCLK_MSEBI_S, "hclk_msebi_s", CLK_REF_SYNC_D4, RB(0x2c, 0),
527		 RB(0x2c, 1), RB(0x2c, 2), RB(0x2c, 3),
528		 RB(0x30, 0), RB(0x30, 1), RB(0x30, 2)),
529	D_MODULE(HCLK_NAND, "hclk_nand", CLK_REF_SYNC_D4, RB(0x50, 0),
530		 RB(0x50, 1), RB(0x50, 2), RB(0x50, 3),
531		 RB(0x5c, 0), RB(0x5c, 1), RB(0x5c, 2)),
532	D_MODULE(HCLK_PG_I, "hclk_pg_i", CLK_REF_SYNC_D4, RB(0xf4, 12),
533		 RB(0xf4, 13), RB(0x00, 0), RB(0xf4, 14),
534		 RB(0x00, 0), RB(0x164, 4), RB(0x164, 5)),
535	D_MODULE(HCLK_PG19, "hclk_pg19", CLK_REF_SYNC_D4, RB(0x44, 12),
536		 RB(0x44, 13), RB(0x44, 14), RB(0x00, 0),
537		 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
538	D_MODULE(HCLK_PG20, "hclk_pg20", CLK_REF_SYNC_D4, RB(0x44, 15),
539		 RB(0x44, 16), RB(0x44, 17), RB(0x00, 0),
540		 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
541	D_MODULE(HCLK_PG3, "hclk_pg3", CLK_REF_SYNC_D4, RB(0xf4, 6),
542		 RB(0xf4, 7), RB(0xf4, 8), RB(0x00, 0),
543		 RB(0x164, 2), RB(0x00, 0), RB(0x00, 0)),
544	D_MODULE(HCLK_PG4, "hclk_pg4", CLK_REF_SYNC_D4, RB(0xf4, 9),
545		 RB(0xf4, 10), RB(0xf4, 11), RB(0x00, 0),
546		 RB(0x164, 3), RB(0x00, 0), RB(0x00, 0)),
547	D_MODULE(HCLK_QSPI0, "hclk_qspi0", CLK_REF_SYNC_D4, RB(0x54, 0),
548		 RB(0x54, 1), RB(0x54, 2), RB(0x54, 3),
549		 RB(0x60, 0), RB(0x60, 1), RB(0x60, 2)),
550	D_MODULE(HCLK_QSPI1, "hclk_qspi1", CLK_REF_SYNC_D4, RB(0x90, 0),
551		 RB(0x90, 1), RB(0x90, 2), RB(0x90, 3),
552		 RB(0x98, 0), RB(0x98, 1), RB(0x98, 2)),
553	D_MODULE(HCLK_ROM, "hclk_rom", CLK_REF_SYNC_D4, RB(0x154, 0),
554		 RB(0x154, 1), RB(0x154, 2), RB(0x00, 0),
555		 RB(0x170, 0), RB(0x00, 0), RB(0x00, 0)),
556	D_MODULE(HCLK_RTC, "hclk_rtc", CLK_REF_SYNC_D8, RB(0x140, 0),
557		 RB(0x140, 3), RB(0x00, 0), RB(0x140, 2),
558		 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
559	D_MODULE(HCLK_SDIO0, "hclk_sdio0", CLK_REF_SYNC_D4, RB(0x0c, 0),
560		 RB(0x0c, 1), RB(0x0c, 2), RB(0x0c, 3),
561		 RB(0x10, 0), RB(0x10, 1), RB(0x10, 2)),
562	D_MODULE(HCLK_SDIO1, "hclk_sdio1", CLK_REF_SYNC_D4, RB(0xc8, 0),
563		 RB(0xc8, 1), RB(0xc8, 2), RB(0xc8, 3),
564		 RB(0xcc, 0), RB(0xcc, 1), RB(0xcc, 2)),
565	D_MODULE(HCLK_SEMAP, "hclk_semap", CLK_REF_SYNC_D4, RB(0xf4, 3),
566		 RB(0xf4, 4), RB(0xf4, 5), RB(0x00, 0),
567		 RB(0x164, 1), RB(0x00, 0), RB(0x00, 0)),
568	D_MODULE(HCLK_SPI0, "hclk_spi0", CLK_REF_SYNC_D4, RB(0x40, 0),
569		 RB(0x40, 1), RB(0x40, 2), RB(0x00, 0),
570		 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
571	D_MODULE(HCLK_SPI1, "hclk_spi1", CLK_REF_SYNC_D4, RB(0x40, 3),
572		 RB(0x40, 4), RB(0x40, 5), RB(0x00, 0),
573		 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
574	D_MODULE(HCLK_SPI2, "hclk_spi2", CLK_REF_SYNC_D4, RB(0x40, 6),
575		 RB(0x40, 7), RB(0x40, 8), RB(0x00, 0),
576		 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
577	D_MODULE(HCLK_SPI3, "hclk_spi3", CLK_REF_SYNC_D4, RB(0x40, 9),
578		 RB(0x40, 10), RB(0x40, 11), RB(0x00, 0),
579		 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
580	D_MODULE(HCLK_SPI4, "hclk_spi4", CLK_REF_SYNC_D4, RB(0x40, 12),
581		 RB(0x40, 13), RB(0x40, 14), RB(0x00, 0),
582		 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
583	D_MODULE(HCLK_SPI5, "hclk_spi5", CLK_REF_SYNC_D4, RB(0x40, 15),
584		 RB(0x40, 16), RB(0x40, 17), RB(0x00, 0),
585		 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
586	D_MODULE(HCLK_SWITCH, "hclk_switch", CLK_REF_SYNC_D4, RB(0x130, 0),
587		 RB(0x00, 0), RB(0x130, 1), RB(0x00, 0),
588		 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
589	D_MODULE(HCLK_SWITCH_RG, "hclk_switch_rg", CLK_REF_SYNC_D4, RB(0x188, 0),
590		 RB(0x188, 1), RB(0x188, 2), RB(0x00, 0),
591		 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
592	D_MODULE(HCLK_UART0, "hclk_uart0", CLK_REF_SYNC_D8, RB(0x34, 0),
593		 RB(0x34, 1), RB(0x34, 2), RB(0x00, 0),
594		 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
595	D_MODULE(HCLK_UART1, "hclk_uart1", CLK_REF_SYNC_D8, RB(0x34, 3),
596		 RB(0x34, 4), RB(0x34, 5), RB(0x00, 0),
597		 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
598	D_MODULE(HCLK_UART2, "hclk_uart2", CLK_REF_SYNC_D8, RB(0x34, 6),
599		 RB(0x34, 7), RB(0x34, 8), RB(0x00, 0),
600		 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
601	D_MODULE(HCLK_UART3, "hclk_uart3", CLK_REF_SYNC_D4, RB(0x40, 24),
602		 RB(0x40, 25), RB(0x40, 26), RB(0x00, 0),
603		 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
604	D_MODULE(HCLK_UART4, "hclk_uart4", CLK_REF_SYNC_D4, RB(0x40, 27),
605		 RB(0x40, 28), RB(0x40, 29), RB(0x00, 0),
606		 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
607	D_MODULE(HCLK_UART5, "hclk_uart5", CLK_REF_SYNC_D4, RB(0x44, 0),
608		 RB(0x44, 1), RB(0x44, 2), RB(0x00, 0),
609		 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
610	D_MODULE(HCLK_UART6, "hclk_uart6", CLK_REF_SYNC_D4, RB(0x44, 3),
611		 RB(0x44, 4), RB(0x44, 5), RB(0x00, 0),
612		 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
613	D_MODULE(HCLK_UART7, "hclk_uart7", CLK_REF_SYNC_D4, RB(0x44, 6),
614		 RB(0x44, 7), RB(0x44, 8), RB(0x00, 0),
615		 RB(0x00, 0), RB(0x00, 0), RB(0x00, 0)),
616	/*
617	 * These are not hardware clocks, but are needed to handle the special
618	 * case where we have a 'selector bit' that doesn't just change the
619	 * parent for a clock, but also the gate it's supposed to use.
620	 */
621	{
622		.index = R9A06G032_UART_GROUP_012,
623		.name = "uart_group_012",
624		.type = K_BITSEL,
625		.source = 1 + R9A06G032_DIV_UART,
626		/* R9A06G032_SYSCTRL_REG_PWRCTRL_PG0_0 */
627		.dual.sel = RB(0x34, 30),
628		.dual.group = 0,
629	},
630	{
631		.index = R9A06G032_UART_GROUP_34567,
632		.name = "uart_group_34567",
633		.type = K_BITSEL,
634		.source = 1 + R9A06G032_DIV_P2_PG,
635		/* R9A06G032_SYSCTRL_REG_PWRCTRL_PG1_PR2 */
636		.dual.sel = RB(0xec, 24),
637		.dual.group = 1,
638	},
639	D_UGATE(CLK_UART0, "clk_uart0", UART_GROUP_012, 0,
640		RB(0x34, 18), RB(0x34, 19), RB(0x34, 20), RB(0x34, 21)),
641	D_UGATE(CLK_UART1, "clk_uart1", UART_GROUP_012, 0,
642		RB(0x34, 22), RB(0x34, 23), RB(0x34, 24), RB(0x34, 25)),
643	D_UGATE(CLK_UART2, "clk_uart2", UART_GROUP_012, 0,
644		RB(0x34, 26), RB(0x34, 27), RB(0x34, 28), RB(0x34, 29)),
645	D_UGATE(CLK_UART3, "clk_uart3", UART_GROUP_34567, 1,
646		RB(0xec, 0), RB(0xec, 1), RB(0xec, 2), RB(0xec, 3)),
647	D_UGATE(CLK_UART4, "clk_uart4", UART_GROUP_34567, 1,
648		RB(0xec, 4), RB(0xec, 5), RB(0xec, 6), RB(0xec, 7)),
649	D_UGATE(CLK_UART5, "clk_uart5", UART_GROUP_34567, 1,
650		RB(0xec, 8), RB(0xec, 9), RB(0xec, 10), RB(0xec, 11)),
651	D_UGATE(CLK_UART6, "clk_uart6", UART_GROUP_34567, 1,
652		RB(0xec, 12), RB(0xec, 13), RB(0xec, 14), RB(0xec, 15)),
653	D_UGATE(CLK_UART7, "clk_uart7", UART_GROUP_34567, 1,
654		RB(0xec, 16), RB(0xec, 17), RB(0xec, 18), RB(0xec, 19)),
655};
656
657struct r9a06g032_priv {
658	struct regmap		*regmap;
659	struct clk		mclk;
660};
661
662static const struct r9a06g032_clkdesc *r9a06g032_clk_get(struct clk *clk)
663{
664	const unsigned long clkid = clk->id & 0xffff;
665	int i;
666
667	for (i = 0; i < ARRAY_SIZE(r9a06g032_clocks); i++) {
668		if (r9a06g032_clocks[i].index == clkid)
669			return &r9a06g032_clocks[i];
670	}
671
672	return NULL;
673}
674
675#define PARENT_ID (~0)
676
677static int r9a06g032_clk_get_parent(struct clk *clk, struct clk *parent)
678{
679	const struct r9a06g032_clkdesc *desc = r9a06g032_clk_get(clk);
680
681	if (!desc)
682		return -ENOENT;
683
684	if (desc->source)
685		parent->id = desc->source - 1;
686	else
687		parent->id = PARENT_ID;	/* Top-level clock */
688
689	parent->dev = clk->dev;
690
691	return 0;
692}
693
694static ulong r9a06g032_clk_get_parent_rate(struct clk *clk)
695{
696	struct clk parent;
697	unsigned long parent_rate;
698	struct r9a06g032_priv *clocks = dev_get_priv(clk->dev);
699
700	if (r9a06g032_clk_get_parent(clk, &parent)) {
701		dev_dbg(clk->dev, "Failed to get parent clock for id=%lu\b", clk->id);
702		return 0;
703	}
704
705	if (parent.id == PARENT_ID)
706		parent_rate = clk_get_rate(&clocks->mclk);
707	else
708		parent_rate = clk_get_rate(&parent);
709
710	if (!parent_rate)
711		dev_dbg(clk->dev, "%s: parent_rate is zero\n", __func__);
712
713	return parent_rate;
714}
715
716/* register/bit pairs are encoded as an uint16_t */
717static void clk_rdesc_set(struct r9a06g032_priv *clocks,
718			  struct regbit rb, unsigned int on)
719{
720	uint reg = rb.reg * 4;
721	uint bit = rb.bit;
722
723	if (!reg && !bit)
724		return;
725
726	uint mask = BIT(bit);
727	uint val = (!!on) << bit;
728
729	regmap_update_bits(clocks->regmap, reg, mask, val);
730}
731
732static int clk_rdesc_get(struct r9a06g032_priv *clocks,
733			 struct regbit rb)
734{
735	uint reg = rb.reg * 4;
736	uint bit = rb.bit;
737	u32 val = 0;
738
739	regmap_read(clocks->regmap, reg, &val);
740
741	return !!(val & BIT(bit));
742}
743
744/*
745 * Cheating a little bit here: leverage the existing code to control the
746 * per-clock reset. It should really be handled by a reset controller instead.
747 */
748void clk_rzn1_reset_state(struct clk *clk, int on)
749{
750	struct r9a06g032_priv *clocks = dev_get_priv(clk->dev);
751	const struct r9a06g032_clkdesc *desc = r9a06g032_clk_get(clk);
752	const struct r9a06g032_gate *g;
753
754	assert(desc);
755	assert(desc->type == K_GATE);
756	g = &desc->gate;
757
758	clk_rdesc_set(clocks, g->reset, on);
759}
760
761/*
762 * This implements the R9A06G032 clock gate 'driver'. We cannot use the system's
763 * clock gate framework as the gates on the R9A06G032 have a special enabling
764 * sequence, therefore we use this little proxy.
765 */
766static int r9a06g032_clk_gate_set(struct clk *clk, int on)
767{
768	struct r9a06g032_priv *clocks = dev_get_priv(clk->dev);
769	const struct r9a06g032_clkdesc *desc = r9a06g032_clk_get(clk);
770	const struct r9a06g032_gate *g;
771
772	assert(desc);
773	assert(desc->type == K_GATE);
774	g = &desc->gate;
775
776	/* Enable or disable the clock */
777	clk_rdesc_set(clocks, g->gate, on);
778
779	/* De-assert reset */
780	clk_rdesc_set(clocks, g->reset, 1);
781
782	/* Hardware manual recommends 5us delay after enabling clock & reset */
783	udelay(5);
784
785	/* If the peripheral is memory mapped (i.e. an AXI slave), there is an
786	 * associated SLVRDY bit in the System Controller that needs to be set
787	 * so that the FlexWAY bus fabric passes on the read/write requests.
788	 */
789	clk_rdesc_set(clocks, g->ready, on);
790
791	/* Clear 'Master Idle Request' bit */
792	clk_rdesc_set(clocks, g->midle, !on);
793
794	/* Note: We don't wait for FlexWAY Socket Connection signal */
795
796	return 0;
797}
798
799static int r9a06g032_clk_gate_enable(struct clk *clk)
800{
801	return r9a06g032_clk_gate_set(clk, 1);
802}
803
804static int r9a06g032_clk_gate_disable(struct clk *clk)
805{
806	return r9a06g032_clk_gate_set(clk, 0);
807}
808
809/*
810 * Fixed factor clock
811 */
812static ulong r9a06g032_ffc_get_rate(struct clk *clk)
813{
814	const struct r9a06g032_clkdesc *desc = r9a06g032_clk_get(clk);
815	unsigned long parent_rate = r9a06g032_clk_get_parent_rate(clk);
816	unsigned long long rate;
817
818	rate = (unsigned long long)parent_rate * desc->mul;
819	rate = DIV_ROUND_UP(rate, desc->div);
820
821	return (ulong)rate;
822}
823
824/*
825 * This implements R9A06G032 clock divider 'driver'. This differs from the
826 * standard clk_divider because the set_rate method must also set b[31] to
827 * trigger the hardware rate change. In theory it should also wait for this
828 * bit to clear.
829 */
830static ulong r9a06g032_div_get_rate(struct clk *clk)
831{
832	struct r9a06g032_priv *clocks = dev_get_priv(clk->dev);
833	const struct r9a06g032_clkdesc *desc = r9a06g032_clk_get(clk);
834	unsigned long parent_rate = r9a06g032_clk_get_parent_rate(clk);
835	u32 div = 0;
836
837	regmap_read(clocks->regmap, 4 * desc->reg, &div);
838
839	if (div < desc->div_min)
840		div = desc->div_min;
841	else if (div > desc->div_max)
842		div = desc->div_max;
843	return DIV_ROUND_UP(parent_rate, div);
844}
845
846static ulong r9a06g032_div_set_rate(struct clk *clk, ulong rate)
847{
848	struct r9a06g032_priv *clocks = dev_get_priv(clk->dev);
849	const struct r9a06g032_clkdesc *desc = r9a06g032_clk_get(clk);
850	unsigned long parent_rate = r9a06g032_clk_get_parent_rate(clk);
851	size_t i;
852
853	/* + 1 to cope with rates that have the remainder dropped */
854	u32 div = DIV_ROUND_UP(parent_rate, rate + 1);
855
856	/* Clamp to allowable range */
857	if (div < desc->div_min)
858		div = desc->div_min;
859	else if (div > desc->div_max)
860		div = desc->div_max;
861
862	/* Limit to allowable divisors */
863	for (i = 0; i < ARRAY_SIZE(desc->div_table) - 2; i++) {
864		u16 div_m = desc->div_table[i];
865		u16 div_p = desc->div_table[i + 1];
866
867		if (!div_m || !div_p)
868			continue;
869
870		if (div >= div_m && div <= div_p) {
871			/*
872			 * select the divider that generates
873			 * the value closest to ideal frequency
874			 */
875			u32 m = rate - DIV_ROUND_UP(parent_rate, div_m);
876			u32 p = DIV_ROUND_UP(parent_rate, div_p) - rate;
877
878			div = p >= m ? div_m : div_p;
879		}
880	}
881
882	dev_dbg(clk->dev, "%s clkid %lu rate %ld parent %ld div %d\n",
883		__func__, clk->id, rate, parent_rate, div);
884
885	/*
886	 * Need to write the bit 31 with the divider value to
887	 * latch it. Technically we should wait until it has been
888	 * cleared too.
889	 * TODO: Find whether this callback is sleepable, in case
890	 * the hardware /does/ require some sort of spinloop here.
891	 */
892	regmap_write(clocks->regmap, 4 * desc->reg, div | BIT(31));
893
894	return 0;
895}
896
897/*
898 * Dual gate. This handles toggling the approprate clock/reset bits,
899 * which depends on the mux setting above.
900 */
901static int r9a06g032_clk_dualgate_setenable(struct r9a06g032_priv *clocks,
902					    const struct r9a06g032_clkdesc *desc,
903					    int enable)
904{
905	u8 sel_bit = clk_rdesc_get(clocks, desc->dual.sel);
906	struct regbit gate[2] = { desc->dual.g1, desc->dual.g2 };
907	struct regbit reset[2] = { desc->dual.r1, desc->dual.r2 };
908
909	/* we always turn off the 'other' gate, regardless */
910	clk_rdesc_set(clocks, gate[!sel_bit], 0);
911	clk_rdesc_set(clocks, reset[!sel_bit], 1);
912
913	/* set the gate as requested */
914	clk_rdesc_set(clocks, gate[sel_bit], enable);
915	clk_rdesc_set(clocks, reset[sel_bit], 1);
916
917	return 0;
918}
919
920static int r9a06g032_clk_dualgate_enable(struct clk *clk)
921{
922	struct r9a06g032_priv *clocks = dev_get_priv(clk->dev);
923	const struct r9a06g032_clkdesc *desc = r9a06g032_clk_get(clk);
924
925	return r9a06g032_clk_dualgate_setenable(clocks, desc, 1);
926}
927
928static int r9a06g032_clk_dualgate_disable(struct clk *clk)
929{
930	struct r9a06g032_priv *clocks = dev_get_priv(clk->dev);
931	const struct r9a06g032_clkdesc *desc = r9a06g032_clk_get(clk);
932
933	return r9a06g032_clk_dualgate_setenable(clocks, desc, 0);
934}
935
936static int r9a06g032_clk_dualgate_is_enabled(struct clk *clk)
937{
938	struct r9a06g032_priv *clocks = dev_get_priv(clk->dev);
939	const struct r9a06g032_clkdesc *desc = r9a06g032_clk_get(clk);
940	u8 sel_bit = clk_rdesc_get(clocks, desc->dual.sel);
941	struct regbit gate[2] = { desc->dual.g1, desc->dual.g2 };
942
943	return clk_rdesc_get(clocks, gate[sel_bit]);
944}
945
946/*
947 * Main clock driver
948 */
949static int r9a06g032_clk_enable(struct clk *clk)
950{
951	const struct r9a06g032_clkdesc *desc = r9a06g032_clk_get(clk);
952
953	switch (desc->type) {
954	case K_GATE:
955		return r9a06g032_clk_gate_enable(clk);
956	case K_DUALGATE:
957		return r9a06g032_clk_dualgate_enable(clk);
958	default:
959		dev_dbg(clk->dev, "ERROR: unhandled type=%d\n", desc->type);
960		break;
961	}
962
963	return 0;
964}
965
966static int r9a06g032_clk_disable(struct clk *clk)
967{
968	const struct r9a06g032_clkdesc *desc = r9a06g032_clk_get(clk);
969
970	switch (desc->type) {
971	case K_GATE:
972		return r9a06g032_clk_gate_disable(clk);
973	case K_DUALGATE:
974		return r9a06g032_clk_dualgate_disable(clk);
975	default:
976		dev_dbg(clk->dev, "ERROR: unhandled type=%d\n", desc->type);
977		break;
978	}
979
980	return 0;
981}
982
983static ulong r9a06g032_clk_get_rate(struct clk *clk)
984{
985	const struct r9a06g032_clkdesc *desc = r9a06g032_clk_get(clk);
986	ulong ret = 0;
987
988	assert(desc);
989
990	switch (desc->type) {
991	case K_FFC:
992		ret = r9a06g032_ffc_get_rate(clk);
993		break;
994	case K_GATE:
995		ret = r9a06g032_clk_get_parent_rate(clk);
996		break;
997	case K_DIV:
998		ret = r9a06g032_div_get_rate(clk);
999		break;
1000	case K_BITSEL:
1001		/*
1002		 * Look at the mux to determine parent.
1003		 * 0 means it is coming from UART DIV (group 012 or 34567)
1004		 * 1 means it is coming from USB_PLL (fixed at 48MHz)
1005		 */
1006		if (r9a06g032_clk_dualgate_is_enabled(clk)) {
1007			struct clk usb_clk = { .id = R9A06G032_CLK_PLL_USB };
1008
1009			ret = r9a06g032_clk_get_parent_rate(&usb_clk);
1010		} else {
1011			ret = r9a06g032_clk_get_parent_rate(clk);
1012		}
1013		break;
1014	case K_DUALGATE:
1015		ret = r9a06g032_clk_get_parent_rate(clk);
1016		break;
1017	}
1018
1019	return ret;
1020}
1021
1022static ulong r9a06g032_clk_set_rate(struct clk *clk, ulong rate)
1023{
1024	const struct r9a06g032_clkdesc *desc = r9a06g032_clk_get(clk);
1025	ulong ret = 0;
1026
1027	assert(desc);
1028
1029	switch (desc->type) {
1030	case K_DIV:
1031		ret = r9a06g032_div_set_rate(clk, rate);
1032		break;
1033	default:
1034		dev_dbg(clk->dev, "ERROR: not implemented for %d\n", desc->type);
1035	};
1036
1037	return ret;
1038}
1039
1040static int r9a06g032_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args)
1041{
1042	if (args->args_count != 1) {
1043		dev_dbg(clk->dev, "Invalid args_count: %d\n", args->args_count);
1044		return -EINVAL;
1045	}
1046
1047	clk->id = args->args[0];
1048
1049	return 0;
1050}
1051
1052static const struct clk_ops r9a06g032_clk_ops = {
1053	.enable		= r9a06g032_clk_enable,
1054	.disable	= r9a06g032_clk_disable,
1055	.get_rate	= r9a06g032_clk_get_rate,
1056	.set_rate	= r9a06g032_clk_set_rate,
1057	.of_xlate	= r9a06g032_clk_of_xlate,
1058};
1059
1060/* Reset Enable Register */
1061#define RZN1_SYSCTRL_REG_RSTEN			288 /* 0x120*/
1062#define RZN1_SYSCTRL_REG_RSTEN_MRESET_EN		BIT(0)
1063#define RZN1_SYSCTRL_REG_RSTEN_WDA7RST_CA7_0_EN		BIT(1)
1064#define RZN1_SYSCTRL_REG_RSTEN_WDA7RST_CA7_1_EN		BIT(2)
1065#define RZN1_SYSCTRL_REG_RSTEN_WDM3RST_EN		BIT(3)
1066#define RZN1_SYSCTRL_REG_RSTEN_CM3LOCKUPRST_EN		BIT(4)
1067#define RZN1_SYSCTRL_REG_RSTEN_CM3SYSRESET_EN		BIT(5)
1068#define RZN1_SYSCTRL_REG_RSTEN_SWRST_EN			BIT(6)
1069
1070static int r9a06g032_clk_probe(struct udevice *dev)
1071{
1072	struct r9a06g032_priv *priv = dev_get_priv(dev);
1073
1074	priv->regmap = syscon_regmap_lookup_by_phandle(dev, "regmap");
1075	if (IS_ERR(priv->regmap)) {
1076		dev_dbg(dev, "unable to find regmap\n");
1077		return PTR_ERR(priv->regmap);
1078	}
1079
1080	/* Enable S/W reset */
1081	regmap_write(priv->regmap, RZN1_SYSCTRL_REG_RSTEN,
1082		     RZN1_SYSCTRL_REG_RSTEN_MRESET_EN |
1083		     RZN1_SYSCTRL_REG_RSTEN_SWRST_EN);
1084
1085	/* Get master clock */
1086	return clk_get_by_name(dev, "mclk", &priv->mclk);
1087}
1088
1089static const struct udevice_id r9a06g032_clk_ids[] = {
1090	{ .compatible = "renesas,r9a06g032-sysctrl" },
1091	{ }
1092};
1093
1094U_BOOT_DRIVER(clk_r9a06g032) = {
1095	.name		= "clk_r9a06g032",
1096	.id		= UCLASS_CLK,
1097	.of_match	= r9a06g032_clk_ids,
1098	.priv_auto	= sizeof(struct r9a06g032_priv),
1099	.ops		= &r9a06g032_clk_ops,
1100	.probe		= &r9a06g032_clk_probe,
1101	.flags		= DM_FLAG_PRE_RELOC,
1102};
1103