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