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