1 // SPDX-License-Identifier: GPL-2.0+ 2 3 /* 4 * Copyright 2022 Pengutronix, Lucas Stach <kernel@pengutronix.de> 5 */ 6 7 #include <linux/bitfield.h> 8 #include <linux/clk.h> 9 #include <linux/clk-provider.h> 10 #include <linux/device.h> 11 #include <linux/interconnect.h> 12 #include <linux/module.h> 13 #include <linux/of.h> 14 #include <linux/platform_device.h> 15 #include <linux/pm_domain.h> 16 #include <linux/pm_runtime.h> 17 #include <linux/regmap.h> 18 19 #include <dt-bindings/power/imx8mp-power.h> 20 21 #define GPR_REG0 0x0 22 #define PCIE_CLOCK_MODULE_EN BIT(0) 23 #define USB_CLOCK_MODULE_EN BIT(1) 24 #define PCIE_PHY_APB_RST BIT(4) 25 #define PCIE_PHY_INIT_RST BIT(5) 26 #define GPR_REG1 0x4 27 #define PLL_LOCK BIT(13) 28 #define GPR_REG2 0x8 29 #define P_PLL_MASK GENMASK(5, 0) 30 #define M_PLL_MASK GENMASK(15, 6) 31 #define S_PLL_MASK GENMASK(18, 16) 32 #define GPR_REG3 0xc 33 #define PLL_CKE BIT(17) 34 #define PLL_RST BIT(31) 35 36 struct imx8mp_blk_ctrl_domain; 37 38 struct imx8mp_blk_ctrl { 39 struct device *dev; 40 struct notifier_block power_nb; 41 struct device *bus_power_dev; 42 struct regmap *regmap; 43 struct imx8mp_blk_ctrl_domain *domains; 44 struct genpd_onecell_data onecell_data; 45 void (*power_off) (struct imx8mp_blk_ctrl *bc, struct imx8mp_blk_ctrl_domain *domain); 46 void (*power_on) (struct imx8mp_blk_ctrl *bc, struct imx8mp_blk_ctrl_domain *domain); 47 }; 48 49 struct imx8mp_blk_ctrl_domain_data { 50 const char *name; 51 const char * const *clk_names; 52 int num_clks; 53 const char * const *path_names; 54 int num_paths; 55 const char *gpc_name; 56 const unsigned int flags; 57 }; 58 59 #define DOMAIN_MAX_CLKS 3 60 #define DOMAIN_MAX_PATHS 3 61 62 struct imx8mp_blk_ctrl_domain { 63 struct generic_pm_domain genpd; 64 const struct imx8mp_blk_ctrl_domain_data *data; 65 struct clk_bulk_data clks[DOMAIN_MAX_CLKS]; 66 struct icc_bulk_data paths[DOMAIN_MAX_PATHS]; 67 struct device *power_dev; 68 struct imx8mp_blk_ctrl *bc; 69 struct notifier_block power_nb; 70 int num_paths; 71 int id; 72 }; 73 74 struct imx8mp_blk_ctrl_data { 75 int max_reg; 76 int (*probe) (struct imx8mp_blk_ctrl *bc); 77 notifier_fn_t power_notifier_fn; 78 void (*power_off) (struct imx8mp_blk_ctrl *bc, struct imx8mp_blk_ctrl_domain *domain); 79 void (*power_on) (struct imx8mp_blk_ctrl *bc, struct imx8mp_blk_ctrl_domain *domain); 80 const struct imx8mp_blk_ctrl_domain_data *domains; 81 int num_domains; 82 }; 83 84 static inline struct imx8mp_blk_ctrl_domain * 85 to_imx8mp_blk_ctrl_domain(struct generic_pm_domain *genpd) 86 { 87 return container_of(genpd, struct imx8mp_blk_ctrl_domain, genpd); 88 } 89 90 struct clk_hsio_pll { 91 struct clk_hw hw; 92 struct regmap *regmap; 93 }; 94 95 static inline struct clk_hsio_pll *to_clk_hsio_pll(struct clk_hw *hw) 96 { 97 return container_of(hw, struct clk_hsio_pll, hw); 98 } 99 100 static int clk_hsio_pll_prepare(struct clk_hw *hw) 101 { 102 struct clk_hsio_pll *clk = to_clk_hsio_pll(hw); 103 u32 val; 104 105 /* set the PLL configuration */ 106 regmap_update_bits(clk->regmap, GPR_REG2, 107 P_PLL_MASK | M_PLL_MASK | S_PLL_MASK, 108 FIELD_PREP(P_PLL_MASK, 12) | 109 FIELD_PREP(M_PLL_MASK, 800) | 110 FIELD_PREP(S_PLL_MASK, 4)); 111 112 /* de-assert PLL reset */ 113 regmap_update_bits(clk->regmap, GPR_REG3, PLL_RST, PLL_RST); 114 115 /* enable PLL */ 116 regmap_update_bits(clk->regmap, GPR_REG3, PLL_CKE, PLL_CKE); 117 118 return regmap_read_poll_timeout(clk->regmap, GPR_REG1, val, 119 val & PLL_LOCK, 10, 100); 120 } 121 122 static void clk_hsio_pll_unprepare(struct clk_hw *hw) 123 { 124 struct clk_hsio_pll *clk = to_clk_hsio_pll(hw); 125 126 regmap_update_bits(clk->regmap, GPR_REG3, PLL_RST | PLL_CKE, 0); 127 } 128 129 static int clk_hsio_pll_is_prepared(struct clk_hw *hw) 130 { 131 struct clk_hsio_pll *clk = to_clk_hsio_pll(hw); 132 133 return regmap_test_bits(clk->regmap, GPR_REG1, PLL_LOCK); 134 } 135 136 static unsigned long clk_hsio_pll_recalc_rate(struct clk_hw *hw, 137 unsigned long parent_rate) 138 { 139 return 100000000; 140 } 141 142 static const struct clk_ops clk_hsio_pll_ops = { 143 .prepare = clk_hsio_pll_prepare, 144 .unprepare = clk_hsio_pll_unprepare, 145 .is_prepared = clk_hsio_pll_is_prepared, 146 .recalc_rate = clk_hsio_pll_recalc_rate, 147 }; 148 149 static int imx8mp_hsio_blk_ctrl_probe(struct imx8mp_blk_ctrl *bc) 150 { 151 struct clk_hsio_pll *clk_hsio_pll; 152 struct clk_hw *hw; 153 struct clk_init_data init = {}; 154 int ret; 155 156 clk_hsio_pll = devm_kzalloc(bc->dev, sizeof(*clk_hsio_pll), GFP_KERNEL); 157 if (!clk_hsio_pll) 158 return -ENOMEM; 159 160 init.name = "hsio_pll"; 161 init.ops = &clk_hsio_pll_ops; 162 init.parent_names = (const char *[]){"osc_24m"}; 163 init.num_parents = 1; 164 165 clk_hsio_pll->regmap = bc->regmap; 166 clk_hsio_pll->hw.init = &init; 167 168 hw = &clk_hsio_pll->hw; 169 ret = devm_clk_hw_register(bc->bus_power_dev, hw); 170 if (ret) 171 return ret; 172 173 return devm_of_clk_add_hw_provider(bc->dev, of_clk_hw_simple_get, hw); 174 } 175 176 static void imx8mp_hsio_blk_ctrl_power_on(struct imx8mp_blk_ctrl *bc, 177 struct imx8mp_blk_ctrl_domain *domain) 178 { 179 switch (domain->id) { 180 case IMX8MP_HSIOBLK_PD_USB: 181 regmap_set_bits(bc->regmap, GPR_REG0, USB_CLOCK_MODULE_EN); 182 break; 183 case IMX8MP_HSIOBLK_PD_PCIE: 184 regmap_set_bits(bc->regmap, GPR_REG0, PCIE_CLOCK_MODULE_EN); 185 break; 186 case IMX8MP_HSIOBLK_PD_PCIE_PHY: 187 regmap_set_bits(bc->regmap, GPR_REG0, 188 PCIE_PHY_APB_RST | PCIE_PHY_INIT_RST); 189 break; 190 default: 191 break; 192 } 193 } 194 195 static void imx8mp_hsio_blk_ctrl_power_off(struct imx8mp_blk_ctrl *bc, 196 struct imx8mp_blk_ctrl_domain *domain) 197 { 198 switch (domain->id) { 199 case IMX8MP_HSIOBLK_PD_USB: 200 regmap_clear_bits(bc->regmap, GPR_REG0, USB_CLOCK_MODULE_EN); 201 break; 202 case IMX8MP_HSIOBLK_PD_PCIE: 203 regmap_clear_bits(bc->regmap, GPR_REG0, PCIE_CLOCK_MODULE_EN); 204 break; 205 case IMX8MP_HSIOBLK_PD_PCIE_PHY: 206 regmap_clear_bits(bc->regmap, GPR_REG0, 207 PCIE_PHY_APB_RST | PCIE_PHY_INIT_RST); 208 break; 209 default: 210 break; 211 } 212 } 213 214 static int imx8mp_hsio_power_notifier(struct notifier_block *nb, 215 unsigned long action, void *data) 216 { 217 struct imx8mp_blk_ctrl *bc = container_of(nb, struct imx8mp_blk_ctrl, 218 power_nb); 219 struct clk_bulk_data *usb_clk = bc->domains[IMX8MP_HSIOBLK_PD_USB].clks; 220 int num_clks = bc->domains[IMX8MP_HSIOBLK_PD_USB].data->num_clks; 221 int ret; 222 223 switch (action) { 224 case GENPD_NOTIFY_ON: 225 /* 226 * enable USB clock for a moment for the power-on ADB handshake 227 * to proceed 228 */ 229 ret = clk_bulk_prepare_enable(num_clks, usb_clk); 230 if (ret) 231 return NOTIFY_BAD; 232 regmap_set_bits(bc->regmap, GPR_REG0, USB_CLOCK_MODULE_EN); 233 234 udelay(5); 235 236 regmap_clear_bits(bc->regmap, GPR_REG0, USB_CLOCK_MODULE_EN); 237 clk_bulk_disable_unprepare(num_clks, usb_clk); 238 break; 239 case GENPD_NOTIFY_PRE_OFF: 240 /* enable USB clock for the power-down ADB handshake to work */ 241 ret = clk_bulk_prepare_enable(num_clks, usb_clk); 242 if (ret) 243 return NOTIFY_BAD; 244 245 regmap_set_bits(bc->regmap, GPR_REG0, USB_CLOCK_MODULE_EN); 246 break; 247 case GENPD_NOTIFY_OFF: 248 clk_bulk_disable_unprepare(num_clks, usb_clk); 249 break; 250 default: 251 break; 252 } 253 254 return NOTIFY_OK; 255 } 256 257 static const struct imx8mp_blk_ctrl_domain_data imx8mp_hsio_domain_data[] = { 258 [IMX8MP_HSIOBLK_PD_USB] = { 259 .name = "hsioblk-usb", 260 .clk_names = (const char *[]){ "usb" }, 261 .num_clks = 1, 262 .gpc_name = "usb", 263 .path_names = (const char *[]){"usb1", "usb2"}, 264 .num_paths = 2, 265 }, 266 [IMX8MP_HSIOBLK_PD_USB_PHY1] = { 267 .name = "hsioblk-usb-phy1", 268 .gpc_name = "usb-phy1", 269 .flags = GENPD_FLAG_ACTIVE_WAKEUP, 270 }, 271 [IMX8MP_HSIOBLK_PD_USB_PHY2] = { 272 .name = "hsioblk-usb-phy2", 273 .gpc_name = "usb-phy2", 274 .flags = GENPD_FLAG_ACTIVE_WAKEUP, 275 }, 276 [IMX8MP_HSIOBLK_PD_PCIE] = { 277 .name = "hsioblk-pcie", 278 .clk_names = (const char *[]){ "pcie" }, 279 .num_clks = 1, 280 .gpc_name = "pcie", 281 .path_names = (const char *[]){"noc-pcie", "pcie"}, 282 .num_paths = 2, 283 }, 284 [IMX8MP_HSIOBLK_PD_PCIE_PHY] = { 285 .name = "hsioblk-pcie-phy", 286 .gpc_name = "pcie-phy", 287 }, 288 }; 289 290 static const struct imx8mp_blk_ctrl_data imx8mp_hsio_blk_ctl_dev_data = { 291 .max_reg = 0x24, 292 .probe = imx8mp_hsio_blk_ctrl_probe, 293 .power_on = imx8mp_hsio_blk_ctrl_power_on, 294 .power_off = imx8mp_hsio_blk_ctrl_power_off, 295 .power_notifier_fn = imx8mp_hsio_power_notifier, 296 .domains = imx8mp_hsio_domain_data, 297 .num_domains = ARRAY_SIZE(imx8mp_hsio_domain_data), 298 }; 299 300 #define HDMI_RTX_RESET_CTL0 0x20 301 #define HDMI_RTX_CLK_CTL0 0x40 302 #define HDMI_RTX_CLK_CTL1 0x50 303 #define HDMI_RTX_CLK_CTL2 0x60 304 #define HDMI_RTX_CLK_CTL3 0x70 305 #define HDMI_RTX_CLK_CTL4 0x80 306 #define HDMI_TX_CONTROL0 0x200 307 #define HDMI_LCDIF_NOC_HURRY_MASK GENMASK(14, 12) 308 309 static void imx8mp_hdmi_blk_ctrl_power_on(struct imx8mp_blk_ctrl *bc, 310 struct imx8mp_blk_ctrl_domain *domain) 311 { 312 switch (domain->id) { 313 case IMX8MP_HDMIBLK_PD_IRQSTEER: 314 regmap_set_bits(bc->regmap, HDMI_RTX_CLK_CTL0, BIT(9)); 315 regmap_set_bits(bc->regmap, HDMI_RTX_RESET_CTL0, BIT(16)); 316 break; 317 case IMX8MP_HDMIBLK_PD_LCDIF: 318 regmap_set_bits(bc->regmap, HDMI_RTX_CLK_CTL0, 319 BIT(16) | BIT(17) | BIT(18) | 320 BIT(19) | BIT(20)); 321 regmap_set_bits(bc->regmap, HDMI_RTX_CLK_CTL1, BIT(11)); 322 regmap_set_bits(bc->regmap, HDMI_RTX_RESET_CTL0, 323 BIT(4) | BIT(5) | BIT(6)); 324 regmap_set_bits(bc->regmap, HDMI_TX_CONTROL0, 325 FIELD_PREP(HDMI_LCDIF_NOC_HURRY_MASK, 7)); 326 break; 327 case IMX8MP_HDMIBLK_PD_PAI: 328 regmap_set_bits(bc->regmap, HDMI_RTX_CLK_CTL1, BIT(17)); 329 regmap_set_bits(bc->regmap, HDMI_RTX_RESET_CTL0, BIT(18)); 330 break; 331 case IMX8MP_HDMIBLK_PD_PVI: 332 regmap_set_bits(bc->regmap, HDMI_RTX_CLK_CTL1, BIT(28)); 333 regmap_set_bits(bc->regmap, HDMI_RTX_RESET_CTL0, BIT(22)); 334 break; 335 case IMX8MP_HDMIBLK_PD_TRNG: 336 regmap_set_bits(bc->regmap, HDMI_RTX_CLK_CTL1, BIT(27) | BIT(30)); 337 regmap_set_bits(bc->regmap, HDMI_RTX_RESET_CTL0, BIT(20)); 338 break; 339 case IMX8MP_HDMIBLK_PD_HDMI_TX: 340 regmap_set_bits(bc->regmap, HDMI_RTX_CLK_CTL0, 341 BIT(2) | BIT(4) | BIT(5)); 342 regmap_set_bits(bc->regmap, HDMI_RTX_CLK_CTL1, 343 BIT(12) | BIT(13) | BIT(14) | BIT(15) | BIT(16) | 344 BIT(18) | BIT(19) | BIT(20) | BIT(21)); 345 regmap_set_bits(bc->regmap, HDMI_RTX_RESET_CTL0, 346 BIT(7) | BIT(10) | BIT(11)); 347 regmap_set_bits(bc->regmap, HDMI_TX_CONTROL0, BIT(1)); 348 break; 349 case IMX8MP_HDMIBLK_PD_HDMI_TX_PHY: 350 regmap_set_bits(bc->regmap, HDMI_RTX_CLK_CTL0, BIT(7)); 351 regmap_set_bits(bc->regmap, HDMI_RTX_CLK_CTL1, BIT(22) | BIT(24)); 352 regmap_set_bits(bc->regmap, HDMI_RTX_RESET_CTL0, BIT(12)); 353 regmap_clear_bits(bc->regmap, HDMI_TX_CONTROL0, BIT(3)); 354 break; 355 case IMX8MP_HDMIBLK_PD_HDCP: 356 regmap_set_bits(bc->regmap, HDMI_RTX_CLK_CTL0, BIT(11)); 357 break; 358 case IMX8MP_HDMIBLK_PD_HRV: 359 regmap_set_bits(bc->regmap, HDMI_RTX_CLK_CTL1, BIT(3) | BIT(4) | BIT(5)); 360 regmap_set_bits(bc->regmap, HDMI_RTX_RESET_CTL0, BIT(15)); 361 break; 362 default: 363 break; 364 } 365 } 366 367 static void imx8mp_hdmi_blk_ctrl_power_off(struct imx8mp_blk_ctrl *bc, 368 struct imx8mp_blk_ctrl_domain *domain) 369 { 370 switch (domain->id) { 371 case IMX8MP_HDMIBLK_PD_IRQSTEER: 372 regmap_clear_bits(bc->regmap, HDMI_RTX_CLK_CTL0, BIT(9)); 373 regmap_clear_bits(bc->regmap, HDMI_RTX_RESET_CTL0, BIT(16)); 374 break; 375 case IMX8MP_HDMIBLK_PD_LCDIF: 376 regmap_clear_bits(bc->regmap, HDMI_RTX_RESET_CTL0, 377 BIT(4) | BIT(5) | BIT(6)); 378 regmap_clear_bits(bc->regmap, HDMI_RTX_CLK_CTL1, BIT(11)); 379 regmap_clear_bits(bc->regmap, HDMI_RTX_CLK_CTL0, 380 BIT(16) | BIT(17) | BIT(18) | 381 BIT(19) | BIT(20)); 382 break; 383 case IMX8MP_HDMIBLK_PD_PAI: 384 regmap_clear_bits(bc->regmap, HDMI_RTX_RESET_CTL0, BIT(18)); 385 regmap_clear_bits(bc->regmap, HDMI_RTX_CLK_CTL1, BIT(17)); 386 break; 387 case IMX8MP_HDMIBLK_PD_PVI: 388 regmap_clear_bits(bc->regmap, HDMI_RTX_RESET_CTL0, BIT(22)); 389 regmap_clear_bits(bc->regmap, HDMI_RTX_CLK_CTL1, BIT(28)); 390 break; 391 case IMX8MP_HDMIBLK_PD_TRNG: 392 regmap_clear_bits(bc->regmap, HDMI_RTX_RESET_CTL0, BIT(20)); 393 regmap_clear_bits(bc->regmap, HDMI_RTX_CLK_CTL1, BIT(27) | BIT(30)); 394 break; 395 case IMX8MP_HDMIBLK_PD_HDMI_TX: 396 regmap_clear_bits(bc->regmap, HDMI_TX_CONTROL0, BIT(1)); 397 regmap_clear_bits(bc->regmap, HDMI_RTX_RESET_CTL0, 398 BIT(7) | BIT(10) | BIT(11)); 399 regmap_clear_bits(bc->regmap, HDMI_RTX_CLK_CTL1, 400 BIT(12) | BIT(13) | BIT(14) | BIT(15) | BIT(16) | 401 BIT(18) | BIT(19) | BIT(20) | BIT(21)); 402 regmap_clear_bits(bc->regmap, HDMI_RTX_CLK_CTL0, 403 BIT(2) | BIT(4) | BIT(5)); 404 break; 405 case IMX8MP_HDMIBLK_PD_HDMI_TX_PHY: 406 regmap_set_bits(bc->regmap, HDMI_TX_CONTROL0, BIT(3)); 407 regmap_clear_bits(bc->regmap, HDMI_RTX_RESET_CTL0, BIT(12)); 408 regmap_clear_bits(bc->regmap, HDMI_RTX_CLK_CTL0, BIT(7)); 409 regmap_clear_bits(bc->regmap, HDMI_RTX_CLK_CTL1, BIT(22) | BIT(24)); 410 break; 411 case IMX8MP_HDMIBLK_PD_HDCP: 412 regmap_clear_bits(bc->regmap, HDMI_RTX_CLK_CTL0, BIT(11)); 413 break; 414 case IMX8MP_HDMIBLK_PD_HRV: 415 regmap_clear_bits(bc->regmap, HDMI_RTX_RESET_CTL0, BIT(15)); 416 regmap_clear_bits(bc->regmap, HDMI_RTX_CLK_CTL1, BIT(3) | BIT(4) | BIT(5)); 417 break; 418 default: 419 break; 420 } 421 } 422 423 static int imx8mp_hdmi_power_notifier(struct notifier_block *nb, 424 unsigned long action, void *data) 425 { 426 struct imx8mp_blk_ctrl *bc = container_of(nb, struct imx8mp_blk_ctrl, 427 power_nb); 428 429 if (action != GENPD_NOTIFY_ON) 430 return NOTIFY_OK; 431 432 /* 433 * Contrary to other blk-ctrls the reset and clock don't clear when the 434 * power domain is powered down. To ensure the proper reset pulsing, 435 * first clear them all to asserted state, then enable the bus clocks 436 * and then release the ADB reset. 437 */ 438 regmap_write(bc->regmap, HDMI_RTX_RESET_CTL0, 0x0); 439 regmap_write(bc->regmap, HDMI_RTX_CLK_CTL0, 0x0); 440 regmap_write(bc->regmap, HDMI_RTX_CLK_CTL1, 0x0); 441 regmap_set_bits(bc->regmap, HDMI_RTX_CLK_CTL0, 442 BIT(0) | BIT(1) | BIT(10)); 443 regmap_set_bits(bc->regmap, HDMI_RTX_RESET_CTL0, BIT(0)); 444 445 /* 446 * On power up we have no software backchannel to the GPC to 447 * wait for the ADB handshake to happen, so we just delay for a 448 * bit. On power down the GPC driver waits for the handshake. 449 */ 450 udelay(5); 451 452 return NOTIFY_OK; 453 } 454 455 static const struct imx8mp_blk_ctrl_domain_data imx8mp_hdmi_domain_data[] = { 456 [IMX8MP_HDMIBLK_PD_IRQSTEER] = { 457 .name = "hdmiblk-irqsteer", 458 .clk_names = (const char *[]){ "apb" }, 459 .num_clks = 1, 460 .gpc_name = "irqsteer", 461 }, 462 [IMX8MP_HDMIBLK_PD_LCDIF] = { 463 .name = "hdmiblk-lcdif", 464 .clk_names = (const char *[]){ "axi", "apb", "fdcc" }, 465 .num_clks = 3, 466 .gpc_name = "lcdif", 467 .path_names = (const char *[]){"lcdif-hdmi"}, 468 .num_paths = 1, 469 }, 470 [IMX8MP_HDMIBLK_PD_PAI] = { 471 .name = "hdmiblk-pai", 472 .clk_names = (const char *[]){ "apb" }, 473 .num_clks = 1, 474 .gpc_name = "pai", 475 }, 476 [IMX8MP_HDMIBLK_PD_PVI] = { 477 .name = "hdmiblk-pvi", 478 .clk_names = (const char *[]){ "apb" }, 479 .num_clks = 1, 480 .gpc_name = "pvi", 481 }, 482 [IMX8MP_HDMIBLK_PD_TRNG] = { 483 .name = "hdmiblk-trng", 484 .clk_names = (const char *[]){ "apb" }, 485 .num_clks = 1, 486 .gpc_name = "trng", 487 }, 488 [IMX8MP_HDMIBLK_PD_HDMI_TX] = { 489 .name = "hdmiblk-hdmi-tx", 490 .clk_names = (const char *[]){ "apb", "ref_266m", "fdcc" }, 491 .num_clks = 3, 492 .gpc_name = "hdmi-tx", 493 }, 494 [IMX8MP_HDMIBLK_PD_HDMI_TX_PHY] = { 495 .name = "hdmiblk-hdmi-tx-phy", 496 .clk_names = (const char *[]){ "apb", "ref_24m" }, 497 .num_clks = 2, 498 .gpc_name = "hdmi-tx-phy", 499 }, 500 [IMX8MP_HDMIBLK_PD_HRV] = { 501 .name = "hdmiblk-hrv", 502 .clk_names = (const char *[]){ "axi", "apb" }, 503 .num_clks = 2, 504 .gpc_name = "hrv", 505 .path_names = (const char *[]){"hrv"}, 506 .num_paths = 1, 507 }, 508 [IMX8MP_HDMIBLK_PD_HDCP] = { 509 .name = "hdmiblk-hdcp", 510 .clk_names = (const char *[]){ "axi", "apb" }, 511 .num_clks = 2, 512 .gpc_name = "hdcp", 513 .path_names = (const char *[]){"hdcp"}, 514 .num_paths = 1, 515 }, 516 }; 517 518 static const struct imx8mp_blk_ctrl_data imx8mp_hdmi_blk_ctl_dev_data = { 519 .max_reg = 0x23c, 520 .power_on = imx8mp_hdmi_blk_ctrl_power_on, 521 .power_off = imx8mp_hdmi_blk_ctrl_power_off, 522 .power_notifier_fn = imx8mp_hdmi_power_notifier, 523 .domains = imx8mp_hdmi_domain_data, 524 .num_domains = ARRAY_SIZE(imx8mp_hdmi_domain_data), 525 }; 526 527 static int imx8mp_blk_ctrl_power_on(struct generic_pm_domain *genpd) 528 { 529 struct imx8mp_blk_ctrl_domain *domain = to_imx8mp_blk_ctrl_domain(genpd); 530 const struct imx8mp_blk_ctrl_domain_data *data = domain->data; 531 struct imx8mp_blk_ctrl *bc = domain->bc; 532 int ret; 533 534 /* make sure bus domain is awake */ 535 ret = pm_runtime_resume_and_get(bc->bus_power_dev); 536 if (ret < 0) { 537 dev_err(bc->dev, "failed to power up bus domain\n"); 538 return ret; 539 } 540 541 /* enable upstream clocks */ 542 ret = clk_bulk_prepare_enable(data->num_clks, domain->clks); 543 if (ret) { 544 dev_err(bc->dev, "failed to enable clocks\n"); 545 goto bus_put; 546 } 547 548 /* domain specific blk-ctrl manipulation */ 549 bc->power_on(bc, domain); 550 551 /* power up upstream GPC domain */ 552 ret = pm_runtime_resume_and_get(domain->power_dev); 553 if (ret < 0) { 554 dev_err(bc->dev, "failed to power up peripheral domain\n"); 555 goto clk_disable; 556 } 557 558 ret = icc_bulk_set_bw(domain->num_paths, domain->paths); 559 if (ret) 560 dev_err(bc->dev, "failed to set icc bw\n"); 561 562 clk_bulk_disable_unprepare(data->num_clks, domain->clks); 563 564 return 0; 565 566 clk_disable: 567 clk_bulk_disable_unprepare(data->num_clks, domain->clks); 568 bus_put: 569 pm_runtime_put(bc->bus_power_dev); 570 571 return ret; 572 } 573 574 static int imx8mp_blk_ctrl_power_off(struct generic_pm_domain *genpd) 575 { 576 struct imx8mp_blk_ctrl_domain *domain = to_imx8mp_blk_ctrl_domain(genpd); 577 const struct imx8mp_blk_ctrl_domain_data *data = domain->data; 578 struct imx8mp_blk_ctrl *bc = domain->bc; 579 int ret; 580 581 ret = clk_bulk_prepare_enable(data->num_clks, domain->clks); 582 if (ret) { 583 dev_err(bc->dev, "failed to enable clocks\n"); 584 return ret; 585 } 586 587 /* domain specific blk-ctrl manipulation */ 588 bc->power_off(bc, domain); 589 590 clk_bulk_disable_unprepare(data->num_clks, domain->clks); 591 592 /* power down upstream GPC domain */ 593 pm_runtime_put(domain->power_dev); 594 595 /* allow bus domain to suspend */ 596 pm_runtime_put(bc->bus_power_dev); 597 598 return 0; 599 } 600 601 static int imx8mp_blk_ctrl_gpc_notifier(struct notifier_block *nb, 602 unsigned long action, void *data) 603 { 604 struct imx8mp_blk_ctrl_domain *domain = 605 container_of(nb, struct imx8mp_blk_ctrl_domain, power_nb); 606 607 if (action == GENPD_NOTIFY_PRE_OFF) { 608 if (domain->genpd.status == GENPD_STATE_ON) 609 return NOTIFY_BAD; 610 } 611 612 return NOTIFY_OK; 613 } 614 615 static struct lock_class_key blk_ctrl_genpd_lock_class; 616 617 static int imx8mp_blk_ctrl_probe(struct platform_device *pdev) 618 { 619 const struct imx8mp_blk_ctrl_data *bc_data; 620 struct device *dev = &pdev->dev; 621 struct imx8mp_blk_ctrl *bc; 622 void __iomem *base; 623 int num_domains, i, ret; 624 625 struct regmap_config regmap_config = { 626 .reg_bits = 32, 627 .val_bits = 32, 628 .reg_stride = 4, 629 }; 630 631 bc = devm_kzalloc(dev, sizeof(*bc), GFP_KERNEL); 632 if (!bc) 633 return -ENOMEM; 634 635 bc->dev = dev; 636 637 bc_data = of_device_get_match_data(dev); 638 num_domains = bc_data->num_domains; 639 640 base = devm_platform_ioremap_resource(pdev, 0); 641 if (IS_ERR(base)) 642 return PTR_ERR(base); 643 644 regmap_config.max_register = bc_data->max_reg; 645 bc->regmap = devm_regmap_init_mmio(dev, base, ®map_config); 646 if (IS_ERR(bc->regmap)) 647 return dev_err_probe(dev, PTR_ERR(bc->regmap), 648 "failed to init regmap\n"); 649 650 bc->domains = devm_kcalloc(dev, num_domains, 651 sizeof(struct imx8mp_blk_ctrl_domain), 652 GFP_KERNEL); 653 if (!bc->domains) 654 return -ENOMEM; 655 656 bc->onecell_data.num_domains = num_domains; 657 bc->onecell_data.domains = 658 devm_kcalloc(dev, num_domains, 659 sizeof(struct generic_pm_domain *), GFP_KERNEL); 660 if (!bc->onecell_data.domains) 661 return -ENOMEM; 662 663 bc->bus_power_dev = dev_pm_domain_attach_by_name(dev, "bus"); 664 if (IS_ERR(bc->bus_power_dev)) 665 return dev_err_probe(dev, PTR_ERR(bc->bus_power_dev), 666 "failed to attach bus power domain\n"); 667 668 bc->power_off = bc_data->power_off; 669 bc->power_on = bc_data->power_on; 670 671 for (i = 0; i < num_domains; i++) { 672 const struct imx8mp_blk_ctrl_domain_data *data = &bc_data->domains[i]; 673 struct imx8mp_blk_ctrl_domain *domain = &bc->domains[i]; 674 int j; 675 676 domain->data = data; 677 domain->num_paths = data->num_paths; 678 679 for (j = 0; j < data->num_clks; j++) 680 domain->clks[j].id = data->clk_names[j]; 681 682 for (j = 0; j < data->num_paths; j++) { 683 domain->paths[j].name = data->path_names[j]; 684 /* Fake value for now, just let ICC could configure NoC mode/priority */ 685 domain->paths[j].avg_bw = 1; 686 domain->paths[j].peak_bw = 1; 687 } 688 689 ret = devm_of_icc_bulk_get(dev, data->num_paths, domain->paths); 690 if (ret) { 691 if (ret != -EPROBE_DEFER) { 692 dev_warn_once(dev, "Could not get interconnect paths, NoC will stay unconfigured!\n"); 693 domain->num_paths = 0; 694 } else { 695 dev_err_probe(dev, ret, "failed to get noc entries\n"); 696 goto cleanup_pds; 697 } 698 } 699 700 ret = devm_clk_bulk_get(dev, data->num_clks, domain->clks); 701 if (ret) { 702 dev_err_probe(dev, ret, "failed to get clock\n"); 703 goto cleanup_pds; 704 } 705 706 domain->power_dev = 707 dev_pm_domain_attach_by_name(dev, data->gpc_name); 708 if (IS_ERR_OR_NULL(domain->power_dev)) { 709 if (!domain->power_dev) 710 ret = -ENODEV; 711 else 712 ret = PTR_ERR(domain->power_dev); 713 dev_err_probe(dev, ret, 714 "failed to attach power domain %s\n", 715 data->gpc_name); 716 goto cleanup_pds; 717 } 718 719 domain->power_nb.notifier_call = imx8mp_blk_ctrl_gpc_notifier; 720 ret = dev_pm_genpd_add_notifier(domain->power_dev, &domain->power_nb); 721 if (ret) { 722 dev_err_probe(dev, ret, "failed to add power notifier\n"); 723 dev_pm_domain_detach(domain->power_dev, true); 724 goto cleanup_pds; 725 } 726 727 domain->genpd.name = data->name; 728 domain->genpd.power_on = imx8mp_blk_ctrl_power_on; 729 domain->genpd.power_off = imx8mp_blk_ctrl_power_off; 730 domain->genpd.flags = data->flags; 731 domain->bc = bc; 732 domain->id = i; 733 734 ret = pm_genpd_init(&domain->genpd, NULL, true); 735 if (ret) { 736 dev_err_probe(dev, ret, "failed to init power domain\n"); 737 dev_pm_genpd_remove_notifier(domain->power_dev); 738 dev_pm_domain_detach(domain->power_dev, true); 739 goto cleanup_pds; 740 } 741 742 /* 743 * We use runtime PM to trigger power on/off of the upstream GPC 744 * domain, as a strict hierarchical parent/child power domain 745 * setup doesn't allow us to meet the sequencing requirements. 746 * This means we have nested locking of genpd locks, without the 747 * nesting being visible at the genpd level, so we need a 748 * separate lock class to make lockdep aware of the fact that 749 * this are separate domain locks that can be nested without a 750 * self-deadlock. 751 */ 752 lockdep_set_class(&domain->genpd.mlock, 753 &blk_ctrl_genpd_lock_class); 754 755 bc->onecell_data.domains[i] = &domain->genpd; 756 } 757 758 ret = of_genpd_add_provider_onecell(dev->of_node, &bc->onecell_data); 759 if (ret) { 760 dev_err_probe(dev, ret, "failed to add power domain provider\n"); 761 goto cleanup_pds; 762 } 763 764 bc->power_nb.notifier_call = bc_data->power_notifier_fn; 765 ret = dev_pm_genpd_add_notifier(bc->bus_power_dev, &bc->power_nb); 766 if (ret) { 767 dev_err_probe(dev, ret, "failed to add power notifier\n"); 768 goto cleanup_provider; 769 } 770 771 if (bc_data->probe) { 772 ret = bc_data->probe(bc); 773 if (ret) 774 goto cleanup_provider; 775 } 776 777 dev_set_drvdata(dev, bc); 778 779 return 0; 780 781 cleanup_provider: 782 of_genpd_del_provider(dev->of_node); 783 cleanup_pds: 784 for (i--; i >= 0; i--) { 785 pm_genpd_remove(&bc->domains[i].genpd); 786 dev_pm_genpd_remove_notifier(bc->domains[i].power_dev); 787 dev_pm_domain_detach(bc->domains[i].power_dev, true); 788 } 789 790 dev_pm_domain_detach(bc->bus_power_dev, true); 791 792 return ret; 793 } 794 795 static void imx8mp_blk_ctrl_remove(struct platform_device *pdev) 796 { 797 struct imx8mp_blk_ctrl *bc = dev_get_drvdata(&pdev->dev); 798 int i; 799 800 of_genpd_del_provider(pdev->dev.of_node); 801 802 for (i = 0; i < bc->onecell_data.num_domains; i++) { 803 struct imx8mp_blk_ctrl_domain *domain = &bc->domains[i]; 804 805 pm_genpd_remove(&domain->genpd); 806 dev_pm_genpd_remove_notifier(domain->power_dev); 807 dev_pm_domain_detach(domain->power_dev, true); 808 } 809 810 dev_pm_genpd_remove_notifier(bc->bus_power_dev); 811 812 dev_pm_domain_detach(bc->bus_power_dev, true); 813 } 814 815 #ifdef CONFIG_PM_SLEEP 816 static int imx8mp_blk_ctrl_suspend(struct device *dev) 817 { 818 struct imx8mp_blk_ctrl *bc = dev_get_drvdata(dev); 819 int ret, i; 820 821 /* 822 * This may look strange, but is done so the generic PM_SLEEP code 823 * can power down our domains and more importantly power them up again 824 * after resume, without tripping over our usage of runtime PM to 825 * control the upstream GPC domains. Things happen in the right order 826 * in the system suspend/resume paths due to the device parent/child 827 * hierarchy. 828 */ 829 ret = pm_runtime_get_sync(bc->bus_power_dev); 830 if (ret < 0) { 831 pm_runtime_put_noidle(bc->bus_power_dev); 832 return ret; 833 } 834 835 for (i = 0; i < bc->onecell_data.num_domains; i++) { 836 struct imx8mp_blk_ctrl_domain *domain = &bc->domains[i]; 837 838 ret = pm_runtime_get_sync(domain->power_dev); 839 if (ret < 0) { 840 pm_runtime_put_noidle(domain->power_dev); 841 goto out_fail; 842 } 843 } 844 845 return 0; 846 847 out_fail: 848 for (i--; i >= 0; i--) 849 pm_runtime_put(bc->domains[i].power_dev); 850 851 pm_runtime_put(bc->bus_power_dev); 852 853 return ret; 854 } 855 856 static int imx8mp_blk_ctrl_resume(struct device *dev) 857 { 858 struct imx8mp_blk_ctrl *bc = dev_get_drvdata(dev); 859 int i; 860 861 for (i = 0; i < bc->onecell_data.num_domains; i++) 862 pm_runtime_put(bc->domains[i].power_dev); 863 864 pm_runtime_put(bc->bus_power_dev); 865 866 return 0; 867 } 868 #endif 869 870 static const struct dev_pm_ops imx8mp_blk_ctrl_pm_ops = { 871 SET_SYSTEM_SLEEP_PM_OPS(imx8mp_blk_ctrl_suspend, 872 imx8mp_blk_ctrl_resume) 873 }; 874 875 static const struct of_device_id imx8mp_blk_ctrl_of_match[] = { 876 { 877 .compatible = "fsl,imx8mp-hsio-blk-ctrl", 878 .data = &imx8mp_hsio_blk_ctl_dev_data, 879 }, { 880 .compatible = "fsl,imx8mp-hdmi-blk-ctrl", 881 .data = &imx8mp_hdmi_blk_ctl_dev_data, 882 }, { 883 /* Sentinel */ 884 } 885 }; 886 MODULE_DEVICE_TABLE(of, imx8mp_blk_ctrl_of_match); 887 888 static struct platform_driver imx8mp_blk_ctrl_driver = { 889 .probe = imx8mp_blk_ctrl_probe, 890 .remove = imx8mp_blk_ctrl_remove, 891 .driver = { 892 .name = "imx8mp-blk-ctrl", 893 .pm = &imx8mp_blk_ctrl_pm_ops, 894 .of_match_table = imx8mp_blk_ctrl_of_match, 895 .suppress_bind_attrs = true, 896 }, 897 }; 898 module_platform_driver(imx8mp_blk_ctrl_driver); 899 MODULE_LICENSE("GPL"); 900