1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (c) 2019 BayLibre, SAS
4  * Author: Neil Armstrong <narmstrong@baylibre.com>
5  */
6 
7 #include <common.h>
8 #include <dm.h>
9 #include <log.h>
10 #include <malloc.h>
11 #include <power-domain-uclass.h>
12 #include <regmap.h>
13 #include <syscon.h>
14 #include <reset.h>
15 #include <clk.h>
16 #include <dt-bindings/power/meson-axg-power.h>
17 #include <dt-bindings/power/meson-g12a-power.h>
18 #include <dt-bindings/power/meson-gxbb-power.h>
19 #include <dt-bindings/power/meson-sm1-power.h>
20 #include <linux/bitops.h>
21 #include <linux/delay.h>
22 #include <linux/err.h>
23 
24 /* AO Offsets */
25 
26 #define AO_RTI_GEN_PWR_SLEEP0		(0x3a << 2)
27 #define AO_RTI_GEN_PWR_ISO0		(0x3b << 2)
28 
29 /* HHI Offsets */
30 
31 #define HHI_MEM_PD_REG0			(0x40 << 2)
32 #define HHI_VPU_MEM_PD_REG0		(0x41 << 2)
33 #define HHI_VPU_MEM_PD_REG1		(0x42 << 2)
34 #define HHI_VPU_MEM_PD_REG3		(0x43 << 2)
35 #define HHI_VPU_MEM_PD_REG4		(0x44 << 2)
36 #define HHI_AUDIO_MEM_PD_REG0		(0x45 << 2)
37 #define HHI_NANOQ_MEM_PD_REG0		(0x46 << 2)
38 #define HHI_NANOQ_MEM_PD_REG1		(0x47 << 2)
39 #define HHI_VPU_MEM_PD_REG2		(0x4d << 2)
40 
41 struct meson_ee_pwrc;
42 struct meson_ee_pwrc_domain;
43 
44 struct meson_ee_pwrc_mem_domain {
45 	unsigned int reg;
46 	unsigned int mask;
47 };
48 
49 struct meson_ee_pwrc_top_domain {
50 	unsigned int sleep_reg;
51 	unsigned int sleep_mask;
52 	unsigned int iso_reg;
53 	unsigned int iso_mask;
54 };
55 
56 struct meson_ee_pwrc_domain_desc {
57 	char *name;
58 	unsigned int reset_names_count;
59 	unsigned int clk_names_count;
60 	struct meson_ee_pwrc_top_domain *top_pd;
61 	unsigned int mem_pd_count;
62 	struct meson_ee_pwrc_mem_domain *mem_pd;
63 	bool (*get_power)(struct power_domain *power_domain);
64 };
65 
66 struct meson_ee_pwrc_domain_data {
67 	unsigned int count;
68 	struct meson_ee_pwrc_domain_desc *domains;
69 };
70 
71 /* TOP Power Domains */
72 
73 static struct meson_ee_pwrc_top_domain gx_pwrc_vpu = {
74 	.sleep_reg = AO_RTI_GEN_PWR_SLEEP0,
75 	.sleep_mask = BIT(8),
76 	.iso_reg = AO_RTI_GEN_PWR_SLEEP0,
77 	.iso_mask = BIT(9),
78 };
79 
80 #define SM1_EE_PD(__bit)					\
81 	{							\
82 		.sleep_reg = AO_RTI_GEN_PWR_SLEEP0,		\
83 		.sleep_mask = BIT(__bit),			\
84 		.iso_reg = AO_RTI_GEN_PWR_ISO0,			\
85 		.iso_mask = BIT(__bit),				\
86 	}
87 
88 static struct meson_ee_pwrc_top_domain sm1_pwrc_vpu = SM1_EE_PD(8);
89 static struct meson_ee_pwrc_top_domain sm1_pwrc_nna = SM1_EE_PD(16);
90 static struct meson_ee_pwrc_top_domain sm1_pwrc_usb = SM1_EE_PD(17);
91 static struct meson_ee_pwrc_top_domain sm1_pwrc_pci = SM1_EE_PD(18);
92 static struct meson_ee_pwrc_top_domain sm1_pwrc_ge2d = SM1_EE_PD(19);
93 
94 /* Memory PD Domains */
95 
96 #define VPU_MEMPD(__reg)					\
97 	{ __reg, GENMASK(1, 0) },				\
98 	{ __reg, GENMASK(3, 2) },				\
99 	{ __reg, GENMASK(5, 4) },				\
100 	{ __reg, GENMASK(7, 6) },				\
101 	{ __reg, GENMASK(9, 8) },				\
102 	{ __reg, GENMASK(11, 10) },				\
103 	{ __reg, GENMASK(13, 12) },				\
104 	{ __reg, GENMASK(15, 14) },				\
105 	{ __reg, GENMASK(17, 16) },				\
106 	{ __reg, GENMASK(19, 18) },				\
107 	{ __reg, GENMASK(21, 20) },				\
108 	{ __reg, GENMASK(23, 22) },				\
109 	{ __reg, GENMASK(25, 24) },				\
110 	{ __reg, GENMASK(27, 26) },				\
111 	{ __reg, GENMASK(29, 28) },				\
112 	{ __reg, GENMASK(31, 30) }
113 
114 #define VPU_HHI_MEMPD(__reg)					\
115 	{ __reg, BIT(8) },					\
116 	{ __reg, BIT(9) },					\
117 	{ __reg, BIT(10) },					\
118 	{ __reg, BIT(11) },					\
119 	{ __reg, BIT(12) },					\
120 	{ __reg, BIT(13) },					\
121 	{ __reg, BIT(14) },					\
122 	{ __reg, BIT(15) }
123 
124 static struct meson_ee_pwrc_mem_domain g12a_pwrc_mem_vpu[] = {
125 	VPU_MEMPD(HHI_VPU_MEM_PD_REG0),
126 	VPU_MEMPD(HHI_VPU_MEM_PD_REG1),
127 	VPU_MEMPD(HHI_VPU_MEM_PD_REG2),
128 	VPU_HHI_MEMPD(HHI_MEM_PD_REG0),
129 };
130 
131 static struct meson_ee_pwrc_mem_domain axg_pwrc_mem_vpu[] = {
132 	VPU_MEMPD(HHI_VPU_MEM_PD_REG0),
133 	VPU_HHI_MEMPD(HHI_MEM_PD_REG0),
134 };
135 
136 static struct meson_ee_pwrc_mem_domain gxbb_pwrc_mem_vpu[] = {
137 	VPU_MEMPD(HHI_VPU_MEM_PD_REG0),
138 	VPU_MEMPD(HHI_VPU_MEM_PD_REG1),
139 	VPU_HHI_MEMPD(HHI_MEM_PD_REG0),
140 };
141 
142 static struct meson_ee_pwrc_mem_domain g12a_pwrc_mem_eth[] = {
143 	{ HHI_MEM_PD_REG0, GENMASK(3, 2) },
144 };
145 
146 static struct meson_ee_pwrc_mem_domain sm1_pwrc_mem_vpu[] = {
147 	VPU_MEMPD(HHI_VPU_MEM_PD_REG0),
148 	VPU_MEMPD(HHI_VPU_MEM_PD_REG1),
149 	VPU_MEMPD(HHI_VPU_MEM_PD_REG2),
150 	VPU_MEMPD(HHI_VPU_MEM_PD_REG3),
151 	{ HHI_VPU_MEM_PD_REG4, GENMASK(1, 0) },
152 	{ HHI_VPU_MEM_PD_REG4, GENMASK(3, 2) },
153 	{ HHI_VPU_MEM_PD_REG4, GENMASK(5, 4) },
154 	{ HHI_VPU_MEM_PD_REG4, GENMASK(7, 6) },
155 	VPU_HHI_MEMPD(HHI_MEM_PD_REG0),
156 };
157 
158 static struct meson_ee_pwrc_mem_domain sm1_pwrc_mem_nna[] = {
159 	{ HHI_NANOQ_MEM_PD_REG0, 0xff },
160 	{ HHI_NANOQ_MEM_PD_REG1, 0xff },
161 };
162 
163 static struct meson_ee_pwrc_mem_domain sm1_pwrc_mem_usb[] = {
164 	{ HHI_MEM_PD_REG0, GENMASK(31, 30) },
165 };
166 
167 static struct meson_ee_pwrc_mem_domain sm1_pwrc_mem_pcie[] = {
168 	{ HHI_MEM_PD_REG0, GENMASK(29, 26) },
169 };
170 
171 static struct meson_ee_pwrc_mem_domain sm1_pwrc_mem_ge2d[] = {
172 	{ HHI_MEM_PD_REG0, GENMASK(25, 18) },
173 };
174 
175 static struct meson_ee_pwrc_mem_domain axg_pwrc_mem_audio[] = {
176 	{ HHI_MEM_PD_REG0, GENMASK(5, 4) },
177 };
178 
179 static struct meson_ee_pwrc_mem_domain sm1_pwrc_mem_audio[] = {
180 	{ HHI_MEM_PD_REG0, GENMASK(5, 4) },
181 	{ HHI_AUDIO_MEM_PD_REG0, GENMASK(1, 0) },
182 	{ HHI_AUDIO_MEM_PD_REG0, GENMASK(3, 2) },
183 	{ HHI_AUDIO_MEM_PD_REG0, GENMASK(5, 4) },
184 	{ HHI_AUDIO_MEM_PD_REG0, GENMASK(7, 6) },
185 	{ HHI_AUDIO_MEM_PD_REG0, GENMASK(13, 12) },
186 	{ HHI_AUDIO_MEM_PD_REG0, GENMASK(15, 14) },
187 	{ HHI_AUDIO_MEM_PD_REG0, GENMASK(17, 16) },
188 	{ HHI_AUDIO_MEM_PD_REG0, GENMASK(19, 18) },
189 	{ HHI_AUDIO_MEM_PD_REG0, GENMASK(21, 20) },
190 	{ HHI_AUDIO_MEM_PD_REG0, GENMASK(23, 22) },
191 	{ HHI_AUDIO_MEM_PD_REG0, GENMASK(25, 24) },
192 	{ HHI_AUDIO_MEM_PD_REG0, GENMASK(27, 26) },
193 };
194 
195 #define VPU_PD(__name, __top_pd, __mem, __get_power, __resets, __clks)	\
196 	{								\
197 		.name = __name,						\
198 		.reset_names_count = __resets,				\
199 		.clk_names_count = __clks,				\
200 		.top_pd = __top_pd,					\
201 		.mem_pd_count = ARRAY_SIZE(__mem),			\
202 		.mem_pd = __mem,					\
203 		.get_power = __get_power,				\
204 	}
205 
206 #define TOP_PD(__name, __top_pd, __mem, __get_power)			\
207 	{								\
208 		.name = __name,						\
209 		.top_pd = __top_pd,					\
210 		.mem_pd_count = ARRAY_SIZE(__mem),			\
211 		.mem_pd = __mem,					\
212 		.get_power = __get_power,				\
213 	}
214 
215 #define MEM_PD(__name, __mem)						\
216 	TOP_PD(__name, NULL, __mem, NULL)
217 
218 static bool pwrc_ee_get_power(struct power_domain *power_domain);
219 
220 static struct meson_ee_pwrc_domain_desc g12a_pwrc_domains[] = {
221 	[PWRC_G12A_VPU_ID]  = VPU_PD("VPU", &gx_pwrc_vpu, g12a_pwrc_mem_vpu,
222 				     pwrc_ee_get_power, 11, 2),
223 	[PWRC_G12A_ETH_ID] = MEM_PD("ETH", g12a_pwrc_mem_eth),
224 };
225 
226 static struct meson_ee_pwrc_domain_desc axg_pwrc_domains[] = {
227 	[PWRC_AXG_VPU_ID]  = VPU_PD("VPU", &gx_pwrc_vpu, axg_pwrc_mem_vpu,
228 			pwrc_ee_get_power, 5, 2),
229 	[PWRC_AXG_ETHERNET_MEM_ID] = MEM_PD("ETH", g12a_pwrc_mem_eth),
230 	[PWRC_AXG_AUDIO_ID] = MEM_PD("AUDIO", axg_pwrc_mem_audio),
231 };
232 
233 static struct meson_ee_pwrc_domain_desc gxbb_pwrc_domains[] = {
234 	[PWRC_GXBB_VPU_ID]  = VPU_PD("VPU", &gx_pwrc_vpu, gxbb_pwrc_mem_vpu,
235 			pwrc_ee_get_power, 12, 2),
236 	[PWRC_GXBB_ETHERNET_MEM_ID] = MEM_PD("ETH", g12a_pwrc_mem_eth),
237 };
238 
239 static struct meson_ee_pwrc_domain_desc sm1_pwrc_domains[] = {
240 	[PWRC_SM1_VPU_ID]  = VPU_PD("VPU", &sm1_pwrc_vpu, sm1_pwrc_mem_vpu,
241 				    pwrc_ee_get_power, 11, 2),
242 	[PWRC_SM1_NNA_ID]  = TOP_PD("NNA", &sm1_pwrc_nna, sm1_pwrc_mem_nna,
243 				    pwrc_ee_get_power),
244 	[PWRC_SM1_USB_ID]  = TOP_PD("USB", &sm1_pwrc_usb, sm1_pwrc_mem_usb,
245 				    pwrc_ee_get_power),
246 	[PWRC_SM1_PCIE_ID] = TOP_PD("PCI", &sm1_pwrc_pci, sm1_pwrc_mem_pcie,
247 				    pwrc_ee_get_power),
248 	[PWRC_SM1_GE2D_ID] = TOP_PD("GE2D", &sm1_pwrc_ge2d, sm1_pwrc_mem_ge2d,
249 				    pwrc_ee_get_power),
250 	[PWRC_SM1_AUDIO_ID] = MEM_PD("AUDIO", sm1_pwrc_mem_audio),
251 	[PWRC_SM1_ETH_ID] = MEM_PD("ETH", g12a_pwrc_mem_eth),
252 };
253 
254 struct meson_ee_pwrc_priv {
255 	struct regmap *regmap_ao;
256 	struct regmap *regmap_hhi;
257 	struct reset_ctl_bulk resets;
258 	struct clk_bulk clks;
259 	const struct meson_ee_pwrc_domain_data *data;
260 };
261 
pwrc_ee_get_power(struct power_domain * power_domain)262 static bool pwrc_ee_get_power(struct power_domain *power_domain)
263 {
264 	struct meson_ee_pwrc_priv *priv = dev_get_priv(power_domain->dev);
265 	struct meson_ee_pwrc_domain_desc *pwrc_domain;
266 	u32 reg;
267 
268 	pwrc_domain = &priv->data->domains[power_domain->id];
269 
270 	regmap_read(priv->regmap_ao,
271 		    pwrc_domain->top_pd->sleep_reg, &reg);
272 
273 	return (reg & pwrc_domain->top_pd->sleep_mask);
274 }
275 
meson_ee_pwrc_request(struct power_domain * power_domain)276 static int meson_ee_pwrc_request(struct power_domain *power_domain)
277 {
278 	return 0;
279 }
280 
meson_ee_pwrc_free(struct power_domain * power_domain)281 static int meson_ee_pwrc_free(struct power_domain *power_domain)
282 {
283 	return 0;
284 }
285 
meson_ee_pwrc_off(struct power_domain * power_domain)286 static int meson_ee_pwrc_off(struct power_domain *power_domain)
287 {
288 	struct meson_ee_pwrc_priv *priv = dev_get_priv(power_domain->dev);
289 	struct meson_ee_pwrc_domain_desc *pwrc_domain;
290 	int i;
291 
292 	pwrc_domain = &priv->data->domains[power_domain->id];
293 
294 	if (pwrc_domain->top_pd)
295 		regmap_update_bits(priv->regmap_ao,
296 				   pwrc_domain->top_pd->sleep_reg,
297 				   pwrc_domain->top_pd->sleep_mask,
298 				   pwrc_domain->top_pd->sleep_mask);
299 	udelay(20);
300 
301 	for (i = 0 ; i < pwrc_domain->mem_pd_count ; ++i)
302 		regmap_update_bits(priv->regmap_hhi,
303 				   pwrc_domain->mem_pd[i].reg,
304 				   pwrc_domain->mem_pd[i].mask,
305 				   pwrc_domain->mem_pd[i].mask);
306 
307 	udelay(20);
308 
309 	if (pwrc_domain->top_pd)
310 		regmap_update_bits(priv->regmap_ao,
311 				   pwrc_domain->top_pd->iso_reg,
312 				   pwrc_domain->top_pd->iso_mask,
313 				   pwrc_domain->top_pd->iso_mask);
314 
315 	if (pwrc_domain->clk_names_count) {
316 		mdelay(20);
317 		clk_disable_bulk(&priv->clks);
318 	}
319 
320 	return 0;
321 }
322 
meson_ee_pwrc_on(struct power_domain * power_domain)323 static int meson_ee_pwrc_on(struct power_domain *power_domain)
324 {
325 	struct meson_ee_pwrc_priv *priv = dev_get_priv(power_domain->dev);
326 	struct meson_ee_pwrc_domain_desc *pwrc_domain;
327 	int i, ret;
328 
329 	pwrc_domain = &priv->data->domains[power_domain->id];
330 
331 	if (pwrc_domain->top_pd)
332 		regmap_update_bits(priv->regmap_ao,
333 				   pwrc_domain->top_pd->sleep_reg,
334 				   pwrc_domain->top_pd->sleep_mask, 0);
335 	udelay(20);
336 
337 	for (i = 0 ; i < pwrc_domain->mem_pd_count ; ++i)
338 		regmap_update_bits(priv->regmap_hhi,
339 				   pwrc_domain->mem_pd[i].reg,
340 				   pwrc_domain->mem_pd[i].mask, 0);
341 
342 	udelay(20);
343 
344 	if (pwrc_domain->reset_names_count) {
345 		ret = reset_assert_bulk(&priv->resets);
346 		if (ret)
347 			return ret;
348 	}
349 
350 	if (pwrc_domain->top_pd)
351 		regmap_update_bits(priv->regmap_ao,
352 				   pwrc_domain->top_pd->iso_reg,
353 				   pwrc_domain->top_pd->iso_mask, 0);
354 
355 	if (pwrc_domain->reset_names_count) {
356 		ret = reset_deassert_bulk(&priv->resets);
357 		if (ret)
358 			return ret;
359 	}
360 
361 	if (pwrc_domain->clk_names_count)
362 		return clk_enable_bulk(&priv->clks);
363 
364 	return 0;
365 }
366 
meson_ee_pwrc_of_xlate(struct power_domain * power_domain,struct ofnode_phandle_args * args)367 static int meson_ee_pwrc_of_xlate(struct power_domain *power_domain,
368 				  struct ofnode_phandle_args *args)
369 {
370 	struct meson_ee_pwrc_priv *priv = dev_get_priv(power_domain->dev);
371 
372 	/* #power-domain-cells is 1 */
373 
374 	if (args->args_count < 1) {
375 		debug("Invalid args_count: %d\n", args->args_count);
376 		return -EINVAL;
377 	}
378 
379 	power_domain->id = args->args[0];
380 
381 	if (power_domain->id >= priv->data->count) {
382 		debug("Invalid domain ID: %lu\n", power_domain->id);
383 		return -EINVAL;
384 	}
385 
386 	return 0;
387 }
388 
389 struct power_domain_ops meson_ee_pwrc_ops = {
390 	.rfree = meson_ee_pwrc_free,
391 	.off = meson_ee_pwrc_off,
392 	.on = meson_ee_pwrc_on,
393 	.request = meson_ee_pwrc_request,
394 	.of_xlate = meson_ee_pwrc_of_xlate,
395 };
396 
397 static struct meson_ee_pwrc_domain_data meson_ee_g12a_pwrc_data = {
398 	.count = ARRAY_SIZE(g12a_pwrc_domains),
399 	.domains = g12a_pwrc_domains,
400 };
401 
402 static struct meson_ee_pwrc_domain_data meson_ee_axg_pwrc_data = {
403 	.count = ARRAY_SIZE(axg_pwrc_domains),
404 	.domains = axg_pwrc_domains,
405 };
406 
407 static struct meson_ee_pwrc_domain_data meson_ee_gxbb_pwrc_data = {
408 	.count = ARRAY_SIZE(gxbb_pwrc_domains),
409 	.domains = gxbb_pwrc_domains,
410 };
411 
412 static struct meson_ee_pwrc_domain_data meson_ee_sm1_pwrc_data = {
413 	.count = ARRAY_SIZE(sm1_pwrc_domains),
414 	.domains = sm1_pwrc_domains,
415 };
416 
417 static const struct udevice_id meson_ee_pwrc_ids[] = {
418 	{
419 		.compatible = "amlogic,meson-g12a-pwrc",
420 		.data = (unsigned long)&meson_ee_g12a_pwrc_data,
421 	},
422 	{
423 		.compatible = "amlogic,meson-gxbb-pwrc",
424 		.data = (unsigned long)&meson_ee_gxbb_pwrc_data,
425 	},
426 	{
427 		.compatible = "amlogic,meson-axg-pwrc",
428 		.data = (unsigned long)&meson_ee_axg_pwrc_data,
429 	},
430 	{
431 		.compatible = "amlogic,meson-sm1-pwrc",
432 		.data = (unsigned long)&meson_ee_sm1_pwrc_data,
433 	},
434 	{ }
435 };
436 
meson_ee_pwrc_probe(struct udevice * dev)437 static int meson_ee_pwrc_probe(struct udevice *dev)
438 {
439 	struct meson_ee_pwrc_priv *priv = dev_get_priv(dev);
440 	u32 ao_phandle;
441 	ofnode ao_node;
442 	int ret;
443 
444 	priv->data = (void *)dev_get_driver_data(dev);
445 	if (!priv->data)
446 		return -EINVAL;
447 
448 	priv->regmap_hhi = syscon_node_to_regmap(dev_ofnode(dev_get_parent(dev)));
449 	if (IS_ERR(priv->regmap_hhi))
450 		return PTR_ERR(priv->regmap_hhi);
451 
452 	ret = ofnode_read_u32(dev_ofnode(dev), "amlogic,ao-sysctrl",
453 			      &ao_phandle);
454 	if (ret)
455 		return ret;
456 
457 	ao_node = ofnode_get_by_phandle(ao_phandle);
458 	if (!ofnode_valid(ao_node))
459 		return -EINVAL;
460 
461 	priv->regmap_ao = syscon_node_to_regmap(ao_node);
462 	if (IS_ERR(priv->regmap_ao))
463 		return PTR_ERR(priv->regmap_ao);
464 
465 	ret = reset_get_bulk(dev, &priv->resets);
466 	if (ret)
467 		return ret;
468 
469 	ret = clk_get_bulk(dev, &priv->clks);
470 	if (ret)
471 		return ret;
472 
473 	return 0;
474 }
475 
476 U_BOOT_DRIVER(meson_ee_pwrc) = {
477 	.name = "meson_ee_pwrc",
478 	.id = UCLASS_POWER_DOMAIN,
479 	.of_match = meson_ee_pwrc_ids,
480 	.probe = meson_ee_pwrc_probe,
481 	.ops = &meson_ee_pwrc_ops,
482 	.priv_auto	= sizeof(struct meson_ee_pwrc_priv),
483 };
484