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