xref: /linux/drivers/pmdomain/imx/imx8mp-blk-ctrl.c (revision 6f7e6393d1ce636bb7ec77a7fe7b77458fddf701)
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, &regmap_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