GNU Linux-libre 5.19-rc6-gnu
[releases.git] / drivers / soc / rockchip / pm_domains.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Rockchip Generic power domain support.
4  *
5  * Copyright (c) 2015 ROCKCHIP, Co. Ltd.
6  */
7
8 #include <linux/io.h>
9 #include <linux/iopoll.h>
10 #include <linux/err.h>
11 #include <linux/mutex.h>
12 #include <linux/pm_clock.h>
13 #include <linux/pm_domain.h>
14 #include <linux/of_address.h>
15 #include <linux/of_clk.h>
16 #include <linux/of_platform.h>
17 #include <linux/clk.h>
18 #include <linux/regmap.h>
19 #include <linux/mfd/syscon.h>
20 #include <soc/rockchip/pm_domains.h>
21 #include <dt-bindings/power/px30-power.h>
22 #include <dt-bindings/power/rk3036-power.h>
23 #include <dt-bindings/power/rk3066-power.h>
24 #include <dt-bindings/power/rk3128-power.h>
25 #include <dt-bindings/power/rk3188-power.h>
26 #include <dt-bindings/power/rk3228-power.h>
27 #include <dt-bindings/power/rk3288-power.h>
28 #include <dt-bindings/power/rk3328-power.h>
29 #include <dt-bindings/power/rk3366-power.h>
30 #include <dt-bindings/power/rk3368-power.h>
31 #include <dt-bindings/power/rk3399-power.h>
32 #include <dt-bindings/power/rk3568-power.h>
33
34 struct rockchip_domain_info {
35         const char *name;
36         int pwr_mask;
37         int status_mask;
38         int req_mask;
39         int idle_mask;
40         int ack_mask;
41         bool active_wakeup;
42         int pwr_w_mask;
43         int req_w_mask;
44 };
45
46 struct rockchip_pmu_info {
47         u32 pwr_offset;
48         u32 status_offset;
49         u32 req_offset;
50         u32 idle_offset;
51         u32 ack_offset;
52
53         u32 core_pwrcnt_offset;
54         u32 gpu_pwrcnt_offset;
55
56         unsigned int core_power_transition_time;
57         unsigned int gpu_power_transition_time;
58
59         int num_domains;
60         const struct rockchip_domain_info *domain_info;
61 };
62
63 #define MAX_QOS_REGS_NUM        5
64 #define QOS_PRIORITY            0x08
65 #define QOS_MODE                0x0c
66 #define QOS_BANDWIDTH           0x10
67 #define QOS_SATURATION          0x14
68 #define QOS_EXTCONTROL          0x18
69
70 struct rockchip_pm_domain {
71         struct generic_pm_domain genpd;
72         const struct rockchip_domain_info *info;
73         struct rockchip_pmu *pmu;
74         int num_qos;
75         struct regmap **qos_regmap;
76         u32 *qos_save_regs[MAX_QOS_REGS_NUM];
77         int num_clks;
78         struct clk_bulk_data *clks;
79 };
80
81 struct rockchip_pmu {
82         struct device *dev;
83         struct regmap *regmap;
84         const struct rockchip_pmu_info *info;
85         struct mutex mutex; /* mutex lock for pmu */
86         struct genpd_onecell_data genpd_data;
87         struct generic_pm_domain *domains[];
88 };
89
90 #define to_rockchip_pd(gpd) container_of(gpd, struct rockchip_pm_domain, genpd)
91
92 #define DOMAIN(_name, pwr, status, req, idle, ack, wakeup)      \
93 {                                                       \
94         .name = _name,                          \
95         .pwr_mask = (pwr),                              \
96         .status_mask = (status),                        \
97         .req_mask = (req),                              \
98         .idle_mask = (idle),                            \
99         .ack_mask = (ack),                              \
100         .active_wakeup = (wakeup),                      \
101 }
102
103 #define DOMAIN_M(_name, pwr, status, req, idle, ack, wakeup)    \
104 {                                                       \
105         .name = _name,                          \
106         .pwr_w_mask = (pwr) << 16,                      \
107         .pwr_mask = (pwr),                              \
108         .status_mask = (status),                        \
109         .req_w_mask = (req) << 16,                      \
110         .req_mask = (req),                              \
111         .idle_mask = (idle),                            \
112         .ack_mask = (ack),                              \
113         .active_wakeup = wakeup,                        \
114 }
115
116 #define DOMAIN_RK3036(_name, req, ack, idle, wakeup)            \
117 {                                                       \
118         .name = _name,                          \
119         .req_mask = (req),                              \
120         .req_w_mask = (req) << 16,                      \
121         .ack_mask = (ack),                              \
122         .idle_mask = (idle),                            \
123         .active_wakeup = wakeup,                        \
124 }
125
126 #define DOMAIN_PX30(name, pwr, status, req, wakeup)             \
127         DOMAIN_M(name, pwr, status, req, (req) << 16, req, wakeup)
128
129 #define DOMAIN_RK3288(name, pwr, status, req, wakeup)           \
130         DOMAIN(name, pwr, status, req, req, (req) << 16, wakeup)
131
132 #define DOMAIN_RK3328(name, pwr, status, req, wakeup)           \
133         DOMAIN_M(name, pwr, pwr, req, (req) << 10, req, wakeup)
134
135 #define DOMAIN_RK3368(name, pwr, status, req, wakeup)           \
136         DOMAIN(name, pwr, status, req, (req) << 16, req, wakeup)
137
138 #define DOMAIN_RK3399(name, pwr, status, req, wakeup)           \
139         DOMAIN(name, pwr, status, req, req, req, wakeup)
140
141 #define DOMAIN_RK3568(name, pwr, req, wakeup)           \
142         DOMAIN_M(name, pwr, pwr, req, req, req, wakeup)
143
144 /*
145  * Dynamic Memory Controller may need to coordinate with us -- see
146  * rockchip_pmu_block().
147  *
148  * dmc_pmu_mutex protects registration-time races, so DMC driver doesn't try to
149  * block() while we're initializing the PMU.
150  */
151 static DEFINE_MUTEX(dmc_pmu_mutex);
152 static struct rockchip_pmu *dmc_pmu;
153
154 /*
155  * Block PMU transitions and make sure they don't interfere with ARM Trusted
156  * Firmware operations. There are two conflicts, noted in the comments below.
157  *
158  * Caller must unblock PMU transitions via rockchip_pmu_unblock().
159  */
160 int rockchip_pmu_block(void)
161 {
162         struct rockchip_pmu *pmu;
163         struct generic_pm_domain *genpd;
164         struct rockchip_pm_domain *pd;
165         int i, ret;
166
167         mutex_lock(&dmc_pmu_mutex);
168
169         /* No PMU (yet)? Then we just block rockchip_pmu_probe(). */
170         if (!dmc_pmu)
171                 return 0;
172         pmu = dmc_pmu;
173
174         /*
175          * mutex blocks all idle transitions: we can't touch the
176          * PMU_BUS_IDLE_REQ (our ".idle_offset") register while ARM Trusted
177          * Firmware might be using it.
178          */
179         mutex_lock(&pmu->mutex);
180
181         /*
182          * Power domain clocks: Per Rockchip, we *must* keep certain clocks
183          * enabled for the duration of power-domain transitions. Most
184          * transitions are handled by this driver, but some cases (in
185          * particular, DRAM DVFS / memory-controller idle) must be handled by
186          * firmware. Firmware can handle most clock management via a special
187          * "ungate" register (PMU_CRU_GATEDIS_CON0), but unfortunately, this
188          * doesn't handle PLLs. We can assist this transition by doing the
189          * clock management on behalf of firmware.
190          */
191         for (i = 0; i < pmu->genpd_data.num_domains; i++) {
192                 genpd = pmu->genpd_data.domains[i];
193                 if (genpd) {
194                         pd = to_rockchip_pd(genpd);
195                         ret = clk_bulk_enable(pd->num_clks, pd->clks);
196                         if (ret < 0) {
197                                 dev_err(pmu->dev,
198                                         "failed to enable clks for domain '%s': %d\n",
199                                         genpd->name, ret);
200                                 goto err;
201                         }
202                 }
203         }
204
205         return 0;
206
207 err:
208         for (i = i - 1; i >= 0; i--) {
209                 genpd = pmu->genpd_data.domains[i];
210                 if (genpd) {
211                         pd = to_rockchip_pd(genpd);
212                         clk_bulk_disable(pd->num_clks, pd->clks);
213                 }
214         }
215         mutex_unlock(&pmu->mutex);
216         mutex_unlock(&dmc_pmu_mutex);
217
218         return ret;
219 }
220 EXPORT_SYMBOL_GPL(rockchip_pmu_block);
221
222 /* Unblock PMU transitions. */
223 void rockchip_pmu_unblock(void)
224 {
225         struct rockchip_pmu *pmu;
226         struct generic_pm_domain *genpd;
227         struct rockchip_pm_domain *pd;
228         int i;
229
230         if (dmc_pmu) {
231                 pmu = dmc_pmu;
232                 for (i = 0; i < pmu->genpd_data.num_domains; i++) {
233                         genpd = pmu->genpd_data.domains[i];
234                         if (genpd) {
235                                 pd = to_rockchip_pd(genpd);
236                                 clk_bulk_disable(pd->num_clks, pd->clks);
237                         }
238                 }
239
240                 mutex_unlock(&pmu->mutex);
241         }
242
243         mutex_unlock(&dmc_pmu_mutex);
244 }
245 EXPORT_SYMBOL_GPL(rockchip_pmu_unblock);
246
247 static bool rockchip_pmu_domain_is_idle(struct rockchip_pm_domain *pd)
248 {
249         struct rockchip_pmu *pmu = pd->pmu;
250         const struct rockchip_domain_info *pd_info = pd->info;
251         unsigned int val;
252
253         regmap_read(pmu->regmap, pmu->info->idle_offset, &val);
254         return (val & pd_info->idle_mask) == pd_info->idle_mask;
255 }
256
257 static unsigned int rockchip_pmu_read_ack(struct rockchip_pmu *pmu)
258 {
259         unsigned int val;
260
261         regmap_read(pmu->regmap, pmu->info->ack_offset, &val);
262         return val;
263 }
264
265 static int rockchip_pmu_set_idle_request(struct rockchip_pm_domain *pd,
266                                          bool idle)
267 {
268         const struct rockchip_domain_info *pd_info = pd->info;
269         struct generic_pm_domain *genpd = &pd->genpd;
270         struct rockchip_pmu *pmu = pd->pmu;
271         unsigned int target_ack;
272         unsigned int val;
273         bool is_idle;
274         int ret;
275
276         if (pd_info->req_mask == 0)
277                 return 0;
278         else if (pd_info->req_w_mask)
279                 regmap_write(pmu->regmap, pmu->info->req_offset,
280                              idle ? (pd_info->req_mask | pd_info->req_w_mask) :
281                              pd_info->req_w_mask);
282         else
283                 regmap_update_bits(pmu->regmap, pmu->info->req_offset,
284                                    pd_info->req_mask, idle ? -1U : 0);
285
286         wmb();
287
288         /* Wait util idle_ack = 1 */
289         target_ack = idle ? pd_info->ack_mask : 0;
290         ret = readx_poll_timeout_atomic(rockchip_pmu_read_ack, pmu, val,
291                                         (val & pd_info->ack_mask) == target_ack,
292                                         0, 10000);
293         if (ret) {
294                 dev_err(pmu->dev,
295                         "failed to get ack on domain '%s', val=0x%x\n",
296                         genpd->name, val);
297                 return ret;
298         }
299
300         ret = readx_poll_timeout_atomic(rockchip_pmu_domain_is_idle, pd,
301                                         is_idle, is_idle == idle, 0, 10000);
302         if (ret) {
303                 dev_err(pmu->dev,
304                         "failed to set idle on domain '%s', val=%d\n",
305                         genpd->name, is_idle);
306                 return ret;
307         }
308
309         return 0;
310 }
311
312 static int rockchip_pmu_save_qos(struct rockchip_pm_domain *pd)
313 {
314         int i;
315
316         for (i = 0; i < pd->num_qos; i++) {
317                 regmap_read(pd->qos_regmap[i],
318                             QOS_PRIORITY,
319                             &pd->qos_save_regs[0][i]);
320                 regmap_read(pd->qos_regmap[i],
321                             QOS_MODE,
322                             &pd->qos_save_regs[1][i]);
323                 regmap_read(pd->qos_regmap[i],
324                             QOS_BANDWIDTH,
325                             &pd->qos_save_regs[2][i]);
326                 regmap_read(pd->qos_regmap[i],
327                             QOS_SATURATION,
328                             &pd->qos_save_regs[3][i]);
329                 regmap_read(pd->qos_regmap[i],
330                             QOS_EXTCONTROL,
331                             &pd->qos_save_regs[4][i]);
332         }
333         return 0;
334 }
335
336 static int rockchip_pmu_restore_qos(struct rockchip_pm_domain *pd)
337 {
338         int i;
339
340         for (i = 0; i < pd->num_qos; i++) {
341                 regmap_write(pd->qos_regmap[i],
342                              QOS_PRIORITY,
343                              pd->qos_save_regs[0][i]);
344                 regmap_write(pd->qos_regmap[i],
345                              QOS_MODE,
346                              pd->qos_save_regs[1][i]);
347                 regmap_write(pd->qos_regmap[i],
348                              QOS_BANDWIDTH,
349                              pd->qos_save_regs[2][i]);
350                 regmap_write(pd->qos_regmap[i],
351                              QOS_SATURATION,
352                              pd->qos_save_regs[3][i]);
353                 regmap_write(pd->qos_regmap[i],
354                              QOS_EXTCONTROL,
355                              pd->qos_save_regs[4][i]);
356         }
357
358         return 0;
359 }
360
361 static bool rockchip_pmu_domain_is_on(struct rockchip_pm_domain *pd)
362 {
363         struct rockchip_pmu *pmu = pd->pmu;
364         unsigned int val;
365
366         /* check idle status for idle-only domains */
367         if (pd->info->status_mask == 0)
368                 return !rockchip_pmu_domain_is_idle(pd);
369
370         regmap_read(pmu->regmap, pmu->info->status_offset, &val);
371
372         /* 1'b0: power on, 1'b1: power off */
373         return !(val & pd->info->status_mask);
374 }
375
376 static void rockchip_do_pmu_set_power_domain(struct rockchip_pm_domain *pd,
377                                              bool on)
378 {
379         struct rockchip_pmu *pmu = pd->pmu;
380         struct generic_pm_domain *genpd = &pd->genpd;
381         bool is_on;
382
383         if (pd->info->pwr_mask == 0)
384                 return;
385         else if (pd->info->pwr_w_mask)
386                 regmap_write(pmu->regmap, pmu->info->pwr_offset,
387                              on ? pd->info->pwr_w_mask :
388                              (pd->info->pwr_mask | pd->info->pwr_w_mask));
389         else
390                 regmap_update_bits(pmu->regmap, pmu->info->pwr_offset,
391                                    pd->info->pwr_mask, on ? 0 : -1U);
392
393         wmb();
394
395         if (readx_poll_timeout_atomic(rockchip_pmu_domain_is_on, pd, is_on,
396                                       is_on == on, 0, 10000)) {
397                 dev_err(pmu->dev,
398                         "failed to set domain '%s', val=%d\n",
399                         genpd->name, is_on);
400                 return;
401         }
402 }
403
404 static int rockchip_pd_power(struct rockchip_pm_domain *pd, bool power_on)
405 {
406         struct rockchip_pmu *pmu = pd->pmu;
407         int ret;
408
409         mutex_lock(&pmu->mutex);
410
411         if (rockchip_pmu_domain_is_on(pd) != power_on) {
412                 ret = clk_bulk_enable(pd->num_clks, pd->clks);
413                 if (ret < 0) {
414                         dev_err(pmu->dev, "failed to enable clocks\n");
415                         mutex_unlock(&pmu->mutex);
416                         return ret;
417                 }
418
419                 if (!power_on) {
420                         rockchip_pmu_save_qos(pd);
421
422                         /* if powering down, idle request to NIU first */
423                         rockchip_pmu_set_idle_request(pd, true);
424                 }
425
426                 rockchip_do_pmu_set_power_domain(pd, power_on);
427
428                 if (power_on) {
429                         /* if powering up, leave idle mode */
430                         rockchip_pmu_set_idle_request(pd, false);
431
432                         rockchip_pmu_restore_qos(pd);
433                 }
434
435                 clk_bulk_disable(pd->num_clks, pd->clks);
436         }
437
438         mutex_unlock(&pmu->mutex);
439         return 0;
440 }
441
442 static int rockchip_pd_power_on(struct generic_pm_domain *domain)
443 {
444         struct rockchip_pm_domain *pd = to_rockchip_pd(domain);
445
446         return rockchip_pd_power(pd, true);
447 }
448
449 static int rockchip_pd_power_off(struct generic_pm_domain *domain)
450 {
451         struct rockchip_pm_domain *pd = to_rockchip_pd(domain);
452
453         return rockchip_pd_power(pd, false);
454 }
455
456 static int rockchip_pd_attach_dev(struct generic_pm_domain *genpd,
457                                   struct device *dev)
458 {
459         struct clk *clk;
460         int i;
461         int error;
462
463         dev_dbg(dev, "attaching to power domain '%s'\n", genpd->name);
464
465         error = pm_clk_create(dev);
466         if (error) {
467                 dev_err(dev, "pm_clk_create failed %d\n", error);
468                 return error;
469         }
470
471         i = 0;
472         while ((clk = of_clk_get(dev->of_node, i++)) && !IS_ERR(clk)) {
473                 dev_dbg(dev, "adding clock '%pC' to list of PM clocks\n", clk);
474                 error = pm_clk_add_clk(dev, clk);
475                 if (error) {
476                         dev_err(dev, "pm_clk_add_clk failed %d\n", error);
477                         clk_put(clk);
478                         pm_clk_destroy(dev);
479                         return error;
480                 }
481         }
482
483         return 0;
484 }
485
486 static void rockchip_pd_detach_dev(struct generic_pm_domain *genpd,
487                                    struct device *dev)
488 {
489         dev_dbg(dev, "detaching from power domain '%s'\n", genpd->name);
490
491         pm_clk_destroy(dev);
492 }
493
494 static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu,
495                                       struct device_node *node)
496 {
497         const struct rockchip_domain_info *pd_info;
498         struct rockchip_pm_domain *pd;
499         struct device_node *qos_node;
500         int i, j;
501         u32 id;
502         int error;
503
504         error = of_property_read_u32(node, "reg", &id);
505         if (error) {
506                 dev_err(pmu->dev,
507                         "%pOFn: failed to retrieve domain id (reg): %d\n",
508                         node, error);
509                 return -EINVAL;
510         }
511
512         if (id >= pmu->info->num_domains) {
513                 dev_err(pmu->dev, "%pOFn: invalid domain id %d\n",
514                         node, id);
515                 return -EINVAL;
516         }
517
518         pd_info = &pmu->info->domain_info[id];
519         if (!pd_info) {
520                 dev_err(pmu->dev, "%pOFn: undefined domain id %d\n",
521                         node, id);
522                 return -EINVAL;
523         }
524
525         pd = devm_kzalloc(pmu->dev, sizeof(*pd), GFP_KERNEL);
526         if (!pd)
527                 return -ENOMEM;
528
529         pd->info = pd_info;
530         pd->pmu = pmu;
531
532         pd->num_clks = of_clk_get_parent_count(node);
533         if (pd->num_clks > 0) {
534                 pd->clks = devm_kcalloc(pmu->dev, pd->num_clks,
535                                         sizeof(*pd->clks), GFP_KERNEL);
536                 if (!pd->clks)
537                         return -ENOMEM;
538         } else {
539                 dev_dbg(pmu->dev, "%pOFn: doesn't have clocks: %d\n",
540                         node, pd->num_clks);
541                 pd->num_clks = 0;
542         }
543
544         for (i = 0; i < pd->num_clks; i++) {
545                 pd->clks[i].clk = of_clk_get(node, i);
546                 if (IS_ERR(pd->clks[i].clk)) {
547                         error = PTR_ERR(pd->clks[i].clk);
548                         dev_err(pmu->dev,
549                                 "%pOFn: failed to get clk at index %d: %d\n",
550                                 node, i, error);
551                         return error;
552                 }
553         }
554
555         error = clk_bulk_prepare(pd->num_clks, pd->clks);
556         if (error)
557                 goto err_put_clocks;
558
559         pd->num_qos = of_count_phandle_with_args(node, "pm_qos",
560                                                  NULL);
561
562         if (pd->num_qos > 0) {
563                 pd->qos_regmap = devm_kcalloc(pmu->dev, pd->num_qos,
564                                               sizeof(*pd->qos_regmap),
565                                               GFP_KERNEL);
566                 if (!pd->qos_regmap) {
567                         error = -ENOMEM;
568                         goto err_unprepare_clocks;
569                 }
570
571                 for (j = 0; j < MAX_QOS_REGS_NUM; j++) {
572                         pd->qos_save_regs[j] = devm_kcalloc(pmu->dev,
573                                                             pd->num_qos,
574                                                             sizeof(u32),
575                                                             GFP_KERNEL);
576                         if (!pd->qos_save_regs[j]) {
577                                 error = -ENOMEM;
578                                 goto err_unprepare_clocks;
579                         }
580                 }
581
582                 for (j = 0; j < pd->num_qos; j++) {
583                         qos_node = of_parse_phandle(node, "pm_qos", j);
584                         if (!qos_node) {
585                                 error = -ENODEV;
586                                 goto err_unprepare_clocks;
587                         }
588                         pd->qos_regmap[j] = syscon_node_to_regmap(qos_node);
589                         if (IS_ERR(pd->qos_regmap[j])) {
590                                 error = -ENODEV;
591                                 of_node_put(qos_node);
592                                 goto err_unprepare_clocks;
593                         }
594                         of_node_put(qos_node);
595                 }
596         }
597
598         error = rockchip_pd_power(pd, true);
599         if (error) {
600                 dev_err(pmu->dev,
601                         "failed to power on domain '%pOFn': %d\n",
602                         node, error);
603                 goto err_unprepare_clocks;
604         }
605
606         if (pd->info->name)
607                 pd->genpd.name = pd->info->name;
608         else
609                 pd->genpd.name = kbasename(node->full_name);
610         pd->genpd.power_off = rockchip_pd_power_off;
611         pd->genpd.power_on = rockchip_pd_power_on;
612         pd->genpd.attach_dev = rockchip_pd_attach_dev;
613         pd->genpd.detach_dev = rockchip_pd_detach_dev;
614         pd->genpd.flags = GENPD_FLAG_PM_CLK;
615         if (pd_info->active_wakeup)
616                 pd->genpd.flags |= GENPD_FLAG_ACTIVE_WAKEUP;
617         pm_genpd_init(&pd->genpd, NULL, false);
618
619         pmu->genpd_data.domains[id] = &pd->genpd;
620         return 0;
621
622 err_unprepare_clocks:
623         clk_bulk_unprepare(pd->num_clks, pd->clks);
624 err_put_clocks:
625         clk_bulk_put(pd->num_clks, pd->clks);
626         return error;
627 }
628
629 static void rockchip_pm_remove_one_domain(struct rockchip_pm_domain *pd)
630 {
631         int ret;
632
633         /*
634          * We're in the error cleanup already, so we only complain,
635          * but won't emit another error on top of the original one.
636          */
637         ret = pm_genpd_remove(&pd->genpd);
638         if (ret < 0)
639                 dev_err(pd->pmu->dev, "failed to remove domain '%s' : %d - state may be inconsistent\n",
640                         pd->genpd.name, ret);
641
642         clk_bulk_unprepare(pd->num_clks, pd->clks);
643         clk_bulk_put(pd->num_clks, pd->clks);
644
645         /* protect the zeroing of pm->num_clks */
646         mutex_lock(&pd->pmu->mutex);
647         pd->num_clks = 0;
648         mutex_unlock(&pd->pmu->mutex);
649
650         /* devm will free our memory */
651 }
652
653 static void rockchip_pm_domain_cleanup(struct rockchip_pmu *pmu)
654 {
655         struct generic_pm_domain *genpd;
656         struct rockchip_pm_domain *pd;
657         int i;
658
659         for (i = 0; i < pmu->genpd_data.num_domains; i++) {
660                 genpd = pmu->genpd_data.domains[i];
661                 if (genpd) {
662                         pd = to_rockchip_pd(genpd);
663                         rockchip_pm_remove_one_domain(pd);
664                 }
665         }
666
667         /* devm will free our memory */
668 }
669
670 static void rockchip_configure_pd_cnt(struct rockchip_pmu *pmu,
671                                       u32 domain_reg_offset,
672                                       unsigned int count)
673 {
674         /* First configure domain power down transition count ... */
675         regmap_write(pmu->regmap, domain_reg_offset, count);
676         /* ... and then power up count. */
677         regmap_write(pmu->regmap, domain_reg_offset + 4, count);
678 }
679
680 static int rockchip_pm_add_subdomain(struct rockchip_pmu *pmu,
681                                      struct device_node *parent)
682 {
683         struct device_node *np;
684         struct generic_pm_domain *child_domain, *parent_domain;
685         int error;
686
687         for_each_child_of_node(parent, np) {
688                 u32 idx;
689
690                 error = of_property_read_u32(parent, "reg", &idx);
691                 if (error) {
692                         dev_err(pmu->dev,
693                                 "%pOFn: failed to retrieve domain id (reg): %d\n",
694                                 parent, error);
695                         goto err_out;
696                 }
697                 parent_domain = pmu->genpd_data.domains[idx];
698
699                 error = rockchip_pm_add_one_domain(pmu, np);
700                 if (error) {
701                         dev_err(pmu->dev, "failed to handle node %pOFn: %d\n",
702                                 np, error);
703                         goto err_out;
704                 }
705
706                 error = of_property_read_u32(np, "reg", &idx);
707                 if (error) {
708                         dev_err(pmu->dev,
709                                 "%pOFn: failed to retrieve domain id (reg): %d\n",
710                                 np, error);
711                         goto err_out;
712                 }
713                 child_domain = pmu->genpd_data.domains[idx];
714
715                 error = pm_genpd_add_subdomain(parent_domain, child_domain);
716                 if (error) {
717                         dev_err(pmu->dev, "%s failed to add subdomain %s: %d\n",
718                                 parent_domain->name, child_domain->name, error);
719                         goto err_out;
720                 } else {
721                         dev_dbg(pmu->dev, "%s add subdomain: %s\n",
722                                 parent_domain->name, child_domain->name);
723                 }
724
725                 rockchip_pm_add_subdomain(pmu, np);
726         }
727
728         return 0;
729
730 err_out:
731         of_node_put(np);
732         return error;
733 }
734
735 static int rockchip_pm_domain_probe(struct platform_device *pdev)
736 {
737         struct device *dev = &pdev->dev;
738         struct device_node *np = dev->of_node;
739         struct device_node *node;
740         struct device *parent;
741         struct rockchip_pmu *pmu;
742         const struct of_device_id *match;
743         const struct rockchip_pmu_info *pmu_info;
744         int error;
745
746         if (!np) {
747                 dev_err(dev, "device tree node not found\n");
748                 return -ENODEV;
749         }
750
751         match = of_match_device(dev->driver->of_match_table, dev);
752         if (!match || !match->data) {
753                 dev_err(dev, "missing pmu data\n");
754                 return -EINVAL;
755         }
756
757         pmu_info = match->data;
758
759         pmu = devm_kzalloc(dev,
760                            struct_size(pmu, domains, pmu_info->num_domains),
761                            GFP_KERNEL);
762         if (!pmu)
763                 return -ENOMEM;
764
765         pmu->dev = &pdev->dev;
766         mutex_init(&pmu->mutex);
767
768         pmu->info = pmu_info;
769
770         pmu->genpd_data.domains = pmu->domains;
771         pmu->genpd_data.num_domains = pmu_info->num_domains;
772
773         parent = dev->parent;
774         if (!parent) {
775                 dev_err(dev, "no parent for syscon devices\n");
776                 return -ENODEV;
777         }
778
779         pmu->regmap = syscon_node_to_regmap(parent->of_node);
780         if (IS_ERR(pmu->regmap)) {
781                 dev_err(dev, "no regmap available\n");
782                 return PTR_ERR(pmu->regmap);
783         }
784
785         /*
786          * Configure power up and down transition delays for CORE
787          * and GPU domains.
788          */
789         if (pmu_info->core_power_transition_time)
790                 rockchip_configure_pd_cnt(pmu, pmu_info->core_pwrcnt_offset,
791                                         pmu_info->core_power_transition_time);
792         if (pmu_info->gpu_pwrcnt_offset)
793                 rockchip_configure_pd_cnt(pmu, pmu_info->gpu_pwrcnt_offset,
794                                         pmu_info->gpu_power_transition_time);
795
796         error = -ENODEV;
797
798         /*
799          * Prevent any rockchip_pmu_block() from racing with the remainder of
800          * setup (clocks, register initialization).
801          */
802         mutex_lock(&dmc_pmu_mutex);
803
804         for_each_available_child_of_node(np, node) {
805                 error = rockchip_pm_add_one_domain(pmu, node);
806                 if (error) {
807                         dev_err(dev, "failed to handle node %pOFn: %d\n",
808                                 node, error);
809                         of_node_put(node);
810                         goto err_out;
811                 }
812
813                 error = rockchip_pm_add_subdomain(pmu, node);
814                 if (error < 0) {
815                         dev_err(dev, "failed to handle subdomain node %pOFn: %d\n",
816                                 node, error);
817                         of_node_put(node);
818                         goto err_out;
819                 }
820         }
821
822         if (error) {
823                 dev_dbg(dev, "no power domains defined\n");
824                 goto err_out;
825         }
826
827         error = of_genpd_add_provider_onecell(np, &pmu->genpd_data);
828         if (error) {
829                 dev_err(dev, "failed to add provider: %d\n", error);
830                 goto err_out;
831         }
832
833         /* We only expect one PMU. */
834         if (!WARN_ON_ONCE(dmc_pmu))
835                 dmc_pmu = pmu;
836
837         mutex_unlock(&dmc_pmu_mutex);
838
839         return 0;
840
841 err_out:
842         rockchip_pm_domain_cleanup(pmu);
843         mutex_unlock(&dmc_pmu_mutex);
844         return error;
845 }
846
847 static const struct rockchip_domain_info px30_pm_domains[] = {
848         [PX30_PD_USB]           = DOMAIN_PX30("usb",      BIT(5),  BIT(5),  BIT(10), false),
849         [PX30_PD_SDCARD]        = DOMAIN_PX30("sdcard",   BIT(8),  BIT(8),  BIT(9),  false),
850         [PX30_PD_GMAC]          = DOMAIN_PX30("gmac",     BIT(10), BIT(10), BIT(6),  false),
851         [PX30_PD_MMC_NAND]      = DOMAIN_PX30("mmc_nand", BIT(11), BIT(11), BIT(5),  false),
852         [PX30_PD_VPU]           = DOMAIN_PX30("vpu",      BIT(12), BIT(12), BIT(14), false),
853         [PX30_PD_VO]            = DOMAIN_PX30("vo",       BIT(13), BIT(13), BIT(7),  false),
854         [PX30_PD_VI]            = DOMAIN_PX30("vi",       BIT(14), BIT(14), BIT(8),  false),
855         [PX30_PD_GPU]           = DOMAIN_PX30("gpu",      BIT(15), BIT(15), BIT(2),  false),
856 };
857
858 static const struct rockchip_domain_info rk3036_pm_domains[] = {
859         [RK3036_PD_MSCH]        = DOMAIN_RK3036("msch", BIT(14), BIT(23), BIT(30), true),
860         [RK3036_PD_CORE]        = DOMAIN_RK3036("core", BIT(13), BIT(17), BIT(24), false),
861         [RK3036_PD_PERI]        = DOMAIN_RK3036("peri", BIT(12), BIT(18), BIT(25), false),
862         [RK3036_PD_VIO]         = DOMAIN_RK3036("vio",  BIT(11), BIT(19), BIT(26), false),
863         [RK3036_PD_VPU]         = DOMAIN_RK3036("vpu",  BIT(10), BIT(20), BIT(27), false),
864         [RK3036_PD_GPU]         = DOMAIN_RK3036("gpu",  BIT(9),  BIT(21), BIT(28), false),
865         [RK3036_PD_SYS]         = DOMAIN_RK3036("sys",  BIT(8),  BIT(22), BIT(29), false),
866 };
867
868 static const struct rockchip_domain_info rk3066_pm_domains[] = {
869         [RK3066_PD_GPU]         = DOMAIN("gpu",   BIT(9), BIT(9), BIT(3), BIT(24), BIT(29), false),
870         [RK3066_PD_VIDEO]       = DOMAIN("video", BIT(8), BIT(8), BIT(4), BIT(23), BIT(28), false),
871         [RK3066_PD_VIO]         = DOMAIN("vio",   BIT(7), BIT(7), BIT(5), BIT(22), BIT(27), false),
872         [RK3066_PD_PERI]        = DOMAIN("peri",  BIT(6), BIT(6), BIT(2), BIT(25), BIT(30), false),
873         [RK3066_PD_CPU]         = DOMAIN("cpu",   0,      BIT(5), BIT(1), BIT(26), BIT(31), false),
874 };
875
876 static const struct rockchip_domain_info rk3128_pm_domains[] = {
877         [RK3128_PD_CORE]        = DOMAIN_RK3288("core",  BIT(0), BIT(0), BIT(4), false),
878         [RK3128_PD_MSCH]        = DOMAIN_RK3288("msch",  0,      0,      BIT(6), true),
879         [RK3128_PD_VIO]         = DOMAIN_RK3288("vio",   BIT(3), BIT(3), BIT(2), false),
880         [RK3128_PD_VIDEO]       = DOMAIN_RK3288("video", BIT(2), BIT(2), BIT(1), false),
881         [RK3128_PD_GPU]         = DOMAIN_RK3288("gpu",   BIT(1), BIT(1), BIT(3), false),
882 };
883
884 static const struct rockchip_domain_info rk3188_pm_domains[] = {
885         [RK3188_PD_GPU]         = DOMAIN("gpu",   BIT(9), BIT(9), BIT(3), BIT(24), BIT(29), false),
886         [RK3188_PD_VIDEO]       = DOMAIN("video", BIT(8), BIT(8), BIT(4), BIT(23), BIT(28), false),
887         [RK3188_PD_VIO]         = DOMAIN("vio",   BIT(7), BIT(7), BIT(5), BIT(22), BIT(27), false),
888         [RK3188_PD_PERI]        = DOMAIN("peri",  BIT(6), BIT(6), BIT(2), BIT(25), BIT(30), false),
889         [RK3188_PD_CPU]         = DOMAIN("cpu",   BIT(5), BIT(5), BIT(1), BIT(26), BIT(31), false),
890 };
891
892 static const struct rockchip_domain_info rk3228_pm_domains[] = {
893         [RK3228_PD_CORE]        = DOMAIN_RK3036("core", BIT(0),  BIT(0),  BIT(16), true),
894         [RK3228_PD_MSCH]        = DOMAIN_RK3036("msch", BIT(1),  BIT(1),  BIT(17), true),
895         [RK3228_PD_BUS]         = DOMAIN_RK3036("bus",  BIT(2),  BIT(2),  BIT(18), true),
896         [RK3228_PD_SYS]         = DOMAIN_RK3036("sys",  BIT(3),  BIT(3),  BIT(19), true),
897         [RK3228_PD_VIO]         = DOMAIN_RK3036("vio",  BIT(4),  BIT(4),  BIT(20), false),
898         [RK3228_PD_VOP]         = DOMAIN_RK3036("vop",  BIT(5),  BIT(5),  BIT(21), false),
899         [RK3228_PD_VPU]         = DOMAIN_RK3036("vpu",  BIT(6),  BIT(6),  BIT(22), false),
900         [RK3228_PD_RKVDEC]      = DOMAIN_RK3036("vdec", BIT(7),  BIT(7),  BIT(23), false),
901         [RK3228_PD_GPU]         = DOMAIN_RK3036("gpu",  BIT(8),  BIT(8),  BIT(24), false),
902         [RK3228_PD_PERI]        = DOMAIN_RK3036("peri", BIT(9),  BIT(9),  BIT(25), true),
903         [RK3228_PD_GMAC]        = DOMAIN_RK3036("gmac", BIT(10), BIT(10), BIT(26), false),
904 };
905
906 static const struct rockchip_domain_info rk3288_pm_domains[] = {
907         [RK3288_PD_VIO]         = DOMAIN_RK3288("vio",   BIT(7),  BIT(7),  BIT(4), false),
908         [RK3288_PD_HEVC]        = DOMAIN_RK3288("hevc",  BIT(14), BIT(10), BIT(9), false),
909         [RK3288_PD_VIDEO]       = DOMAIN_RK3288("video", BIT(8),  BIT(8),  BIT(3), false),
910         [RK3288_PD_GPU]         = DOMAIN_RK3288("gpu",   BIT(9),  BIT(9),  BIT(2), false),
911 };
912
913 static const struct rockchip_domain_info rk3328_pm_domains[] = {
914         [RK3328_PD_CORE]        = DOMAIN_RK3328("core",  0, BIT(0), BIT(0), false),
915         [RK3328_PD_GPU]         = DOMAIN_RK3328("gpu",   0, BIT(1), BIT(1), false),
916         [RK3328_PD_BUS]         = DOMAIN_RK3328("bus",   0, BIT(2), BIT(2), true),
917         [RK3328_PD_MSCH]        = DOMAIN_RK3328("msch",  0, BIT(3), BIT(3), true),
918         [RK3328_PD_PERI]        = DOMAIN_RK3328("peri",  0, BIT(4), BIT(4), true),
919         [RK3328_PD_VIDEO]       = DOMAIN_RK3328("video", 0, BIT(5), BIT(5), false),
920         [RK3328_PD_HEVC]        = DOMAIN_RK3328("hevc",  0, BIT(6), BIT(6), false),
921         [RK3328_PD_VIO]         = DOMAIN_RK3328("vio",   0, BIT(8), BIT(8), false),
922         [RK3328_PD_VPU]         = DOMAIN_RK3328("vpu",   0, BIT(9), BIT(9), false),
923 };
924
925 static const struct rockchip_domain_info rk3366_pm_domains[] = {
926         [RK3366_PD_PERI]        = DOMAIN_RK3368("peri",   BIT(10), BIT(10), BIT(6), true),
927         [RK3366_PD_VIO]         = DOMAIN_RK3368("vio",    BIT(14), BIT(14), BIT(8), false),
928         [RK3366_PD_VIDEO]       = DOMAIN_RK3368("video",  BIT(13), BIT(13), BIT(7), false),
929         [RK3366_PD_RKVDEC]      = DOMAIN_RK3368("vdec",   BIT(11), BIT(11), BIT(7), false),
930         [RK3366_PD_WIFIBT]      = DOMAIN_RK3368("wifibt", BIT(8),  BIT(8),  BIT(9), false),
931         [RK3366_PD_VPU]         = DOMAIN_RK3368("vpu",    BIT(12), BIT(12), BIT(7), false),
932         [RK3366_PD_GPU]         = DOMAIN_RK3368("gpu",    BIT(15), BIT(15), BIT(2), false),
933 };
934
935 static const struct rockchip_domain_info rk3368_pm_domains[] = {
936         [RK3368_PD_PERI]        = DOMAIN_RK3368("peri",  BIT(13), BIT(12), BIT(6), true),
937         [RK3368_PD_VIO]         = DOMAIN_RK3368("vio",   BIT(15), BIT(14), BIT(8), false),
938         [RK3368_PD_VIDEO]       = DOMAIN_RK3368("video", BIT(14), BIT(13), BIT(7), false),
939         [RK3368_PD_GPU_0]       = DOMAIN_RK3368("gpu_0", BIT(16), BIT(15), BIT(2), false),
940         [RK3368_PD_GPU_1]       = DOMAIN_RK3368("gpu_1", BIT(17), BIT(16), BIT(2), false),
941 };
942
943 static const struct rockchip_domain_info rk3399_pm_domains[] = {
944         [RK3399_PD_TCPD0]       = DOMAIN_RK3399("tcpd0",     BIT(8),  BIT(8),  0,       false),
945         [RK3399_PD_TCPD1]       = DOMAIN_RK3399("tcpd1",     BIT(9),  BIT(9),  0,       false),
946         [RK3399_PD_CCI]         = DOMAIN_RK3399("cci",       BIT(10), BIT(10), 0,       true),
947         [RK3399_PD_CCI0]        = DOMAIN_RK3399("cci0",      0,       0,       BIT(15), true),
948         [RK3399_PD_CCI1]        = DOMAIN_RK3399("cci1",      0,       0,       BIT(16), true),
949         [RK3399_PD_PERILP]      = DOMAIN_RK3399("perilp",    BIT(11), BIT(11), BIT(1),  true),
950         [RK3399_PD_PERIHP]      = DOMAIN_RK3399("perihp",    BIT(12), BIT(12), BIT(2),  true),
951         [RK3399_PD_CENTER]      = DOMAIN_RK3399("center",    BIT(13), BIT(13), BIT(14), true),
952         [RK3399_PD_VIO]         = DOMAIN_RK3399("vio",       BIT(14), BIT(14), BIT(17), false),
953         [RK3399_PD_GPU]         = DOMAIN_RK3399("gpu",       BIT(15), BIT(15), BIT(0),  false),
954         [RK3399_PD_VCODEC]      = DOMAIN_RK3399("vcodec",    BIT(16), BIT(16), BIT(3),  false),
955         [RK3399_PD_VDU]         = DOMAIN_RK3399("vdu",       BIT(17), BIT(17), BIT(4),  false),
956         [RK3399_PD_RGA]         = DOMAIN_RK3399("rga",       BIT(18), BIT(18), BIT(5),  false),
957         [RK3399_PD_IEP]         = DOMAIN_RK3399("iep",       BIT(19), BIT(19), BIT(6),  false),
958         [RK3399_PD_VO]          = DOMAIN_RK3399("vo",        BIT(20), BIT(20), 0,       false),
959         [RK3399_PD_VOPB]        = DOMAIN_RK3399("vopb",      0,       0,       BIT(7),  false),
960         [RK3399_PD_VOPL]        = DOMAIN_RK3399("vopl",      0,       0,       BIT(8),  false),
961         [RK3399_PD_ISP0]        = DOMAIN_RK3399("isp0",      BIT(22), BIT(22), BIT(9),  false),
962         [RK3399_PD_ISP1]        = DOMAIN_RK3399("isp1",      BIT(23), BIT(23), BIT(10), false),
963         [RK3399_PD_HDCP]        = DOMAIN_RK3399("hdcp",      BIT(24), BIT(24), BIT(11), false),
964         [RK3399_PD_GMAC]        = DOMAIN_RK3399("gmac",      BIT(25), BIT(25), BIT(23), true),
965         [RK3399_PD_EMMC]        = DOMAIN_RK3399("emmc",      BIT(26), BIT(26), BIT(24), true),
966         [RK3399_PD_USB3]        = DOMAIN_RK3399("usb3",      BIT(27), BIT(27), BIT(12), true),
967         [RK3399_PD_EDP]         = DOMAIN_RK3399("edp",       BIT(28), BIT(28), BIT(22), false),
968         [RK3399_PD_GIC]         = DOMAIN_RK3399("gic",       BIT(29), BIT(29), BIT(27), true),
969         [RK3399_PD_SD]          = DOMAIN_RK3399("sd",        BIT(30), BIT(30), BIT(28), true),
970         [RK3399_PD_SDIOAUDIO]   = DOMAIN_RK3399("sdioaudio", BIT(31), BIT(31), BIT(29), true),
971 };
972
973 static const struct rockchip_domain_info rk3568_pm_domains[] = {
974         [RK3568_PD_NPU]         = DOMAIN_RK3568("npu",  BIT(1), BIT(2),  false),
975         [RK3568_PD_GPU]         = DOMAIN_RK3568("gpu",  BIT(0), BIT(1),  false),
976         [RK3568_PD_VI]          = DOMAIN_RK3568("vi",   BIT(6), BIT(3),  false),
977         [RK3568_PD_VO]          = DOMAIN_RK3568("vo",   BIT(7), BIT(4),  false),
978         [RK3568_PD_RGA]         = DOMAIN_RK3568("rga",  BIT(5), BIT(5),  false),
979         [RK3568_PD_VPU]         = DOMAIN_RK3568("vpu",  BIT(2), BIT(6),  false),
980         [RK3568_PD_RKVDEC]      = DOMAIN_RK3568("vdec", BIT(4), BIT(8),  false),
981         [RK3568_PD_RKVENC]      = DOMAIN_RK3568("venc", BIT(3), BIT(7),  false),
982         [RK3568_PD_PIPE]        = DOMAIN_RK3568("pipe", BIT(8), BIT(11), false),
983 };
984
985 static const struct rockchip_pmu_info px30_pmu = {
986         .pwr_offset = 0x18,
987         .status_offset = 0x20,
988         .req_offset = 0x64,
989         .idle_offset = 0x6c,
990         .ack_offset = 0x6c,
991
992         .num_domains = ARRAY_SIZE(px30_pm_domains),
993         .domain_info = px30_pm_domains,
994 };
995
996 static const struct rockchip_pmu_info rk3036_pmu = {
997         .req_offset = 0x148,
998         .idle_offset = 0x14c,
999         .ack_offset = 0x14c,
1000
1001         .num_domains = ARRAY_SIZE(rk3036_pm_domains),
1002         .domain_info = rk3036_pm_domains,
1003 };
1004
1005 static const struct rockchip_pmu_info rk3066_pmu = {
1006         .pwr_offset = 0x08,
1007         .status_offset = 0x0c,
1008         .req_offset = 0x38, /* PMU_MISC_CON1 */
1009         .idle_offset = 0x0c,
1010         .ack_offset = 0x0c,
1011
1012         .num_domains = ARRAY_SIZE(rk3066_pm_domains),
1013         .domain_info = rk3066_pm_domains,
1014 };
1015
1016 static const struct rockchip_pmu_info rk3128_pmu = {
1017         .pwr_offset = 0x04,
1018         .status_offset = 0x08,
1019         .req_offset = 0x0c,
1020         .idle_offset = 0x10,
1021         .ack_offset = 0x10,
1022
1023         .num_domains = ARRAY_SIZE(rk3128_pm_domains),
1024         .domain_info = rk3128_pm_domains,
1025 };
1026
1027 static const struct rockchip_pmu_info rk3188_pmu = {
1028         .pwr_offset = 0x08,
1029         .status_offset = 0x0c,
1030         .req_offset = 0x38, /* PMU_MISC_CON1 */
1031         .idle_offset = 0x0c,
1032         .ack_offset = 0x0c,
1033
1034         .num_domains = ARRAY_SIZE(rk3188_pm_domains),
1035         .domain_info = rk3188_pm_domains,
1036 };
1037
1038 static const struct rockchip_pmu_info rk3228_pmu = {
1039         .req_offset = 0x40c,
1040         .idle_offset = 0x488,
1041         .ack_offset = 0x488,
1042
1043         .num_domains = ARRAY_SIZE(rk3228_pm_domains),
1044         .domain_info = rk3228_pm_domains,
1045 };
1046
1047 static const struct rockchip_pmu_info rk3288_pmu = {
1048         .pwr_offset = 0x08,
1049         .status_offset = 0x0c,
1050         .req_offset = 0x10,
1051         .idle_offset = 0x14,
1052         .ack_offset = 0x14,
1053
1054         .core_pwrcnt_offset = 0x34,
1055         .gpu_pwrcnt_offset = 0x3c,
1056
1057         .core_power_transition_time = 24, /* 1us */
1058         .gpu_power_transition_time = 24, /* 1us */
1059
1060         .num_domains = ARRAY_SIZE(rk3288_pm_domains),
1061         .domain_info = rk3288_pm_domains,
1062 };
1063
1064 static const struct rockchip_pmu_info rk3328_pmu = {
1065         .req_offset = 0x414,
1066         .idle_offset = 0x484,
1067         .ack_offset = 0x484,
1068
1069         .num_domains = ARRAY_SIZE(rk3328_pm_domains),
1070         .domain_info = rk3328_pm_domains,
1071 };
1072
1073 static const struct rockchip_pmu_info rk3366_pmu = {
1074         .pwr_offset = 0x0c,
1075         .status_offset = 0x10,
1076         .req_offset = 0x3c,
1077         .idle_offset = 0x40,
1078         .ack_offset = 0x40,
1079
1080         .core_pwrcnt_offset = 0x48,
1081         .gpu_pwrcnt_offset = 0x50,
1082
1083         .core_power_transition_time = 24,
1084         .gpu_power_transition_time = 24,
1085
1086         .num_domains = ARRAY_SIZE(rk3366_pm_domains),
1087         .domain_info = rk3366_pm_domains,
1088 };
1089
1090 static const struct rockchip_pmu_info rk3368_pmu = {
1091         .pwr_offset = 0x0c,
1092         .status_offset = 0x10,
1093         .req_offset = 0x3c,
1094         .idle_offset = 0x40,
1095         .ack_offset = 0x40,
1096
1097         .core_pwrcnt_offset = 0x48,
1098         .gpu_pwrcnt_offset = 0x50,
1099
1100         .core_power_transition_time = 24,
1101         .gpu_power_transition_time = 24,
1102
1103         .num_domains = ARRAY_SIZE(rk3368_pm_domains),
1104         .domain_info = rk3368_pm_domains,
1105 };
1106
1107 static const struct rockchip_pmu_info rk3399_pmu = {
1108         .pwr_offset = 0x14,
1109         .status_offset = 0x18,
1110         .req_offset = 0x60,
1111         .idle_offset = 0x64,
1112         .ack_offset = 0x68,
1113
1114         /* ARM Trusted Firmware manages power transition times */
1115
1116         .num_domains = ARRAY_SIZE(rk3399_pm_domains),
1117         .domain_info = rk3399_pm_domains,
1118 };
1119
1120 static const struct rockchip_pmu_info rk3568_pmu = {
1121         .pwr_offset = 0xa0,
1122         .status_offset = 0x98,
1123         .req_offset = 0x50,
1124         .idle_offset = 0x68,
1125         .ack_offset = 0x60,
1126
1127         .num_domains = ARRAY_SIZE(rk3568_pm_domains),
1128         .domain_info = rk3568_pm_domains,
1129 };
1130
1131 static const struct of_device_id rockchip_pm_domain_dt_match[] = {
1132         {
1133                 .compatible = "rockchip,px30-power-controller",
1134                 .data = (void *)&px30_pmu,
1135         },
1136         {
1137                 .compatible = "rockchip,rk3036-power-controller",
1138                 .data = (void *)&rk3036_pmu,
1139         },
1140         {
1141                 .compatible = "rockchip,rk3066-power-controller",
1142                 .data = (void *)&rk3066_pmu,
1143         },
1144         {
1145                 .compatible = "rockchip,rk3128-power-controller",
1146                 .data = (void *)&rk3128_pmu,
1147         },
1148         {
1149                 .compatible = "rockchip,rk3188-power-controller",
1150                 .data = (void *)&rk3188_pmu,
1151         },
1152         {
1153                 .compatible = "rockchip,rk3228-power-controller",
1154                 .data = (void *)&rk3228_pmu,
1155         },
1156         {
1157                 .compatible = "rockchip,rk3288-power-controller",
1158                 .data = (void *)&rk3288_pmu,
1159         },
1160         {
1161                 .compatible = "rockchip,rk3328-power-controller",
1162                 .data = (void *)&rk3328_pmu,
1163         },
1164         {
1165                 .compatible = "rockchip,rk3366-power-controller",
1166                 .data = (void *)&rk3366_pmu,
1167         },
1168         {
1169                 .compatible = "rockchip,rk3368-power-controller",
1170                 .data = (void *)&rk3368_pmu,
1171         },
1172         {
1173                 .compatible = "rockchip,rk3399-power-controller",
1174                 .data = (void *)&rk3399_pmu,
1175         },
1176         {
1177                 .compatible = "rockchip,rk3568-power-controller",
1178                 .data = (void *)&rk3568_pmu,
1179         },
1180         { /* sentinel */ },
1181 };
1182
1183 static struct platform_driver rockchip_pm_domain_driver = {
1184         .probe = rockchip_pm_domain_probe,
1185         .driver = {
1186                 .name   = "rockchip-pm-domain",
1187                 .of_match_table = rockchip_pm_domain_dt_match,
1188                 /*
1189                  * We can't forcibly eject devices from the power
1190                  * domain, so we can't really remove power domains
1191                  * once they were added.
1192                  */
1193                 .suppress_bind_attrs = true,
1194         },
1195 };
1196
1197 static int __init rockchip_pm_domain_drv_register(void)
1198 {
1199         return platform_driver_register(&rockchip_pm_domain_driver);
1200 }
1201 postcore_initcall(rockchip_pm_domain_drv_register);