1 /* SPDX-License-Identifier: GPL-2.0+ */
2 /*
3  * Renesas RCar Gen3 CPG MSSR driver
4  *
5  * Copyright (C) 2017-2018 Marek Vasut <marek.vasut@gmail.com>
6  *
7  * Based on the following driver from Linux kernel:
8  * r8a7796 Clock Pulse Generator / Module Standby and Software Reset
9  *
10  * Copyright (C) 2016 Glider bvba
11  */
12 
13 #ifndef __DRIVERS_CLK_RENESAS_CPG_MSSR__
14 #define __DRIVERS_CLK_RENESAS_CPG_MSSR__
15 
16 #include <linux/bitops.h>
17 
18 enum clk_reg_layout {
19 	CLK_REG_LAYOUT_RCAR_GEN2_AND_GEN3 = 0,
20 	CLK_REG_LAYOUT_RCAR_GEN4,
21 };
22 
23 struct cpg_mssr_info {
24 	const struct cpg_core_clk	*core_clk;
25 	unsigned int			core_clk_size;
26 	enum clk_reg_layout		reg_layout;
27 	const struct mssr_mod_clk	*mod_clk;
28 	unsigned int			mod_clk_size;
29 	const struct mstp_stop_table	*mstp_table;
30 	unsigned int			mstp_table_size;
31 	const char			*reset_node;
32 	unsigned int			reset_modemr_offset;
33 	const char			*extalr_node;
34 	const char			*extal_usb_node;
35 	unsigned int			mod_clk_base;
36 	unsigned int			clk_extal_id;
37 	unsigned int			clk_extalr_id;
38 	unsigned int			clk_extal_usb_id;
39 	unsigned int			pll0_div;
40 	const void			*(*get_pll_config)(const u32 cpg_mode);
41 	const u16			*status_regs;
42 	const u16			*control_regs;
43 	const u16			*reset_regs;
44 	const u16			*reset_clear_regs;
45 };
46 
47 /*
48  * Definitions of CPG Core Clocks
49  *
50  * These include:
51  *   - Clock outputs exported to DT
52  *   - External input clocks
53  *   - Internal CPG clocks
54  */
55 struct cpg_core_clk {
56 	/* Common */
57 	const char *name;
58 	unsigned int id;
59 	unsigned int type;
60 	/* Depending on type */
61 	unsigned int parent;	/* Core Clocks only */
62 	unsigned int div;
63 	unsigned int mult;
64 	unsigned int offset;
65 };
66 
67 enum clk_types {
68 	/* Generic */
69 	CLK_TYPE_IN,		/* External Clock Input */
70 	CLK_TYPE_FF,		/* Fixed Factor Clock */
71 	CLK_TYPE_DIV6P1,	/* DIV6 Clock with 1 parent clock */
72 	CLK_TYPE_DIV6_RO,	/* DIV6 Clock read only with extra divisor */
73 	CLK_TYPE_FR,		/* Fixed Rate Clock */
74 
75 	/* Custom definitions start here */
76 	CLK_TYPE_CUSTOM,
77 };
78 
79 #define DEF_TYPE(_name, _id, _type...)	\
80 	{ .name = _name, .id = _id, .type = _type }
81 #define DEF_BASE(_name, _id, _type, _parent...)	\
82 	DEF_TYPE(_name, _id, _type, .parent = _parent)
83 
84 #define DEF_INPUT(_name, _id) \
85 	DEF_TYPE(_name, _id, CLK_TYPE_IN)
86 #define DEF_FIXED(_name, _id, _parent, _div, _mult)	\
87 	DEF_BASE(_name, _id, CLK_TYPE_FF, _parent, .div = _div, .mult = _mult)
88 #define DEF_DIV6P1(_name, _id, _parent, _offset)	\
89 	DEF_BASE(_name, _id, CLK_TYPE_DIV6P1, _parent, .offset = _offset)
90 #define DEF_DIV6_RO(_name, _id, _parent, _offset, _div)	\
91 	DEF_BASE(_name, _id, CLK_TYPE_DIV6_RO, _parent, .offset = _offset, .div = _div, .mult = 1)
92 #define DEF_RATE(_name, _id, _rate)	\
93 	DEF_TYPE(_name, _id, CLK_TYPE_FR, .mult = _rate)
94 
95 /*
96  * Definitions of Module Clocks
97  */
98 struct mssr_mod_clk {
99 	const char *name;
100 	unsigned int id;
101 	unsigned int parent;	/* Add MOD_CLK_BASE for Module Clocks */
102 };
103 
104 /* Convert from sparse base-100 to packed index space */
105 #define MOD_CLK_PACK(x)	((x) - ((x) / 100) * (100 - 32))
106 
107 #define MOD_CLK_ID(x)	(MOD_CLK_BASE + MOD_CLK_PACK(x))
108 
109 #define DEF_MOD(_name, _mod, _parent...)	\
110 	{ .name = _name, .id = MOD_CLK_ID(_mod), .parent = _parent }
111 
112 struct mstp_stop_table {
113 	u32	sdis;
114 	u32	sen;
115 	u32	rdis;
116 	u32	ren;
117 };
118 
119 #define TSTR0		0x04
120 #define TSTR0_STR0	BIT(0)
121 
122 bool renesas_clk_is_mod(struct clk *clk);
123 int renesas_clk_get_mod(struct clk *clk, struct cpg_mssr_info *info,
124 			const struct mssr_mod_clk **mssr);
125 int renesas_clk_get_core(struct clk *clk, struct cpg_mssr_info *info,
126 			 const struct cpg_core_clk **core);
127 int renesas_clk_get_parent(struct clk *clk, struct cpg_mssr_info *info,
128 			   struct clk *parent);
129 int renesas_clk_endisable(struct clk *clk, void __iomem *base,
130 			  struct cpg_mssr_info *info, bool enable);
131 int renesas_clk_remove(void __iomem *base, struct cpg_mssr_info *info);
132 
133 /*
134  * Module Standby and Software Reset register offets.
135  *
136  * If the registers exist, these are valid for SH-Mobile, R-Mobile,
137  * R-Car Gen2, R-Car Gen3, R-Car Gen4 and RZ/G1.
138  * These are NOT valid for R-Car Gen1 and RZ/A1!
139  */
140 
141 /*
142  * Module Stop Status Register offsets
143  */
144 
145 static const u16 mstpsr[] = {
146 	0x030, 0x038, 0x040, 0x048, 0x04C, 0x03C, 0x1C0, 0x1C4,
147 	0x9A0, 0x9A4, 0x9A8, 0x9AC,
148 };
149 
150 static const u16 mstpsr_for_gen4[] = {
151 	0x2E00, 0x2E04, 0x2E08, 0x2E0C, 0x2E10, 0x2E14, 0x2E18, 0x2E1C,
152 	0x2E20, 0x2E24, 0x2E28, 0x2E2C, 0x2E30, 0x2E34, 0x2E38, 0x2E3C,
153 	0x2E40, 0x2E44, 0x2E48, 0x2E4C, 0x2E50, 0x2E54, 0x2E58, 0x2E5C,
154 	0x2E60, 0x2E64, 0x2E68, 0x2E6C,
155 };
156 
157 /*
158  * System Module Stop Control Register offsets
159  */
160 
161 static const u16 smstpcr[] = {
162 	0x130, 0x134, 0x138, 0x13C, 0x140, 0x144, 0x148, 0x14C,
163 	0x990, 0x994, 0x998, 0x99C,
164 };
165 
166 static const u16 mstpcr_for_gen4[] = {
167 	0x2D00, 0x2D04, 0x2D08, 0x2D0C, 0x2D10, 0x2D14, 0x2D18, 0x2D1C,
168 	0x2D20, 0x2D24, 0x2D28, 0x2D2C, 0x2D30, 0x2D34, 0x2D38, 0x2D3C,
169 	0x2D40, 0x2D44, 0x2D48, 0x2D4C, 0x2D50, 0x2D54, 0x2D58, 0x2D5C,
170 	0x2D60, 0x2D64, 0x2D68, 0x2D6C,
171 };
172 
173 /*
174  * Software Reset Register offsets
175  */
176 
177 static const u16 srcr[] = {
178 	0x0A0, 0x0A8, 0x0B0, 0x0B8, 0x0BC, 0x0C4, 0x1C8, 0x1CC,
179 	0x920, 0x924, 0x928, 0x92C,
180 };
181 
182 static const u16 srcr_for_gen4[] = {
183 	0x2C00, 0x2C04, 0x2C08, 0x2C0C, 0x2C10, 0x2C14, 0x2C18, 0x2C1C,
184 	0x2C20, 0x2C24, 0x2C28, 0x2C2C, 0x2C30, 0x2C34, 0x2C38, 0x2C3C,
185 	0x2C40, 0x2C44, 0x2C48, 0x2C4C, 0x2C50, 0x2C54, 0x2C58, 0x2C5C,
186 	0x2C60, 0x2C64, 0x2C68, 0x2C6C,
187 };
188 
189 /* Realtime Module Stop Control Register offsets */
190 #define RMSTPCR(i)	((i) < 8 ? smstpcr[i] - 0x20 : smstpcr[i] - 0x10)
191 
192 /* Modem Module Stop Control Register offsets (r8a73a4) */
193 #define MMSTPCR(i)	(smstpcr[i] + 0x20)
194 
195 /* Software Reset Clearing Register offsets */
196 
197 static const u16 srstclr[] = {
198 	0x940, 0x944, 0x948, 0x94C, 0x950, 0x954, 0x958, 0x95C,
199 	0x960, 0x964, 0x968, 0x96C,
200 };
201 
202 static const u16 srstclr_for_gen4[] = {
203 	0x2C80, 0x2C84, 0x2C88, 0x2C8C, 0x2C90, 0x2C94, 0x2C98, 0x2C9C,
204 	0x2CA0, 0x2CA4, 0x2CA8, 0x2CAC, 0x2CB0, 0x2CB4, 0x2CB8, 0x2CBC,
205 	0x2CC0, 0x2CC4, 0x2CC8, 0x2CCC, 0x2CD0, 0x2CD4, 0x2CD8, 0x2CDC,
206 	0x2CE0, 0x2CE4, 0x2CE8, 0x2CEC,
207 };
208 
209 #endif /* __DRIVERS_CLK_RENESAS_CPG_MSSR__ */
210