1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (c) 2019 BayLibre, SAS
4 * Author: Neil Armstrong <narmstrong@baylibre.com>
7 #include <linux/of_address.h>
8 #include <linux/platform_device.h>
9 #include <linux/pm_domain.h>
10 #include <linux/bitfield.h>
11 #include <linux/regmap.h>
12 #include <linux/mfd/syscon.h>
13 #include <linux/of_device.h>
14 #include <linux/reset-controller.h>
15 #include <linux/reset.h>
16 #include <linux/clk.h>
17 #include <linux/module.h>
18 #include <dt-bindings/power/meson8-power.h>
19 #include <dt-bindings/power/meson-axg-power.h>
20 #include <dt-bindings/power/meson-g12a-power.h>
21 #include <dt-bindings/power/meson-gxbb-power.h>
22 #include <dt-bindings/power/meson-sm1-power.h>
26 #define GX_AO_RTI_GEN_PWR_SLEEP0 (0x3a << 2)
27 #define GX_AO_RTI_GEN_PWR_ISO0 (0x3b << 2)
30 * Meson8/Meson8b/Meson8m2 only expose the power management registers of the
31 * AO-bus as syscon. 0x3a from GX translates to 0x02, 0x3b translates to 0x03
34 #define MESON8_AO_RTI_GEN_PWR_SLEEP0 (0x02 << 2)
35 #define MESON8_AO_RTI_GEN_PWR_ISO0 (0x03 << 2)
39 #define HHI_MEM_PD_REG0 (0x40 << 2)
40 #define HHI_VPU_MEM_PD_REG0 (0x41 << 2)
41 #define HHI_VPU_MEM_PD_REG1 (0x42 << 2)
42 #define HHI_VPU_MEM_PD_REG3 (0x43 << 2)
43 #define HHI_VPU_MEM_PD_REG4 (0x44 << 2)
44 #define HHI_AUDIO_MEM_PD_REG0 (0x45 << 2)
45 #define HHI_NANOQ_MEM_PD_REG0 (0x46 << 2)
46 #define HHI_NANOQ_MEM_PD_REG1 (0x47 << 2)
47 #define HHI_VPU_MEM_PD_REG2 (0x4d << 2)
50 struct meson_ee_pwrc_domain
;
52 struct meson_ee_pwrc_mem_domain
{
57 struct meson_ee_pwrc_top_domain
{
58 unsigned int sleep_reg
;
59 unsigned int sleep_mask
;
61 unsigned int iso_mask
;
64 struct meson_ee_pwrc_domain_desc
{
66 unsigned int reset_names_count
;
67 unsigned int clk_names_count
;
68 struct meson_ee_pwrc_top_domain
*top_pd
;
69 unsigned int mem_pd_count
;
70 struct meson_ee_pwrc_mem_domain
*mem_pd
;
71 bool (*get_power
)(struct meson_ee_pwrc_domain
*pwrc_domain
);
74 struct meson_ee_pwrc_domain_data
{
76 struct meson_ee_pwrc_domain_desc
*domains
;
79 /* TOP Power Domains */
81 static struct meson_ee_pwrc_top_domain gx_pwrc_vpu
= {
82 .sleep_reg
= GX_AO_RTI_GEN_PWR_SLEEP0
,
84 .iso_reg
= GX_AO_RTI_GEN_PWR_SLEEP0
,
88 static struct meson_ee_pwrc_top_domain meson8_pwrc_vpu
= {
89 .sleep_reg
= MESON8_AO_RTI_GEN_PWR_SLEEP0
,
91 .iso_reg
= MESON8_AO_RTI_GEN_PWR_SLEEP0
,
95 #define SM1_EE_PD(__bit) \
97 .sleep_reg = GX_AO_RTI_GEN_PWR_SLEEP0, \
98 .sleep_mask = BIT(__bit), \
99 .iso_reg = GX_AO_RTI_GEN_PWR_ISO0, \
100 .iso_mask = BIT(__bit), \
103 static struct meson_ee_pwrc_top_domain sm1_pwrc_vpu
= SM1_EE_PD(8);
104 static struct meson_ee_pwrc_top_domain sm1_pwrc_nna
= SM1_EE_PD(16);
105 static struct meson_ee_pwrc_top_domain sm1_pwrc_usb
= SM1_EE_PD(17);
106 static struct meson_ee_pwrc_top_domain sm1_pwrc_pci
= SM1_EE_PD(18);
107 static struct meson_ee_pwrc_top_domain sm1_pwrc_ge2d
= SM1_EE_PD(19);
109 /* Memory PD Domains */
111 #define VPU_MEMPD(__reg) \
112 { __reg, GENMASK(1, 0) }, \
113 { __reg, GENMASK(3, 2) }, \
114 { __reg, GENMASK(5, 4) }, \
115 { __reg, GENMASK(7, 6) }, \
116 { __reg, GENMASK(9, 8) }, \
117 { __reg, GENMASK(11, 10) }, \
118 { __reg, GENMASK(13, 12) }, \
119 { __reg, GENMASK(15, 14) }, \
120 { __reg, GENMASK(17, 16) }, \
121 { __reg, GENMASK(19, 18) }, \
122 { __reg, GENMASK(21, 20) }, \
123 { __reg, GENMASK(23, 22) }, \
124 { __reg, GENMASK(25, 24) }, \
125 { __reg, GENMASK(27, 26) }, \
126 { __reg, GENMASK(29, 28) }, \
127 { __reg, GENMASK(31, 30) }
129 #define VPU_HHI_MEMPD(__reg) \
132 { __reg, BIT(10) }, \
133 { __reg, BIT(11) }, \
134 { __reg, BIT(12) }, \
135 { __reg, BIT(13) }, \
136 { __reg, BIT(14) }, \
139 static struct meson_ee_pwrc_mem_domain axg_pwrc_mem_vpu
[] = {
140 VPU_MEMPD(HHI_VPU_MEM_PD_REG0
),
141 VPU_HHI_MEMPD(HHI_MEM_PD_REG0
),
144 static struct meson_ee_pwrc_mem_domain g12a_pwrc_mem_vpu
[] = {
145 VPU_MEMPD(HHI_VPU_MEM_PD_REG0
),
146 VPU_MEMPD(HHI_VPU_MEM_PD_REG1
),
147 VPU_MEMPD(HHI_VPU_MEM_PD_REG2
),
148 VPU_HHI_MEMPD(HHI_MEM_PD_REG0
),
151 static struct meson_ee_pwrc_mem_domain gxbb_pwrc_mem_vpu
[] = {
152 VPU_MEMPD(HHI_VPU_MEM_PD_REG0
),
153 VPU_MEMPD(HHI_VPU_MEM_PD_REG1
),
154 VPU_HHI_MEMPD(HHI_MEM_PD_REG0
),
157 static struct meson_ee_pwrc_mem_domain meson_pwrc_mem_eth
[] = {
158 { HHI_MEM_PD_REG0
, GENMASK(3, 2) },
161 static struct meson_ee_pwrc_mem_domain meson8_pwrc_audio_dsp_mem
[] = {
162 { HHI_MEM_PD_REG0
, GENMASK(1, 0) },
165 static struct meson_ee_pwrc_mem_domain meson8_pwrc_mem_vpu
[] = {
166 VPU_MEMPD(HHI_VPU_MEM_PD_REG0
),
167 VPU_MEMPD(HHI_VPU_MEM_PD_REG1
),
168 VPU_HHI_MEMPD(HHI_MEM_PD_REG0
),
171 static struct meson_ee_pwrc_mem_domain sm1_pwrc_mem_vpu
[] = {
172 VPU_MEMPD(HHI_VPU_MEM_PD_REG0
),
173 VPU_MEMPD(HHI_VPU_MEM_PD_REG1
),
174 VPU_MEMPD(HHI_VPU_MEM_PD_REG2
),
175 VPU_MEMPD(HHI_VPU_MEM_PD_REG3
),
176 { HHI_VPU_MEM_PD_REG4
, GENMASK(1, 0) },
177 { HHI_VPU_MEM_PD_REG4
, GENMASK(3, 2) },
178 { HHI_VPU_MEM_PD_REG4
, GENMASK(5, 4) },
179 { HHI_VPU_MEM_PD_REG4
, GENMASK(7, 6) },
180 VPU_HHI_MEMPD(HHI_MEM_PD_REG0
),
183 static struct meson_ee_pwrc_mem_domain sm1_pwrc_mem_nna
[] = {
184 { HHI_NANOQ_MEM_PD_REG0
, 0xff },
185 { HHI_NANOQ_MEM_PD_REG1
, 0xff },
188 static struct meson_ee_pwrc_mem_domain sm1_pwrc_mem_usb
[] = {
189 { HHI_MEM_PD_REG0
, GENMASK(31, 30) },
192 static struct meson_ee_pwrc_mem_domain sm1_pwrc_mem_pcie
[] = {
193 { HHI_MEM_PD_REG0
, GENMASK(29, 26) },
196 static struct meson_ee_pwrc_mem_domain sm1_pwrc_mem_ge2d
[] = {
197 { HHI_MEM_PD_REG0
, GENMASK(25, 18) },
200 static struct meson_ee_pwrc_mem_domain axg_pwrc_mem_audio
[] = {
201 { HHI_MEM_PD_REG0
, GENMASK(5, 4) },
204 static struct meson_ee_pwrc_mem_domain sm1_pwrc_mem_audio
[] = {
205 { HHI_MEM_PD_REG0
, GENMASK(5, 4) },
206 { HHI_AUDIO_MEM_PD_REG0
, GENMASK(1, 0) },
207 { HHI_AUDIO_MEM_PD_REG0
, GENMASK(3, 2) },
208 { HHI_AUDIO_MEM_PD_REG0
, GENMASK(5, 4) },
209 { HHI_AUDIO_MEM_PD_REG0
, GENMASK(7, 6) },
210 { HHI_AUDIO_MEM_PD_REG0
, GENMASK(13, 12) },
211 { HHI_AUDIO_MEM_PD_REG0
, GENMASK(15, 14) },
212 { HHI_AUDIO_MEM_PD_REG0
, GENMASK(17, 16) },
213 { HHI_AUDIO_MEM_PD_REG0
, GENMASK(19, 18) },
214 { HHI_AUDIO_MEM_PD_REG0
, GENMASK(21, 20) },
215 { HHI_AUDIO_MEM_PD_REG0
, GENMASK(23, 22) },
216 { HHI_AUDIO_MEM_PD_REG0
, GENMASK(25, 24) },
217 { HHI_AUDIO_MEM_PD_REG0
, GENMASK(27, 26) },
220 #define VPU_PD(__name, __top_pd, __mem, __get_power, __resets, __clks) \
223 .reset_names_count = __resets, \
224 .clk_names_count = __clks, \
225 .top_pd = __top_pd, \
226 .mem_pd_count = ARRAY_SIZE(__mem), \
228 .get_power = __get_power, \
231 #define TOP_PD(__name, __top_pd, __mem, __get_power) \
234 .top_pd = __top_pd, \
235 .mem_pd_count = ARRAY_SIZE(__mem), \
237 .get_power = __get_power, \
240 #define MEM_PD(__name, __mem) \
241 TOP_PD(__name, NULL, __mem, NULL)
243 static bool pwrc_ee_get_power(struct meson_ee_pwrc_domain
*pwrc_domain
);
245 static struct meson_ee_pwrc_domain_desc axg_pwrc_domains
[] = {
246 [PWRC_AXG_VPU_ID
] = VPU_PD("VPU", &gx_pwrc_vpu
, axg_pwrc_mem_vpu
,
247 pwrc_ee_get_power
, 5, 2),
248 [PWRC_AXG_ETHERNET_MEM_ID
] = MEM_PD("ETH", meson_pwrc_mem_eth
),
249 [PWRC_AXG_AUDIO_ID
] = MEM_PD("AUDIO", axg_pwrc_mem_audio
),
252 static struct meson_ee_pwrc_domain_desc g12a_pwrc_domains
[] = {
253 [PWRC_G12A_VPU_ID
] = VPU_PD("VPU", &gx_pwrc_vpu
, g12a_pwrc_mem_vpu
,
254 pwrc_ee_get_power
, 11, 2),
255 [PWRC_G12A_ETH_ID
] = MEM_PD("ETH", meson_pwrc_mem_eth
),
258 static struct meson_ee_pwrc_domain_desc gxbb_pwrc_domains
[] = {
259 [PWRC_GXBB_VPU_ID
] = VPU_PD("VPU", &gx_pwrc_vpu
, gxbb_pwrc_mem_vpu
,
260 pwrc_ee_get_power
, 12, 2),
261 [PWRC_GXBB_ETHERNET_MEM_ID
] = MEM_PD("ETH", meson_pwrc_mem_eth
),
264 static struct meson_ee_pwrc_domain_desc meson8_pwrc_domains
[] = {
265 [PWRC_MESON8_VPU_ID
] = VPU_PD("VPU", &meson8_pwrc_vpu
,
266 meson8_pwrc_mem_vpu
, pwrc_ee_get_power
,
268 [PWRC_MESON8_ETHERNET_MEM_ID
] = MEM_PD("ETHERNET_MEM",
270 [PWRC_MESON8_AUDIO_DSP_MEM_ID
] = MEM_PD("AUDIO_DSP_MEM",
271 meson8_pwrc_audio_dsp_mem
),
274 static struct meson_ee_pwrc_domain_desc meson8b_pwrc_domains
[] = {
275 [PWRC_MESON8_VPU_ID
] = VPU_PD("VPU", &meson8_pwrc_vpu
,
276 meson8_pwrc_mem_vpu
, pwrc_ee_get_power
,
278 [PWRC_MESON8_ETHERNET_MEM_ID
] = MEM_PD("ETHERNET_MEM",
280 [PWRC_MESON8_AUDIO_DSP_MEM_ID
] = MEM_PD("AUDIO_DSP_MEM",
281 meson8_pwrc_audio_dsp_mem
),
284 static struct meson_ee_pwrc_domain_desc sm1_pwrc_domains
[] = {
285 [PWRC_SM1_VPU_ID
] = VPU_PD("VPU", &sm1_pwrc_vpu
, sm1_pwrc_mem_vpu
,
286 pwrc_ee_get_power
, 11, 2),
287 [PWRC_SM1_NNA_ID
] = TOP_PD("NNA", &sm1_pwrc_nna
, sm1_pwrc_mem_nna
,
289 [PWRC_SM1_USB_ID
] = TOP_PD("USB", &sm1_pwrc_usb
, sm1_pwrc_mem_usb
,
291 [PWRC_SM1_PCIE_ID
] = TOP_PD("PCI", &sm1_pwrc_pci
, sm1_pwrc_mem_pcie
,
293 [PWRC_SM1_GE2D_ID
] = TOP_PD("GE2D", &sm1_pwrc_ge2d
, sm1_pwrc_mem_ge2d
,
295 [PWRC_SM1_AUDIO_ID
] = MEM_PD("AUDIO", sm1_pwrc_mem_audio
),
296 [PWRC_SM1_ETH_ID
] = MEM_PD("ETH", meson_pwrc_mem_eth
),
299 struct meson_ee_pwrc_domain
{
300 struct generic_pm_domain base
;
302 struct meson_ee_pwrc
*pwrc
;
303 struct meson_ee_pwrc_domain_desc desc
;
304 struct clk_bulk_data
*clks
;
306 struct reset_control
*rstc
;
310 struct meson_ee_pwrc
{
311 struct regmap
*regmap_ao
;
312 struct regmap
*regmap_hhi
;
313 struct meson_ee_pwrc_domain
*domains
;
314 struct genpd_onecell_data xlate
;
317 static bool pwrc_ee_get_power(struct meson_ee_pwrc_domain
*pwrc_domain
)
321 regmap_read(pwrc_domain
->pwrc
->regmap_ao
,
322 pwrc_domain
->desc
.top_pd
->sleep_reg
, ®
);
324 return (reg
& pwrc_domain
->desc
.top_pd
->sleep_mask
);
327 static int meson_ee_pwrc_off(struct generic_pm_domain
*domain
)
329 struct meson_ee_pwrc_domain
*pwrc_domain
=
330 container_of(domain
, struct meson_ee_pwrc_domain
, base
);
333 if (pwrc_domain
->desc
.top_pd
)
334 regmap_update_bits(pwrc_domain
->pwrc
->regmap_ao
,
335 pwrc_domain
->desc
.top_pd
->sleep_reg
,
336 pwrc_domain
->desc
.top_pd
->sleep_mask
,
337 pwrc_domain
->desc
.top_pd
->sleep_mask
);
340 for (i
= 0 ; i
< pwrc_domain
->desc
.mem_pd_count
; ++i
)
341 regmap_update_bits(pwrc_domain
->pwrc
->regmap_hhi
,
342 pwrc_domain
->desc
.mem_pd
[i
].reg
,
343 pwrc_domain
->desc
.mem_pd
[i
].mask
,
344 pwrc_domain
->desc
.mem_pd
[i
].mask
);
348 if (pwrc_domain
->desc
.top_pd
)
349 regmap_update_bits(pwrc_domain
->pwrc
->regmap_ao
,
350 pwrc_domain
->desc
.top_pd
->iso_reg
,
351 pwrc_domain
->desc
.top_pd
->iso_mask
,
352 pwrc_domain
->desc
.top_pd
->iso_mask
);
354 if (pwrc_domain
->num_clks
) {
356 clk_bulk_disable_unprepare(pwrc_domain
->num_clks
,
363 static int meson_ee_pwrc_on(struct generic_pm_domain
*domain
)
365 struct meson_ee_pwrc_domain
*pwrc_domain
=
366 container_of(domain
, struct meson_ee_pwrc_domain
, base
);
369 if (pwrc_domain
->desc
.top_pd
)
370 regmap_update_bits(pwrc_domain
->pwrc
->regmap_ao
,
371 pwrc_domain
->desc
.top_pd
->sleep_reg
,
372 pwrc_domain
->desc
.top_pd
->sleep_mask
, 0);
375 for (i
= 0 ; i
< pwrc_domain
->desc
.mem_pd_count
; ++i
)
376 regmap_update_bits(pwrc_domain
->pwrc
->regmap_hhi
,
377 pwrc_domain
->desc
.mem_pd
[i
].reg
,
378 pwrc_domain
->desc
.mem_pd
[i
].mask
, 0);
382 ret
= reset_control_assert(pwrc_domain
->rstc
);
386 if (pwrc_domain
->desc
.top_pd
)
387 regmap_update_bits(pwrc_domain
->pwrc
->regmap_ao
,
388 pwrc_domain
->desc
.top_pd
->iso_reg
,
389 pwrc_domain
->desc
.top_pd
->iso_mask
, 0);
391 ret
= reset_control_deassert(pwrc_domain
->rstc
);
395 return clk_bulk_prepare_enable(pwrc_domain
->num_clks
,
399 static int meson_ee_pwrc_init_domain(struct platform_device
*pdev
,
400 struct meson_ee_pwrc
*pwrc
,
401 struct meson_ee_pwrc_domain
*dom
)
406 dom
->num_rstc
= dom
->desc
.reset_names_count
;
407 dom
->num_clks
= dom
->desc
.clk_names_count
;
410 int count
= reset_control_get_count(&pdev
->dev
);
412 if (count
!= dom
->num_rstc
)
413 dev_warn(&pdev
->dev
, "Invalid resets count %d for domain %s\n",
414 count
, dom
->desc
.name
);
416 dom
->rstc
= devm_reset_control_array_get_exclusive(&pdev
->dev
);
417 if (IS_ERR(dom
->rstc
))
418 return PTR_ERR(dom
->rstc
);
422 int ret
= devm_clk_bulk_get_all(&pdev
->dev
, &dom
->clks
);
426 if (dom
->num_clks
!= ret
) {
427 dev_warn(&pdev
->dev
, "Invalid clocks count %d for domain %s\n",
428 ret
, dom
->desc
.name
);
433 dom
->base
.name
= dom
->desc
.name
;
434 dom
->base
.power_on
= meson_ee_pwrc_on
;
435 dom
->base
.power_off
= meson_ee_pwrc_off
;
438 * TOFIX: This is a special case for the VPU power domain, which can
439 * be enabled previously by the bootloader. In this case the VPU
440 * pipeline may be functional but no driver maybe never attach
441 * to this power domain, and if the domain is disabled it could
442 * cause system errors. This is why the pm_domain_always_on_gov
444 * For the same reason, the clocks should be enabled in case
445 * we need to power the domain off, otherwise the internal clocks
446 * prepare/enable counters won't be in sync.
448 if (dom
->num_clks
&& dom
->desc
.get_power
&& !dom
->desc
.get_power(dom
)) {
449 ret
= clk_bulk_prepare_enable(dom
->num_clks
, dom
->clks
);
453 dom
->base
.flags
= GENPD_FLAG_ALWAYS_ON
;
454 ret
= pm_genpd_init(&dom
->base
, NULL
, false);
458 ret
= pm_genpd_init(&dom
->base
, NULL
,
459 (dom
->desc
.get_power
?
460 dom
->desc
.get_power(dom
) : true));
468 static int meson_ee_pwrc_probe(struct platform_device
*pdev
)
470 const struct meson_ee_pwrc_domain_data
*match
;
471 struct regmap
*regmap_ao
, *regmap_hhi
;
472 struct meson_ee_pwrc
*pwrc
;
475 match
= of_device_get_match_data(&pdev
->dev
);
477 dev_err(&pdev
->dev
, "failed to get match data\n");
481 pwrc
= devm_kzalloc(&pdev
->dev
, sizeof(*pwrc
), GFP_KERNEL
);
485 pwrc
->xlate
.domains
= devm_kcalloc(&pdev
->dev
, match
->count
,
486 sizeof(*pwrc
->xlate
.domains
),
488 if (!pwrc
->xlate
.domains
)
491 pwrc
->domains
= devm_kcalloc(&pdev
->dev
, match
->count
,
492 sizeof(*pwrc
->domains
), GFP_KERNEL
);
496 pwrc
->xlate
.num_domains
= match
->count
;
498 regmap_hhi
= syscon_node_to_regmap(of_get_parent(pdev
->dev
.of_node
));
499 if (IS_ERR(regmap_hhi
)) {
500 dev_err(&pdev
->dev
, "failed to get HHI regmap\n");
501 return PTR_ERR(regmap_hhi
);
504 regmap_ao
= syscon_regmap_lookup_by_phandle(pdev
->dev
.of_node
,
505 "amlogic,ao-sysctrl");
506 if (IS_ERR(regmap_ao
)) {
507 dev_err(&pdev
->dev
, "failed to get AO regmap\n");
508 return PTR_ERR(regmap_ao
);
511 pwrc
->regmap_ao
= regmap_ao
;
512 pwrc
->regmap_hhi
= regmap_hhi
;
514 platform_set_drvdata(pdev
, pwrc
);
516 for (i
= 0 ; i
< match
->count
; ++i
) {
517 struct meson_ee_pwrc_domain
*dom
= &pwrc
->domains
[i
];
519 memcpy(&dom
->desc
, &match
->domains
[i
], sizeof(dom
->desc
));
521 ret
= meson_ee_pwrc_init_domain(pdev
, pwrc
, dom
);
525 pwrc
->xlate
.domains
[i
] = &dom
->base
;
528 return of_genpd_add_provider_onecell(pdev
->dev
.of_node
, &pwrc
->xlate
);
531 static void meson_ee_pwrc_shutdown(struct platform_device
*pdev
)
533 struct meson_ee_pwrc
*pwrc
= platform_get_drvdata(pdev
);
536 for (i
= 0 ; i
< pwrc
->xlate
.num_domains
; ++i
) {
537 struct meson_ee_pwrc_domain
*dom
= &pwrc
->domains
[i
];
539 if (dom
->desc
.get_power
&& !dom
->desc
.get_power(dom
))
540 meson_ee_pwrc_off(&dom
->base
);
544 static struct meson_ee_pwrc_domain_data meson_ee_g12a_pwrc_data
= {
545 .count
= ARRAY_SIZE(g12a_pwrc_domains
),
546 .domains
= g12a_pwrc_domains
,
549 static struct meson_ee_pwrc_domain_data meson_ee_axg_pwrc_data
= {
550 .count
= ARRAY_SIZE(axg_pwrc_domains
),
551 .domains
= axg_pwrc_domains
,
554 static struct meson_ee_pwrc_domain_data meson_ee_gxbb_pwrc_data
= {
555 .count
= ARRAY_SIZE(gxbb_pwrc_domains
),
556 .domains
= gxbb_pwrc_domains
,
559 static struct meson_ee_pwrc_domain_data meson_ee_m8_pwrc_data
= {
560 .count
= ARRAY_SIZE(meson8_pwrc_domains
),
561 .domains
= meson8_pwrc_domains
,
564 static struct meson_ee_pwrc_domain_data meson_ee_m8b_pwrc_data
= {
565 .count
= ARRAY_SIZE(meson8b_pwrc_domains
),
566 .domains
= meson8b_pwrc_domains
,
569 static struct meson_ee_pwrc_domain_data meson_ee_sm1_pwrc_data
= {
570 .count
= ARRAY_SIZE(sm1_pwrc_domains
),
571 .domains
= sm1_pwrc_domains
,
574 static const struct of_device_id meson_ee_pwrc_match_table
[] = {
576 .compatible
= "amlogic,meson8-pwrc",
577 .data
= &meson_ee_m8_pwrc_data
,
580 .compatible
= "amlogic,meson8b-pwrc",
581 .data
= &meson_ee_m8b_pwrc_data
,
584 .compatible
= "amlogic,meson8m2-pwrc",
585 .data
= &meson_ee_m8b_pwrc_data
,
588 .compatible
= "amlogic,meson-axg-pwrc",
589 .data
= &meson_ee_axg_pwrc_data
,
592 .compatible
= "amlogic,meson-gxbb-pwrc",
593 .data
= &meson_ee_gxbb_pwrc_data
,
596 .compatible
= "amlogic,meson-g12a-pwrc",
597 .data
= &meson_ee_g12a_pwrc_data
,
600 .compatible
= "amlogic,meson-sm1-pwrc",
601 .data
= &meson_ee_sm1_pwrc_data
,
605 MODULE_DEVICE_TABLE(of
, meson_ee_pwrc_match_table
);
607 static struct platform_driver meson_ee_pwrc_driver
= {
608 .probe
= meson_ee_pwrc_probe
,
609 .shutdown
= meson_ee_pwrc_shutdown
,
611 .name
= "meson_ee_pwrc",
612 .of_match_table
= meson_ee_pwrc_match_table
,
615 module_platform_driver(meson_ee_pwrc_driver
);
616 MODULE_LICENSE("GPL v2");