18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0+
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright (c) 2019 BayLibre, SAS
48c2ecf20Sopenharmony_ci * Author: Neil Armstrong <narmstrong@baylibre.com>
58c2ecf20Sopenharmony_ci */
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ci#include <linux/of_address.h>
88c2ecf20Sopenharmony_ci#include <linux/platform_device.h>
98c2ecf20Sopenharmony_ci#include <linux/pm_domain.h>
108c2ecf20Sopenharmony_ci#include <linux/bitfield.h>
118c2ecf20Sopenharmony_ci#include <linux/regmap.h>
128c2ecf20Sopenharmony_ci#include <linux/mfd/syscon.h>
138c2ecf20Sopenharmony_ci#include <linux/of_device.h>
148c2ecf20Sopenharmony_ci#include <linux/reset-controller.h>
158c2ecf20Sopenharmony_ci#include <linux/reset.h>
168c2ecf20Sopenharmony_ci#include <linux/clk.h>
178c2ecf20Sopenharmony_ci#include <dt-bindings/power/meson8-power.h>
188c2ecf20Sopenharmony_ci#include <dt-bindings/power/meson-axg-power.h>
198c2ecf20Sopenharmony_ci#include <dt-bindings/power/meson-g12a-power.h>
208c2ecf20Sopenharmony_ci#include <dt-bindings/power/meson-gxbb-power.h>
218c2ecf20Sopenharmony_ci#include <dt-bindings/power/meson-sm1-power.h>
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ci/* AO Offsets */
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ci#define GX_AO_RTI_GEN_PWR_SLEEP0	(0x3a << 2)
268c2ecf20Sopenharmony_ci#define GX_AO_RTI_GEN_PWR_ISO0		(0x3b << 2)
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_ci/*
298c2ecf20Sopenharmony_ci * Meson8/Meson8b/Meson8m2 only expose the power management registers of the
308c2ecf20Sopenharmony_ci * AO-bus as syscon. 0x3a from GX translates to 0x02, 0x3b translates to 0x03
318c2ecf20Sopenharmony_ci * and so on.
328c2ecf20Sopenharmony_ci */
338c2ecf20Sopenharmony_ci#define MESON8_AO_RTI_GEN_PWR_SLEEP0	(0x02 << 2)
348c2ecf20Sopenharmony_ci#define MESON8_AO_RTI_GEN_PWR_ISO0	(0x03 << 2)
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ci/* HHI Offsets */
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_ci#define HHI_MEM_PD_REG0			(0x40 << 2)
398c2ecf20Sopenharmony_ci#define HHI_VPU_MEM_PD_REG0		(0x41 << 2)
408c2ecf20Sopenharmony_ci#define HHI_VPU_MEM_PD_REG1		(0x42 << 2)
418c2ecf20Sopenharmony_ci#define HHI_VPU_MEM_PD_REG3		(0x43 << 2)
428c2ecf20Sopenharmony_ci#define HHI_VPU_MEM_PD_REG4		(0x44 << 2)
438c2ecf20Sopenharmony_ci#define HHI_AUDIO_MEM_PD_REG0		(0x45 << 2)
448c2ecf20Sopenharmony_ci#define HHI_NANOQ_MEM_PD_REG0		(0x46 << 2)
458c2ecf20Sopenharmony_ci#define HHI_NANOQ_MEM_PD_REG1		(0x47 << 2)
468c2ecf20Sopenharmony_ci#define HHI_VPU_MEM_PD_REG2		(0x4d << 2)
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_cistruct meson_ee_pwrc;
498c2ecf20Sopenharmony_cistruct meson_ee_pwrc_domain;
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_cistruct meson_ee_pwrc_mem_domain {
528c2ecf20Sopenharmony_ci	unsigned int reg;
538c2ecf20Sopenharmony_ci	unsigned int mask;
548c2ecf20Sopenharmony_ci};
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_cistruct meson_ee_pwrc_top_domain {
578c2ecf20Sopenharmony_ci	unsigned int sleep_reg;
588c2ecf20Sopenharmony_ci	unsigned int sleep_mask;
598c2ecf20Sopenharmony_ci	unsigned int iso_reg;
608c2ecf20Sopenharmony_ci	unsigned int iso_mask;
618c2ecf20Sopenharmony_ci};
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_cistruct meson_ee_pwrc_domain_desc {
648c2ecf20Sopenharmony_ci	char *name;
658c2ecf20Sopenharmony_ci	unsigned int reset_names_count;
668c2ecf20Sopenharmony_ci	unsigned int clk_names_count;
678c2ecf20Sopenharmony_ci	struct meson_ee_pwrc_top_domain *top_pd;
688c2ecf20Sopenharmony_ci	unsigned int mem_pd_count;
698c2ecf20Sopenharmony_ci	struct meson_ee_pwrc_mem_domain *mem_pd;
708c2ecf20Sopenharmony_ci	bool (*get_power)(struct meson_ee_pwrc_domain *pwrc_domain);
718c2ecf20Sopenharmony_ci};
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_cistruct meson_ee_pwrc_domain_data {
748c2ecf20Sopenharmony_ci	unsigned int count;
758c2ecf20Sopenharmony_ci	struct meson_ee_pwrc_domain_desc *domains;
768c2ecf20Sopenharmony_ci};
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_ci/* TOP Power Domains */
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_cistatic struct meson_ee_pwrc_top_domain gx_pwrc_vpu = {
818c2ecf20Sopenharmony_ci	.sleep_reg = GX_AO_RTI_GEN_PWR_SLEEP0,
828c2ecf20Sopenharmony_ci	.sleep_mask = BIT(8),
838c2ecf20Sopenharmony_ci	.iso_reg = GX_AO_RTI_GEN_PWR_SLEEP0,
848c2ecf20Sopenharmony_ci	.iso_mask = BIT(9),
858c2ecf20Sopenharmony_ci};
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_cistatic struct meson_ee_pwrc_top_domain meson8_pwrc_vpu = {
888c2ecf20Sopenharmony_ci	.sleep_reg = MESON8_AO_RTI_GEN_PWR_SLEEP0,
898c2ecf20Sopenharmony_ci	.sleep_mask = BIT(8),
908c2ecf20Sopenharmony_ci	.iso_reg = MESON8_AO_RTI_GEN_PWR_SLEEP0,
918c2ecf20Sopenharmony_ci	.iso_mask = BIT(9),
928c2ecf20Sopenharmony_ci};
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_ci#define SM1_EE_PD(__bit)					\
958c2ecf20Sopenharmony_ci	{							\
968c2ecf20Sopenharmony_ci		.sleep_reg = GX_AO_RTI_GEN_PWR_SLEEP0, 		\
978c2ecf20Sopenharmony_ci		.sleep_mask = BIT(__bit), 			\
988c2ecf20Sopenharmony_ci		.iso_reg = GX_AO_RTI_GEN_PWR_ISO0, 		\
998c2ecf20Sopenharmony_ci		.iso_mask = BIT(__bit), 			\
1008c2ecf20Sopenharmony_ci	}
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_cistatic struct meson_ee_pwrc_top_domain sm1_pwrc_vpu = SM1_EE_PD(8);
1038c2ecf20Sopenharmony_cistatic struct meson_ee_pwrc_top_domain sm1_pwrc_nna = SM1_EE_PD(16);
1048c2ecf20Sopenharmony_cistatic struct meson_ee_pwrc_top_domain sm1_pwrc_usb = SM1_EE_PD(17);
1058c2ecf20Sopenharmony_cistatic struct meson_ee_pwrc_top_domain sm1_pwrc_pci = SM1_EE_PD(18);
1068c2ecf20Sopenharmony_cistatic struct meson_ee_pwrc_top_domain sm1_pwrc_ge2d = SM1_EE_PD(19);
1078c2ecf20Sopenharmony_ci
1088c2ecf20Sopenharmony_ci/* Memory PD Domains */
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_ci#define VPU_MEMPD(__reg)					\
1118c2ecf20Sopenharmony_ci	{ __reg, GENMASK(1, 0) },				\
1128c2ecf20Sopenharmony_ci	{ __reg, GENMASK(3, 2) },				\
1138c2ecf20Sopenharmony_ci	{ __reg, GENMASK(5, 4) },				\
1148c2ecf20Sopenharmony_ci	{ __reg, GENMASK(7, 6) },				\
1158c2ecf20Sopenharmony_ci	{ __reg, GENMASK(9, 8) },				\
1168c2ecf20Sopenharmony_ci	{ __reg, GENMASK(11, 10) },				\
1178c2ecf20Sopenharmony_ci	{ __reg, GENMASK(13, 12) },				\
1188c2ecf20Sopenharmony_ci	{ __reg, GENMASK(15, 14) },				\
1198c2ecf20Sopenharmony_ci	{ __reg, GENMASK(17, 16) },				\
1208c2ecf20Sopenharmony_ci	{ __reg, GENMASK(19, 18) },				\
1218c2ecf20Sopenharmony_ci	{ __reg, GENMASK(21, 20) },				\
1228c2ecf20Sopenharmony_ci	{ __reg, GENMASK(23, 22) },				\
1238c2ecf20Sopenharmony_ci	{ __reg, GENMASK(25, 24) },				\
1248c2ecf20Sopenharmony_ci	{ __reg, GENMASK(27, 26) },				\
1258c2ecf20Sopenharmony_ci	{ __reg, GENMASK(29, 28) },				\
1268c2ecf20Sopenharmony_ci	{ __reg, GENMASK(31, 30) }
1278c2ecf20Sopenharmony_ci
1288c2ecf20Sopenharmony_ci#define VPU_HHI_MEMPD(__reg)					\
1298c2ecf20Sopenharmony_ci	{ __reg, BIT(8) },					\
1308c2ecf20Sopenharmony_ci	{ __reg, BIT(9) },					\
1318c2ecf20Sopenharmony_ci	{ __reg, BIT(10) },					\
1328c2ecf20Sopenharmony_ci	{ __reg, BIT(11) },					\
1338c2ecf20Sopenharmony_ci	{ __reg, BIT(12) },					\
1348c2ecf20Sopenharmony_ci	{ __reg, BIT(13) },					\
1358c2ecf20Sopenharmony_ci	{ __reg, BIT(14) },					\
1368c2ecf20Sopenharmony_ci	{ __reg, BIT(15) }
1378c2ecf20Sopenharmony_ci
1388c2ecf20Sopenharmony_cistatic struct meson_ee_pwrc_mem_domain axg_pwrc_mem_vpu[] = {
1398c2ecf20Sopenharmony_ci	VPU_MEMPD(HHI_VPU_MEM_PD_REG0),
1408c2ecf20Sopenharmony_ci	VPU_HHI_MEMPD(HHI_MEM_PD_REG0),
1418c2ecf20Sopenharmony_ci};
1428c2ecf20Sopenharmony_ci
1438c2ecf20Sopenharmony_cistatic struct meson_ee_pwrc_mem_domain g12a_pwrc_mem_vpu[] = {
1448c2ecf20Sopenharmony_ci	VPU_MEMPD(HHI_VPU_MEM_PD_REG0),
1458c2ecf20Sopenharmony_ci	VPU_MEMPD(HHI_VPU_MEM_PD_REG1),
1468c2ecf20Sopenharmony_ci	VPU_MEMPD(HHI_VPU_MEM_PD_REG2),
1478c2ecf20Sopenharmony_ci	VPU_HHI_MEMPD(HHI_MEM_PD_REG0),
1488c2ecf20Sopenharmony_ci};
1498c2ecf20Sopenharmony_ci
1508c2ecf20Sopenharmony_cistatic struct meson_ee_pwrc_mem_domain gxbb_pwrc_mem_vpu[] = {
1518c2ecf20Sopenharmony_ci	VPU_MEMPD(HHI_VPU_MEM_PD_REG0),
1528c2ecf20Sopenharmony_ci	VPU_MEMPD(HHI_VPU_MEM_PD_REG1),
1538c2ecf20Sopenharmony_ci	VPU_HHI_MEMPD(HHI_MEM_PD_REG0),
1548c2ecf20Sopenharmony_ci};
1558c2ecf20Sopenharmony_ci
1568c2ecf20Sopenharmony_cistatic struct meson_ee_pwrc_mem_domain meson_pwrc_mem_eth[] = {
1578c2ecf20Sopenharmony_ci	{ HHI_MEM_PD_REG0, GENMASK(3, 2) },
1588c2ecf20Sopenharmony_ci};
1598c2ecf20Sopenharmony_ci
1608c2ecf20Sopenharmony_cistatic struct meson_ee_pwrc_mem_domain meson8_pwrc_audio_dsp_mem[] = {
1618c2ecf20Sopenharmony_ci	{ HHI_MEM_PD_REG0, GENMASK(1, 0) },
1628c2ecf20Sopenharmony_ci};
1638c2ecf20Sopenharmony_ci
1648c2ecf20Sopenharmony_cistatic struct meson_ee_pwrc_mem_domain meson8_pwrc_mem_vpu[] = {
1658c2ecf20Sopenharmony_ci	VPU_MEMPD(HHI_VPU_MEM_PD_REG0),
1668c2ecf20Sopenharmony_ci	VPU_MEMPD(HHI_VPU_MEM_PD_REG1),
1678c2ecf20Sopenharmony_ci	VPU_HHI_MEMPD(HHI_MEM_PD_REG0),
1688c2ecf20Sopenharmony_ci};
1698c2ecf20Sopenharmony_ci
1708c2ecf20Sopenharmony_cistatic struct meson_ee_pwrc_mem_domain sm1_pwrc_mem_vpu[] = {
1718c2ecf20Sopenharmony_ci	VPU_MEMPD(HHI_VPU_MEM_PD_REG0),
1728c2ecf20Sopenharmony_ci	VPU_MEMPD(HHI_VPU_MEM_PD_REG1),
1738c2ecf20Sopenharmony_ci	VPU_MEMPD(HHI_VPU_MEM_PD_REG2),
1748c2ecf20Sopenharmony_ci	VPU_MEMPD(HHI_VPU_MEM_PD_REG3),
1758c2ecf20Sopenharmony_ci	{ HHI_VPU_MEM_PD_REG4, GENMASK(1, 0) },
1768c2ecf20Sopenharmony_ci	{ HHI_VPU_MEM_PD_REG4, GENMASK(3, 2) },
1778c2ecf20Sopenharmony_ci	{ HHI_VPU_MEM_PD_REG4, GENMASK(5, 4) },
1788c2ecf20Sopenharmony_ci	{ HHI_VPU_MEM_PD_REG4, GENMASK(7, 6) },
1798c2ecf20Sopenharmony_ci	VPU_HHI_MEMPD(HHI_MEM_PD_REG0),
1808c2ecf20Sopenharmony_ci};
1818c2ecf20Sopenharmony_ci
1828c2ecf20Sopenharmony_cistatic struct meson_ee_pwrc_mem_domain sm1_pwrc_mem_nna[] = {
1838c2ecf20Sopenharmony_ci	{ HHI_NANOQ_MEM_PD_REG0, 0xff },
1848c2ecf20Sopenharmony_ci	{ HHI_NANOQ_MEM_PD_REG1, 0xff },
1858c2ecf20Sopenharmony_ci};
1868c2ecf20Sopenharmony_ci
1878c2ecf20Sopenharmony_cistatic struct meson_ee_pwrc_mem_domain sm1_pwrc_mem_usb[] = {
1888c2ecf20Sopenharmony_ci	{ HHI_MEM_PD_REG0, GENMASK(31, 30) },
1898c2ecf20Sopenharmony_ci};
1908c2ecf20Sopenharmony_ci
1918c2ecf20Sopenharmony_cistatic struct meson_ee_pwrc_mem_domain sm1_pwrc_mem_pcie[] = {
1928c2ecf20Sopenharmony_ci	{ HHI_MEM_PD_REG0, GENMASK(29, 26) },
1938c2ecf20Sopenharmony_ci};
1948c2ecf20Sopenharmony_ci
1958c2ecf20Sopenharmony_cistatic struct meson_ee_pwrc_mem_domain sm1_pwrc_mem_ge2d[] = {
1968c2ecf20Sopenharmony_ci	{ HHI_MEM_PD_REG0, GENMASK(25, 18) },
1978c2ecf20Sopenharmony_ci};
1988c2ecf20Sopenharmony_ci
1998c2ecf20Sopenharmony_cistatic struct meson_ee_pwrc_mem_domain axg_pwrc_mem_audio[] = {
2008c2ecf20Sopenharmony_ci	{ HHI_MEM_PD_REG0, GENMASK(5, 4) },
2018c2ecf20Sopenharmony_ci};
2028c2ecf20Sopenharmony_ci
2038c2ecf20Sopenharmony_cistatic struct meson_ee_pwrc_mem_domain sm1_pwrc_mem_audio[] = {
2048c2ecf20Sopenharmony_ci	{ HHI_MEM_PD_REG0, GENMASK(5, 4) },
2058c2ecf20Sopenharmony_ci	{ HHI_AUDIO_MEM_PD_REG0, GENMASK(1, 0) },
2068c2ecf20Sopenharmony_ci	{ HHI_AUDIO_MEM_PD_REG0, GENMASK(3, 2) },
2078c2ecf20Sopenharmony_ci	{ HHI_AUDIO_MEM_PD_REG0, GENMASK(5, 4) },
2088c2ecf20Sopenharmony_ci	{ HHI_AUDIO_MEM_PD_REG0, GENMASK(7, 6) },
2098c2ecf20Sopenharmony_ci	{ HHI_AUDIO_MEM_PD_REG0, GENMASK(13, 12) },
2108c2ecf20Sopenharmony_ci	{ HHI_AUDIO_MEM_PD_REG0, GENMASK(15, 14) },
2118c2ecf20Sopenharmony_ci	{ HHI_AUDIO_MEM_PD_REG0, GENMASK(17, 16) },
2128c2ecf20Sopenharmony_ci	{ HHI_AUDIO_MEM_PD_REG0, GENMASK(19, 18) },
2138c2ecf20Sopenharmony_ci	{ HHI_AUDIO_MEM_PD_REG0, GENMASK(21, 20) },
2148c2ecf20Sopenharmony_ci	{ HHI_AUDIO_MEM_PD_REG0, GENMASK(23, 22) },
2158c2ecf20Sopenharmony_ci	{ HHI_AUDIO_MEM_PD_REG0, GENMASK(25, 24) },
2168c2ecf20Sopenharmony_ci	{ HHI_AUDIO_MEM_PD_REG0, GENMASK(27, 26) },
2178c2ecf20Sopenharmony_ci};
2188c2ecf20Sopenharmony_ci
2198c2ecf20Sopenharmony_ci#define VPU_PD(__name, __top_pd, __mem, __get_power, __resets, __clks)	\
2208c2ecf20Sopenharmony_ci	{								\
2218c2ecf20Sopenharmony_ci		.name = __name,						\
2228c2ecf20Sopenharmony_ci		.reset_names_count = __resets,				\
2238c2ecf20Sopenharmony_ci		.clk_names_count = __clks,				\
2248c2ecf20Sopenharmony_ci		.top_pd = __top_pd,					\
2258c2ecf20Sopenharmony_ci		.mem_pd_count = ARRAY_SIZE(__mem),			\
2268c2ecf20Sopenharmony_ci		.mem_pd = __mem,					\
2278c2ecf20Sopenharmony_ci		.get_power = __get_power,				\
2288c2ecf20Sopenharmony_ci	}
2298c2ecf20Sopenharmony_ci
2308c2ecf20Sopenharmony_ci#define TOP_PD(__name, __top_pd, __mem, __get_power)			\
2318c2ecf20Sopenharmony_ci	{								\
2328c2ecf20Sopenharmony_ci		.name = __name,						\
2338c2ecf20Sopenharmony_ci		.top_pd = __top_pd,					\
2348c2ecf20Sopenharmony_ci		.mem_pd_count = ARRAY_SIZE(__mem),			\
2358c2ecf20Sopenharmony_ci		.mem_pd = __mem,					\
2368c2ecf20Sopenharmony_ci		.get_power = __get_power,				\
2378c2ecf20Sopenharmony_ci	}
2388c2ecf20Sopenharmony_ci
2398c2ecf20Sopenharmony_ci#define MEM_PD(__name, __mem)						\
2408c2ecf20Sopenharmony_ci	TOP_PD(__name, NULL, __mem, NULL)
2418c2ecf20Sopenharmony_ci
2428c2ecf20Sopenharmony_cistatic bool pwrc_ee_get_power(struct meson_ee_pwrc_domain *pwrc_domain);
2438c2ecf20Sopenharmony_ci
2448c2ecf20Sopenharmony_cistatic struct meson_ee_pwrc_domain_desc axg_pwrc_domains[] = {
2458c2ecf20Sopenharmony_ci	[PWRC_AXG_VPU_ID]  = VPU_PD("VPU", &gx_pwrc_vpu, axg_pwrc_mem_vpu,
2468c2ecf20Sopenharmony_ci				     pwrc_ee_get_power, 5, 2),
2478c2ecf20Sopenharmony_ci	[PWRC_AXG_ETHERNET_MEM_ID] = MEM_PD("ETH", meson_pwrc_mem_eth),
2488c2ecf20Sopenharmony_ci	[PWRC_AXG_AUDIO_ID] = MEM_PD("AUDIO", axg_pwrc_mem_audio),
2498c2ecf20Sopenharmony_ci};
2508c2ecf20Sopenharmony_ci
2518c2ecf20Sopenharmony_cistatic struct meson_ee_pwrc_domain_desc g12a_pwrc_domains[] = {
2528c2ecf20Sopenharmony_ci	[PWRC_G12A_VPU_ID]  = VPU_PD("VPU", &gx_pwrc_vpu, g12a_pwrc_mem_vpu,
2538c2ecf20Sopenharmony_ci				     pwrc_ee_get_power, 11, 2),
2548c2ecf20Sopenharmony_ci	[PWRC_G12A_ETH_ID] = MEM_PD("ETH", meson_pwrc_mem_eth),
2558c2ecf20Sopenharmony_ci};
2568c2ecf20Sopenharmony_ci
2578c2ecf20Sopenharmony_cistatic struct meson_ee_pwrc_domain_desc gxbb_pwrc_domains[] = {
2588c2ecf20Sopenharmony_ci	[PWRC_GXBB_VPU_ID]  = VPU_PD("VPU", &gx_pwrc_vpu, gxbb_pwrc_mem_vpu,
2598c2ecf20Sopenharmony_ci				     pwrc_ee_get_power, 12, 2),
2608c2ecf20Sopenharmony_ci	[PWRC_GXBB_ETHERNET_MEM_ID] = MEM_PD("ETH", meson_pwrc_mem_eth),
2618c2ecf20Sopenharmony_ci};
2628c2ecf20Sopenharmony_ci
2638c2ecf20Sopenharmony_cistatic struct meson_ee_pwrc_domain_desc meson8_pwrc_domains[] = {
2648c2ecf20Sopenharmony_ci	[PWRC_MESON8_VPU_ID]  = VPU_PD("VPU", &meson8_pwrc_vpu,
2658c2ecf20Sopenharmony_ci				       meson8_pwrc_mem_vpu, pwrc_ee_get_power,
2668c2ecf20Sopenharmony_ci				       0, 1),
2678c2ecf20Sopenharmony_ci	[PWRC_MESON8_ETHERNET_MEM_ID] = MEM_PD("ETHERNET_MEM",
2688c2ecf20Sopenharmony_ci					       meson_pwrc_mem_eth),
2698c2ecf20Sopenharmony_ci	[PWRC_MESON8_AUDIO_DSP_MEM_ID] = MEM_PD("AUDIO_DSP_MEM",
2708c2ecf20Sopenharmony_ci						meson8_pwrc_audio_dsp_mem),
2718c2ecf20Sopenharmony_ci};
2728c2ecf20Sopenharmony_ci
2738c2ecf20Sopenharmony_cistatic struct meson_ee_pwrc_domain_desc meson8b_pwrc_domains[] = {
2748c2ecf20Sopenharmony_ci	[PWRC_MESON8_VPU_ID]  = VPU_PD("VPU", &meson8_pwrc_vpu,
2758c2ecf20Sopenharmony_ci				       meson8_pwrc_mem_vpu, pwrc_ee_get_power,
2768c2ecf20Sopenharmony_ci				       11, 1),
2778c2ecf20Sopenharmony_ci	[PWRC_MESON8_ETHERNET_MEM_ID] = MEM_PD("ETHERNET_MEM",
2788c2ecf20Sopenharmony_ci					       meson_pwrc_mem_eth),
2798c2ecf20Sopenharmony_ci	[PWRC_MESON8_AUDIO_DSP_MEM_ID] = MEM_PD("AUDIO_DSP_MEM",
2808c2ecf20Sopenharmony_ci						meson8_pwrc_audio_dsp_mem),
2818c2ecf20Sopenharmony_ci};
2828c2ecf20Sopenharmony_ci
2838c2ecf20Sopenharmony_cistatic struct meson_ee_pwrc_domain_desc sm1_pwrc_domains[] = {
2848c2ecf20Sopenharmony_ci	[PWRC_SM1_VPU_ID]  = VPU_PD("VPU", &sm1_pwrc_vpu, sm1_pwrc_mem_vpu,
2858c2ecf20Sopenharmony_ci				    pwrc_ee_get_power, 11, 2),
2868c2ecf20Sopenharmony_ci	[PWRC_SM1_NNA_ID]  = TOP_PD("NNA", &sm1_pwrc_nna, sm1_pwrc_mem_nna,
2878c2ecf20Sopenharmony_ci				    pwrc_ee_get_power),
2888c2ecf20Sopenharmony_ci	[PWRC_SM1_USB_ID]  = TOP_PD("USB", &sm1_pwrc_usb, sm1_pwrc_mem_usb,
2898c2ecf20Sopenharmony_ci				    pwrc_ee_get_power),
2908c2ecf20Sopenharmony_ci	[PWRC_SM1_PCIE_ID] = TOP_PD("PCI", &sm1_pwrc_pci, sm1_pwrc_mem_pcie,
2918c2ecf20Sopenharmony_ci				    pwrc_ee_get_power),
2928c2ecf20Sopenharmony_ci	[PWRC_SM1_GE2D_ID] = TOP_PD("GE2D", &sm1_pwrc_ge2d, sm1_pwrc_mem_ge2d,
2938c2ecf20Sopenharmony_ci				    pwrc_ee_get_power),
2948c2ecf20Sopenharmony_ci	[PWRC_SM1_AUDIO_ID] = MEM_PD("AUDIO", sm1_pwrc_mem_audio),
2958c2ecf20Sopenharmony_ci	[PWRC_SM1_ETH_ID] = MEM_PD("ETH", meson_pwrc_mem_eth),
2968c2ecf20Sopenharmony_ci};
2978c2ecf20Sopenharmony_ci
2988c2ecf20Sopenharmony_cistruct meson_ee_pwrc_domain {
2998c2ecf20Sopenharmony_ci	struct generic_pm_domain base;
3008c2ecf20Sopenharmony_ci	bool enabled;
3018c2ecf20Sopenharmony_ci	struct meson_ee_pwrc *pwrc;
3028c2ecf20Sopenharmony_ci	struct meson_ee_pwrc_domain_desc desc;
3038c2ecf20Sopenharmony_ci	struct clk_bulk_data *clks;
3048c2ecf20Sopenharmony_ci	int num_clks;
3058c2ecf20Sopenharmony_ci	struct reset_control *rstc;
3068c2ecf20Sopenharmony_ci	int num_rstc;
3078c2ecf20Sopenharmony_ci};
3088c2ecf20Sopenharmony_ci
3098c2ecf20Sopenharmony_cistruct meson_ee_pwrc {
3108c2ecf20Sopenharmony_ci	struct regmap *regmap_ao;
3118c2ecf20Sopenharmony_ci	struct regmap *regmap_hhi;
3128c2ecf20Sopenharmony_ci	struct meson_ee_pwrc_domain *domains;
3138c2ecf20Sopenharmony_ci	struct genpd_onecell_data xlate;
3148c2ecf20Sopenharmony_ci};
3158c2ecf20Sopenharmony_ci
3168c2ecf20Sopenharmony_cistatic bool pwrc_ee_get_power(struct meson_ee_pwrc_domain *pwrc_domain)
3178c2ecf20Sopenharmony_ci{
3188c2ecf20Sopenharmony_ci	u32 reg;
3198c2ecf20Sopenharmony_ci
3208c2ecf20Sopenharmony_ci	regmap_read(pwrc_domain->pwrc->regmap_ao,
3218c2ecf20Sopenharmony_ci		    pwrc_domain->desc.top_pd->sleep_reg, &reg);
3228c2ecf20Sopenharmony_ci
3238c2ecf20Sopenharmony_ci	return (reg & pwrc_domain->desc.top_pd->sleep_mask);
3248c2ecf20Sopenharmony_ci}
3258c2ecf20Sopenharmony_ci
3268c2ecf20Sopenharmony_cistatic int meson_ee_pwrc_off(struct generic_pm_domain *domain)
3278c2ecf20Sopenharmony_ci{
3288c2ecf20Sopenharmony_ci	struct meson_ee_pwrc_domain *pwrc_domain =
3298c2ecf20Sopenharmony_ci		container_of(domain, struct meson_ee_pwrc_domain, base);
3308c2ecf20Sopenharmony_ci	int i;
3318c2ecf20Sopenharmony_ci
3328c2ecf20Sopenharmony_ci	if (pwrc_domain->desc.top_pd)
3338c2ecf20Sopenharmony_ci		regmap_update_bits(pwrc_domain->pwrc->regmap_ao,
3348c2ecf20Sopenharmony_ci				   pwrc_domain->desc.top_pd->sleep_reg,
3358c2ecf20Sopenharmony_ci				   pwrc_domain->desc.top_pd->sleep_mask,
3368c2ecf20Sopenharmony_ci				   pwrc_domain->desc.top_pd->sleep_mask);
3378c2ecf20Sopenharmony_ci	udelay(20);
3388c2ecf20Sopenharmony_ci
3398c2ecf20Sopenharmony_ci	for (i = 0 ; i < pwrc_domain->desc.mem_pd_count ; ++i)
3408c2ecf20Sopenharmony_ci		regmap_update_bits(pwrc_domain->pwrc->regmap_hhi,
3418c2ecf20Sopenharmony_ci				   pwrc_domain->desc.mem_pd[i].reg,
3428c2ecf20Sopenharmony_ci				   pwrc_domain->desc.mem_pd[i].mask,
3438c2ecf20Sopenharmony_ci				   pwrc_domain->desc.mem_pd[i].mask);
3448c2ecf20Sopenharmony_ci
3458c2ecf20Sopenharmony_ci	udelay(20);
3468c2ecf20Sopenharmony_ci
3478c2ecf20Sopenharmony_ci	if (pwrc_domain->desc.top_pd)
3488c2ecf20Sopenharmony_ci		regmap_update_bits(pwrc_domain->pwrc->regmap_ao,
3498c2ecf20Sopenharmony_ci				   pwrc_domain->desc.top_pd->iso_reg,
3508c2ecf20Sopenharmony_ci				   pwrc_domain->desc.top_pd->iso_mask,
3518c2ecf20Sopenharmony_ci				   pwrc_domain->desc.top_pd->iso_mask);
3528c2ecf20Sopenharmony_ci
3538c2ecf20Sopenharmony_ci	if (pwrc_domain->num_clks) {
3548c2ecf20Sopenharmony_ci		msleep(20);
3558c2ecf20Sopenharmony_ci		clk_bulk_disable_unprepare(pwrc_domain->num_clks,
3568c2ecf20Sopenharmony_ci					   pwrc_domain->clks);
3578c2ecf20Sopenharmony_ci	}
3588c2ecf20Sopenharmony_ci
3598c2ecf20Sopenharmony_ci	return 0;
3608c2ecf20Sopenharmony_ci}
3618c2ecf20Sopenharmony_ci
3628c2ecf20Sopenharmony_cistatic int meson_ee_pwrc_on(struct generic_pm_domain *domain)
3638c2ecf20Sopenharmony_ci{
3648c2ecf20Sopenharmony_ci	struct meson_ee_pwrc_domain *pwrc_domain =
3658c2ecf20Sopenharmony_ci		container_of(domain, struct meson_ee_pwrc_domain, base);
3668c2ecf20Sopenharmony_ci	int i, ret;
3678c2ecf20Sopenharmony_ci
3688c2ecf20Sopenharmony_ci	if (pwrc_domain->desc.top_pd)
3698c2ecf20Sopenharmony_ci		regmap_update_bits(pwrc_domain->pwrc->regmap_ao,
3708c2ecf20Sopenharmony_ci				   pwrc_domain->desc.top_pd->sleep_reg,
3718c2ecf20Sopenharmony_ci				   pwrc_domain->desc.top_pd->sleep_mask, 0);
3728c2ecf20Sopenharmony_ci	udelay(20);
3738c2ecf20Sopenharmony_ci
3748c2ecf20Sopenharmony_ci	for (i = 0 ; i < pwrc_domain->desc.mem_pd_count ; ++i)
3758c2ecf20Sopenharmony_ci		regmap_update_bits(pwrc_domain->pwrc->regmap_hhi,
3768c2ecf20Sopenharmony_ci				   pwrc_domain->desc.mem_pd[i].reg,
3778c2ecf20Sopenharmony_ci				   pwrc_domain->desc.mem_pd[i].mask, 0);
3788c2ecf20Sopenharmony_ci
3798c2ecf20Sopenharmony_ci	udelay(20);
3808c2ecf20Sopenharmony_ci
3818c2ecf20Sopenharmony_ci	ret = reset_control_assert(pwrc_domain->rstc);
3828c2ecf20Sopenharmony_ci	if (ret)
3838c2ecf20Sopenharmony_ci		return ret;
3848c2ecf20Sopenharmony_ci
3858c2ecf20Sopenharmony_ci	if (pwrc_domain->desc.top_pd)
3868c2ecf20Sopenharmony_ci		regmap_update_bits(pwrc_domain->pwrc->regmap_ao,
3878c2ecf20Sopenharmony_ci				   pwrc_domain->desc.top_pd->iso_reg,
3888c2ecf20Sopenharmony_ci				   pwrc_domain->desc.top_pd->iso_mask, 0);
3898c2ecf20Sopenharmony_ci
3908c2ecf20Sopenharmony_ci	ret = reset_control_deassert(pwrc_domain->rstc);
3918c2ecf20Sopenharmony_ci	if (ret)
3928c2ecf20Sopenharmony_ci		return ret;
3938c2ecf20Sopenharmony_ci
3948c2ecf20Sopenharmony_ci	return clk_bulk_prepare_enable(pwrc_domain->num_clks,
3958c2ecf20Sopenharmony_ci				       pwrc_domain->clks);
3968c2ecf20Sopenharmony_ci}
3978c2ecf20Sopenharmony_ci
3988c2ecf20Sopenharmony_cistatic int meson_ee_pwrc_init_domain(struct platform_device *pdev,
3998c2ecf20Sopenharmony_ci				     struct meson_ee_pwrc *pwrc,
4008c2ecf20Sopenharmony_ci				     struct meson_ee_pwrc_domain *dom)
4018c2ecf20Sopenharmony_ci{
4028c2ecf20Sopenharmony_ci	int ret;
4038c2ecf20Sopenharmony_ci
4048c2ecf20Sopenharmony_ci	dom->pwrc = pwrc;
4058c2ecf20Sopenharmony_ci	dom->num_rstc = dom->desc.reset_names_count;
4068c2ecf20Sopenharmony_ci	dom->num_clks = dom->desc.clk_names_count;
4078c2ecf20Sopenharmony_ci
4088c2ecf20Sopenharmony_ci	if (dom->num_rstc) {
4098c2ecf20Sopenharmony_ci		int count = reset_control_get_count(&pdev->dev);
4108c2ecf20Sopenharmony_ci
4118c2ecf20Sopenharmony_ci		if (count != dom->num_rstc)
4128c2ecf20Sopenharmony_ci			dev_warn(&pdev->dev, "Invalid resets count %d for domain %s\n",
4138c2ecf20Sopenharmony_ci				 count, dom->desc.name);
4148c2ecf20Sopenharmony_ci
4158c2ecf20Sopenharmony_ci		dom->rstc = devm_reset_control_array_get(&pdev->dev, false,
4168c2ecf20Sopenharmony_ci							 false);
4178c2ecf20Sopenharmony_ci		if (IS_ERR(dom->rstc))
4188c2ecf20Sopenharmony_ci			return PTR_ERR(dom->rstc);
4198c2ecf20Sopenharmony_ci	}
4208c2ecf20Sopenharmony_ci
4218c2ecf20Sopenharmony_ci	if (dom->num_clks) {
4228c2ecf20Sopenharmony_ci		int ret = devm_clk_bulk_get_all(&pdev->dev, &dom->clks);
4238c2ecf20Sopenharmony_ci		if (ret < 0)
4248c2ecf20Sopenharmony_ci			return ret;
4258c2ecf20Sopenharmony_ci
4268c2ecf20Sopenharmony_ci		if (dom->num_clks != ret) {
4278c2ecf20Sopenharmony_ci			dev_warn(&pdev->dev, "Invalid clocks count %d for domain %s\n",
4288c2ecf20Sopenharmony_ci				 ret, dom->desc.name);
4298c2ecf20Sopenharmony_ci			dom->num_clks = ret;
4308c2ecf20Sopenharmony_ci		}
4318c2ecf20Sopenharmony_ci	}
4328c2ecf20Sopenharmony_ci
4338c2ecf20Sopenharmony_ci	dom->base.name = dom->desc.name;
4348c2ecf20Sopenharmony_ci	dom->base.power_on = meson_ee_pwrc_on;
4358c2ecf20Sopenharmony_ci	dom->base.power_off = meson_ee_pwrc_off;
4368c2ecf20Sopenharmony_ci
4378c2ecf20Sopenharmony_ci	/*
4388c2ecf20Sopenharmony_ci         * TOFIX: This is a special case for the VPU power domain, which can
4398c2ecf20Sopenharmony_ci	 * be enabled previously by the bootloader. In this case the VPU
4408c2ecf20Sopenharmony_ci         * pipeline may be functional but no driver maybe never attach
4418c2ecf20Sopenharmony_ci         * to this power domain, and if the domain is disabled it could
4428c2ecf20Sopenharmony_ci         * cause system errors. This is why the pm_domain_always_on_gov
4438c2ecf20Sopenharmony_ci         * is used here.
4448c2ecf20Sopenharmony_ci         * For the same reason, the clocks should be enabled in case
4458c2ecf20Sopenharmony_ci         * we need to power the domain off, otherwise the internal clocks
4468c2ecf20Sopenharmony_ci         * prepare/enable counters won't be in sync.
4478c2ecf20Sopenharmony_ci         */
4488c2ecf20Sopenharmony_ci	if (dom->num_clks && dom->desc.get_power && !dom->desc.get_power(dom)) {
4498c2ecf20Sopenharmony_ci		ret = clk_bulk_prepare_enable(dom->num_clks, dom->clks);
4508c2ecf20Sopenharmony_ci		if (ret)
4518c2ecf20Sopenharmony_ci			return ret;
4528c2ecf20Sopenharmony_ci
4538c2ecf20Sopenharmony_ci		dom->base.flags = GENPD_FLAG_ALWAYS_ON;
4548c2ecf20Sopenharmony_ci		ret = pm_genpd_init(&dom->base, NULL, false);
4558c2ecf20Sopenharmony_ci		if (ret)
4568c2ecf20Sopenharmony_ci			return ret;
4578c2ecf20Sopenharmony_ci	} else {
4588c2ecf20Sopenharmony_ci		ret = pm_genpd_init(&dom->base, NULL,
4598c2ecf20Sopenharmony_ci				    (dom->desc.get_power ?
4608c2ecf20Sopenharmony_ci				     dom->desc.get_power(dom) : true));
4618c2ecf20Sopenharmony_ci		if (ret)
4628c2ecf20Sopenharmony_ci			return ret;
4638c2ecf20Sopenharmony_ci	}
4648c2ecf20Sopenharmony_ci
4658c2ecf20Sopenharmony_ci	return 0;
4668c2ecf20Sopenharmony_ci}
4678c2ecf20Sopenharmony_ci
4688c2ecf20Sopenharmony_cistatic int meson_ee_pwrc_probe(struct platform_device *pdev)
4698c2ecf20Sopenharmony_ci{
4708c2ecf20Sopenharmony_ci	const struct meson_ee_pwrc_domain_data *match;
4718c2ecf20Sopenharmony_ci	struct regmap *regmap_ao, *regmap_hhi;
4728c2ecf20Sopenharmony_ci	struct meson_ee_pwrc *pwrc;
4738c2ecf20Sopenharmony_ci	int i, ret;
4748c2ecf20Sopenharmony_ci
4758c2ecf20Sopenharmony_ci	match = of_device_get_match_data(&pdev->dev);
4768c2ecf20Sopenharmony_ci	if (!match) {
4778c2ecf20Sopenharmony_ci		dev_err(&pdev->dev, "failed to get match data\n");
4788c2ecf20Sopenharmony_ci		return -ENODEV;
4798c2ecf20Sopenharmony_ci	}
4808c2ecf20Sopenharmony_ci
4818c2ecf20Sopenharmony_ci	pwrc = devm_kzalloc(&pdev->dev, sizeof(*pwrc), GFP_KERNEL);
4828c2ecf20Sopenharmony_ci	if (!pwrc)
4838c2ecf20Sopenharmony_ci		return -ENOMEM;
4848c2ecf20Sopenharmony_ci
4858c2ecf20Sopenharmony_ci	pwrc->xlate.domains = devm_kcalloc(&pdev->dev, match->count,
4868c2ecf20Sopenharmony_ci					   sizeof(*pwrc->xlate.domains),
4878c2ecf20Sopenharmony_ci					   GFP_KERNEL);
4888c2ecf20Sopenharmony_ci	if (!pwrc->xlate.domains)
4898c2ecf20Sopenharmony_ci		return -ENOMEM;
4908c2ecf20Sopenharmony_ci
4918c2ecf20Sopenharmony_ci	pwrc->domains = devm_kcalloc(&pdev->dev, match->count,
4928c2ecf20Sopenharmony_ci				     sizeof(*pwrc->domains), GFP_KERNEL);
4938c2ecf20Sopenharmony_ci	if (!pwrc->domains)
4948c2ecf20Sopenharmony_ci		return -ENOMEM;
4958c2ecf20Sopenharmony_ci
4968c2ecf20Sopenharmony_ci	pwrc->xlate.num_domains = match->count;
4978c2ecf20Sopenharmony_ci
4988c2ecf20Sopenharmony_ci	regmap_hhi = syscon_node_to_regmap(of_get_parent(pdev->dev.of_node));
4998c2ecf20Sopenharmony_ci	if (IS_ERR(regmap_hhi)) {
5008c2ecf20Sopenharmony_ci		dev_err(&pdev->dev, "failed to get HHI regmap\n");
5018c2ecf20Sopenharmony_ci		return PTR_ERR(regmap_hhi);
5028c2ecf20Sopenharmony_ci	}
5038c2ecf20Sopenharmony_ci
5048c2ecf20Sopenharmony_ci	regmap_ao = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
5058c2ecf20Sopenharmony_ci						    "amlogic,ao-sysctrl");
5068c2ecf20Sopenharmony_ci	if (IS_ERR(regmap_ao)) {
5078c2ecf20Sopenharmony_ci		dev_err(&pdev->dev, "failed to get AO regmap\n");
5088c2ecf20Sopenharmony_ci		return PTR_ERR(regmap_ao);
5098c2ecf20Sopenharmony_ci	}
5108c2ecf20Sopenharmony_ci
5118c2ecf20Sopenharmony_ci	pwrc->regmap_ao = regmap_ao;
5128c2ecf20Sopenharmony_ci	pwrc->regmap_hhi = regmap_hhi;
5138c2ecf20Sopenharmony_ci
5148c2ecf20Sopenharmony_ci	platform_set_drvdata(pdev, pwrc);
5158c2ecf20Sopenharmony_ci
5168c2ecf20Sopenharmony_ci	for (i = 0 ; i < match->count ; ++i) {
5178c2ecf20Sopenharmony_ci		struct meson_ee_pwrc_domain *dom = &pwrc->domains[i];
5188c2ecf20Sopenharmony_ci
5198c2ecf20Sopenharmony_ci		memcpy(&dom->desc, &match->domains[i], sizeof(dom->desc));
5208c2ecf20Sopenharmony_ci
5218c2ecf20Sopenharmony_ci		ret = meson_ee_pwrc_init_domain(pdev, pwrc, dom);
5228c2ecf20Sopenharmony_ci		if (ret)
5238c2ecf20Sopenharmony_ci			return ret;
5248c2ecf20Sopenharmony_ci
5258c2ecf20Sopenharmony_ci		pwrc->xlate.domains[i] = &dom->base;
5268c2ecf20Sopenharmony_ci	}
5278c2ecf20Sopenharmony_ci
5288c2ecf20Sopenharmony_ci	return of_genpd_add_provider_onecell(pdev->dev.of_node, &pwrc->xlate);
5298c2ecf20Sopenharmony_ci}
5308c2ecf20Sopenharmony_ci
5318c2ecf20Sopenharmony_cistatic void meson_ee_pwrc_shutdown(struct platform_device *pdev)
5328c2ecf20Sopenharmony_ci{
5338c2ecf20Sopenharmony_ci	struct meson_ee_pwrc *pwrc = platform_get_drvdata(pdev);
5348c2ecf20Sopenharmony_ci	int i;
5358c2ecf20Sopenharmony_ci
5368c2ecf20Sopenharmony_ci	for (i = 0 ; i < pwrc->xlate.num_domains ; ++i) {
5378c2ecf20Sopenharmony_ci		struct meson_ee_pwrc_domain *dom = &pwrc->domains[i];
5388c2ecf20Sopenharmony_ci
5398c2ecf20Sopenharmony_ci		if (dom->desc.get_power && !dom->desc.get_power(dom))
5408c2ecf20Sopenharmony_ci			meson_ee_pwrc_off(&dom->base);
5418c2ecf20Sopenharmony_ci	}
5428c2ecf20Sopenharmony_ci}
5438c2ecf20Sopenharmony_ci
5448c2ecf20Sopenharmony_cistatic struct meson_ee_pwrc_domain_data meson_ee_g12a_pwrc_data = {
5458c2ecf20Sopenharmony_ci	.count = ARRAY_SIZE(g12a_pwrc_domains),
5468c2ecf20Sopenharmony_ci	.domains = g12a_pwrc_domains,
5478c2ecf20Sopenharmony_ci};
5488c2ecf20Sopenharmony_ci
5498c2ecf20Sopenharmony_cistatic struct meson_ee_pwrc_domain_data meson_ee_axg_pwrc_data = {
5508c2ecf20Sopenharmony_ci	.count = ARRAY_SIZE(axg_pwrc_domains),
5518c2ecf20Sopenharmony_ci	.domains = axg_pwrc_domains,
5528c2ecf20Sopenharmony_ci};
5538c2ecf20Sopenharmony_ci
5548c2ecf20Sopenharmony_cistatic struct meson_ee_pwrc_domain_data meson_ee_gxbb_pwrc_data = {
5558c2ecf20Sopenharmony_ci	.count = ARRAY_SIZE(gxbb_pwrc_domains),
5568c2ecf20Sopenharmony_ci	.domains = gxbb_pwrc_domains,
5578c2ecf20Sopenharmony_ci};
5588c2ecf20Sopenharmony_ci
5598c2ecf20Sopenharmony_cistatic struct meson_ee_pwrc_domain_data meson_ee_m8_pwrc_data = {
5608c2ecf20Sopenharmony_ci	.count = ARRAY_SIZE(meson8_pwrc_domains),
5618c2ecf20Sopenharmony_ci	.domains = meson8_pwrc_domains,
5628c2ecf20Sopenharmony_ci};
5638c2ecf20Sopenharmony_ci
5648c2ecf20Sopenharmony_cistatic struct meson_ee_pwrc_domain_data meson_ee_m8b_pwrc_data = {
5658c2ecf20Sopenharmony_ci	.count = ARRAY_SIZE(meson8b_pwrc_domains),
5668c2ecf20Sopenharmony_ci	.domains = meson8b_pwrc_domains,
5678c2ecf20Sopenharmony_ci};
5688c2ecf20Sopenharmony_ci
5698c2ecf20Sopenharmony_cistatic struct meson_ee_pwrc_domain_data meson_ee_sm1_pwrc_data = {
5708c2ecf20Sopenharmony_ci	.count = ARRAY_SIZE(sm1_pwrc_domains),
5718c2ecf20Sopenharmony_ci	.domains = sm1_pwrc_domains,
5728c2ecf20Sopenharmony_ci};
5738c2ecf20Sopenharmony_ci
5748c2ecf20Sopenharmony_cistatic const struct of_device_id meson_ee_pwrc_match_table[] = {
5758c2ecf20Sopenharmony_ci	{
5768c2ecf20Sopenharmony_ci		.compatible = "amlogic,meson8-pwrc",
5778c2ecf20Sopenharmony_ci		.data = &meson_ee_m8_pwrc_data,
5788c2ecf20Sopenharmony_ci	},
5798c2ecf20Sopenharmony_ci	{
5808c2ecf20Sopenharmony_ci		.compatible = "amlogic,meson8b-pwrc",
5818c2ecf20Sopenharmony_ci		.data = &meson_ee_m8b_pwrc_data,
5828c2ecf20Sopenharmony_ci	},
5838c2ecf20Sopenharmony_ci	{
5848c2ecf20Sopenharmony_ci		.compatible = "amlogic,meson8m2-pwrc",
5858c2ecf20Sopenharmony_ci		.data = &meson_ee_m8b_pwrc_data,
5868c2ecf20Sopenharmony_ci	},
5878c2ecf20Sopenharmony_ci	{
5888c2ecf20Sopenharmony_ci		.compatible = "amlogic,meson-axg-pwrc",
5898c2ecf20Sopenharmony_ci		.data = &meson_ee_axg_pwrc_data,
5908c2ecf20Sopenharmony_ci	},
5918c2ecf20Sopenharmony_ci	{
5928c2ecf20Sopenharmony_ci		.compatible = "amlogic,meson-gxbb-pwrc",
5938c2ecf20Sopenharmony_ci		.data = &meson_ee_gxbb_pwrc_data,
5948c2ecf20Sopenharmony_ci	},
5958c2ecf20Sopenharmony_ci	{
5968c2ecf20Sopenharmony_ci		.compatible = "amlogic,meson-g12a-pwrc",
5978c2ecf20Sopenharmony_ci		.data = &meson_ee_g12a_pwrc_data,
5988c2ecf20Sopenharmony_ci	},
5998c2ecf20Sopenharmony_ci	{
6008c2ecf20Sopenharmony_ci		.compatible = "amlogic,meson-sm1-pwrc",
6018c2ecf20Sopenharmony_ci		.data = &meson_ee_sm1_pwrc_data,
6028c2ecf20Sopenharmony_ci	},
6038c2ecf20Sopenharmony_ci	{ /* sentinel */ }
6048c2ecf20Sopenharmony_ci};
6058c2ecf20Sopenharmony_ci
6068c2ecf20Sopenharmony_cistatic struct platform_driver meson_ee_pwrc_driver = {
6078c2ecf20Sopenharmony_ci	.probe = meson_ee_pwrc_probe,
6088c2ecf20Sopenharmony_ci	.shutdown = meson_ee_pwrc_shutdown,
6098c2ecf20Sopenharmony_ci	.driver = {
6108c2ecf20Sopenharmony_ci		.name		= "meson_ee_pwrc",
6118c2ecf20Sopenharmony_ci		.of_match_table	= meson_ee_pwrc_match_table,
6128c2ecf20Sopenharmony_ci	},
6138c2ecf20Sopenharmony_ci};
6148c2ecf20Sopenharmony_cibuiltin_platform_driver(meson_ee_pwrc_driver);
615