1 // SPDX-License-Identifier: GPL-2.0+
4 * Copyright 2022 Pengutronix, Lucas Stach <kernel@pengutronix.de>
7 #include <linux/bitfield.h>
9 #include <linux/clk-provider.h>
10 #include <linux/device.h>
11 #include <linux/interconnect.h>
12 #include <linux/module.h>
14 #include <linux/platform_device.h>
15 #include <linux/pm_domain.h>
16 #include <linux/pm_runtime.h>
17 #include <linux/regmap.h>
19 #include <dt-bindings/power/imx8mp-power.h>
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)
27 #define PLL_LOCK BIT(13)
29 #define P_PLL_MASK GENMASK(5, 0)
30 #define M_PLL_MASK GENMASK(15, 6)
31 #define S_PLL_MASK GENMASK(18, 16)
33 #define PLL_CKE BIT(17)
34 #define PLL_RST BIT(31)
36 struct imx8mp_blk_ctrl_domain
;
38 struct imx8mp_blk_ctrl
{
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
);
49 struct imx8mp_blk_ctrl_domain_data
{
51 const char * const *clk_names
;
53 const char * const *path_names
;
58 #define DOMAIN_MAX_CLKS 3
59 #define DOMAIN_MAX_PATHS 3
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
;
72 struct imx8mp_blk_ctrl_data
{
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
;
82 static inline struct imx8mp_blk_ctrl_domain
*
83 to_imx8mp_blk_ctrl_domain(struct generic_pm_domain
*genpd
)
85 return container_of(genpd
, struct imx8mp_blk_ctrl_domain
, genpd
);
90 struct regmap
*regmap
;
93 static inline struct clk_hsio_pll
*to_clk_hsio_pll(struct clk_hw
*hw
)
95 return container_of(hw
, struct clk_hsio_pll
, hw
);
98 static int clk_hsio_pll_prepare(struct clk_hw
*hw
)
100 struct clk_hsio_pll
*clk
= to_clk_hsio_pll(hw
);
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));
110 /* de-assert PLL reset */
111 regmap_update_bits(clk
->regmap
, GPR_REG3
, PLL_RST
, PLL_RST
);
114 regmap_update_bits(clk
->regmap
, GPR_REG3
, PLL_CKE
, PLL_CKE
);
116 return regmap_read_poll_timeout(clk
->regmap
, GPR_REG1
, val
,
117 val
& PLL_LOCK
, 10, 100);
120 static void clk_hsio_pll_unprepare(struct clk_hw
*hw
)
122 struct clk_hsio_pll
*clk
= to_clk_hsio_pll(hw
);
124 regmap_update_bits(clk
->regmap
, GPR_REG3
, PLL_RST
| PLL_CKE
, 0);
127 static int clk_hsio_pll_is_prepared(struct clk_hw
*hw
)
129 struct clk_hsio_pll
*clk
= to_clk_hsio_pll(hw
);
131 return regmap_test_bits(clk
->regmap
, GPR_REG1
, PLL_LOCK
);
134 static unsigned long clk_hsio_pll_recalc_rate(struct clk_hw
*hw
,
135 unsigned long parent_rate
)
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
,
147 static int imx8mp_hsio_blk_ctrl_probe(struct imx8mp_blk_ctrl
*bc
)
149 struct clk_hsio_pll
*clk_hsio_pll
;
151 struct clk_init_data init
= {};
154 clk_hsio_pll
= devm_kzalloc(bc
->dev
, sizeof(*clk_hsio_pll
), GFP_KERNEL
);
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;
163 clk_hsio_pll
->regmap
= bc
->regmap
;
164 clk_hsio_pll
->hw
.init
= &init
;
166 hw
= &clk_hsio_pll
->hw
;
167 ret
= devm_clk_hw_register(bc
->bus_power_dev
, hw
);
171 return devm_of_clk_add_hw_provider(bc
->dev
, of_clk_hw_simple_get
, hw
);
174 static void imx8mp_hsio_blk_ctrl_power_on(struct imx8mp_blk_ctrl
*bc
,
175 struct imx8mp_blk_ctrl_domain
*domain
)
177 switch (domain
->id
) {
178 case IMX8MP_HSIOBLK_PD_USB
:
179 regmap_set_bits(bc
->regmap
, GPR_REG0
, USB_CLOCK_MODULE_EN
);
181 case IMX8MP_HSIOBLK_PD_PCIE
:
182 regmap_set_bits(bc
->regmap
, GPR_REG0
, PCIE_CLOCK_MODULE_EN
);
184 case IMX8MP_HSIOBLK_PD_PCIE_PHY
:
185 regmap_set_bits(bc
->regmap
, GPR_REG0
,
186 PCIE_PHY_APB_RST
| PCIE_PHY_INIT_RST
);
193 static void imx8mp_hsio_blk_ctrl_power_off(struct imx8mp_blk_ctrl
*bc
,
194 struct imx8mp_blk_ctrl_domain
*domain
)
196 switch (domain
->id
) {
197 case IMX8MP_HSIOBLK_PD_USB
:
198 regmap_clear_bits(bc
->regmap
, GPR_REG0
, USB_CLOCK_MODULE_EN
);
200 case IMX8MP_HSIOBLK_PD_PCIE
:
201 regmap_clear_bits(bc
->regmap
, GPR_REG0
, PCIE_CLOCK_MODULE_EN
);
203 case IMX8MP_HSIOBLK_PD_PCIE_PHY
:
204 regmap_clear_bits(bc
->regmap
, GPR_REG0
,
205 PCIE_PHY_APB_RST
| PCIE_PHY_INIT_RST
);
212 static int imx8mp_hsio_power_notifier(struct notifier_block
*nb
,
213 unsigned long action
, void *data
)
215 struct imx8mp_blk_ctrl
*bc
= container_of(nb
, struct imx8mp_blk_ctrl
,
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
;
222 case GENPD_NOTIFY_ON
:
224 * enable USB clock for a moment for the power-on ADB handshake
227 ret
= clk_bulk_prepare_enable(num_clks
, usb_clk
);
230 regmap_set_bits(bc
->regmap
, GPR_REG0
, USB_CLOCK_MODULE_EN
);
234 regmap_clear_bits(bc
->regmap
, GPR_REG0
, USB_CLOCK_MODULE_EN
);
235 clk_bulk_disable_unprepare(num_clks
, usb_clk
);
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
);
243 regmap_set_bits(bc
->regmap
, GPR_REG0
, USB_CLOCK_MODULE_EN
);
245 case GENPD_NOTIFY_OFF
:
246 clk_bulk_disable_unprepare(num_clks
, usb_clk
);
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" },
261 .path_names
= (const char *[]){"usb1", "usb2"},
264 [IMX8MP_HSIOBLK_PD_USB_PHY1
] = {
265 .name
= "hsioblk-usb-phy1",
266 .gpc_name
= "usb-phy1",
268 [IMX8MP_HSIOBLK_PD_USB_PHY2
] = {
269 .name
= "hsioblk-usb-phy2",
270 .gpc_name
= "usb-phy2",
272 [IMX8MP_HSIOBLK_PD_PCIE
] = {
273 .name
= "hsioblk-pcie",
274 .clk_names
= (const char *[]){ "pcie" },
277 .path_names
= (const char *[]){"noc-pcie", "pcie"},
280 [IMX8MP_HSIOBLK_PD_PCIE_PHY
] = {
281 .name
= "hsioblk-pcie-phy",
282 .gpc_name
= "pcie-phy",
286 static const struct imx8mp_blk_ctrl_data imx8mp_hsio_blk_ctl_dev_data
= {
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
),
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)
305 static void imx8mp_hdmi_blk_ctrl_power_on(struct imx8mp_blk_ctrl
*bc
,
306 struct imx8mp_blk_ctrl_domain
*domain
)
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));
313 case IMX8MP_HDMIBLK_PD_LCDIF
:
314 regmap_set_bits(bc
->regmap
, HDMI_RTX_CLK_CTL0
,
315 BIT(16) | BIT(17) | BIT(18) |
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));
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));
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));
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));
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));
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));
351 case IMX8MP_HDMIBLK_PD_HDCP
:
352 regmap_set_bits(bc
->regmap
, HDMI_RTX_CLK_CTL0
, BIT(11));
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));
363 static void imx8mp_hdmi_blk_ctrl_power_off(struct imx8mp_blk_ctrl
*bc
,
364 struct imx8mp_blk_ctrl_domain
*domain
)
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));
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) |
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));
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));
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));
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));
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));
407 case IMX8MP_HDMIBLK_PD_HDCP
:
408 regmap_clear_bits(bc
->regmap
, HDMI_RTX_CLK_CTL0
, BIT(11));
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));
419 static int imx8mp_hdmi_power_notifier(struct notifier_block
*nb
,
420 unsigned long action
, void *data
)
422 struct imx8mp_blk_ctrl
*bc
= container_of(nb
, struct imx8mp_blk_ctrl
,
425 if (action
!= GENPD_NOTIFY_ON
)
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.
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));
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.
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" },
456 .gpc_name
= "irqsteer",
458 [IMX8MP_HDMIBLK_PD_LCDIF
] = {
459 .name
= "hdmiblk-lcdif",
460 .clk_names
= (const char *[]){ "axi", "apb", "fdcc" },
463 .path_names
= (const char *[]){"lcdif-hdmi"},
466 [IMX8MP_HDMIBLK_PD_PAI
] = {
467 .name
= "hdmiblk-pai",
468 .clk_names
= (const char *[]){ "apb" },
472 [IMX8MP_HDMIBLK_PD_PVI
] = {
473 .name
= "hdmiblk-pvi",
474 .clk_names
= (const char *[]){ "apb" },
478 [IMX8MP_HDMIBLK_PD_TRNG
] = {
479 .name
= "hdmiblk-trng",
480 .clk_names
= (const char *[]){ "apb" },
484 [IMX8MP_HDMIBLK_PD_HDMI_TX
] = {
485 .name
= "hdmiblk-hdmi-tx",
486 .clk_names
= (const char *[]){ "apb", "ref_266m", "fdcc" },
488 .gpc_name
= "hdmi-tx",
490 [IMX8MP_HDMIBLK_PD_HDMI_TX_PHY
] = {
491 .name
= "hdmiblk-hdmi-tx-phy",
492 .clk_names
= (const char *[]){ "apb", "ref_24m" },
494 .gpc_name
= "hdmi-tx-phy",
496 [IMX8MP_HDMIBLK_PD_HRV
] = {
497 .name
= "hdmiblk-hrv",
498 .clk_names
= (const char *[]){ "axi", "apb" },
501 .path_names
= (const char *[]){"hrv"},
504 [IMX8MP_HDMIBLK_PD_HDCP
] = {
505 .name
= "hdmiblk-hdcp",
506 .clk_names
= (const char *[]){ "axi", "apb" },
509 .path_names
= (const char *[]){"hdcp"},
514 static const struct imx8mp_blk_ctrl_data imx8mp_hdmi_blk_ctl_dev_data
= {
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
),
523 static int imx8mp_blk_ctrl_power_on(struct generic_pm_domain
*genpd
)
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
;
530 /* make sure bus domain is awake */
531 ret
= pm_runtime_resume_and_get(bc
->bus_power_dev
);
533 dev_err(bc
->dev
, "failed to power up bus domain\n");
537 /* enable upstream clocks */
538 ret
= clk_bulk_prepare_enable(data
->num_clks
, domain
->clks
);
540 dev_err(bc
->dev
, "failed to enable clocks\n");
544 /* domain specific blk-ctrl manipulation */
545 bc
->power_on(bc
, domain
);
547 /* power up upstream GPC domain */
548 ret
= pm_runtime_resume_and_get(domain
->power_dev
);
550 dev_err(bc
->dev
, "failed to power up peripheral domain\n");
554 ret
= icc_bulk_set_bw(domain
->num_paths
, domain
->paths
);
556 dev_err(bc
->dev
, "failed to set icc bw\n");
558 clk_bulk_disable_unprepare(data
->num_clks
, domain
->clks
);
563 clk_bulk_disable_unprepare(data
->num_clks
, domain
->clks
);
565 pm_runtime_put(bc
->bus_power_dev
);
570 static int imx8mp_blk_ctrl_power_off(struct generic_pm_domain
*genpd
)
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
;
577 ret
= clk_bulk_prepare_enable(data
->num_clks
, domain
->clks
);
579 dev_err(bc
->dev
, "failed to enable clocks\n");
583 /* domain specific blk-ctrl manipulation */
584 bc
->power_off(bc
, domain
);
586 clk_bulk_disable_unprepare(data
->num_clks
, domain
->clks
);
588 /* power down upstream GPC domain */
589 pm_runtime_put(domain
->power_dev
);
591 /* allow bus domain to suspend */
592 pm_runtime_put(bc
->bus_power_dev
);
597 static struct lock_class_key blk_ctrl_genpd_lock_class
;
599 static int imx8mp_blk_ctrl_probe(struct platform_device
*pdev
)
601 const struct imx8mp_blk_ctrl_data
*bc_data
;
602 struct device
*dev
= &pdev
->dev
;
603 struct imx8mp_blk_ctrl
*bc
;
605 int num_domains
, i
, ret
;
607 struct regmap_config regmap_config
= {
613 bc
= devm_kzalloc(dev
, sizeof(*bc
), GFP_KERNEL
);
619 bc_data
= of_device_get_match_data(dev
);
620 num_domains
= bc_data
->num_domains
;
622 base
= devm_platform_ioremap_resource(pdev
, 0);
624 return PTR_ERR(base
);
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");
632 bc
->domains
= devm_kcalloc(dev
, num_domains
,
633 sizeof(struct imx8mp_blk_ctrl_domain
),
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
)
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");
650 bc
->power_off
= bc_data
->power_off
;
651 bc
->power_on
= bc_data
->power_on
;
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
];
659 domain
->num_paths
= data
->num_paths
;
661 for (j
= 0; j
< data
->num_clks
; j
++)
662 domain
->clks
[j
].id
= data
->clk_names
[j
];
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;
671 ret
= devm_of_icc_bulk_get(dev
, data
->num_paths
, domain
->paths
);
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;
677 dev_err_probe(dev
, ret
, "failed to get noc entries\n");
682 ret
= devm_clk_bulk_get(dev
, data
->num_clks
, domain
->clks
);
684 dev_err_probe(dev
, ret
, "failed to get clock\n");
689 dev_pm_domain_attach_by_name(dev
, data
->gpc_name
);
690 if (IS_ERR_OR_NULL(domain
->power_dev
)) {
691 if (!domain
->power_dev
)
694 ret
= PTR_ERR(domain
->power_dev
);
695 dev_err_probe(dev
, ret
,
696 "failed to attach power domain %s\n",
701 domain
->genpd
.name
= data
->name
;
702 domain
->genpd
.power_on
= imx8mp_blk_ctrl_power_on
;
703 domain
->genpd
.power_off
= imx8mp_blk_ctrl_power_off
;
707 ret
= pm_genpd_init(&domain
->genpd
, NULL
, true);
709 dev_err_probe(dev
, ret
, "failed to init power domain\n");
710 dev_pm_domain_detach(domain
->power_dev
, true);
715 * We use runtime PM to trigger power on/off of the upstream GPC
716 * domain, as a strict hierarchical parent/child power domain
717 * setup doesn't allow us to meet the sequencing requirements.
718 * This means we have nested locking of genpd locks, without the
719 * nesting being visible at the genpd level, so we need a
720 * separate lock class to make lockdep aware of the fact that
721 * this are separate domain locks that can be nested without a
724 lockdep_set_class(&domain
->genpd
.mlock
,
725 &blk_ctrl_genpd_lock_class
);
727 bc
->onecell_data
.domains
[i
] = &domain
->genpd
;
730 ret
= of_genpd_add_provider_onecell(dev
->of_node
, &bc
->onecell_data
);
732 dev_err_probe(dev
, ret
, "failed to add power domain provider\n");
736 bc
->power_nb
.notifier_call
= bc_data
->power_notifier_fn
;
737 ret
= dev_pm_genpd_add_notifier(bc
->bus_power_dev
, &bc
->power_nb
);
739 dev_err_probe(dev
, ret
, "failed to add power notifier\n");
740 goto cleanup_provider
;
743 if (bc_data
->probe
) {
744 ret
= bc_data
->probe(bc
);
746 goto cleanup_provider
;
749 dev_set_drvdata(dev
, bc
);
754 of_genpd_del_provider(dev
->of_node
);
756 for (i
--; i
>= 0; i
--) {
757 pm_genpd_remove(&bc
->domains
[i
].genpd
);
758 dev_pm_domain_detach(bc
->domains
[i
].power_dev
, true);
761 dev_pm_domain_detach(bc
->bus_power_dev
, true);
766 static void imx8mp_blk_ctrl_remove(struct platform_device
*pdev
)
768 struct imx8mp_blk_ctrl
*bc
= dev_get_drvdata(&pdev
->dev
);
771 of_genpd_del_provider(pdev
->dev
.of_node
);
773 for (i
= 0; bc
->onecell_data
.num_domains
; i
++) {
774 struct imx8mp_blk_ctrl_domain
*domain
= &bc
->domains
[i
];
776 pm_genpd_remove(&domain
->genpd
);
777 dev_pm_domain_detach(domain
->power_dev
, true);
780 dev_pm_genpd_remove_notifier(bc
->bus_power_dev
);
782 dev_pm_domain_detach(bc
->bus_power_dev
, true);
785 #ifdef CONFIG_PM_SLEEP
786 static int imx8mp_blk_ctrl_suspend(struct device
*dev
)
788 struct imx8mp_blk_ctrl
*bc
= dev_get_drvdata(dev
);
792 * This may look strange, but is done so the generic PM_SLEEP code
793 * can power down our domains and more importantly power them up again
794 * after resume, without tripping over our usage of runtime PM to
795 * control the upstream GPC domains. Things happen in the right order
796 * in the system suspend/resume paths due to the device parent/child
799 ret
= pm_runtime_get_sync(bc
->bus_power_dev
);
801 pm_runtime_put_noidle(bc
->bus_power_dev
);
805 for (i
= 0; i
< bc
->onecell_data
.num_domains
; i
++) {
806 struct imx8mp_blk_ctrl_domain
*domain
= &bc
->domains
[i
];
808 ret
= pm_runtime_get_sync(domain
->power_dev
);
810 pm_runtime_put_noidle(domain
->power_dev
);
818 for (i
--; i
>= 0; i
--)
819 pm_runtime_put(bc
->domains
[i
].power_dev
);
821 pm_runtime_put(bc
->bus_power_dev
);
826 static int imx8mp_blk_ctrl_resume(struct device
*dev
)
828 struct imx8mp_blk_ctrl
*bc
= dev_get_drvdata(dev
);
831 for (i
= 0; i
< bc
->onecell_data
.num_domains
; i
++)
832 pm_runtime_put(bc
->domains
[i
].power_dev
);
834 pm_runtime_put(bc
->bus_power_dev
);
840 static const struct dev_pm_ops imx8mp_blk_ctrl_pm_ops
= {
841 SET_SYSTEM_SLEEP_PM_OPS(imx8mp_blk_ctrl_suspend
,
842 imx8mp_blk_ctrl_resume
)
845 static const struct of_device_id imx8mp_blk_ctrl_of_match
[] = {
847 .compatible
= "fsl,imx8mp-hsio-blk-ctrl",
848 .data
= &imx8mp_hsio_blk_ctl_dev_data
,
850 .compatible
= "fsl,imx8mp-hdmi-blk-ctrl",
851 .data
= &imx8mp_hdmi_blk_ctl_dev_data
,
856 MODULE_DEVICE_TABLE(of
, imx8mp_blk_ctrl_of_match
);
858 static struct platform_driver imx8mp_blk_ctrl_driver
= {
859 .probe
= imx8mp_blk_ctrl_probe
,
860 .remove
= imx8mp_blk_ctrl_remove
,
862 .name
= "imx8mp-blk-ctrl",
863 .pm
= &imx8mp_blk_ctrl_pm_ops
,
864 .of_match_table
= imx8mp_blk_ctrl_of_match
,
867 module_platform_driver(imx8mp_blk_ctrl_driver
);
868 MODULE_LICENSE("GPL");