xref: /OK3568_Linux_fs/kernel/drivers/clk/renesas/renesas-cpg-mssr.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Renesas Clock Pulse Generator / Module Standby and Software Reset
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright (C) 2015 Glider bvba
6*4882a593Smuzhiyun  */
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #ifndef __CLK_RENESAS_CPG_MSSR_H__
9*4882a593Smuzhiyun #define __CLK_RENESAS_CPG_MSSR_H__
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun     /*
12*4882a593Smuzhiyun      * Definitions of CPG Core Clocks
13*4882a593Smuzhiyun      *
14*4882a593Smuzhiyun      * These include:
15*4882a593Smuzhiyun      *   - Clock outputs exported to DT
16*4882a593Smuzhiyun      *   - External input clocks
17*4882a593Smuzhiyun      *   - Internal CPG clocks
18*4882a593Smuzhiyun      */
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun struct cpg_core_clk {
21*4882a593Smuzhiyun 	/* Common */
22*4882a593Smuzhiyun 	const char *name;
23*4882a593Smuzhiyun 	unsigned int id;
24*4882a593Smuzhiyun 	unsigned int type;
25*4882a593Smuzhiyun 	/* Depending on type */
26*4882a593Smuzhiyun 	unsigned int parent;	/* Core Clocks only */
27*4882a593Smuzhiyun 	unsigned int div;
28*4882a593Smuzhiyun 	unsigned int mult;
29*4882a593Smuzhiyun 	unsigned int offset;
30*4882a593Smuzhiyun };
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun enum clk_types {
33*4882a593Smuzhiyun 	/* Generic */
34*4882a593Smuzhiyun 	CLK_TYPE_IN,		/* External Clock Input */
35*4882a593Smuzhiyun 	CLK_TYPE_FF,		/* Fixed Factor Clock */
36*4882a593Smuzhiyun 	CLK_TYPE_DIV6P1,	/* DIV6 Clock with 1 parent clock */
37*4882a593Smuzhiyun 	CLK_TYPE_DIV6_RO,	/* DIV6 Clock read only with extra divisor */
38*4882a593Smuzhiyun 	CLK_TYPE_FR,		/* Fixed Rate Clock */
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun 	/* Custom definitions start here */
41*4882a593Smuzhiyun 	CLK_TYPE_CUSTOM,
42*4882a593Smuzhiyun };
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun #define DEF_TYPE(_name, _id, _type...)	\
45*4882a593Smuzhiyun 	{ .name = _name, .id = _id, .type = _type }
46*4882a593Smuzhiyun #define DEF_BASE(_name, _id, _type, _parent...)	\
47*4882a593Smuzhiyun 	DEF_TYPE(_name, _id, _type, .parent = _parent)
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun #define DEF_INPUT(_name, _id) \
50*4882a593Smuzhiyun 	DEF_TYPE(_name, _id, CLK_TYPE_IN)
51*4882a593Smuzhiyun #define DEF_FIXED(_name, _id, _parent, _div, _mult)	\
52*4882a593Smuzhiyun 	DEF_BASE(_name, _id, CLK_TYPE_FF, _parent, .div = _div, .mult = _mult)
53*4882a593Smuzhiyun #define DEF_DIV6P1(_name, _id, _parent, _offset)	\
54*4882a593Smuzhiyun 	DEF_BASE(_name, _id, CLK_TYPE_DIV6P1, _parent, .offset = _offset)
55*4882a593Smuzhiyun #define DEF_DIV6_RO(_name, _id, _parent, _offset, _div)	\
56*4882a593Smuzhiyun 	DEF_BASE(_name, _id, CLK_TYPE_DIV6_RO, _parent, .offset = _offset, .div = _div, .mult = 1)
57*4882a593Smuzhiyun #define DEF_RATE(_name, _id, _rate)	\
58*4882a593Smuzhiyun 	DEF_TYPE(_name, _id, CLK_TYPE_FR, .mult = _rate)
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun     /*
61*4882a593Smuzhiyun      * Definitions of Module Clocks
62*4882a593Smuzhiyun      */
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun struct mssr_mod_clk {
65*4882a593Smuzhiyun 	const char *name;
66*4882a593Smuzhiyun 	unsigned int id;
67*4882a593Smuzhiyun 	unsigned int parent;	/* Add MOD_CLK_BASE for Module Clocks */
68*4882a593Smuzhiyun };
69*4882a593Smuzhiyun 
70*4882a593Smuzhiyun /* Convert from sparse base-100 to packed index space */
71*4882a593Smuzhiyun #define MOD_CLK_PACK(x)	((x) - ((x) / 100) * (100 - 32))
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun #define MOD_CLK_ID(x)	(MOD_CLK_BASE + MOD_CLK_PACK(x))
74*4882a593Smuzhiyun 
75*4882a593Smuzhiyun #define DEF_MOD(_name, _mod, _parent...)	\
76*4882a593Smuzhiyun 	{ .name = _name, .id = MOD_CLK_ID(_mod), .parent = _parent }
77*4882a593Smuzhiyun 
78*4882a593Smuzhiyun /* Convert from sparse base-10 to packed index space */
79*4882a593Smuzhiyun #define MOD_CLK_PACK_10(x)	((x / 10) * 32 + (x % 10))
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun #define MOD_CLK_ID_10(x)	(MOD_CLK_BASE + MOD_CLK_PACK_10(x))
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun #define DEF_MOD_STB(_name, _mod, _parent...)	\
84*4882a593Smuzhiyun 	{ .name = _name, .id = MOD_CLK_ID_10(_mod), .parent = _parent }
85*4882a593Smuzhiyun 
86*4882a593Smuzhiyun struct device_node;
87*4882a593Smuzhiyun 
88*4882a593Smuzhiyun enum clk_reg_layout {
89*4882a593Smuzhiyun 	CLK_REG_LAYOUT_RCAR_GEN2_AND_GEN3 = 0,
90*4882a593Smuzhiyun 	CLK_REG_LAYOUT_RZ_A,
91*4882a593Smuzhiyun 	CLK_REG_LAYOUT_RCAR_V3U,
92*4882a593Smuzhiyun };
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun     /**
95*4882a593Smuzhiyun      * SoC-specific CPG/MSSR Description
96*4882a593Smuzhiyun      *
97*4882a593Smuzhiyun      * @early_core_clks: Array of Early Core Clock definitions
98*4882a593Smuzhiyun      * @num_early_core_clks: Number of entries in early_core_clks[]
99*4882a593Smuzhiyun      * @early_mod_clks: Array of Early Module Clock definitions
100*4882a593Smuzhiyun      * @num_early_mod_clks: Number of entries in early_mod_clks[]
101*4882a593Smuzhiyun      *
102*4882a593Smuzhiyun      * @core_clks: Array of Core Clock definitions
103*4882a593Smuzhiyun      * @num_core_clks: Number of entries in core_clks[]
104*4882a593Smuzhiyun      * @last_dt_core_clk: ID of the last Core Clock exported to DT
105*4882a593Smuzhiyun      * @num_total_core_clks: Total number of Core Clocks (exported + internal)
106*4882a593Smuzhiyun      *
107*4882a593Smuzhiyun      * @mod_clks: Array of Module Clock definitions
108*4882a593Smuzhiyun      * @num_mod_clks: Number of entries in mod_clks[]
109*4882a593Smuzhiyun      * @num_hw_mod_clks: Number of Module Clocks supported by the hardware
110*4882a593Smuzhiyun      *
111*4882a593Smuzhiyun      * @crit_mod_clks: Array with Module Clock IDs of critical clocks that
112*4882a593Smuzhiyun      *                 should not be disabled without a knowledgeable driver
113*4882a593Smuzhiyun      * @num_crit_mod_clks: Number of entries in crit_mod_clks[]
114*4882a593Smuzhiyun      * @reg_layout: CPG/MSSR register layout from enum clk_reg_layout
115*4882a593Smuzhiyun      *
116*4882a593Smuzhiyun      * @core_pm_clks: Array with IDs of Core Clocks that are suitable for Power
117*4882a593Smuzhiyun      *                Management, in addition to Module Clocks
118*4882a593Smuzhiyun      * @num_core_pm_clks: Number of entries in core_pm_clks[]
119*4882a593Smuzhiyun      *
120*4882a593Smuzhiyun      * @init: Optional callback to perform SoC-specific initialization
121*4882a593Smuzhiyun      * @cpg_clk_register: Optional callback to handle special Core Clock types
122*4882a593Smuzhiyun      */
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun struct cpg_mssr_info {
125*4882a593Smuzhiyun 	/* Early Clocks */
126*4882a593Smuzhiyun 	const struct cpg_core_clk *early_core_clks;
127*4882a593Smuzhiyun 	unsigned int num_early_core_clks;
128*4882a593Smuzhiyun 	const struct mssr_mod_clk *early_mod_clks;
129*4882a593Smuzhiyun 	unsigned int num_early_mod_clks;
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun 	/* Core Clocks */
132*4882a593Smuzhiyun 	const struct cpg_core_clk *core_clks;
133*4882a593Smuzhiyun 	unsigned int num_core_clks;
134*4882a593Smuzhiyun 	unsigned int last_dt_core_clk;
135*4882a593Smuzhiyun 	unsigned int num_total_core_clks;
136*4882a593Smuzhiyun 	enum clk_reg_layout reg_layout;
137*4882a593Smuzhiyun 
138*4882a593Smuzhiyun 	/* Module Clocks */
139*4882a593Smuzhiyun 	const struct mssr_mod_clk *mod_clks;
140*4882a593Smuzhiyun 	unsigned int num_mod_clks;
141*4882a593Smuzhiyun 	unsigned int num_hw_mod_clks;
142*4882a593Smuzhiyun 
143*4882a593Smuzhiyun 	/* Critical Module Clocks that should not be disabled */
144*4882a593Smuzhiyun 	const unsigned int *crit_mod_clks;
145*4882a593Smuzhiyun 	unsigned int num_crit_mod_clks;
146*4882a593Smuzhiyun 
147*4882a593Smuzhiyun 	/* Core Clocks suitable for PM, in addition to the Module Clocks */
148*4882a593Smuzhiyun 	const unsigned int *core_pm_clks;
149*4882a593Smuzhiyun 	unsigned int num_core_pm_clks;
150*4882a593Smuzhiyun 
151*4882a593Smuzhiyun 	/* Callbacks */
152*4882a593Smuzhiyun 	int (*init)(struct device *dev);
153*4882a593Smuzhiyun 	struct clk *(*cpg_clk_register)(struct device *dev,
154*4882a593Smuzhiyun 					const struct cpg_core_clk *core,
155*4882a593Smuzhiyun 					const struct cpg_mssr_info *info,
156*4882a593Smuzhiyun 					struct clk **clks, void __iomem *base,
157*4882a593Smuzhiyun 					struct raw_notifier_head *notifiers);
158*4882a593Smuzhiyun };
159*4882a593Smuzhiyun 
160*4882a593Smuzhiyun extern const struct cpg_mssr_info r7s9210_cpg_mssr_info;
161*4882a593Smuzhiyun extern const struct cpg_mssr_info r8a7742_cpg_mssr_info;
162*4882a593Smuzhiyun extern const struct cpg_mssr_info r8a7743_cpg_mssr_info;
163*4882a593Smuzhiyun extern const struct cpg_mssr_info r8a7745_cpg_mssr_info;
164*4882a593Smuzhiyun extern const struct cpg_mssr_info r8a77470_cpg_mssr_info;
165*4882a593Smuzhiyun extern const struct cpg_mssr_info r8a774a1_cpg_mssr_info;
166*4882a593Smuzhiyun extern const struct cpg_mssr_info r8a774b1_cpg_mssr_info;
167*4882a593Smuzhiyun extern const struct cpg_mssr_info r8a774c0_cpg_mssr_info;
168*4882a593Smuzhiyun extern const struct cpg_mssr_info r8a774e1_cpg_mssr_info;
169*4882a593Smuzhiyun extern const struct cpg_mssr_info r8a7790_cpg_mssr_info;
170*4882a593Smuzhiyun extern const struct cpg_mssr_info r8a7791_cpg_mssr_info;
171*4882a593Smuzhiyun extern const struct cpg_mssr_info r8a7792_cpg_mssr_info;
172*4882a593Smuzhiyun extern const struct cpg_mssr_info r8a7794_cpg_mssr_info;
173*4882a593Smuzhiyun extern const struct cpg_mssr_info r8a7795_cpg_mssr_info;
174*4882a593Smuzhiyun extern const struct cpg_mssr_info r8a7796_cpg_mssr_info;
175*4882a593Smuzhiyun extern const struct cpg_mssr_info r8a77965_cpg_mssr_info;
176*4882a593Smuzhiyun extern const struct cpg_mssr_info r8a77970_cpg_mssr_info;
177*4882a593Smuzhiyun extern const struct cpg_mssr_info r8a77980_cpg_mssr_info;
178*4882a593Smuzhiyun extern const struct cpg_mssr_info r8a77990_cpg_mssr_info;
179*4882a593Smuzhiyun extern const struct cpg_mssr_info r8a77995_cpg_mssr_info;
180*4882a593Smuzhiyun extern const struct cpg_mssr_info r8a779a0_cpg_mssr_info;
181*4882a593Smuzhiyun 
182*4882a593Smuzhiyun void __init cpg_mssr_early_init(struct device_node *np,
183*4882a593Smuzhiyun 				const struct cpg_mssr_info *info);
184*4882a593Smuzhiyun 
185*4882a593Smuzhiyun     /*
186*4882a593Smuzhiyun      * Helpers for fixing up clock tables depending on SoC revision
187*4882a593Smuzhiyun      */
188*4882a593Smuzhiyun 
189*4882a593Smuzhiyun struct mssr_mod_reparent {
190*4882a593Smuzhiyun 	unsigned int clk, parent;
191*4882a593Smuzhiyun };
192*4882a593Smuzhiyun 
193*4882a593Smuzhiyun 
194*4882a593Smuzhiyun extern void cpg_core_nullify_range(struct cpg_core_clk *core_clks,
195*4882a593Smuzhiyun 				   unsigned int num_core_clks,
196*4882a593Smuzhiyun 				   unsigned int first_clk,
197*4882a593Smuzhiyun 				   unsigned int last_clk);
198*4882a593Smuzhiyun extern void mssr_mod_nullify(struct mssr_mod_clk *mod_clks,
199*4882a593Smuzhiyun 			     unsigned int num_mod_clks,
200*4882a593Smuzhiyun 			     const unsigned int *clks, unsigned int n);
201*4882a593Smuzhiyun extern void mssr_mod_reparent(struct mssr_mod_clk *mod_clks,
202*4882a593Smuzhiyun 			      unsigned int num_mod_clks,
203*4882a593Smuzhiyun 			      const struct mssr_mod_reparent *clks,
204*4882a593Smuzhiyun 			      unsigned int n);
205*4882a593Smuzhiyun #endif
206