xref: /OK3568_Linux_fs/kernel/drivers/soc/rockchip/grf.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Rockchip Generic Register Files setup
4  *
5  * Copyright (c) 2016 Heiko Stuebner <heiko@sntech.de>
6  */
7 
8 #include <linux/bitfield.h>
9 #include <linux/err.h>
10 #include <linux/mfd/syscon.h>
11 #include <linux/module.h>
12 #include <linux/of_device.h>
13 #include <linux/platform_device.h>
14 #include <linux/regmap.h>
15 
16 struct rockchip_grf;
17 
18 struct rockchip_grf_funcs {
19 	int (*reset)(struct rockchip_grf *grf);
20 };
21 
22 struct rockchip_grf {
23 	struct regmap *regmap;
24 	const struct rockchip_grf_funcs *funcs;
25 };
26 
rockchip_edp_phy_grf_probe(struct platform_device * pdev)27 static int rockchip_edp_phy_grf_probe(struct platform_device *pdev)
28 {
29 	struct device *dev = &pdev->dev;
30 	struct rockchip_grf *grf;
31 	int ret;
32 
33 	grf = devm_kzalloc(dev, sizeof(*grf), GFP_KERNEL);
34 	if (!grf)
35 		return -ENOMEM;
36 
37 	grf->funcs = of_device_get_match_data(dev);
38 	if (!grf->funcs)
39 		return -ENODEV;
40 
41 	grf->regmap = syscon_node_to_regmap(dev->of_node);
42 	if (IS_ERR(grf->regmap)) {
43 		ret = PTR_ERR(grf->regmap);
44 		dev_err(dev, "failed to get grf: %d\n", ret);
45 		return ret;
46 	}
47 
48 	ret = grf->funcs->reset(grf);
49 	if (ret)
50 		return ret;
51 
52 	platform_set_drvdata(pdev, grf);
53 
54 	return 0;
55 }
56 
rockchip_edp_phy_grf_resume(struct device * dev)57 static int __maybe_unused rockchip_edp_phy_grf_resume(struct device *dev)
58 {
59 	struct rockchip_grf *grf = dev_get_drvdata(dev);
60 
61 	return grf->funcs->reset(grf);
62 }
63 
64 static const struct dev_pm_ops rockchip_edp_phy_grf_pm_ops = {
65 	SET_LATE_SYSTEM_SLEEP_PM_OPS(NULL, rockchip_edp_phy_grf_resume)
66 };
67 
rk3568_edp_phy_grf_reset(struct rockchip_grf * grf)68 static int rk3568_edp_phy_grf_reset(struct rockchip_grf *grf)
69 {
70 	u32 status;
71 	int ret;
72 
73 	ret = regmap_read(grf->regmap, 0x0030, &status);
74 	if (ret < 0)
75 		return ret;
76 
77 	if (!FIELD_GET(0x1, status)) {
78 		regmap_write(grf->regmap, 0x0028, 0x00070007);
79 		regmap_write(grf->regmap, 0x0000, 0x0ff10ff1);
80 	}
81 
82 	return 0;
83 }
84 
85 static const struct rockchip_grf_funcs rk3568_edp_phy_grf_funcs = {
86 	.reset = rk3568_edp_phy_grf_reset,
87 };
88 
89 static const struct of_device_id rockchip_edp_phy_grf_match[] = {
90 	{
91 		.compatible = "rockchip,rk3568-edp-phy-grf",
92 		.data = &rk3568_edp_phy_grf_funcs,
93 	},
94 	{}
95 };
96 MODULE_DEVICE_TABLE(of, rockchip_edp_phy_grf_match);
97 
98 static struct platform_driver rockchip_edp_phy_grf_driver = {
99 	.driver = {
100 		.name = "rockchip-edp-phy-grf",
101 		.of_match_table = rockchip_edp_phy_grf_match,
102 		.pm = &rockchip_edp_phy_grf_pm_ops,
103 	},
104 	.probe = rockchip_edp_phy_grf_probe,
105 };
106 
107 #define HIWORD_UPDATE(val, mask, shift) \
108 		((val) << (shift) | (mask) << ((shift) + 16))
109 
110 struct rockchip_grf_value {
111 	const char *desc;
112 	u32 reg;
113 	u32 val;
114 };
115 
116 struct rockchip_grf_info {
117 	const struct rockchip_grf_value *values;
118 	int num_values;
119 };
120 
121 #define PX30_GRF_SOC_CON5		0x414
122 
123 static const struct rockchip_grf_value px30_defaults[] __initconst = {
124 	/*
125 	 * Postponing auto jtag/sdmmc switching by 5 seconds.
126 	 * The counter value is calculated based on 24MHz clock.
127 	 */
128 	{ "jtag switching delay", PX30_GRF_SOC_CON5, 0x7270E00},
129 };
130 
131 static const struct rockchip_grf_info px30_grf __initconst = {
132 	.values = px30_defaults,
133 	.num_values = ARRAY_SIZE(px30_defaults),
134 };
135 
136 #define RK3036_GRF_SOC_CON0		0x140
137 
138 static const struct rockchip_grf_value rk3036_defaults[] __initconst = {
139 	/*
140 	 * Disable auto jtag/sdmmc switching that causes issues with the
141 	 * clock-framework and the mmc controllers making them unreliable.
142 	 */
143 	{ "jtag switching", RK3036_GRF_SOC_CON0, HIWORD_UPDATE(0, 1, 11) },
144 };
145 
146 static const struct rockchip_grf_info rk3036_grf __initconst = {
147 	.values = rk3036_defaults,
148 	.num_values = ARRAY_SIZE(rk3036_defaults),
149 };
150 
151 #define RK3128_GRF_SOC_CON0		0x140
152 
153 static const struct rockchip_grf_value rk3128_defaults[] __initconst = {
154 	{ "jtag switching", RK3128_GRF_SOC_CON0, HIWORD_UPDATE(0, 1, 8) },
155 };
156 
157 static const struct rockchip_grf_info rk3128_grf __initconst = {
158 	.values = rk3128_defaults,
159 	.num_values = ARRAY_SIZE(rk3128_defaults),
160 };
161 
162 #define RK3228_GRF_SOC_CON6		0x418
163 
164 static const struct rockchip_grf_value rk3228_defaults[] __initconst = {
165 	{ "jtag switching", RK3228_GRF_SOC_CON6, HIWORD_UPDATE(0, 1, 8) },
166 };
167 
168 static const struct rockchip_grf_info rk3228_grf __initconst = {
169 	.values = rk3228_defaults,
170 	.num_values = ARRAY_SIZE(rk3228_defaults),
171 };
172 
173 #define RK3288_GRF_SOC_CON0		0x244
174 #define RK3288_GRF_SOC_CON2		0x24c
175 
176 static const struct rockchip_grf_value rk3288_defaults[] __initconst = {
177 	{ "jtag switching", RK3288_GRF_SOC_CON0, HIWORD_UPDATE(0, 1, 12) },
178 	{ "pwm select", RK3288_GRF_SOC_CON2, HIWORD_UPDATE(1, 1, 0) },
179 };
180 
181 static const struct rockchip_grf_info rk3288_grf __initconst = {
182 	.values = rk3288_defaults,
183 	.num_values = ARRAY_SIZE(rk3288_defaults),
184 };
185 
186 #define RK3328_GRF_SOC_CON4		0x410
187 
188 static const struct rockchip_grf_value rk3328_defaults[] __initconst = {
189 	{ "jtag switching", RK3328_GRF_SOC_CON4, HIWORD_UPDATE(0, 1, 12) },
190 };
191 
192 static const struct rockchip_grf_info rk3328_grf __initconst = {
193 	.values = rk3328_defaults,
194 	.num_values = ARRAY_SIZE(rk3328_defaults),
195 };
196 
197 #define RK3308_GRF_SOC_CON3		0x30c
198 #define RK3308_GRF_SOC_CON13		0x608
199 
200 static const struct rockchip_grf_value rk3308_defaults[] __initconst = {
201 	{ "uart dma mask", RK3308_GRF_SOC_CON3, HIWORD_UPDATE(0, 0x1f, 10) },
202 	{ "uart2 auto switching", RK3308_GRF_SOC_CON13, HIWORD_UPDATE(0, 0x1, 12) },
203 };
204 
205 static const struct rockchip_grf_info rk3308_grf __initconst = {
206 	.values = rk3308_defaults,
207 	.num_values = ARRAY_SIZE(rk3308_defaults),
208 };
209 
210 #define RK3368_GRF_SOC_CON15		0x43c
211 
212 static const struct rockchip_grf_value rk3368_defaults[] __initconst = {
213 	{ "jtag switching", RK3368_GRF_SOC_CON15, HIWORD_UPDATE(0, 1, 13) },
214 };
215 
216 static const struct rockchip_grf_info rk3368_grf __initconst = {
217 	.values = rk3368_defaults,
218 	.num_values = ARRAY_SIZE(rk3368_defaults),
219 };
220 
221 #define RK3399_GRF_SOC_CON7		0xe21c
222 
223 static const struct rockchip_grf_value rk3399_defaults[] __initconst = {
224 	{ "jtag switching", RK3399_GRF_SOC_CON7, HIWORD_UPDATE(0, 1, 12) },
225 };
226 
227 static const struct rockchip_grf_info rk3399_grf __initconst = {
228 	.values = rk3399_defaults,
229 	.num_values = ARRAY_SIZE(rk3399_defaults),
230 };
231 
232 #define RK3588_SYS_GRF_SOC_CON7		0x031c
233 
234 static const struct rockchip_grf_value rk3588_sys_grf_defaults[] __initconst = {
235 	{ "Connect EDP hpd to IO", RK3588_SYS_GRF_SOC_CON7, HIWORD_UPDATE(0x3, 0x3, 14) },
236 };
237 
238 static const struct rockchip_grf_info rk3588_sys_grf __initconst = {
239 	.values = rk3588_sys_grf_defaults,
240 	.num_values = ARRAY_SIZE(rk3588_sys_grf_defaults),
241 };
242 
243 #define DELAY_ONE_SECOND		0x16E3600
244 
245 #define RV1126_GRF1_SDDETFLT_CON	0x10254
246 #define RV1126_GRF1_UART2RX_LOW_CON	0x10258
247 #define RV1126_GRF1_IOFUNC_CON1		0x10264
248 #define RV1126_GRF1_IOFUNC_CON3		0x1026C
249 #define RV1126_JTAG_GROUP0		0x0      /* mux to sdmmc*/
250 #define RV1126_JTAG_GROUP1		0x1      /* mux to uart2 */
251 #define FORCE_JTAG_ENABLE		0x1
252 #define FORCE_JTAG_DISABLE		0x0
253 
254 static const struct rockchip_grf_value rv1126_defaults[] __initconst = {
255 	{ "jtag group0 force", RV1126_GRF1_IOFUNC_CON3,
256 		HIWORD_UPDATE(FORCE_JTAG_DISABLE, 1, 4) },
257 	{ "jtag group1 force", RV1126_GRF1_IOFUNC_CON3,
258 		HIWORD_UPDATE(FORCE_JTAG_DISABLE, 1, 5) },
259 	{ "jtag group1 tms low delay", RV1126_GRF1_UART2RX_LOW_CON, DELAY_ONE_SECOND },
260 	{ "switch to jtag groupx", RV1126_GRF1_IOFUNC_CON1, HIWORD_UPDATE(RV1126_JTAG_GROUP0, 1, 15) },
261 	{ "jtag group0 switching delay", RV1126_GRF1_SDDETFLT_CON, DELAY_ONE_SECOND * 5 },
262 };
263 
264 static const struct rockchip_grf_info rv1126_grf __initconst = {
265 	.values = rv1126_defaults,
266 	.num_values = ARRAY_SIZE(rv1126_defaults),
267 };
268 
269 static const struct of_device_id rockchip_grf_dt_match[] __initconst = {
270 	{
271 		.compatible = "rockchip,px30-grf",
272 		.data = (void *)&px30_grf,
273 	}, {
274 		.compatible = "rockchip,rk3036-grf",
275 		.data = (void *)&rk3036_grf,
276 	}, {
277 		.compatible = "rockchip,rk3128-grf",
278 		.data = (void *)&rk3128_grf,
279 	}, {
280 		.compatible = "rockchip,rk3228-grf",
281 		.data = (void *)&rk3228_grf,
282 	}, {
283 		.compatible = "rockchip,rk3288-grf",
284 		.data = (void *)&rk3288_grf,
285 	}, {
286 		.compatible = "rockchip,rk3308-grf",
287 		.data = (void *)&rk3308_grf,
288 	}, {
289 		.compatible = "rockchip,rk3328-grf",
290 		.data = (void *)&rk3328_grf,
291 	}, {
292 		.compatible = "rockchip,rk3368-grf",
293 		.data = (void *)&rk3368_grf,
294 	}, {
295 		.compatible = "rockchip,rk3399-grf",
296 		.data = (void *)&rk3399_grf,
297 	}, {
298 		.compatible = "rockchip,rk3588-sys-grf",
299 		.data = (void *)&rk3588_sys_grf,
300 	}, {
301 		.compatible = "rockchip,rv1126-grf",
302 		.data = (void *)&rv1126_grf,
303 	},
304 	{ /* sentinel */ },
305 };
306 
rockchip_grf_init(void)307 static int __init rockchip_grf_init(void)
308 {
309 	const struct rockchip_grf_info *grf_info;
310 	const struct of_device_id *match;
311 	struct device_node *np;
312 	struct regmap *grf;
313 	int ret, i;
314 
315 	ret = platform_driver_register(&rockchip_edp_phy_grf_driver);
316 	if (ret)
317 		return ret;
318 
319 	np = of_find_matching_node_and_match(NULL, rockchip_grf_dt_match,
320 					     &match);
321 	if (!np)
322 		return 0;
323 	if (!match || !match->data) {
324 		pr_err("%s: missing grf data\n", __func__);
325 		of_node_put(np);
326 		return -EINVAL;
327 	}
328 
329 	grf_info = match->data;
330 
331 	grf = syscon_node_to_regmap(np);
332 	of_node_put(np);
333 	if (IS_ERR(grf)) {
334 		pr_err("%s: could not get grf syscon\n", __func__);
335 		return PTR_ERR(grf);
336 	}
337 
338 	for (i = 0; i < grf_info->num_values; i++) {
339 		const struct rockchip_grf_value *val = &grf_info->values[i];
340 
341 		pr_debug("%s: adjusting %s in %#6x to %#10x\n", __func__,
342 			val->desc, val->reg, val->val);
343 		ret = regmap_write(grf, val->reg, val->val);
344 		if (ret < 0)
345 			pr_err("%s: write to %#6x failed with %d\n",
346 			       __func__, val->reg, ret);
347 	}
348 
349 	return 0;
350 }
351 postcore_initcall(rockchip_grf_init);
352 
353 MODULE_DESCRIPTION("Rockchip GRF");
354 MODULE_LICENSE("GPL");
355