summaryrefslogtreecommitdiffstats
path: root/drivers/clk/renesas/rzv2h-cpg.h
blob: 1bd406c69015ba5ad762ea8c4bec33e2a693bf99 (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
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Renesas RZ/V2H(P) Clock Pulse Generator
 *
 * Copyright (C) 2024 Renesas Electronics Corp.
 */

#ifndef __RENESAS_RZV2H_CPG_H__
#define __RENESAS_RZV2H_CPG_H__

/**
 * struct ddiv - Structure for dynamic switching divider
 *
 * @offset: register offset
 * @shift: position of the divider bit
 * @width: width of the divider
 * @monbit: monitor bit in CPG_CLKSTATUS0 register
 */
struct ddiv {
	unsigned int offset:11;
	unsigned int shift:4;
	unsigned int width:4;
	unsigned int monbit:5;
};

#define DDIV_PACK(_offset, _shift, _width, _monbit) \
	((struct ddiv){ \
		.offset = _offset, \
		.shift = _shift, \
		.width = _width, \
		.monbit = _monbit \
	})

#define CPG_CDDIV0		(0x400)

#define CDDIV0_DIVCTL2	DDIV_PACK(CPG_CDDIV0, 8, 3, 2)

/**
 * 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;
	union {
		unsigned int conf;
		struct ddiv ddiv;
	} cfg;
	const struct clk_div_table *dtable;
	u32 flag;
};

enum clk_types {
	/* Generic */
	CLK_TYPE_IN,		/* External Clock Input */
	CLK_TYPE_FF,		/* Fixed Factor Clock */
	CLK_TYPE_PLL,
	CLK_TYPE_DDIV,		/* Dynamic Switching Divider */
};

/* BIT(31) indicates if CLK1/2 are accessible or not */
#define PLL_CONF(n)		(BIT(31) | ((n) & ~GENMASK(31, 16)))
#define PLL_CLK_ACCESS(n)	((n) & BIT(31) ? 1 : 0)
#define PLL_CLK1_OFFSET(n)	((n) & ~GENMASK(31, 16))
#define PLL_CLK2_OFFSET(n)	(((n) & ~GENMASK(31, 16)) + (0x4))

#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_PLL(_name, _id, _parent, _conf) \
	DEF_TYPE(_name, _id, CLK_TYPE_PLL, .parent = _parent, .cfg.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_DDIV(_name, _id, _parent, _ddiv_packed, _dtable) \
	DEF_TYPE(_name, _id, CLK_TYPE_DDIV, \
		.cfg.ddiv = _ddiv_packed, \
		.parent = _parent, \
		.dtable = _dtable, \
		.flag = CLK_DIVIDER_HIWORD_MASK)

/**
 * struct rzv2h_mod_clk - Module Clocks definitions
 *
 * @name: handle between common and hardware-specific interfaces
 * @parent: id of parent clock
 * @critical: flag to indicate the clock is critical
 * @on_index: control register index
 * @on_bit: ON bit
 * @mon_index: monitor register index
 * @mon_bit: monitor bit
 */
struct rzv2h_mod_clk {
	const char *name;
	u16 parent;
	bool critical;
	u8 on_index;
	u8 on_bit;
	s8 mon_index;
	u8 mon_bit;
};

#define DEF_MOD_BASE(_name, _parent, _critical, _onindex, _onbit, _monindex, _monbit) \
	{ \
		.name = (_name), \
		.parent = (_parent), \
		.critical = (_critical), \
		.on_index = (_onindex), \
		.on_bit = (_onbit), \
		.mon_index = (_monindex), \
		.mon_bit = (_monbit), \
	}

#define DEF_MOD(_name, _parent, _onindex, _onbit, _monindex, _monbit)		\
	DEF_MOD_BASE(_name, _parent, false, _onindex, _onbit, _monindex, _monbit)

#define DEF_MOD_CRITICAL(_name, _parent, _onindex, _onbit, _monindex, _monbit)	\
	DEF_MOD_BASE(_name, _parent, true, _onindex, _onbit, _monindex, _monbit)

/**
 * struct rzv2h_reset - Reset definitions
 *
 * @reset_index: reset register index
 * @reset_bit: reset bit
 * @mon_index: monitor register index
 * @mon_bit: monitor bit
 */
struct rzv2h_reset {
	u8 reset_index;
	u8 reset_bit;
	u8 mon_index;
	u8 mon_bit;
};

#define DEF_RST_BASE(_resindex, _resbit, _monindex, _monbit)	\
	{ \
		.reset_index = (_resindex), \
		.reset_bit = (_resbit), \
		.mon_index = (_monindex), \
		.mon_bit = (_monbit), \
	}

#define DEF_RST(_resindex, _resbit, _monindex, _monbit)	\
	DEF_RST_BASE(_resindex, _resbit, _monindex, _monbit)

/**
 * struct rzv2h_cpg_info - SoC-specific CPG Description
 *
 * @core_clks: Array of Core Clock definitions
 * @num_core_clks: Number of entries in core_clks[]
 * @last_dt_core_clk: ID of the last Core Clock exported to DT
 * @num_total_core_clks: Total number of Core Clocks (exported + internal)
 *
 * @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[]
 */
struct rzv2h_cpg_info {
	/* Core Clocks */
	const struct cpg_core_clk *core_clks;
	unsigned int num_core_clks;
	unsigned int last_dt_core_clk;
	unsigned int num_total_core_clks;

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

	/* Resets */
	const struct rzv2h_reset *resets;
	unsigned int num_resets;
};

extern const struct rzv2h_cpg_info r9a09g057_cpg_info;

#endif	/* __RENESAS_RZV2H_CPG_H__ */