aboutsummaryrefslogtreecommitdiff
path: root/drivers/clk/renesas/rzg2l-cpg.h
blob: 7cb6c481a6292cc3155e9ab1cd0b49d09a523a4a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * RZ/G2L Clock Pulse Generator
 *
 * Copyright (C) 2021-2023 Renesas Electronics Corp.
 *
 */

#ifndef __RENESAS_RZG2L_CPG_H__
#define __RENESAS_RZG2L_CPG_H__

#define CPG_SIPLL5_STBY		0x140
#define CPG_SIPLL5_CLK1		0x144
#define CPG_SIPLL5_CLK3		0x14C
#define CPG_SIPLL5_CLK4		0x150
#define CPG_SIPLL5_CLK5		0x154
#define CPG_SIPLL5_MON		0x15C
#define CPG_PL1_DDIV		0x200
#define CPG_PL2_DDIV		0x204
#define CPG_PL3A_DDIV		0x208
#define CPG_PL6_DDIV		0x210
#define CPG_PL2SDHI_DSEL	0x218
#define CPG_CLKSTATUS		0x280
#define CPG_PL3_SSEL		0x408
#define CPG_PL6_SSEL		0x414
#define CPG_PL6_ETH_SSEL	0x418
#define CPG_PL5_SDIV		0x420
#define CPG_RST_MON		0x680
#define CPG_OTHERFUNC1_REG	0xBE8

#define CPG_SIPLL5_STBY_RESETB		BIT(0)
#define CPG_SIPLL5_STBY_RESETB_WEN	BIT(16)
#define CPG_SIPLL5_STBY_SSCG_EN_WEN	BIT(18)
#define CPG_SIPLL5_STBY_DOWNSPREAD_WEN	BIT(20)
#define CPG_SIPLL5_CLK4_RESV_LSB	0xFF
#define CPG_SIPLL5_MON_PLL5_LOCK	BIT(4)

#define CPG_OTHERFUNC1_REG_RES0_ON_WEN	BIT(16)

#define CPG_PL5_SDIV_DIV_DSI_A_WEN	BIT(16)
#define CPG_PL5_SDIV_DIV_DSI_B_WEN	BIT(24)

#define CPG_CLKSTATUS_SELSDHI0_STS	BIT(28)
#define CPG_CLKSTATUS_SELSDHI1_STS	BIT(29)

#define CPG_SDHI_CLK_SWITCH_STATUS_TIMEOUT_US	20000

/* n = 0/1/2 for PLL1/4/6 */
#define CPG_SAMPLL_CLK1(n)	(0x04 + (16 * (n)))
#define CPG_SAMPLL_CLK2(n)	(0x08 + (16 * (n)))

#define PLL146_CONF(n)	(CPG_SAMPLL_CLK1(n) << 22 | CPG_SAMPLL_CLK2(n) << 12)

#define DDIV_PACK(offset, bitpos, size) \
		(((offset) << 20) | ((bitpos) << 12) | ((size) << 8))
#define DIVPL1A		DDIV_PACK(CPG_PL1_DDIV, 0, 2)
#define DIVPL2A		DDIV_PACK(CPG_PL2_DDIV, 0, 3)
#define DIVDSILPCLK	DDIV_PACK(CPG_PL2_DDIV, 12, 2)
#define DIVPL3A		DDIV_PACK(CPG_PL3A_DDIV, 0, 3)
#define DIVPL3B		DDIV_PACK(CPG_PL3A_DDIV, 4, 3)
#define DIVPL3C		DDIV_PACK(CPG_PL3A_DDIV, 8, 3)
#define DIVGPU		DDIV_PACK(CPG_PL6_DDIV, 0, 2)

#define SEL_PLL_PACK(offset, bitpos, size) \
		(((offset) << 20) | ((bitpos) << 12) | ((size) << 8))

#define SEL_PLL3_3	SEL_PLL_PACK(CPG_PL3_SSEL, 8, 1)
#define SEL_PLL5_4	SEL_PLL_PACK(CPG_OTHERFUNC1_REG, 0, 1)
#define SEL_PLL6_2	SEL_PLL_PACK(CPG_PL6_ETH_SSEL, 0, 1)
#define SEL_GPU2	SEL_PLL_PACK(CPG_PL6_SSEL, 12, 1)

#define SEL_SDHI0	DDIV_PACK(CPG_PL2SDHI_DSEL, 0, 2)
#define SEL_SDHI1	DDIV_PACK(CPG_PL2SDHI_DSEL, 4, 2)

#define SEL_SDHI_533MHz		1
#define SEL_SDHI_400MHz		2
#define SEL_SDHI_266MHz		3
#define SEL_SDHI_WRITE_ENABLE	0x10000

/* Unpack CPG conf value create by DDIV_PACK() or SEL_PLL_PACK(). */
#define CPG_CONF_OFFSET(x)	((x) >> 20)
#define CPG_CONF_BITPOS(x)	(((x) >> 12) & 0xff)
#define CPG_CONF_SIZE(x)	(((x) >> 8) & 0xf)
#define CPG_CONF_BITMASK(x)	GENMASK(CPG_CONF_SIZE(x) - 1, 0)

#define EXTAL_FREQ_IN_MEGA_HZ	24

/**
 * Definitions of CPG Core Clocks
 *
 * These include:
 *   - Clock outputs exported to DT
 *   - External input clocks
 *   - Internal CPG clocks
 */
struct cpg_core_clk {
	const char *name;
	unsigned int id;
	unsigned int parent;
	unsigned int div;
	unsigned int mult;
	unsigned int type;
	unsigned int conf;
	const struct clk_div_table *dtable;
	const char * const *parent_names;
	int flag;
	int mux_flags;
	int num_parents;
};

enum clk_types {
	/* Generic */
	CLK_TYPE_IN,		/* External Clock Input */
	CLK_TYPE_FF,		/* Fixed Factor Clock */
	CLK_TYPE_SAM_PLL,

	/* Clock with divider */
	CLK_TYPE_DIV,

	/* Clock with clock source selector */
	CLK_TYPE_MUX,

	/* Clock with SD clock source selector */
	CLK_TYPE_SD_MUX,

	/* Clock for SIPLL5 */
	CLK_TYPE_SIPLL5,

	/* Clock for PLL5_4 clock source selector */
	CLK_TYPE_PLL5_4_MUX,

	/* Clock for DSI divider */
	CLK_TYPE_DSI_DIV,

};

#define DEF_TYPE(_name, _id, _type...) \
	{ .name = _name, .id = _id, .type = _type }
#define DEF_BASE(_name, _id, _type, _parent...) \
	DEF_TYPE(_name, _id, _type, .parent = _parent)
#define DEF_SAMPLL(_name, _id, _parent, _conf) \
	DEF_TYPE(_name, _id, CLK_TYPE_SAM_PLL, .parent = _parent, .conf = _conf)
#define DEF_INPUT(_name, _id) \
	DEF_TYPE(_name, _id, CLK_TYPE_IN)
#define DEF_FIXED(_name, _id, _parent, _mult, _div) \
	DEF_BASE(_name, _id, CLK_TYPE_FF, _parent, .div = _div, .mult = _mult)
#define DEF_DIV(_name, _id, _parent, _conf, _dtable) \
	DEF_TYPE(_name, _id, CLK_TYPE_DIV, .conf = _conf, \
		 .parent = _parent, .dtable = _dtable, \
		 .flag = CLK_DIVIDER_HIWORD_MASK)
#define DEF_DIV_RO(_name, _id, _parent, _conf, _dtable) \
	DEF_TYPE(_name, _id, CLK_TYPE_DIV, .conf = _conf, \
		 .parent = _parent, .dtable = _dtable, \
		 .flag = CLK_DIVIDER_READ_ONLY)
#define DEF_MUX(_name, _id, _conf, _parent_names) \
	DEF_TYPE(_name, _id, CLK_TYPE_MUX, .conf = _conf, \
		 .parent_names = _parent_names, \
		 .num_parents = ARRAY_SIZE(_parent_names), \
		 .mux_flags = CLK_MUX_HIWORD_MASK)
#define DEF_MUX_RO(_name, _id, _conf, _parent_names) \
	DEF_TYPE(_name, _id, CLK_TYPE_MUX, .conf = _conf, \
		 .parent_names = _parent_names, \
		 .num_parents = ARRAY_SIZE(_parent_names), \
		 .mux_flags = CLK_MUX_READ_ONLY)
#define DEF_SD_MUX(_name, _id, _conf, _parent_names) \
	DEF_TYPE(_name, _id, CLK_TYPE_SD_MUX, .conf = _conf, \
		 .parent_names = _parent_names, \
		 .num_parents = ARRAY_SIZE(_parent_names))
#define DEF_PLL5_FOUTPOSTDIV(_name, _id, _parent) \
	DEF_TYPE(_name, _id, CLK_TYPE_SIPLL5, .parent = _parent)
#define DEF_PLL5_4_MUX(_name, _id, _conf, _parent_names) \
	DEF_TYPE(_name, _id, CLK_TYPE_PLL5_4_MUX, .conf = _conf, \
		 .parent_names = _parent_names, \
		 .num_parents = ARRAY_SIZE(_parent_names))
#define DEF_DSI_DIV(_name, _id, _parent, _flag) \
	DEF_TYPE(_name, _id, CLK_TYPE_DSI_DIV, .parent = _parent, .flag = _flag)

/**
 * struct rzg2l_mod_clk - Module Clocks definitions
 *
 * @name: handle between common and hardware-specific interfaces
 * @id: clock index in array containing all Core and Module Clocks
 * @parent: id of parent clock
 * @off: register offset
 * @bit: ON/MON bit
 * @is_coupled: flag to indicate coupled clock
 */
struct rzg2l_mod_clk {
	const char *name;
	unsigned int id;
	unsigned int parent;
	u16 off;
	u8 bit;
	bool is_coupled;
};

#define DEF_MOD_BASE(_name, _id, _parent, _off, _bit, _is_coupled)	\
	{ \
		.name = (_name), \
		.id = (_id), \
		.parent = (_parent), \
		.off = (_off), \
		.bit = (_bit), \
		.is_coupled = (_is_coupled), \
	}

#define DEF_MOD(_name, _id, _parent, _off, _bit)	\
	DEF_MOD_BASE(_name, _id, _parent, _off, _bit, false)

#define DEF_COUPLED(_name, _id, _parent, _off, _bit)	\
	DEF_MOD_BASE(_name, _id, _parent, _off, _bit, true)

/**
 * struct rzg2l_reset - Reset definitions
 *
 * @off: register offset
 * @bit: reset bit
 * @monbit: monitor bit in CPG_RST_MON register, -1 if none
 */
struct rzg2l_reset {
	u16 off;
	u8 bit;
	s8 monbit;
};

#define DEF_RST_MON(_id, _off, _bit, _monbit)	\
	[_id] = { \
		.off = (_off), \
		.bit = (_bit), \
		.monbit = (_monbit) \
	}
#define DEF_RST(_id, _off, _bit)	\
	DEF_RST_MON(_id, _off, _bit, -1)

/**
 * struct rzg2l_cpg_info - SoC-specific CPG Description
 *
 * @core_clks: Array of Core Clock definitions
 * @num_core_clks: Number of entries in core_clks[]
 *
 * @mod_clks: Array of Module Clock definitions
 * @num_mod_clks: Number of entries in mod_clks[]
 * @num_hw_mod_clks: Number of Module Clocks supported by the hardware
 *
 * @resets: Array of Module Reset definitions
 * @num_resets: Number of entries in resets[]
 *
 * @has_clk_mon_regs: Flag indicating whether the SoC has CLK_MON registers
 */
struct rzg2l_cpg_info {
	/* Core Clocks */
	const struct cpg_core_clk *core_clks;
	unsigned int num_core_clks;

	/* Module Clocks */
	const struct rzg2l_mod_clk *mod_clks;
	unsigned int num_mod_clks;
	unsigned int num_hw_mod_clks;

	/* Resets */
	const struct rzg2l_reset *resets;
	unsigned int num_resets;

	bool has_clk_mon_regs;
};

extern const struct rzg2l_cpg_info r9a07g044_cpg_info;

int rzg2l_cpg_bind(struct udevice *parent);

/*
 * Clock IDs start at an offset to avoid overlapping with core & module clock
 * IDs defined in the dt-bindings headers.
 */
enum clk_ids {
	/* External Input Clocks */
	CLK_EXTAL = 0x100,

	/* Internal Core Clocks */
	CLK_OSC_DIV1000 = 0x200,
	CLK_PLL1,
	CLK_PLL2,
	CLK_PLL2_DIV2,
	CLK_PLL2_DIV2_8,
	CLK_PLL2_DIV2_10,
	CLK_PLL3,
	CLK_PLL3_400,
	CLK_PLL3_533,
	CLK_M2_DIV2,
	CLK_PLL3_DIV2,
	CLK_PLL3_DIV2_2,
	CLK_PLL3_DIV2_4,
	CLK_PLL3_DIV2_4_2,
	CLK_SEL_PLL3_3,
	CLK_DIV_PLL3_C,
	CLK_PLL4,
	CLK_PLL5,
	CLK_PLL5_FOUTPOSTDIV,
	CLK_PLL5_FOUT1PH0,
	CLK_PLL5_FOUT3,
	CLK_PLL5_250,
	CLK_PLL6,
	CLK_PLL6_250,
	CLK_P1_DIV2,
	CLK_PLL2_800,
	CLK_PLL2_SDHI_533,
	CLK_PLL2_SDHI_400,
	CLK_PLL2_SDHI_266,
	CLK_SD0_DIV4,
	CLK_SD1_DIV4,
	CLK_SEL_GPU2,
	CLK_SEL_PLL5_4,
	CLK_DSI_DIV,
	CLK_PLL2_533,
	CLK_PLL2_533_DIV2,
	CLK_DIV_DSI_LPCLK,
};

#endif