1 // SPDX-License-Identifier: GPL-2.0+ 2 3 /* 4 * Copyright 2021 Pengutronix, Lucas Stach <kernel@pengutronix.de> 5 */ 6 7 #include <linux/bitfield.h> 8 #include <linux/device.h> 9 #include <linux/interconnect.h> 10 #include <linux/module.h> 11 #include <linux/of.h> 12 #include <linux/of_platform.h> 13 #include <linux/platform_device.h> 14 #include <linux/pm_domain.h> 15 #include <linux/pm_runtime.h> 16 #include <linux/regmap.h> 17 #include <linux/clk.h> 18 #include <linux/mutex.h> 19 20 #include <dt-bindings/power/imx8mm-power.h> 21 #include <dt-bindings/power/imx8mn-power.h> 22 #include <dt-bindings/power/imx8mp-power.h> 23 #include <dt-bindings/power/imx8mq-power.h> 24 25 #define BLK_SFT_RSTN 0x0 26 #define BLK_CLK_EN 0x4 27 #define BLK_MIPI_RESET_DIV 0x8 /* Mini/Nano/Plus DISPLAY_BLK_CTRL only */ 28 29 struct imx8m_blk_ctrl_domain; 30 31 struct imx8m_blk_ctrl { 32 struct device *dev; 33 struct notifier_block power_nb; 34 struct device *bus_power_dev; 35 struct regmap *regmap; 36 struct imx8m_blk_ctrl_domain *domains; 37 struct genpd_onecell_data onecell_data; 38 /* 39 * Serializes the blk-ctrl reset/clock sequence across sibling domains; 40 * their transitions interact through the shared VPUMIX bus domain, 41 * VPU_NOC and the not-ack-verified ADB400 handshake (ERR050531). 42 */ 43 struct mutex power_lock; 44 }; 45 46 struct imx8m_blk_ctrl_domain_data { 47 const char *name; 48 const char * const *clk_names; 49 const char * const *path_names; 50 const char *gpc_name; 51 int num_clks; 52 int num_paths; 53 u32 rst_mask; 54 u32 clk_mask; 55 56 /* 57 * i.MX8M Mini, Nano and Plus have a third DISPLAY_BLK_CTRL register 58 * which is used to control the reset for the MIPI Phy. 59 * Since it's only present in certain circumstances, 60 * an if-statement should be used before setting and clearing this 61 * register. 62 */ 63 u32 mipi_phy_rst_mask; 64 65 /* 66 * VC8000E reset de-assertion edge and AXI clock may have a timing issue. 67 * Workaround: Set bit2 (vc8000e_clk_en) of BLK_CLK_EN_CSR to 0 to gate off 68 * both AXI clock and VC8000E clock sent to VC8000E and AXI clock sent to 69 * VPU_NOC m_v_2 interface during VC8000E power up(VC8000E reset is 70 * de-asserted by HW) 71 */ 72 bool is_errata_err050531; 73 }; 74 75 #define DOMAIN_MAX_CLKS 4 76 #define DOMAIN_MAX_PATHS 4 77 78 struct imx8m_blk_ctrl_domain { 79 struct generic_pm_domain genpd; 80 const struct imx8m_blk_ctrl_domain_data *data; 81 struct clk_bulk_data clks[DOMAIN_MAX_CLKS]; 82 struct icc_bulk_data paths[DOMAIN_MAX_PATHS]; 83 struct device *power_dev; 84 struct imx8m_blk_ctrl *bc; 85 int num_paths; 86 }; 87 88 struct imx8m_blk_ctrl_data { 89 int max_reg; 90 notifier_fn_t power_notifier_fn; 91 const struct imx8m_blk_ctrl_domain_data *domains; 92 int num_domains; 93 }; 94 95 static inline struct imx8m_blk_ctrl_domain * 96 to_imx8m_blk_ctrl_domain(struct generic_pm_domain *genpd) 97 { 98 return container_of(genpd, struct imx8m_blk_ctrl_domain, genpd); 99 } 100 101 static int imx8m_blk_ctrl_power_on(struct generic_pm_domain *genpd) 102 { 103 struct imx8m_blk_ctrl_domain *domain = to_imx8m_blk_ctrl_domain(genpd); 104 const struct imx8m_blk_ctrl_domain_data *data = domain->data; 105 struct imx8m_blk_ctrl *bc = domain->bc; 106 int ret; 107 108 guard(mutex)(&bc->power_lock); 109 110 /* make sure bus domain is awake */ 111 ret = pm_runtime_resume_and_get(bc->bus_power_dev); 112 if (ret < 0) { 113 dev_err(bc->dev, "failed to power up bus domain\n"); 114 return ret; 115 } 116 117 /* put devices into reset */ 118 regmap_clear_bits(bc->regmap, BLK_SFT_RSTN, data->rst_mask); 119 if (data->mipi_phy_rst_mask) 120 regmap_clear_bits(bc->regmap, BLK_MIPI_RESET_DIV, data->mipi_phy_rst_mask); 121 122 /* enable upstream and blk-ctrl clocks to allow reset to propagate */ 123 ret = clk_bulk_prepare_enable(data->num_clks, domain->clks); 124 if (ret) { 125 dev_err(bc->dev, "failed to enable clocks\n"); 126 goto bus_put; 127 } 128 129 if (data->is_errata_err050531) 130 regmap_clear_bits(bc->regmap, BLK_CLK_EN, data->clk_mask); 131 else 132 regmap_set_bits(bc->regmap, BLK_CLK_EN, data->clk_mask); 133 134 /* power up upstream GPC domain */ 135 ret = pm_runtime_get_sync(domain->power_dev); 136 if (ret < 0) { 137 dev_err(bc->dev, "failed to power up peripheral domain\n"); 138 goto clk_disable; 139 } 140 141 if (data->is_errata_err050531) 142 regmap_set_bits(bc->regmap, BLK_CLK_EN, data->clk_mask); 143 144 /* wait for reset to propagate */ 145 udelay(5); 146 147 /* release reset */ 148 regmap_set_bits(bc->regmap, BLK_SFT_RSTN, data->rst_mask); 149 if (data->mipi_phy_rst_mask) 150 regmap_set_bits(bc->regmap, BLK_MIPI_RESET_DIV, data->mipi_phy_rst_mask); 151 152 ret = icc_bulk_set_bw(domain->num_paths, domain->paths); 153 if (ret) 154 dev_err(bc->dev, "failed to set icc bw\n"); 155 156 /* disable upstream clocks */ 157 clk_bulk_disable_unprepare(data->num_clks, domain->clks); 158 159 return 0; 160 161 clk_disable: 162 clk_bulk_disable_unprepare(data->num_clks, domain->clks); 163 bus_put: 164 pm_runtime_put(bc->bus_power_dev); 165 166 return ret; 167 } 168 169 static int imx8m_blk_ctrl_power_off(struct generic_pm_domain *genpd) 170 { 171 struct imx8m_blk_ctrl_domain *domain = to_imx8m_blk_ctrl_domain(genpd); 172 const struct imx8m_blk_ctrl_domain_data *data = domain->data; 173 struct imx8m_blk_ctrl *bc = domain->bc; 174 175 guard(mutex)(&bc->power_lock); 176 177 /* put devices into reset and disable clocks */ 178 if (data->mipi_phy_rst_mask) 179 regmap_clear_bits(bc->regmap, BLK_MIPI_RESET_DIV, data->mipi_phy_rst_mask); 180 181 regmap_clear_bits(bc->regmap, BLK_SFT_RSTN, data->rst_mask); 182 regmap_clear_bits(bc->regmap, BLK_CLK_EN, data->clk_mask); 183 184 /* power down upstream GPC domain */ 185 pm_runtime_put(domain->power_dev); 186 187 /* allow bus domain to suspend */ 188 pm_runtime_put(bc->bus_power_dev); 189 190 return 0; 191 } 192 193 static struct lock_class_key blk_ctrl_genpd_lock_class; 194 195 static int imx8m_blk_ctrl_probe(struct platform_device *pdev) 196 { 197 const struct imx8m_blk_ctrl_data *bc_data; 198 struct device *dev = &pdev->dev; 199 struct imx8m_blk_ctrl *bc; 200 void __iomem *base; 201 int i, ret; 202 203 struct regmap_config regmap_config = { 204 .reg_bits = 32, 205 .val_bits = 32, 206 .reg_stride = 4, 207 }; 208 209 bc = devm_kzalloc(dev, sizeof(*bc), GFP_KERNEL); 210 if (!bc) 211 return -ENOMEM; 212 213 bc->dev = dev; 214 215 ret = devm_mutex_init(dev, &bc->power_lock); 216 if (ret) 217 return ret; 218 219 bc_data = of_device_get_match_data(dev); 220 221 base = devm_platform_ioremap_resource(pdev, 0); 222 if (IS_ERR(base)) 223 return PTR_ERR(base); 224 225 regmap_config.max_register = bc_data->max_reg; 226 bc->regmap = devm_regmap_init_mmio(dev, base, ®map_config); 227 if (IS_ERR(bc->regmap)) 228 return dev_err_probe(dev, PTR_ERR(bc->regmap), 229 "failed to init regmap\n"); 230 231 bc->domains = devm_kcalloc(dev, bc_data->num_domains, 232 sizeof(struct imx8m_blk_ctrl_domain), 233 GFP_KERNEL); 234 if (!bc->domains) 235 return -ENOMEM; 236 237 bc->onecell_data.num_domains = bc_data->num_domains; 238 bc->onecell_data.domains = 239 devm_kcalloc(dev, bc_data->num_domains, 240 sizeof(struct generic_pm_domain *), GFP_KERNEL); 241 if (!bc->onecell_data.domains) 242 return -ENOMEM; 243 244 bc->bus_power_dev = dev_pm_domain_attach_by_name(dev, "bus"); 245 if (IS_ERR(bc->bus_power_dev)) { 246 if (PTR_ERR(bc->bus_power_dev) == -ENODEV) 247 return dev_err_probe(dev, -EPROBE_DEFER, 248 "failed to attach power domain \"bus\"\n"); 249 else 250 return dev_err_probe(dev, PTR_ERR(bc->bus_power_dev), 251 "failed to attach power domain \"bus\"\n"); 252 } 253 254 for (i = 0; i < bc_data->num_domains; i++) { 255 const struct imx8m_blk_ctrl_domain_data *data = &bc_data->domains[i]; 256 struct imx8m_blk_ctrl_domain *domain = &bc->domains[i]; 257 int j; 258 259 domain->data = data; 260 domain->num_paths = data->num_paths; 261 262 for (j = 0; j < data->num_clks; j++) 263 domain->clks[j].id = data->clk_names[j]; 264 265 for (j = 0; j < data->num_paths; j++) { 266 domain->paths[j].name = data->path_names[j]; 267 /* Fake value for now, just let ICC could configure NoC mode/priority */ 268 domain->paths[j].avg_bw = 1; 269 domain->paths[j].peak_bw = 1; 270 } 271 272 ret = devm_of_icc_bulk_get(dev, data->num_paths, domain->paths); 273 if (ret) { 274 if (ret != -EPROBE_DEFER) { 275 dev_warn_once(dev, "Could not get interconnect paths, NoC will stay unconfigured!\n"); 276 domain->num_paths = 0; 277 } else { 278 dev_err_probe(dev, ret, "failed to get noc entries\n"); 279 goto cleanup_pds; 280 } 281 } 282 283 ret = devm_clk_bulk_get(dev, data->num_clks, domain->clks); 284 if (ret) { 285 dev_err_probe(dev, ret, "failed to get clock\n"); 286 goto cleanup_pds; 287 } 288 289 domain->power_dev = 290 dev_pm_domain_attach_by_name(dev, data->gpc_name); 291 if (IS_ERR_OR_NULL(domain->power_dev)) { 292 if (!domain->power_dev) 293 ret = -ENODEV; 294 else 295 ret = PTR_ERR(domain->power_dev); 296 dev_err_probe(dev, ret, 297 "failed to attach power domain \"%s\"\n", 298 data->gpc_name); 299 goto cleanup_pds; 300 } 301 302 domain->genpd.name = data->name; 303 domain->genpd.power_on = imx8m_blk_ctrl_power_on; 304 domain->genpd.power_off = imx8m_blk_ctrl_power_off; 305 domain->bc = bc; 306 307 ret = pm_genpd_init(&domain->genpd, NULL, true); 308 if (ret) { 309 dev_err_probe(dev, ret, 310 "failed to init power domain \"%s\"\n", 311 data->gpc_name); 312 dev_pm_domain_detach(domain->power_dev, true); 313 goto cleanup_pds; 314 } 315 316 /* 317 * We use runtime PM to trigger power on/off of the upstream GPC 318 * domain, as a strict hierarchical parent/child power domain 319 * setup doesn't allow us to meet the sequencing requirements. 320 * This means we have nested locking of genpd locks, without the 321 * nesting being visible at the genpd level, so we need a 322 * separate lock class to make lockdep aware of the fact that 323 * this are separate domain locks that can be nested without a 324 * self-deadlock. 325 */ 326 lockdep_set_class(&domain->genpd.mlock, 327 &blk_ctrl_genpd_lock_class); 328 329 bc->onecell_data.domains[i] = &domain->genpd; 330 } 331 332 ret = of_genpd_add_provider_onecell(dev->of_node, &bc->onecell_data); 333 if (ret) { 334 dev_err_probe(dev, ret, "failed to add power domain provider\n"); 335 goto cleanup_pds; 336 } 337 338 bc->power_nb.notifier_call = bc_data->power_notifier_fn; 339 ret = dev_pm_genpd_add_notifier(bc->bus_power_dev, &bc->power_nb); 340 if (ret) { 341 dev_err_probe(dev, ret, "failed to add power notifier\n"); 342 goto cleanup_provider; 343 } 344 345 dev_set_drvdata(dev, bc); 346 347 ret = devm_of_platform_populate(dev); 348 if (ret) 349 goto cleanup_provider; 350 351 return 0; 352 353 cleanup_provider: 354 of_genpd_del_provider(dev->of_node); 355 cleanup_pds: 356 for (i--; i >= 0; i--) { 357 pm_genpd_remove(&bc->domains[i].genpd); 358 dev_pm_domain_detach(bc->domains[i].power_dev, true); 359 } 360 361 dev_pm_domain_detach(bc->bus_power_dev, true); 362 363 return ret; 364 } 365 366 static void imx8m_blk_ctrl_remove(struct platform_device *pdev) 367 { 368 struct imx8m_blk_ctrl *bc = dev_get_drvdata(&pdev->dev); 369 int i; 370 371 of_genpd_del_provider(pdev->dev.of_node); 372 373 for (i = 0; i < bc->onecell_data.num_domains; i++) { 374 struct imx8m_blk_ctrl_domain *domain = &bc->domains[i]; 375 376 pm_genpd_remove(&domain->genpd); 377 dev_pm_domain_detach(domain->power_dev, true); 378 } 379 380 dev_pm_genpd_remove_notifier(bc->bus_power_dev); 381 382 dev_pm_domain_detach(bc->bus_power_dev, true); 383 } 384 385 #ifdef CONFIG_PM_SLEEP 386 static int imx8m_blk_ctrl_suspend(struct device *dev) 387 { 388 struct imx8m_blk_ctrl *bc = dev_get_drvdata(dev); 389 int ret, i; 390 391 /* 392 * This may look strange, but is done so the generic PM_SLEEP code 393 * can power down our domains and more importantly power them up again 394 * after resume, without tripping over our usage of runtime PM to 395 * control the upstream GPC domains. Things happen in the right order 396 * in the system suspend/resume paths due to the device parent/child 397 * hierarchy. 398 */ 399 ret = pm_runtime_resume_and_get(bc->bus_power_dev); 400 if (ret < 0) 401 return ret; 402 403 for (i = 0; i < bc->onecell_data.num_domains; i++) { 404 struct imx8m_blk_ctrl_domain *domain = &bc->domains[i]; 405 406 ret = pm_runtime_resume_and_get(domain->power_dev); 407 if (ret < 0) 408 goto out_fail; 409 } 410 411 return 0; 412 413 out_fail: 414 for (i--; i >= 0; i--) 415 pm_runtime_put(bc->domains[i].power_dev); 416 417 pm_runtime_put(bc->bus_power_dev); 418 419 return ret; 420 } 421 422 static int imx8m_blk_ctrl_resume(struct device *dev) 423 { 424 struct imx8m_blk_ctrl *bc = dev_get_drvdata(dev); 425 int i; 426 427 for (i = 0; i < bc->onecell_data.num_domains; i++) 428 pm_runtime_put(bc->domains[i].power_dev); 429 430 pm_runtime_put(bc->bus_power_dev); 431 432 return 0; 433 } 434 #endif 435 436 static const struct dev_pm_ops imx8m_blk_ctrl_pm_ops = { 437 SET_SYSTEM_SLEEP_PM_OPS(imx8m_blk_ctrl_suspend, imx8m_blk_ctrl_resume) 438 }; 439 440 static int imx8mm_vpu_power_notifier(struct notifier_block *nb, 441 unsigned long action, void *data) 442 { 443 struct imx8m_blk_ctrl *bc = container_of(nb, struct imx8m_blk_ctrl, 444 power_nb); 445 446 if (action != GENPD_NOTIFY_ON && action != GENPD_NOTIFY_PRE_OFF) 447 return NOTIFY_OK; 448 449 /* 450 * The ADB in the VPUMIX domain has no separate reset and clock 451 * enable bits, but is ungated together with the VPU clocks. To 452 * allow the handshake with the GPC to progress we put the VPUs 453 * in reset and ungate the clocks. 454 */ 455 regmap_clear_bits(bc->regmap, BLK_SFT_RSTN, BIT(0) | BIT(1) | BIT(2)); 456 regmap_set_bits(bc->regmap, BLK_CLK_EN, BIT(0) | BIT(1) | BIT(2)); 457 458 if (action == GENPD_NOTIFY_ON) { 459 /* 460 * On power up we have no software backchannel to the GPC to 461 * wait for the ADB handshake to happen, so we just delay for a 462 * bit. On power down the GPC driver waits for the handshake. 463 */ 464 udelay(5); 465 466 /* set "fuse" bits to enable the VPUs */ 467 regmap_set_bits(bc->regmap, 0x8, 0xffffffff); 468 regmap_set_bits(bc->regmap, 0xc, 0xffffffff); 469 regmap_set_bits(bc->regmap, 0x10, 0xffffffff); 470 regmap_set_bits(bc->regmap, 0x14, 0xffffffff); 471 } 472 473 return NOTIFY_OK; 474 } 475 476 static const struct imx8m_blk_ctrl_domain_data imx8mm_vpu_blk_ctl_domain_data[] = { 477 [IMX8MM_VPUBLK_PD_G1] = { 478 .name = "vpublk-g1", 479 .clk_names = (const char *[]){ "g1", }, 480 .num_clks = 1, 481 .gpc_name = "g1", 482 .rst_mask = BIT(1), 483 .clk_mask = BIT(1), 484 }, 485 [IMX8MM_VPUBLK_PD_G2] = { 486 .name = "vpublk-g2", 487 .clk_names = (const char *[]){ "g2", }, 488 .num_clks = 1, 489 .gpc_name = "g2", 490 .rst_mask = BIT(0), 491 .clk_mask = BIT(0), 492 }, 493 [IMX8MM_VPUBLK_PD_H1] = { 494 .name = "vpublk-h1", 495 .clk_names = (const char *[]){ "h1", }, 496 .num_clks = 1, 497 .gpc_name = "h1", 498 .rst_mask = BIT(2), 499 .clk_mask = BIT(2), 500 }, 501 }; 502 503 static const struct imx8m_blk_ctrl_data imx8mm_vpu_blk_ctl_dev_data = { 504 .max_reg = 0x18, 505 .power_notifier_fn = imx8mm_vpu_power_notifier, 506 .domains = imx8mm_vpu_blk_ctl_domain_data, 507 .num_domains = ARRAY_SIZE(imx8mm_vpu_blk_ctl_domain_data), 508 }; 509 510 static const struct imx8m_blk_ctrl_domain_data imx8mp_vpu_blk_ctl_domain_data[] = { 511 [IMX8MP_VPUBLK_PD_G1] = { 512 .name = "vpublk-g1", 513 .clk_names = (const char *[]){ "g1", }, 514 .num_clks = 1, 515 .gpc_name = "g1", 516 .rst_mask = BIT(1), 517 .clk_mask = BIT(1), 518 .path_names = (const char *[]){"g1"}, 519 .num_paths = 1, 520 }, 521 [IMX8MP_VPUBLK_PD_G2] = { 522 .name = "vpublk-g2", 523 .clk_names = (const char *[]){ "g2", }, 524 .num_clks = 1, 525 .gpc_name = "g2", 526 .rst_mask = BIT(0), 527 .clk_mask = BIT(0), 528 .path_names = (const char *[]){"g2"}, 529 .num_paths = 1, 530 }, 531 [IMX8MP_VPUBLK_PD_VC8000E] = { 532 .name = "vpublk-vc8000e", 533 .clk_names = (const char *[]){ "vc8000e", }, 534 .num_clks = 1, 535 .gpc_name = "vc8000e", 536 .rst_mask = BIT(2), 537 .clk_mask = BIT(2), 538 .path_names = (const char *[]){"vc8000e"}, 539 .num_paths = 1, 540 .is_errata_err050531 = true, 541 }, 542 }; 543 544 static int imx8mp_vpu_power_notifier(struct notifier_block *nb, 545 unsigned long action, void *data) 546 { 547 struct imx8m_blk_ctrl *bc = container_of(nb, struct imx8m_blk_ctrl, 548 power_nb); 549 550 if (action == GENPD_NOTIFY_ON) { 551 /* 552 * On power up we have no software backchannel to the GPC to 553 * wait for the ADB handshake to happen, so we just delay for a 554 * bit. On power down the GPC driver waits for the handshake. 555 */ 556 557 udelay(5); 558 559 /* set "fuse" bits to enable the VPUs */ 560 regmap_set_bits(bc->regmap, 0x8, 0xffffffff); 561 regmap_set_bits(bc->regmap, 0xc, 0xffffffff); 562 regmap_set_bits(bc->regmap, 0x10, 0xffffffff); 563 regmap_set_bits(bc->regmap, 0x14, 0xffffffff); 564 } 565 566 return NOTIFY_OK; 567 } 568 569 static const struct imx8m_blk_ctrl_data imx8mp_vpu_blk_ctl_dev_data = { 570 .max_reg = 0x18, 571 .power_notifier_fn = imx8mp_vpu_power_notifier, 572 .domains = imx8mp_vpu_blk_ctl_domain_data, 573 .num_domains = ARRAY_SIZE(imx8mp_vpu_blk_ctl_domain_data), 574 }; 575 576 static int imx8mm_disp_power_notifier(struct notifier_block *nb, 577 unsigned long action, void *data) 578 { 579 struct imx8m_blk_ctrl *bc = container_of(nb, struct imx8m_blk_ctrl, 580 power_nb); 581 582 if (action != GENPD_NOTIFY_ON && action != GENPD_NOTIFY_PRE_OFF) 583 return NOTIFY_OK; 584 585 /* Enable bus clock and deassert bus reset */ 586 regmap_set_bits(bc->regmap, BLK_CLK_EN, BIT(12)); 587 regmap_set_bits(bc->regmap, BLK_SFT_RSTN, BIT(6)); 588 589 /* 590 * On power up we have no software backchannel to the GPC to 591 * wait for the ADB handshake to happen, so we just delay for a 592 * bit. On power down the GPC driver waits for the handshake. 593 */ 594 if (action == GENPD_NOTIFY_ON) 595 udelay(5); 596 597 598 return NOTIFY_OK; 599 } 600 601 static const struct imx8m_blk_ctrl_domain_data imx8mm_disp_blk_ctl_domain_data[] = { 602 [IMX8MM_DISPBLK_PD_CSI_BRIDGE] = { 603 .name = "dispblk-csi-bridge", 604 .clk_names = (const char *[]){ "csi-bridge-axi", "csi-bridge-apb", 605 "csi-bridge-core", }, 606 .num_clks = 3, 607 .gpc_name = "csi-bridge", 608 .rst_mask = BIT(0) | BIT(1) | BIT(2), 609 .clk_mask = BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5), 610 }, 611 [IMX8MM_DISPBLK_PD_LCDIF] = { 612 .name = "dispblk-lcdif", 613 .clk_names = (const char *[]){ "lcdif-axi", "lcdif-apb", "lcdif-pix", }, 614 .num_clks = 3, 615 .gpc_name = "lcdif", 616 .clk_mask = BIT(6) | BIT(7), 617 }, 618 [IMX8MM_DISPBLK_PD_MIPI_DSI] = { 619 .name = "dispblk-mipi-dsi", 620 .clk_names = (const char *[]){ "dsi-pclk", "dsi-ref", }, 621 .num_clks = 2, 622 .gpc_name = "mipi-dsi", 623 .rst_mask = BIT(5), 624 .clk_mask = BIT(8) | BIT(9), 625 .mipi_phy_rst_mask = BIT(17), 626 }, 627 [IMX8MM_DISPBLK_PD_MIPI_CSI] = { 628 .name = "dispblk-mipi-csi", 629 .clk_names = (const char *[]){ "csi-aclk", "csi-pclk" }, 630 .num_clks = 2, 631 .gpc_name = "mipi-csi", 632 .rst_mask = BIT(3) | BIT(4), 633 .clk_mask = BIT(10) | BIT(11), 634 .mipi_phy_rst_mask = BIT(16), 635 }, 636 }; 637 638 static const struct imx8m_blk_ctrl_data imx8mm_disp_blk_ctl_dev_data = { 639 .max_reg = 0x2c, 640 .power_notifier_fn = imx8mm_disp_power_notifier, 641 .domains = imx8mm_disp_blk_ctl_domain_data, 642 .num_domains = ARRAY_SIZE(imx8mm_disp_blk_ctl_domain_data), 643 }; 644 645 646 static int imx8mn_disp_power_notifier(struct notifier_block *nb, 647 unsigned long action, void *data) 648 { 649 struct imx8m_blk_ctrl *bc = container_of(nb, struct imx8m_blk_ctrl, 650 power_nb); 651 652 if (action != GENPD_NOTIFY_ON && action != GENPD_NOTIFY_PRE_OFF) 653 return NOTIFY_OK; 654 655 /* Enable bus clock and deassert bus reset */ 656 regmap_set_bits(bc->regmap, BLK_CLK_EN, BIT(8)); 657 regmap_set_bits(bc->regmap, BLK_SFT_RSTN, BIT(8)); 658 659 /* 660 * On power up we have no software backchannel to the GPC to 661 * wait for the ADB handshake to happen, so we just delay for a 662 * bit. On power down the GPC driver waits for the handshake. 663 */ 664 if (action == GENPD_NOTIFY_ON) 665 udelay(5); 666 667 668 return NOTIFY_OK; 669 } 670 671 static const struct imx8m_blk_ctrl_domain_data imx8mn_disp_blk_ctl_domain_data[] = { 672 [IMX8MN_DISPBLK_PD_MIPI_DSI] = { 673 .name = "dispblk-mipi-dsi", 674 .clk_names = (const char *[]){ "dsi-pclk", "dsi-ref", }, 675 .num_clks = 2, 676 .gpc_name = "mipi-dsi", 677 .rst_mask = BIT(0) | BIT(1), 678 .clk_mask = BIT(0) | BIT(1), 679 .mipi_phy_rst_mask = BIT(17), 680 }, 681 [IMX8MN_DISPBLK_PD_MIPI_CSI] = { 682 .name = "dispblk-mipi-csi", 683 .clk_names = (const char *[]){ "csi-aclk", "csi-pclk" }, 684 .num_clks = 2, 685 .gpc_name = "mipi-csi", 686 .rst_mask = BIT(2) | BIT(3), 687 .clk_mask = BIT(2) | BIT(3), 688 .mipi_phy_rst_mask = BIT(16), 689 }, 690 [IMX8MN_DISPBLK_PD_LCDIF] = { 691 .name = "dispblk-lcdif", 692 .clk_names = (const char *[]){ "lcdif-axi", "lcdif-apb", "lcdif-pix", }, 693 .num_clks = 3, 694 .gpc_name = "lcdif", 695 .rst_mask = BIT(4) | BIT(5), 696 .clk_mask = BIT(4) | BIT(5), 697 }, 698 [IMX8MN_DISPBLK_PD_ISI] = { 699 .name = "dispblk-isi", 700 .clk_names = (const char *[]){ "disp_axi", "disp_apb", "disp_axi_root", 701 "disp_apb_root"}, 702 .num_clks = 4, 703 .gpc_name = "isi", 704 .rst_mask = BIT(6) | BIT(7), 705 .clk_mask = BIT(6) | BIT(7), 706 }, 707 }; 708 709 static const struct imx8m_blk_ctrl_data imx8mn_disp_blk_ctl_dev_data = { 710 .max_reg = 0x84, 711 .power_notifier_fn = imx8mn_disp_power_notifier, 712 .domains = imx8mn_disp_blk_ctl_domain_data, 713 .num_domains = ARRAY_SIZE(imx8mn_disp_blk_ctl_domain_data), 714 }; 715 716 #define LCDIF_ARCACHE_CTRL 0x4c 717 #define LCDIF_1_RD_HURRY GENMASK(15, 13) 718 #define LCDIF_0_RD_HURRY GENMASK(12, 10) 719 720 #define ISI_CACHE_CTRL 0x50 721 #define ISI_V_WR_HURRY GENMASK(28, 26) 722 #define ISI_U_WR_HURRY GENMASK(25, 23) 723 #define ISI_Y_WR_HURRY GENMASK(22, 20) 724 725 static int imx8mp_media_power_notifier(struct notifier_block *nb, 726 unsigned long action, void *data) 727 { 728 struct imx8m_blk_ctrl *bc = container_of(nb, struct imx8m_blk_ctrl, 729 power_nb); 730 731 if (action != GENPD_NOTIFY_ON && action != GENPD_NOTIFY_PRE_OFF) 732 return NOTIFY_OK; 733 734 /* Enable bus clock and deassert bus reset */ 735 regmap_set_bits(bc->regmap, BLK_CLK_EN, BIT(8)); 736 regmap_set_bits(bc->regmap, BLK_SFT_RSTN, BIT(8)); 737 738 if (action == GENPD_NOTIFY_ON) { 739 /* 740 * On power up we have no software backchannel to the GPC to 741 * wait for the ADB handshake to happen, so we just delay for a 742 * bit. On power down the GPC driver waits for the handshake. 743 */ 744 udelay(5); 745 746 /* 747 * Set panic read hurry level for both LCDIF interfaces to 748 * maximum priority to minimize chances of display FIFO 749 * underflow. 750 */ 751 regmap_set_bits(bc->regmap, LCDIF_ARCACHE_CTRL, 752 FIELD_PREP(LCDIF_1_RD_HURRY, 7) | 753 FIELD_PREP(LCDIF_0_RD_HURRY, 7)); 754 /* Same here for ISI */ 755 regmap_set_bits(bc->regmap, ISI_CACHE_CTRL, 756 FIELD_PREP(ISI_V_WR_HURRY, 7) | 757 FIELD_PREP(ISI_U_WR_HURRY, 7) | 758 FIELD_PREP(ISI_Y_WR_HURRY, 7)); 759 } 760 761 return NOTIFY_OK; 762 } 763 764 /* 765 * From i.MX 8M Plus Applications Processor Reference Manual, Rev. 1, 766 * section 13.2.2, 13.2.3 767 * isp-ahb and dwe are not in Figure 13-5. Media BLK_CTRL Clocks 768 */ 769 static const struct imx8m_blk_ctrl_domain_data imx8mp_media_blk_ctl_domain_data[] = { 770 [IMX8MP_MEDIABLK_PD_MIPI_DSI_1] = { 771 .name = "mediablk-mipi-dsi-1", 772 .clk_names = (const char *[]){ "apb", "phy", }, 773 .num_clks = 2, 774 .gpc_name = "mipi-dsi1", 775 .rst_mask = BIT(0) | BIT(1), 776 .clk_mask = BIT(0) | BIT(1), 777 .mipi_phy_rst_mask = BIT(17), 778 }, 779 [IMX8MP_MEDIABLK_PD_MIPI_CSI2_1] = { 780 .name = "mediablk-mipi-csi2-1", 781 .clk_names = (const char *[]){ "apb", "cam1" }, 782 .num_clks = 2, 783 .gpc_name = "mipi-csi1", 784 .rst_mask = BIT(2) | BIT(3), 785 .clk_mask = BIT(2) | BIT(3), 786 .mipi_phy_rst_mask = BIT(16), 787 }, 788 [IMX8MP_MEDIABLK_PD_LCDIF_1] = { 789 .name = "mediablk-lcdif-1", 790 .clk_names = (const char *[]){ "disp1", "apb", "axi", }, 791 .num_clks = 3, 792 .gpc_name = "lcdif1", 793 .rst_mask = BIT(4) | BIT(5) | BIT(23), 794 .clk_mask = BIT(4) | BIT(5) | BIT(23), 795 .path_names = (const char *[]){"lcdif-rd", "lcdif-wr"}, 796 .num_paths = 2, 797 }, 798 [IMX8MP_MEDIABLK_PD_ISI] = { 799 .name = "mediablk-isi", 800 .clk_names = (const char *[]){ "axi", "apb" }, 801 .num_clks = 2, 802 .gpc_name = "isi", 803 .rst_mask = BIT(6) | BIT(7), 804 .clk_mask = BIT(6) | BIT(7), 805 .path_names = (const char *[]){"isi0", "isi1", "isi2"}, 806 .num_paths = 3, 807 }, 808 [IMX8MP_MEDIABLK_PD_MIPI_CSI2_2] = { 809 .name = "mediablk-mipi-csi2-2", 810 .clk_names = (const char *[]){ "apb", "cam2" }, 811 .num_clks = 2, 812 .gpc_name = "mipi-csi2", 813 .rst_mask = BIT(9) | BIT(10), 814 .clk_mask = BIT(9) | BIT(10), 815 .mipi_phy_rst_mask = BIT(30), 816 }, 817 [IMX8MP_MEDIABLK_PD_LCDIF_2] = { 818 .name = "mediablk-lcdif-2", 819 .clk_names = (const char *[]){ "disp2", "apb", "axi", }, 820 .num_clks = 3, 821 .gpc_name = "lcdif2", 822 .rst_mask = BIT(11) | BIT(12) | BIT(24), 823 .clk_mask = BIT(11) | BIT(12) | BIT(24), 824 .path_names = (const char *[]){"lcdif-rd", "lcdif-wr"}, 825 .num_paths = 2, 826 }, 827 [IMX8MP_MEDIABLK_PD_ISP] = { 828 .name = "mediablk-isp", 829 .clk_names = (const char *[]){ "isp", "axi", "apb" }, 830 .num_clks = 3, 831 .gpc_name = "isp", 832 .rst_mask = BIT(16) | BIT(17) | BIT(18), 833 .clk_mask = BIT(16) | BIT(17) | BIT(18), 834 .path_names = (const char *[]){"isp0", "isp1"}, 835 .num_paths = 2, 836 }, 837 [IMX8MP_MEDIABLK_PD_DWE] = { 838 .name = "mediablk-dwe", 839 .clk_names = (const char *[]){ "axi", "apb" }, 840 .num_clks = 2, 841 .gpc_name = "dwe", 842 .rst_mask = BIT(19) | BIT(20) | BIT(21), 843 .clk_mask = BIT(19) | BIT(20) | BIT(21), 844 .path_names = (const char *[]){"dwe"}, 845 .num_paths = 1, 846 }, 847 [IMX8MP_MEDIABLK_PD_MIPI_DSI_2] = { 848 .name = "mediablk-mipi-dsi-2", 849 .clk_names = (const char *[]){ "phy", }, 850 .num_clks = 1, 851 .gpc_name = "mipi-dsi2", 852 .rst_mask = BIT(22), 853 .clk_mask = BIT(22), 854 .mipi_phy_rst_mask = BIT(29), 855 }, 856 }; 857 858 static const struct imx8m_blk_ctrl_data imx8mp_media_blk_ctl_dev_data = { 859 .max_reg = 0x138, 860 .power_notifier_fn = imx8mp_media_power_notifier, 861 .domains = imx8mp_media_blk_ctl_domain_data, 862 .num_domains = ARRAY_SIZE(imx8mp_media_blk_ctl_domain_data), 863 }; 864 865 static int imx8mq_vpu_power_notifier(struct notifier_block *nb, 866 unsigned long action, void *data) 867 { 868 struct imx8m_blk_ctrl *bc = container_of(nb, struct imx8m_blk_ctrl, 869 power_nb); 870 871 if (action != GENPD_NOTIFY_ON && action != GENPD_NOTIFY_PRE_OFF) 872 return NOTIFY_OK; 873 874 /* 875 * The ADB in the VPUMIX domain has no separate reset and clock 876 * enable bits, but is ungated and reset together with the VPUs. The 877 * reset and clock enable inputs to the ADB is a logical OR of the 878 * VPU bits. In order to set the G2 fuse bits, the G2 clock must 879 * also be enabled. 880 */ 881 regmap_set_bits(bc->regmap, BLK_SFT_RSTN, BIT(0) | BIT(1)); 882 regmap_set_bits(bc->regmap, BLK_CLK_EN, BIT(0) | BIT(1)); 883 884 if (action == GENPD_NOTIFY_ON) { 885 /* 886 * On power up we have no software backchannel to the GPC to 887 * wait for the ADB handshake to happen, so we just delay for a 888 * bit. On power down the GPC driver waits for the handshake. 889 */ 890 udelay(5); 891 892 /* set "fuse" bits to enable the VPUs */ 893 regmap_set_bits(bc->regmap, 0x8, 0xffffffff); 894 regmap_set_bits(bc->regmap, 0xc, 0xffffffff); 895 regmap_set_bits(bc->regmap, 0x10, 0xffffffff); 896 } 897 898 return NOTIFY_OK; 899 } 900 901 /* 902 * For i.MX8MQ, the ADB in the VPUMIX domain has no separate reset and clock 903 * enable bits, but is ungated and reset together with the VPUs. 904 * Resetting G1 or G2 separately may led to system hang. 905 * Remove the rst_mask and clk_mask from the domain data of G1 and G2, 906 * Let imx8mq_vpu_power_notifier() do really vpu reset. 907 */ 908 static const struct imx8m_blk_ctrl_domain_data imx8mq_vpu_blk_ctl_domain_data[] = { 909 [IMX8MQ_VPUBLK_PD_G1] = { 910 .name = "vpublk-g1", 911 .clk_names = (const char *[]){ "g1", }, 912 .num_clks = 1, 913 .gpc_name = "g1", 914 }, 915 [IMX8MQ_VPUBLK_PD_G2] = { 916 .name = "vpublk-g2", 917 .clk_names = (const char *[]){ "g2", }, 918 .num_clks = 1, 919 .gpc_name = "g2", 920 }, 921 }; 922 923 static const struct imx8m_blk_ctrl_data imx8mq_vpu_blk_ctl_dev_data = { 924 .max_reg = 0x14, 925 .power_notifier_fn = imx8mq_vpu_power_notifier, 926 .domains = imx8mq_vpu_blk_ctl_domain_data, 927 .num_domains = ARRAY_SIZE(imx8mq_vpu_blk_ctl_domain_data), 928 }; 929 930 static const struct of_device_id imx8m_blk_ctrl_of_match[] = { 931 { 932 .compatible = "fsl,imx8mm-vpu-blk-ctrl", 933 .data = &imx8mm_vpu_blk_ctl_dev_data 934 }, { 935 .compatible = "fsl,imx8mm-disp-blk-ctrl", 936 .data = &imx8mm_disp_blk_ctl_dev_data 937 }, { 938 .compatible = "fsl,imx8mn-disp-blk-ctrl", 939 .data = &imx8mn_disp_blk_ctl_dev_data 940 }, { 941 .compatible = "fsl,imx8mp-media-blk-ctrl", 942 .data = &imx8mp_media_blk_ctl_dev_data 943 }, { 944 .compatible = "fsl,imx8mq-vpu-blk-ctrl", 945 .data = &imx8mq_vpu_blk_ctl_dev_data 946 }, { 947 .compatible = "fsl,imx8mp-vpu-blk-ctrl", 948 .data = &imx8mp_vpu_blk_ctl_dev_data 949 }, { 950 /* Sentinel */ 951 } 952 }; 953 MODULE_DEVICE_TABLE(of, imx8m_blk_ctrl_of_match); 954 955 static struct platform_driver imx8m_blk_ctrl_driver = { 956 .probe = imx8m_blk_ctrl_probe, 957 .remove = imx8m_blk_ctrl_remove, 958 .driver = { 959 .name = "imx8m-blk-ctrl", 960 .pm = &imx8m_blk_ctrl_pm_ops, 961 .of_match_table = imx8m_blk_ctrl_of_match, 962 .suppress_bind_attrs = true, 963 }, 964 }; 965 module_platform_driver(imx8m_blk_ctrl_driver); 966 MODULE_DESCRIPTION("NXP i.MX8M power domain driver"); 967 MODULE_LICENSE("GPL"); 968