0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/io.h>
0009 #include <linux/iopoll.h>
0010 #include <linux/err.h>
0011 #include <linux/mutex.h>
0012 #include <linux/pm_clock.h>
0013 #include <linux/pm_domain.h>
0014 #include <linux/of_address.h>
0015 #include <linux/of_clk.h>
0016 #include <linux/of_platform.h>
0017 #include <linux/clk.h>
0018 #include <linux/regmap.h>
0019 #include <linux/mfd/syscon.h>
0020 #include <soc/rockchip/pm_domains.h>
0021 #include <dt-bindings/power/px30-power.h>
0022 #include <dt-bindings/power/rk3036-power.h>
0023 #include <dt-bindings/power/rk3066-power.h>
0024 #include <dt-bindings/power/rk3128-power.h>
0025 #include <dt-bindings/power/rk3188-power.h>
0026 #include <dt-bindings/power/rk3228-power.h>
0027 #include <dt-bindings/power/rk3288-power.h>
0028 #include <dt-bindings/power/rk3328-power.h>
0029 #include <dt-bindings/power/rk3366-power.h>
0030 #include <dt-bindings/power/rk3368-power.h>
0031 #include <dt-bindings/power/rk3399-power.h>
0032 #include <dt-bindings/power/rk3568-power.h>
0033
0034 struct rockchip_domain_info {
0035 const char *name;
0036 int pwr_mask;
0037 int status_mask;
0038 int req_mask;
0039 int idle_mask;
0040 int ack_mask;
0041 bool active_wakeup;
0042 int pwr_w_mask;
0043 int req_w_mask;
0044 };
0045
0046 struct rockchip_pmu_info {
0047 u32 pwr_offset;
0048 u32 status_offset;
0049 u32 req_offset;
0050 u32 idle_offset;
0051 u32 ack_offset;
0052
0053 u32 core_pwrcnt_offset;
0054 u32 gpu_pwrcnt_offset;
0055
0056 unsigned int core_power_transition_time;
0057 unsigned int gpu_power_transition_time;
0058
0059 int num_domains;
0060 const struct rockchip_domain_info *domain_info;
0061 };
0062
0063 #define MAX_QOS_REGS_NUM 5
0064 #define QOS_PRIORITY 0x08
0065 #define QOS_MODE 0x0c
0066 #define QOS_BANDWIDTH 0x10
0067 #define QOS_SATURATION 0x14
0068 #define QOS_EXTCONTROL 0x18
0069
0070 struct rockchip_pm_domain {
0071 struct generic_pm_domain genpd;
0072 const struct rockchip_domain_info *info;
0073 struct rockchip_pmu *pmu;
0074 int num_qos;
0075 struct regmap **qos_regmap;
0076 u32 *qos_save_regs[MAX_QOS_REGS_NUM];
0077 int num_clks;
0078 struct clk_bulk_data *clks;
0079 };
0080
0081 struct rockchip_pmu {
0082 struct device *dev;
0083 struct regmap *regmap;
0084 const struct rockchip_pmu_info *info;
0085 struct mutex mutex;
0086 struct genpd_onecell_data genpd_data;
0087 struct generic_pm_domain *domains[];
0088 };
0089
0090 #define to_rockchip_pd(gpd) container_of(gpd, struct rockchip_pm_domain, genpd)
0091
0092 #define DOMAIN(_name, pwr, status, req, idle, ack, wakeup) \
0093 { \
0094 .name = _name, \
0095 .pwr_mask = (pwr), \
0096 .status_mask = (status), \
0097 .req_mask = (req), \
0098 .idle_mask = (idle), \
0099 .ack_mask = (ack), \
0100 .active_wakeup = (wakeup), \
0101 }
0102
0103 #define DOMAIN_M(_name, pwr, status, req, idle, ack, wakeup) \
0104 { \
0105 .name = _name, \
0106 .pwr_w_mask = (pwr) << 16, \
0107 .pwr_mask = (pwr), \
0108 .status_mask = (status), \
0109 .req_w_mask = (req) << 16, \
0110 .req_mask = (req), \
0111 .idle_mask = (idle), \
0112 .ack_mask = (ack), \
0113 .active_wakeup = wakeup, \
0114 }
0115
0116 #define DOMAIN_RK3036(_name, req, ack, idle, wakeup) \
0117 { \
0118 .name = _name, \
0119 .req_mask = (req), \
0120 .req_w_mask = (req) << 16, \
0121 .ack_mask = (ack), \
0122 .idle_mask = (idle), \
0123 .active_wakeup = wakeup, \
0124 }
0125
0126 #define DOMAIN_PX30(name, pwr, status, req, wakeup) \
0127 DOMAIN_M(name, pwr, status, req, (req) << 16, req, wakeup)
0128
0129 #define DOMAIN_RK3288(name, pwr, status, req, wakeup) \
0130 DOMAIN(name, pwr, status, req, req, (req) << 16, wakeup)
0131
0132 #define DOMAIN_RK3328(name, pwr, status, req, wakeup) \
0133 DOMAIN_M(name, pwr, pwr, req, (req) << 10, req, wakeup)
0134
0135 #define DOMAIN_RK3368(name, pwr, status, req, wakeup) \
0136 DOMAIN(name, pwr, status, req, (req) << 16, req, wakeup)
0137
0138 #define DOMAIN_RK3399(name, pwr, status, req, wakeup) \
0139 DOMAIN(name, pwr, status, req, req, req, wakeup)
0140
0141 #define DOMAIN_RK3568(name, pwr, req, wakeup) \
0142 DOMAIN_M(name, pwr, pwr, req, req, req, wakeup)
0143
0144
0145
0146
0147
0148
0149
0150
0151 static DEFINE_MUTEX(dmc_pmu_mutex);
0152 static struct rockchip_pmu *dmc_pmu;
0153
0154
0155
0156
0157
0158
0159
0160 int rockchip_pmu_block(void)
0161 {
0162 struct rockchip_pmu *pmu;
0163 struct generic_pm_domain *genpd;
0164 struct rockchip_pm_domain *pd;
0165 int i, ret;
0166
0167 mutex_lock(&dmc_pmu_mutex);
0168
0169
0170 if (!dmc_pmu)
0171 return 0;
0172 pmu = dmc_pmu;
0173
0174
0175
0176
0177
0178
0179 mutex_lock(&pmu->mutex);
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191 for (i = 0; i < pmu->genpd_data.num_domains; i++) {
0192 genpd = pmu->genpd_data.domains[i];
0193 if (genpd) {
0194 pd = to_rockchip_pd(genpd);
0195 ret = clk_bulk_enable(pd->num_clks, pd->clks);
0196 if (ret < 0) {
0197 dev_err(pmu->dev,
0198 "failed to enable clks for domain '%s': %d\n",
0199 genpd->name, ret);
0200 goto err;
0201 }
0202 }
0203 }
0204
0205 return 0;
0206
0207 err:
0208 for (i = i - 1; i >= 0; i--) {
0209 genpd = pmu->genpd_data.domains[i];
0210 if (genpd) {
0211 pd = to_rockchip_pd(genpd);
0212 clk_bulk_disable(pd->num_clks, pd->clks);
0213 }
0214 }
0215 mutex_unlock(&pmu->mutex);
0216 mutex_unlock(&dmc_pmu_mutex);
0217
0218 return ret;
0219 }
0220 EXPORT_SYMBOL_GPL(rockchip_pmu_block);
0221
0222
0223 void rockchip_pmu_unblock(void)
0224 {
0225 struct rockchip_pmu *pmu;
0226 struct generic_pm_domain *genpd;
0227 struct rockchip_pm_domain *pd;
0228 int i;
0229
0230 if (dmc_pmu) {
0231 pmu = dmc_pmu;
0232 for (i = 0; i < pmu->genpd_data.num_domains; i++) {
0233 genpd = pmu->genpd_data.domains[i];
0234 if (genpd) {
0235 pd = to_rockchip_pd(genpd);
0236 clk_bulk_disable(pd->num_clks, pd->clks);
0237 }
0238 }
0239
0240 mutex_unlock(&pmu->mutex);
0241 }
0242
0243 mutex_unlock(&dmc_pmu_mutex);
0244 }
0245 EXPORT_SYMBOL_GPL(rockchip_pmu_unblock);
0246
0247 static bool rockchip_pmu_domain_is_idle(struct rockchip_pm_domain *pd)
0248 {
0249 struct rockchip_pmu *pmu = pd->pmu;
0250 const struct rockchip_domain_info *pd_info = pd->info;
0251 unsigned int val;
0252
0253 regmap_read(pmu->regmap, pmu->info->idle_offset, &val);
0254 return (val & pd_info->idle_mask) == pd_info->idle_mask;
0255 }
0256
0257 static unsigned int rockchip_pmu_read_ack(struct rockchip_pmu *pmu)
0258 {
0259 unsigned int val;
0260
0261 regmap_read(pmu->regmap, pmu->info->ack_offset, &val);
0262 return val;
0263 }
0264
0265 static int rockchip_pmu_set_idle_request(struct rockchip_pm_domain *pd,
0266 bool idle)
0267 {
0268 const struct rockchip_domain_info *pd_info = pd->info;
0269 struct generic_pm_domain *genpd = &pd->genpd;
0270 struct rockchip_pmu *pmu = pd->pmu;
0271 unsigned int target_ack;
0272 unsigned int val;
0273 bool is_idle;
0274 int ret;
0275
0276 if (pd_info->req_mask == 0)
0277 return 0;
0278 else if (pd_info->req_w_mask)
0279 regmap_write(pmu->regmap, pmu->info->req_offset,
0280 idle ? (pd_info->req_mask | pd_info->req_w_mask) :
0281 pd_info->req_w_mask);
0282 else
0283 regmap_update_bits(pmu->regmap, pmu->info->req_offset,
0284 pd_info->req_mask, idle ? -1U : 0);
0285
0286 wmb();
0287
0288
0289 target_ack = idle ? pd_info->ack_mask : 0;
0290 ret = readx_poll_timeout_atomic(rockchip_pmu_read_ack, pmu, val,
0291 (val & pd_info->ack_mask) == target_ack,
0292 0, 10000);
0293 if (ret) {
0294 dev_err(pmu->dev,
0295 "failed to get ack on domain '%s', val=0x%x\n",
0296 genpd->name, val);
0297 return ret;
0298 }
0299
0300 ret = readx_poll_timeout_atomic(rockchip_pmu_domain_is_idle, pd,
0301 is_idle, is_idle == idle, 0, 10000);
0302 if (ret) {
0303 dev_err(pmu->dev,
0304 "failed to set idle on domain '%s', val=%d\n",
0305 genpd->name, is_idle);
0306 return ret;
0307 }
0308
0309 return 0;
0310 }
0311
0312 static int rockchip_pmu_save_qos(struct rockchip_pm_domain *pd)
0313 {
0314 int i;
0315
0316 for (i = 0; i < pd->num_qos; i++) {
0317 regmap_read(pd->qos_regmap[i],
0318 QOS_PRIORITY,
0319 &pd->qos_save_regs[0][i]);
0320 regmap_read(pd->qos_regmap[i],
0321 QOS_MODE,
0322 &pd->qos_save_regs[1][i]);
0323 regmap_read(pd->qos_regmap[i],
0324 QOS_BANDWIDTH,
0325 &pd->qos_save_regs[2][i]);
0326 regmap_read(pd->qos_regmap[i],
0327 QOS_SATURATION,
0328 &pd->qos_save_regs[3][i]);
0329 regmap_read(pd->qos_regmap[i],
0330 QOS_EXTCONTROL,
0331 &pd->qos_save_regs[4][i]);
0332 }
0333 return 0;
0334 }
0335
0336 static int rockchip_pmu_restore_qos(struct rockchip_pm_domain *pd)
0337 {
0338 int i;
0339
0340 for (i = 0; i < pd->num_qos; i++) {
0341 regmap_write(pd->qos_regmap[i],
0342 QOS_PRIORITY,
0343 pd->qos_save_regs[0][i]);
0344 regmap_write(pd->qos_regmap[i],
0345 QOS_MODE,
0346 pd->qos_save_regs[1][i]);
0347 regmap_write(pd->qos_regmap[i],
0348 QOS_BANDWIDTH,
0349 pd->qos_save_regs[2][i]);
0350 regmap_write(pd->qos_regmap[i],
0351 QOS_SATURATION,
0352 pd->qos_save_regs[3][i]);
0353 regmap_write(pd->qos_regmap[i],
0354 QOS_EXTCONTROL,
0355 pd->qos_save_regs[4][i]);
0356 }
0357
0358 return 0;
0359 }
0360
0361 static bool rockchip_pmu_domain_is_on(struct rockchip_pm_domain *pd)
0362 {
0363 struct rockchip_pmu *pmu = pd->pmu;
0364 unsigned int val;
0365
0366
0367 if (pd->info->status_mask == 0)
0368 return !rockchip_pmu_domain_is_idle(pd);
0369
0370 regmap_read(pmu->regmap, pmu->info->status_offset, &val);
0371
0372
0373 return !(val & pd->info->status_mask);
0374 }
0375
0376 static void rockchip_do_pmu_set_power_domain(struct rockchip_pm_domain *pd,
0377 bool on)
0378 {
0379 struct rockchip_pmu *pmu = pd->pmu;
0380 struct generic_pm_domain *genpd = &pd->genpd;
0381 bool is_on;
0382
0383 if (pd->info->pwr_mask == 0)
0384 return;
0385 else if (pd->info->pwr_w_mask)
0386 regmap_write(pmu->regmap, pmu->info->pwr_offset,
0387 on ? pd->info->pwr_w_mask :
0388 (pd->info->pwr_mask | pd->info->pwr_w_mask));
0389 else
0390 regmap_update_bits(pmu->regmap, pmu->info->pwr_offset,
0391 pd->info->pwr_mask, on ? 0 : -1U);
0392
0393 wmb();
0394
0395 if (readx_poll_timeout_atomic(rockchip_pmu_domain_is_on, pd, is_on,
0396 is_on == on, 0, 10000)) {
0397 dev_err(pmu->dev,
0398 "failed to set domain '%s', val=%d\n",
0399 genpd->name, is_on);
0400 return;
0401 }
0402 }
0403
0404 static int rockchip_pd_power(struct rockchip_pm_domain *pd, bool power_on)
0405 {
0406 struct rockchip_pmu *pmu = pd->pmu;
0407 int ret;
0408
0409 mutex_lock(&pmu->mutex);
0410
0411 if (rockchip_pmu_domain_is_on(pd) != power_on) {
0412 ret = clk_bulk_enable(pd->num_clks, pd->clks);
0413 if (ret < 0) {
0414 dev_err(pmu->dev, "failed to enable clocks\n");
0415 mutex_unlock(&pmu->mutex);
0416 return ret;
0417 }
0418
0419 if (!power_on) {
0420 rockchip_pmu_save_qos(pd);
0421
0422
0423 rockchip_pmu_set_idle_request(pd, true);
0424 }
0425
0426 rockchip_do_pmu_set_power_domain(pd, power_on);
0427
0428 if (power_on) {
0429
0430 rockchip_pmu_set_idle_request(pd, false);
0431
0432 rockchip_pmu_restore_qos(pd);
0433 }
0434
0435 clk_bulk_disable(pd->num_clks, pd->clks);
0436 }
0437
0438 mutex_unlock(&pmu->mutex);
0439 return 0;
0440 }
0441
0442 static int rockchip_pd_power_on(struct generic_pm_domain *domain)
0443 {
0444 struct rockchip_pm_domain *pd = to_rockchip_pd(domain);
0445
0446 return rockchip_pd_power(pd, true);
0447 }
0448
0449 static int rockchip_pd_power_off(struct generic_pm_domain *domain)
0450 {
0451 struct rockchip_pm_domain *pd = to_rockchip_pd(domain);
0452
0453 return rockchip_pd_power(pd, false);
0454 }
0455
0456 static int rockchip_pd_attach_dev(struct generic_pm_domain *genpd,
0457 struct device *dev)
0458 {
0459 struct clk *clk;
0460 int i;
0461 int error;
0462
0463 dev_dbg(dev, "attaching to power domain '%s'\n", genpd->name);
0464
0465 error = pm_clk_create(dev);
0466 if (error) {
0467 dev_err(dev, "pm_clk_create failed %d\n", error);
0468 return error;
0469 }
0470
0471 i = 0;
0472 while ((clk = of_clk_get(dev->of_node, i++)) && !IS_ERR(clk)) {
0473 dev_dbg(dev, "adding clock '%pC' to list of PM clocks\n", clk);
0474 error = pm_clk_add_clk(dev, clk);
0475 if (error) {
0476 dev_err(dev, "pm_clk_add_clk failed %d\n", error);
0477 clk_put(clk);
0478 pm_clk_destroy(dev);
0479 return error;
0480 }
0481 }
0482
0483 return 0;
0484 }
0485
0486 static void rockchip_pd_detach_dev(struct generic_pm_domain *genpd,
0487 struct device *dev)
0488 {
0489 dev_dbg(dev, "detaching from power domain '%s'\n", genpd->name);
0490
0491 pm_clk_destroy(dev);
0492 }
0493
0494 static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu,
0495 struct device_node *node)
0496 {
0497 const struct rockchip_domain_info *pd_info;
0498 struct rockchip_pm_domain *pd;
0499 struct device_node *qos_node;
0500 int i, j;
0501 u32 id;
0502 int error;
0503
0504 error = of_property_read_u32(node, "reg", &id);
0505 if (error) {
0506 dev_err(pmu->dev,
0507 "%pOFn: failed to retrieve domain id (reg): %d\n",
0508 node, error);
0509 return -EINVAL;
0510 }
0511
0512 if (id >= pmu->info->num_domains) {
0513 dev_err(pmu->dev, "%pOFn: invalid domain id %d\n",
0514 node, id);
0515 return -EINVAL;
0516 }
0517
0518 pd_info = &pmu->info->domain_info[id];
0519 if (!pd_info) {
0520 dev_err(pmu->dev, "%pOFn: undefined domain id %d\n",
0521 node, id);
0522 return -EINVAL;
0523 }
0524
0525 pd = devm_kzalloc(pmu->dev, sizeof(*pd), GFP_KERNEL);
0526 if (!pd)
0527 return -ENOMEM;
0528
0529 pd->info = pd_info;
0530 pd->pmu = pmu;
0531
0532 pd->num_clks = of_clk_get_parent_count(node);
0533 if (pd->num_clks > 0) {
0534 pd->clks = devm_kcalloc(pmu->dev, pd->num_clks,
0535 sizeof(*pd->clks), GFP_KERNEL);
0536 if (!pd->clks)
0537 return -ENOMEM;
0538 } else {
0539 dev_dbg(pmu->dev, "%pOFn: doesn't have clocks: %d\n",
0540 node, pd->num_clks);
0541 pd->num_clks = 0;
0542 }
0543
0544 for (i = 0; i < pd->num_clks; i++) {
0545 pd->clks[i].clk = of_clk_get(node, i);
0546 if (IS_ERR(pd->clks[i].clk)) {
0547 error = PTR_ERR(pd->clks[i].clk);
0548 dev_err(pmu->dev,
0549 "%pOFn: failed to get clk at index %d: %d\n",
0550 node, i, error);
0551 return error;
0552 }
0553 }
0554
0555 error = clk_bulk_prepare(pd->num_clks, pd->clks);
0556 if (error)
0557 goto err_put_clocks;
0558
0559 pd->num_qos = of_count_phandle_with_args(node, "pm_qos",
0560 NULL);
0561
0562 if (pd->num_qos > 0) {
0563 pd->qos_regmap = devm_kcalloc(pmu->dev, pd->num_qos,
0564 sizeof(*pd->qos_regmap),
0565 GFP_KERNEL);
0566 if (!pd->qos_regmap) {
0567 error = -ENOMEM;
0568 goto err_unprepare_clocks;
0569 }
0570
0571 for (j = 0; j < MAX_QOS_REGS_NUM; j++) {
0572 pd->qos_save_regs[j] = devm_kcalloc(pmu->dev,
0573 pd->num_qos,
0574 sizeof(u32),
0575 GFP_KERNEL);
0576 if (!pd->qos_save_regs[j]) {
0577 error = -ENOMEM;
0578 goto err_unprepare_clocks;
0579 }
0580 }
0581
0582 for (j = 0; j < pd->num_qos; j++) {
0583 qos_node = of_parse_phandle(node, "pm_qos", j);
0584 if (!qos_node) {
0585 error = -ENODEV;
0586 goto err_unprepare_clocks;
0587 }
0588 pd->qos_regmap[j] = syscon_node_to_regmap(qos_node);
0589 if (IS_ERR(pd->qos_regmap[j])) {
0590 error = -ENODEV;
0591 of_node_put(qos_node);
0592 goto err_unprepare_clocks;
0593 }
0594 of_node_put(qos_node);
0595 }
0596 }
0597
0598 error = rockchip_pd_power(pd, true);
0599 if (error) {
0600 dev_err(pmu->dev,
0601 "failed to power on domain '%pOFn': %d\n",
0602 node, error);
0603 goto err_unprepare_clocks;
0604 }
0605
0606 if (pd->info->name)
0607 pd->genpd.name = pd->info->name;
0608 else
0609 pd->genpd.name = kbasename(node->full_name);
0610 pd->genpd.power_off = rockchip_pd_power_off;
0611 pd->genpd.power_on = rockchip_pd_power_on;
0612 pd->genpd.attach_dev = rockchip_pd_attach_dev;
0613 pd->genpd.detach_dev = rockchip_pd_detach_dev;
0614 pd->genpd.flags = GENPD_FLAG_PM_CLK;
0615 if (pd_info->active_wakeup)
0616 pd->genpd.flags |= GENPD_FLAG_ACTIVE_WAKEUP;
0617 pm_genpd_init(&pd->genpd, NULL, false);
0618
0619 pmu->genpd_data.domains[id] = &pd->genpd;
0620 return 0;
0621
0622 err_unprepare_clocks:
0623 clk_bulk_unprepare(pd->num_clks, pd->clks);
0624 err_put_clocks:
0625 clk_bulk_put(pd->num_clks, pd->clks);
0626 return error;
0627 }
0628
0629 static void rockchip_pm_remove_one_domain(struct rockchip_pm_domain *pd)
0630 {
0631 int ret;
0632
0633
0634
0635
0636
0637 ret = pm_genpd_remove(&pd->genpd);
0638 if (ret < 0)
0639 dev_err(pd->pmu->dev, "failed to remove domain '%s' : %d - state may be inconsistent\n",
0640 pd->genpd.name, ret);
0641
0642 clk_bulk_unprepare(pd->num_clks, pd->clks);
0643 clk_bulk_put(pd->num_clks, pd->clks);
0644
0645
0646 mutex_lock(&pd->pmu->mutex);
0647 pd->num_clks = 0;
0648 mutex_unlock(&pd->pmu->mutex);
0649
0650
0651 }
0652
0653 static void rockchip_pm_domain_cleanup(struct rockchip_pmu *pmu)
0654 {
0655 struct generic_pm_domain *genpd;
0656 struct rockchip_pm_domain *pd;
0657 int i;
0658
0659 for (i = 0; i < pmu->genpd_data.num_domains; i++) {
0660 genpd = pmu->genpd_data.domains[i];
0661 if (genpd) {
0662 pd = to_rockchip_pd(genpd);
0663 rockchip_pm_remove_one_domain(pd);
0664 }
0665 }
0666
0667
0668 }
0669
0670 static void rockchip_configure_pd_cnt(struct rockchip_pmu *pmu,
0671 u32 domain_reg_offset,
0672 unsigned int count)
0673 {
0674
0675 regmap_write(pmu->regmap, domain_reg_offset, count);
0676
0677 regmap_write(pmu->regmap, domain_reg_offset + 4, count);
0678 }
0679
0680 static int rockchip_pm_add_subdomain(struct rockchip_pmu *pmu,
0681 struct device_node *parent)
0682 {
0683 struct device_node *np;
0684 struct generic_pm_domain *child_domain, *parent_domain;
0685 int error;
0686
0687 for_each_child_of_node(parent, np) {
0688 u32 idx;
0689
0690 error = of_property_read_u32(parent, "reg", &idx);
0691 if (error) {
0692 dev_err(pmu->dev,
0693 "%pOFn: failed to retrieve domain id (reg): %d\n",
0694 parent, error);
0695 goto err_out;
0696 }
0697 parent_domain = pmu->genpd_data.domains[idx];
0698
0699 error = rockchip_pm_add_one_domain(pmu, np);
0700 if (error) {
0701 dev_err(pmu->dev, "failed to handle node %pOFn: %d\n",
0702 np, error);
0703 goto err_out;
0704 }
0705
0706 error = of_property_read_u32(np, "reg", &idx);
0707 if (error) {
0708 dev_err(pmu->dev,
0709 "%pOFn: failed to retrieve domain id (reg): %d\n",
0710 np, error);
0711 goto err_out;
0712 }
0713 child_domain = pmu->genpd_data.domains[idx];
0714
0715 error = pm_genpd_add_subdomain(parent_domain, child_domain);
0716 if (error) {
0717 dev_err(pmu->dev, "%s failed to add subdomain %s: %d\n",
0718 parent_domain->name, child_domain->name, error);
0719 goto err_out;
0720 } else {
0721 dev_dbg(pmu->dev, "%s add subdomain: %s\n",
0722 parent_domain->name, child_domain->name);
0723 }
0724
0725 rockchip_pm_add_subdomain(pmu, np);
0726 }
0727
0728 return 0;
0729
0730 err_out:
0731 of_node_put(np);
0732 return error;
0733 }
0734
0735 static int rockchip_pm_domain_probe(struct platform_device *pdev)
0736 {
0737 struct device *dev = &pdev->dev;
0738 struct device_node *np = dev->of_node;
0739 struct device_node *node;
0740 struct device *parent;
0741 struct rockchip_pmu *pmu;
0742 const struct of_device_id *match;
0743 const struct rockchip_pmu_info *pmu_info;
0744 int error;
0745
0746 if (!np) {
0747 dev_err(dev, "device tree node not found\n");
0748 return -ENODEV;
0749 }
0750
0751 match = of_match_device(dev->driver->of_match_table, dev);
0752 if (!match || !match->data) {
0753 dev_err(dev, "missing pmu data\n");
0754 return -EINVAL;
0755 }
0756
0757 pmu_info = match->data;
0758
0759 pmu = devm_kzalloc(dev,
0760 struct_size(pmu, domains, pmu_info->num_domains),
0761 GFP_KERNEL);
0762 if (!pmu)
0763 return -ENOMEM;
0764
0765 pmu->dev = &pdev->dev;
0766 mutex_init(&pmu->mutex);
0767
0768 pmu->info = pmu_info;
0769
0770 pmu->genpd_data.domains = pmu->domains;
0771 pmu->genpd_data.num_domains = pmu_info->num_domains;
0772
0773 parent = dev->parent;
0774 if (!parent) {
0775 dev_err(dev, "no parent for syscon devices\n");
0776 return -ENODEV;
0777 }
0778
0779 pmu->regmap = syscon_node_to_regmap(parent->of_node);
0780 if (IS_ERR(pmu->regmap)) {
0781 dev_err(dev, "no regmap available\n");
0782 return PTR_ERR(pmu->regmap);
0783 }
0784
0785
0786
0787
0788
0789 if (pmu_info->core_power_transition_time)
0790 rockchip_configure_pd_cnt(pmu, pmu_info->core_pwrcnt_offset,
0791 pmu_info->core_power_transition_time);
0792 if (pmu_info->gpu_pwrcnt_offset)
0793 rockchip_configure_pd_cnt(pmu, pmu_info->gpu_pwrcnt_offset,
0794 pmu_info->gpu_power_transition_time);
0795
0796 error = -ENODEV;
0797
0798
0799
0800
0801
0802 mutex_lock(&dmc_pmu_mutex);
0803
0804 for_each_available_child_of_node(np, node) {
0805 error = rockchip_pm_add_one_domain(pmu, node);
0806 if (error) {
0807 dev_err(dev, "failed to handle node %pOFn: %d\n",
0808 node, error);
0809 of_node_put(node);
0810 goto err_out;
0811 }
0812
0813 error = rockchip_pm_add_subdomain(pmu, node);
0814 if (error < 0) {
0815 dev_err(dev, "failed to handle subdomain node %pOFn: %d\n",
0816 node, error);
0817 of_node_put(node);
0818 goto err_out;
0819 }
0820 }
0821
0822 if (error) {
0823 dev_dbg(dev, "no power domains defined\n");
0824 goto err_out;
0825 }
0826
0827 error = of_genpd_add_provider_onecell(np, &pmu->genpd_data);
0828 if (error) {
0829 dev_err(dev, "failed to add provider: %d\n", error);
0830 goto err_out;
0831 }
0832
0833
0834 if (!WARN_ON_ONCE(dmc_pmu))
0835 dmc_pmu = pmu;
0836
0837 mutex_unlock(&dmc_pmu_mutex);
0838
0839 return 0;
0840
0841 err_out:
0842 rockchip_pm_domain_cleanup(pmu);
0843 mutex_unlock(&dmc_pmu_mutex);
0844 return error;
0845 }
0846
0847 static const struct rockchip_domain_info px30_pm_domains[] = {
0848 [PX30_PD_USB] = DOMAIN_PX30("usb", BIT(5), BIT(5), BIT(10), false),
0849 [PX30_PD_SDCARD] = DOMAIN_PX30("sdcard", BIT(8), BIT(8), BIT(9), false),
0850 [PX30_PD_GMAC] = DOMAIN_PX30("gmac", BIT(10), BIT(10), BIT(6), false),
0851 [PX30_PD_MMC_NAND] = DOMAIN_PX30("mmc_nand", BIT(11), BIT(11), BIT(5), false),
0852 [PX30_PD_VPU] = DOMAIN_PX30("vpu", BIT(12), BIT(12), BIT(14), false),
0853 [PX30_PD_VO] = DOMAIN_PX30("vo", BIT(13), BIT(13), BIT(7), false),
0854 [PX30_PD_VI] = DOMAIN_PX30("vi", BIT(14), BIT(14), BIT(8), false),
0855 [PX30_PD_GPU] = DOMAIN_PX30("gpu", BIT(15), BIT(15), BIT(2), false),
0856 };
0857
0858 static const struct rockchip_domain_info rk3036_pm_domains[] = {
0859 [RK3036_PD_MSCH] = DOMAIN_RK3036("msch", BIT(14), BIT(23), BIT(30), true),
0860 [RK3036_PD_CORE] = DOMAIN_RK3036("core", BIT(13), BIT(17), BIT(24), false),
0861 [RK3036_PD_PERI] = DOMAIN_RK3036("peri", BIT(12), BIT(18), BIT(25), false),
0862 [RK3036_PD_VIO] = DOMAIN_RK3036("vio", BIT(11), BIT(19), BIT(26), false),
0863 [RK3036_PD_VPU] = DOMAIN_RK3036("vpu", BIT(10), BIT(20), BIT(27), false),
0864 [RK3036_PD_GPU] = DOMAIN_RK3036("gpu", BIT(9), BIT(21), BIT(28), false),
0865 [RK3036_PD_SYS] = DOMAIN_RK3036("sys", BIT(8), BIT(22), BIT(29), false),
0866 };
0867
0868 static const struct rockchip_domain_info rk3066_pm_domains[] = {
0869 [RK3066_PD_GPU] = DOMAIN("gpu", BIT(9), BIT(9), BIT(3), BIT(24), BIT(29), false),
0870 [RK3066_PD_VIDEO] = DOMAIN("video", BIT(8), BIT(8), BIT(4), BIT(23), BIT(28), false),
0871 [RK3066_PD_VIO] = DOMAIN("vio", BIT(7), BIT(7), BIT(5), BIT(22), BIT(27), false),
0872 [RK3066_PD_PERI] = DOMAIN("peri", BIT(6), BIT(6), BIT(2), BIT(25), BIT(30), false),
0873 [RK3066_PD_CPU] = DOMAIN("cpu", 0, BIT(5), BIT(1), BIT(26), BIT(31), false),
0874 };
0875
0876 static const struct rockchip_domain_info rk3128_pm_domains[] = {
0877 [RK3128_PD_CORE] = DOMAIN_RK3288("core", BIT(0), BIT(0), BIT(4), false),
0878 [RK3128_PD_MSCH] = DOMAIN_RK3288("msch", 0, 0, BIT(6), true),
0879 [RK3128_PD_VIO] = DOMAIN_RK3288("vio", BIT(3), BIT(3), BIT(2), false),
0880 [RK3128_PD_VIDEO] = DOMAIN_RK3288("video", BIT(2), BIT(2), BIT(1), false),
0881 [RK3128_PD_GPU] = DOMAIN_RK3288("gpu", BIT(1), BIT(1), BIT(3), false),
0882 };
0883
0884 static const struct rockchip_domain_info rk3188_pm_domains[] = {
0885 [RK3188_PD_GPU] = DOMAIN("gpu", BIT(9), BIT(9), BIT(3), BIT(24), BIT(29), false),
0886 [RK3188_PD_VIDEO] = DOMAIN("video", BIT(8), BIT(8), BIT(4), BIT(23), BIT(28), false),
0887 [RK3188_PD_VIO] = DOMAIN("vio", BIT(7), BIT(7), BIT(5), BIT(22), BIT(27), false),
0888 [RK3188_PD_PERI] = DOMAIN("peri", BIT(6), BIT(6), BIT(2), BIT(25), BIT(30), false),
0889 [RK3188_PD_CPU] = DOMAIN("cpu", BIT(5), BIT(5), BIT(1), BIT(26), BIT(31), false),
0890 };
0891
0892 static const struct rockchip_domain_info rk3228_pm_domains[] = {
0893 [RK3228_PD_CORE] = DOMAIN_RK3036("core", BIT(0), BIT(0), BIT(16), true),
0894 [RK3228_PD_MSCH] = DOMAIN_RK3036("msch", BIT(1), BIT(1), BIT(17), true),
0895 [RK3228_PD_BUS] = DOMAIN_RK3036("bus", BIT(2), BIT(2), BIT(18), true),
0896 [RK3228_PD_SYS] = DOMAIN_RK3036("sys", BIT(3), BIT(3), BIT(19), true),
0897 [RK3228_PD_VIO] = DOMAIN_RK3036("vio", BIT(4), BIT(4), BIT(20), false),
0898 [RK3228_PD_VOP] = DOMAIN_RK3036("vop", BIT(5), BIT(5), BIT(21), false),
0899 [RK3228_PD_VPU] = DOMAIN_RK3036("vpu", BIT(6), BIT(6), BIT(22), false),
0900 [RK3228_PD_RKVDEC] = DOMAIN_RK3036("vdec", BIT(7), BIT(7), BIT(23), false),
0901 [RK3228_PD_GPU] = DOMAIN_RK3036("gpu", BIT(8), BIT(8), BIT(24), false),
0902 [RK3228_PD_PERI] = DOMAIN_RK3036("peri", BIT(9), BIT(9), BIT(25), true),
0903 [RK3228_PD_GMAC] = DOMAIN_RK3036("gmac", BIT(10), BIT(10), BIT(26), false),
0904 };
0905
0906 static const struct rockchip_domain_info rk3288_pm_domains[] = {
0907 [RK3288_PD_VIO] = DOMAIN_RK3288("vio", BIT(7), BIT(7), BIT(4), false),
0908 [RK3288_PD_HEVC] = DOMAIN_RK3288("hevc", BIT(14), BIT(10), BIT(9), false),
0909 [RK3288_PD_VIDEO] = DOMAIN_RK3288("video", BIT(8), BIT(8), BIT(3), false),
0910 [RK3288_PD_GPU] = DOMAIN_RK3288("gpu", BIT(9), BIT(9), BIT(2), false),
0911 };
0912
0913 static const struct rockchip_domain_info rk3328_pm_domains[] = {
0914 [RK3328_PD_CORE] = DOMAIN_RK3328("core", 0, BIT(0), BIT(0), false),
0915 [RK3328_PD_GPU] = DOMAIN_RK3328("gpu", 0, BIT(1), BIT(1), false),
0916 [RK3328_PD_BUS] = DOMAIN_RK3328("bus", 0, BIT(2), BIT(2), true),
0917 [RK3328_PD_MSCH] = DOMAIN_RK3328("msch", 0, BIT(3), BIT(3), true),
0918 [RK3328_PD_PERI] = DOMAIN_RK3328("peri", 0, BIT(4), BIT(4), true),
0919 [RK3328_PD_VIDEO] = DOMAIN_RK3328("video", 0, BIT(5), BIT(5), false),
0920 [RK3328_PD_HEVC] = DOMAIN_RK3328("hevc", 0, BIT(6), BIT(6), false),
0921 [RK3328_PD_VIO] = DOMAIN_RK3328("vio", 0, BIT(8), BIT(8), false),
0922 [RK3328_PD_VPU] = DOMAIN_RK3328("vpu", 0, BIT(9), BIT(9), false),
0923 };
0924
0925 static const struct rockchip_domain_info rk3366_pm_domains[] = {
0926 [RK3366_PD_PERI] = DOMAIN_RK3368("peri", BIT(10), BIT(10), BIT(6), true),
0927 [RK3366_PD_VIO] = DOMAIN_RK3368("vio", BIT(14), BIT(14), BIT(8), false),
0928 [RK3366_PD_VIDEO] = DOMAIN_RK3368("video", BIT(13), BIT(13), BIT(7), false),
0929 [RK3366_PD_RKVDEC] = DOMAIN_RK3368("vdec", BIT(11), BIT(11), BIT(7), false),
0930 [RK3366_PD_WIFIBT] = DOMAIN_RK3368("wifibt", BIT(8), BIT(8), BIT(9), false),
0931 [RK3366_PD_VPU] = DOMAIN_RK3368("vpu", BIT(12), BIT(12), BIT(7), false),
0932 [RK3366_PD_GPU] = DOMAIN_RK3368("gpu", BIT(15), BIT(15), BIT(2), false),
0933 };
0934
0935 static const struct rockchip_domain_info rk3368_pm_domains[] = {
0936 [RK3368_PD_PERI] = DOMAIN_RK3368("peri", BIT(13), BIT(12), BIT(6), true),
0937 [RK3368_PD_VIO] = DOMAIN_RK3368("vio", BIT(15), BIT(14), BIT(8), false),
0938 [RK3368_PD_VIDEO] = DOMAIN_RK3368("video", BIT(14), BIT(13), BIT(7), false),
0939 [RK3368_PD_GPU_0] = DOMAIN_RK3368("gpu_0", BIT(16), BIT(15), BIT(2), false),
0940 [RK3368_PD_GPU_1] = DOMAIN_RK3368("gpu_1", BIT(17), BIT(16), BIT(2), false),
0941 };
0942
0943 static const struct rockchip_domain_info rk3399_pm_domains[] = {
0944 [RK3399_PD_TCPD0] = DOMAIN_RK3399("tcpd0", BIT(8), BIT(8), 0, false),
0945 [RK3399_PD_TCPD1] = DOMAIN_RK3399("tcpd1", BIT(9), BIT(9), 0, false),
0946 [RK3399_PD_CCI] = DOMAIN_RK3399("cci", BIT(10), BIT(10), 0, true),
0947 [RK3399_PD_CCI0] = DOMAIN_RK3399("cci0", 0, 0, BIT(15), true),
0948 [RK3399_PD_CCI1] = DOMAIN_RK3399("cci1", 0, 0, BIT(16), true),
0949 [RK3399_PD_PERILP] = DOMAIN_RK3399("perilp", BIT(11), BIT(11), BIT(1), true),
0950 [RK3399_PD_PERIHP] = DOMAIN_RK3399("perihp", BIT(12), BIT(12), BIT(2), true),
0951 [RK3399_PD_CENTER] = DOMAIN_RK3399("center", BIT(13), BIT(13), BIT(14), true),
0952 [RK3399_PD_VIO] = DOMAIN_RK3399("vio", BIT(14), BIT(14), BIT(17), false),
0953 [RK3399_PD_GPU] = DOMAIN_RK3399("gpu", BIT(15), BIT(15), BIT(0), false),
0954 [RK3399_PD_VCODEC] = DOMAIN_RK3399("vcodec", BIT(16), BIT(16), BIT(3), false),
0955 [RK3399_PD_VDU] = DOMAIN_RK3399("vdu", BIT(17), BIT(17), BIT(4), false),
0956 [RK3399_PD_RGA] = DOMAIN_RK3399("rga", BIT(18), BIT(18), BIT(5), false),
0957 [RK3399_PD_IEP] = DOMAIN_RK3399("iep", BIT(19), BIT(19), BIT(6), false),
0958 [RK3399_PD_VO] = DOMAIN_RK3399("vo", BIT(20), BIT(20), 0, false),
0959 [RK3399_PD_VOPB] = DOMAIN_RK3399("vopb", 0, 0, BIT(7), false),
0960 [RK3399_PD_VOPL] = DOMAIN_RK3399("vopl", 0, 0, BIT(8), false),
0961 [RK3399_PD_ISP0] = DOMAIN_RK3399("isp0", BIT(22), BIT(22), BIT(9), false),
0962 [RK3399_PD_ISP1] = DOMAIN_RK3399("isp1", BIT(23), BIT(23), BIT(10), false),
0963 [RK3399_PD_HDCP] = DOMAIN_RK3399("hdcp", BIT(24), BIT(24), BIT(11), false),
0964 [RK3399_PD_GMAC] = DOMAIN_RK3399("gmac", BIT(25), BIT(25), BIT(23), true),
0965 [RK3399_PD_EMMC] = DOMAIN_RK3399("emmc", BIT(26), BIT(26), BIT(24), true),
0966 [RK3399_PD_USB3] = DOMAIN_RK3399("usb3", BIT(27), BIT(27), BIT(12), true),
0967 [RK3399_PD_EDP] = DOMAIN_RK3399("edp", BIT(28), BIT(28), BIT(22), false),
0968 [RK3399_PD_GIC] = DOMAIN_RK3399("gic", BIT(29), BIT(29), BIT(27), true),
0969 [RK3399_PD_SD] = DOMAIN_RK3399("sd", BIT(30), BIT(30), BIT(28), true),
0970 [RK3399_PD_SDIOAUDIO] = DOMAIN_RK3399("sdioaudio", BIT(31), BIT(31), BIT(29), true),
0971 };
0972
0973 static const struct rockchip_domain_info rk3568_pm_domains[] = {
0974 [RK3568_PD_NPU] = DOMAIN_RK3568("npu", BIT(1), BIT(2), false),
0975 [RK3568_PD_GPU] = DOMAIN_RK3568("gpu", BIT(0), BIT(1), false),
0976 [RK3568_PD_VI] = DOMAIN_RK3568("vi", BIT(6), BIT(3), false),
0977 [RK3568_PD_VO] = DOMAIN_RK3568("vo", BIT(7), BIT(4), false),
0978 [RK3568_PD_RGA] = DOMAIN_RK3568("rga", BIT(5), BIT(5), false),
0979 [RK3568_PD_VPU] = DOMAIN_RK3568("vpu", BIT(2), BIT(6), false),
0980 [RK3568_PD_RKVDEC] = DOMAIN_RK3568("vdec", BIT(4), BIT(8), false),
0981 [RK3568_PD_RKVENC] = DOMAIN_RK3568("venc", BIT(3), BIT(7), false),
0982 [RK3568_PD_PIPE] = DOMAIN_RK3568("pipe", BIT(8), BIT(11), false),
0983 };
0984
0985 static const struct rockchip_pmu_info px30_pmu = {
0986 .pwr_offset = 0x18,
0987 .status_offset = 0x20,
0988 .req_offset = 0x64,
0989 .idle_offset = 0x6c,
0990 .ack_offset = 0x6c,
0991
0992 .num_domains = ARRAY_SIZE(px30_pm_domains),
0993 .domain_info = px30_pm_domains,
0994 };
0995
0996 static const struct rockchip_pmu_info rk3036_pmu = {
0997 .req_offset = 0x148,
0998 .idle_offset = 0x14c,
0999 .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,
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,
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,
1058 .gpu_power_transition_time = 24,
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
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 { },
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
1190
1191
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);