xref: /linux/drivers/pmdomain/imx/imx8mp-blk-ctrl.c (revision d58305b2dbe3434c9b21ede210329b97c44ee9e8)
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 *
to_imx8mp_blk_ctrl_domain(struct generic_pm_domain * genpd)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 
to_clk_hsio_pll(struct clk_hw * hw)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 
clk_hsio_pll_prepare(struct clk_hw * hw)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 
clk_hsio_pll_unprepare(struct clk_hw * hw)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 
clk_hsio_pll_is_prepared(struct clk_hw * hw)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 
clk_hsio_pll_recalc_rate(struct clk_hw * hw,unsigned long parent_rate)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 
imx8mp_hsio_blk_ctrl_probe(struct imx8mp_blk_ctrl * bc)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 
imx8mp_hsio_blk_ctrl_power_on(struct imx8mp_blk_ctrl * bc,struct imx8mp_blk_ctrl_domain * domain)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 
imx8mp_hsio_blk_ctrl_power_off(struct imx8mp_blk_ctrl * bc,struct imx8mp_blk_ctrl_domain * domain)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 
imx8mp_hsio_power_notifier(struct notifier_block * nb,unsigned long action,void * data)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 
imx8mp_hdmi_blk_ctrl_power_on(struct imx8mp_blk_ctrl * bc,struct imx8mp_blk_ctrl_domain * domain)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_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 
imx8mp_hdmi_blk_ctrl_power_off(struct imx8mp_blk_ctrl * bc,struct imx8mp_blk_ctrl_domain * domain)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_HRV:
409 		regmap_clear_bits(bc->regmap, HDMI_RTX_RESET_CTL0, BIT(15));
410 		regmap_clear_bits(bc->regmap, HDMI_RTX_CLK_CTL1, BIT(3) | BIT(4) | BIT(5));
411 		break;
412 	default:
413 		break;
414 	}
415 }
416 
imx8mp_hdmi_power_notifier(struct notifier_block * nb,unsigned long action,void * data)417 static int imx8mp_hdmi_power_notifier(struct notifier_block *nb,
418 				      unsigned long action, void *data)
419 {
420 	struct imx8mp_blk_ctrl *bc = container_of(nb, struct imx8mp_blk_ctrl,
421 						 power_nb);
422 
423 	if (action != GENPD_NOTIFY_ON)
424 		return NOTIFY_OK;
425 
426 	/*
427 	 * Contrary to other blk-ctrls the reset and clock don't clear when the
428 	 * power domain is powered down. To ensure the proper reset pulsing,
429 	 * first clear them all to asserted state, then enable the bus clocks
430 	 * and then release the ADB reset.
431 	 */
432 	regmap_write(bc->regmap, HDMI_RTX_RESET_CTL0, 0x0);
433 	regmap_write(bc->regmap, HDMI_RTX_CLK_CTL0, 0x0);
434 	regmap_write(bc->regmap, HDMI_RTX_CLK_CTL1, 0x0);
435 	regmap_set_bits(bc->regmap, HDMI_RTX_CLK_CTL0,
436 			BIT(0) | BIT(1) | BIT(10) | BIT(11));
437 	regmap_set_bits(bc->regmap, HDMI_RTX_RESET_CTL0, BIT(0));
438 
439 	/*
440 	 * On power up we have no software backchannel to the GPC to
441 	 * wait for the ADB handshake to happen, so we just delay for a
442 	 * bit. On power down the GPC driver waits for the handshake.
443 	 */
444 	udelay(5);
445 
446 	return NOTIFY_OK;
447 }
448 
449 static const struct imx8mp_blk_ctrl_domain_data imx8mp_hdmi_domain_data[] = {
450 	[IMX8MP_HDMIBLK_PD_IRQSTEER] = {
451 		.name = "hdmiblk-irqsteer",
452 		.clk_names = (const char *[]){ "apb" },
453 		.num_clks = 1,
454 		.gpc_name = "irqsteer",
455 	},
456 	[IMX8MP_HDMIBLK_PD_LCDIF] = {
457 		.name = "hdmiblk-lcdif",
458 		.clk_names = (const char *[]){ "axi", "apb", "fdcc" },
459 		.num_clks = 3,
460 		.gpc_name = "lcdif",
461 		.path_names = (const char *[]){"lcdif-hdmi"},
462 		.num_paths = 1,
463 	},
464 	[IMX8MP_HDMIBLK_PD_PAI] = {
465 		.name = "hdmiblk-pai",
466 		.clk_names = (const char *[]){ "apb" },
467 		.num_clks = 1,
468 		.gpc_name = "pai",
469 	},
470 	[IMX8MP_HDMIBLK_PD_PVI] = {
471 		.name = "hdmiblk-pvi",
472 		.clk_names = (const char *[]){ "apb" },
473 		.num_clks = 1,
474 		.gpc_name = "pvi",
475 	},
476 	[IMX8MP_HDMIBLK_PD_TRNG] = {
477 		.name = "hdmiblk-trng",
478 		.clk_names = (const char *[]){ "apb" },
479 		.num_clks = 1,
480 		.gpc_name = "trng",
481 	},
482 	[IMX8MP_HDMIBLK_PD_HDMI_TX] = {
483 		.name = "hdmiblk-hdmi-tx",
484 		.clk_names = (const char *[]){ "apb", "ref_266m", "fdcc" },
485 		.num_clks = 3,
486 		.gpc_name = "hdmi-tx",
487 	},
488 	[IMX8MP_HDMIBLK_PD_HDMI_TX_PHY] = {
489 		.name = "hdmiblk-hdmi-tx-phy",
490 		.clk_names = (const char *[]){ "apb", "ref_24m" },
491 		.num_clks = 2,
492 		.gpc_name = "hdmi-tx-phy",
493 	},
494 	[IMX8MP_HDMIBLK_PD_HRV] = {
495 		.name = "hdmiblk-hrv",
496 		.clk_names = (const char *[]){ "axi", "apb" },
497 		.num_clks = 2,
498 		.gpc_name = "hrv",
499 		.path_names = (const char *[]){"hrv"},
500 		.num_paths = 1,
501 	},
502 	[IMX8MP_HDMIBLK_PD_HDCP] = {
503 		.name = "hdmiblk-hdcp",
504 		.clk_names = (const char *[]){ "axi", "apb" },
505 		.num_clks = 2,
506 		.gpc_name = "hdcp",
507 		.path_names = (const char *[]){"hdcp"},
508 		.num_paths = 1,
509 	},
510 };
511 
512 static const struct imx8mp_blk_ctrl_data imx8mp_hdmi_blk_ctl_dev_data = {
513 	.max_reg = 0x23c,
514 	.power_on = imx8mp_hdmi_blk_ctrl_power_on,
515 	.power_off = imx8mp_hdmi_blk_ctrl_power_off,
516 	.power_notifier_fn = imx8mp_hdmi_power_notifier,
517 	.domains = imx8mp_hdmi_domain_data,
518 	.num_domains = ARRAY_SIZE(imx8mp_hdmi_domain_data),
519 };
520 
imx8mp_blk_ctrl_power_on(struct generic_pm_domain * genpd)521 static int imx8mp_blk_ctrl_power_on(struct generic_pm_domain *genpd)
522 {
523 	struct imx8mp_blk_ctrl_domain *domain = to_imx8mp_blk_ctrl_domain(genpd);
524 	const struct imx8mp_blk_ctrl_domain_data *data = domain->data;
525 	struct imx8mp_blk_ctrl *bc = domain->bc;
526 	int ret;
527 
528 	/* make sure bus domain is awake */
529 	ret = pm_runtime_resume_and_get(bc->bus_power_dev);
530 	if (ret < 0) {
531 		dev_err(bc->dev, "failed to power up bus domain\n");
532 		return ret;
533 	}
534 
535 	/* enable upstream clocks */
536 	ret = clk_bulk_prepare_enable(data->num_clks, domain->clks);
537 	if (ret) {
538 		dev_err(bc->dev, "failed to enable clocks\n");
539 		goto bus_put;
540 	}
541 
542 	/* domain specific blk-ctrl manipulation */
543 	bc->power_on(bc, domain);
544 
545 	/* power up upstream GPC domain */
546 	ret = pm_runtime_resume_and_get(domain->power_dev);
547 	if (ret < 0) {
548 		dev_err(bc->dev, "failed to power up peripheral domain\n");
549 		goto clk_disable;
550 	}
551 
552 	ret = icc_bulk_set_bw(domain->num_paths, domain->paths);
553 	if (ret)
554 		dev_err(bc->dev, "failed to set icc bw\n");
555 
556 	clk_bulk_disable_unprepare(data->num_clks, domain->clks);
557 
558 	return 0;
559 
560 clk_disable:
561 	clk_bulk_disable_unprepare(data->num_clks, domain->clks);
562 bus_put:
563 	pm_runtime_put(bc->bus_power_dev);
564 
565 	return ret;
566 }
567 
imx8mp_blk_ctrl_power_off(struct generic_pm_domain * genpd)568 static int imx8mp_blk_ctrl_power_off(struct generic_pm_domain *genpd)
569 {
570 	struct imx8mp_blk_ctrl_domain *domain = to_imx8mp_blk_ctrl_domain(genpd);
571 	const struct imx8mp_blk_ctrl_domain_data *data = domain->data;
572 	struct imx8mp_blk_ctrl *bc = domain->bc;
573 	int ret;
574 
575 	ret = clk_bulk_prepare_enable(data->num_clks, domain->clks);
576 	if (ret) {
577 		dev_err(bc->dev, "failed to enable clocks\n");
578 		return ret;
579 	}
580 
581 	/* domain specific blk-ctrl manipulation */
582 	bc->power_off(bc, domain);
583 
584 	clk_bulk_disable_unprepare(data->num_clks, domain->clks);
585 
586 	/* power down upstream GPC domain */
587 	pm_runtime_put(domain->power_dev);
588 
589 	/* allow bus domain to suspend */
590 	pm_runtime_put(bc->bus_power_dev);
591 
592 	return 0;
593 }
594 
imx8mp_blk_ctrl_gpc_notifier(struct notifier_block * nb,unsigned long action,void * data)595 static int imx8mp_blk_ctrl_gpc_notifier(struct notifier_block *nb,
596 					unsigned long action, void *data)
597 {
598 	struct imx8mp_blk_ctrl_domain *domain =
599 			container_of(nb, struct imx8mp_blk_ctrl_domain, power_nb);
600 
601 	if (action == GENPD_NOTIFY_PRE_OFF) {
602 		if (domain->genpd.status == GENPD_STATE_ON)
603 			return NOTIFY_BAD;
604 	}
605 
606 	return NOTIFY_OK;
607 }
608 
609 static struct lock_class_key blk_ctrl_genpd_lock_class;
610 
imx8mp_blk_ctrl_probe(struct platform_device * pdev)611 static int imx8mp_blk_ctrl_probe(struct platform_device *pdev)
612 {
613 	const struct imx8mp_blk_ctrl_data *bc_data;
614 	struct device *dev = &pdev->dev;
615 	struct imx8mp_blk_ctrl *bc;
616 	void __iomem *base;
617 	int num_domains, i, ret;
618 
619 	struct regmap_config regmap_config = {
620 		.reg_bits	= 32,
621 		.val_bits	= 32,
622 		.reg_stride	= 4,
623 	};
624 
625 	bc = devm_kzalloc(dev, sizeof(*bc), GFP_KERNEL);
626 	if (!bc)
627 		return -ENOMEM;
628 
629 	bc->dev = dev;
630 
631 	bc_data = of_device_get_match_data(dev);
632 	num_domains = bc_data->num_domains;
633 
634 	base = devm_platform_ioremap_resource(pdev, 0);
635 	if (IS_ERR(base))
636 		return PTR_ERR(base);
637 
638 	regmap_config.max_register = bc_data->max_reg;
639 	bc->regmap = devm_regmap_init_mmio(dev, base, &regmap_config);
640 	if (IS_ERR(bc->regmap))
641 		return dev_err_probe(dev, PTR_ERR(bc->regmap),
642 				     "failed to init regmap\n");
643 
644 	bc->domains = devm_kcalloc(dev, num_domains,
645 				   sizeof(struct imx8mp_blk_ctrl_domain),
646 				   GFP_KERNEL);
647 	if (!bc->domains)
648 		return -ENOMEM;
649 
650 	bc->onecell_data.num_domains = num_domains;
651 	bc->onecell_data.domains =
652 		devm_kcalloc(dev, num_domains,
653 			     sizeof(struct generic_pm_domain *), GFP_KERNEL);
654 	if (!bc->onecell_data.domains)
655 		return -ENOMEM;
656 
657 	bc->bus_power_dev = dev_pm_domain_attach_by_name(dev, "bus");
658 	if (IS_ERR(bc->bus_power_dev))
659 		return dev_err_probe(dev, PTR_ERR(bc->bus_power_dev),
660 				     "failed to attach bus power domain\n");
661 
662 	bc->power_off = bc_data->power_off;
663 	bc->power_on = bc_data->power_on;
664 
665 	for (i = 0; i < num_domains; i++) {
666 		const struct imx8mp_blk_ctrl_domain_data *data = &bc_data->domains[i];
667 		struct imx8mp_blk_ctrl_domain *domain = &bc->domains[i];
668 		int j;
669 
670 		domain->data = data;
671 		domain->num_paths = data->num_paths;
672 
673 		for (j = 0; j < data->num_clks; j++)
674 			domain->clks[j].id = data->clk_names[j];
675 
676 		for (j = 0; j < data->num_paths; j++) {
677 			domain->paths[j].name = data->path_names[j];
678 			/* Fake value for now, just let ICC could configure NoC mode/priority */
679 			domain->paths[j].avg_bw = 1;
680 			domain->paths[j].peak_bw = 1;
681 		}
682 
683 		ret = devm_of_icc_bulk_get(dev, data->num_paths, domain->paths);
684 		if (ret) {
685 			if (ret != -EPROBE_DEFER) {
686 				dev_warn_once(dev, "Could not get interconnect paths, NoC will stay unconfigured!\n");
687 				domain->num_paths = 0;
688 			} else {
689 				dev_err_probe(dev, ret, "failed to get noc entries\n");
690 				goto cleanup_pds;
691 			}
692 		}
693 
694 		ret = devm_clk_bulk_get(dev, data->num_clks, domain->clks);
695 		if (ret) {
696 			dev_err_probe(dev, ret, "failed to get clock\n");
697 			goto cleanup_pds;
698 		}
699 
700 		domain->power_dev =
701 			dev_pm_domain_attach_by_name(dev, data->gpc_name);
702 		if (IS_ERR_OR_NULL(domain->power_dev)) {
703 			if (!domain->power_dev)
704 				ret = -ENODEV;
705 			else
706 				ret = PTR_ERR(domain->power_dev);
707 			dev_err_probe(dev, ret,
708 				      "failed to attach power domain %s\n",
709 				      data->gpc_name);
710 			goto cleanup_pds;
711 		}
712 
713 		domain->power_nb.notifier_call = imx8mp_blk_ctrl_gpc_notifier;
714 		ret = dev_pm_genpd_add_notifier(domain->power_dev, &domain->power_nb);
715 		if (ret) {
716 			dev_err_probe(dev, ret, "failed to add power notifier\n");
717 			dev_pm_domain_detach(domain->power_dev, true);
718 			goto cleanup_pds;
719 		}
720 
721 		domain->genpd.name = data->name;
722 		domain->genpd.power_on = imx8mp_blk_ctrl_power_on;
723 		domain->genpd.power_off = imx8mp_blk_ctrl_power_off;
724 		domain->genpd.flags = data->flags;
725 		domain->bc = bc;
726 		domain->id = i;
727 
728 		ret = pm_genpd_init(&domain->genpd, NULL, true);
729 		if (ret) {
730 			dev_err_probe(dev, ret, "failed to init power domain\n");
731 			dev_pm_genpd_remove_notifier(domain->power_dev);
732 			dev_pm_domain_detach(domain->power_dev, true);
733 			goto cleanup_pds;
734 		}
735 
736 		/*
737 		 * We use runtime PM to trigger power on/off of the upstream GPC
738 		 * domain, as a strict hierarchical parent/child power domain
739 		 * setup doesn't allow us to meet the sequencing requirements.
740 		 * This means we have nested locking of genpd locks, without the
741 		 * nesting being visible at the genpd level, so we need a
742 		 * separate lock class to make lockdep aware of the fact that
743 		 * this are separate domain locks that can be nested without a
744 		 * self-deadlock.
745 		 */
746 		lockdep_set_class(&domain->genpd.mlock,
747 				  &blk_ctrl_genpd_lock_class);
748 
749 		bc->onecell_data.domains[i] = &domain->genpd;
750 	}
751 
752 	ret = of_genpd_add_provider_onecell(dev->of_node, &bc->onecell_data);
753 	if (ret) {
754 		dev_err_probe(dev, ret, "failed to add power domain provider\n");
755 		goto cleanup_pds;
756 	}
757 
758 	bc->power_nb.notifier_call = bc_data->power_notifier_fn;
759 	ret = dev_pm_genpd_add_notifier(bc->bus_power_dev, &bc->power_nb);
760 	if (ret) {
761 		dev_err_probe(dev, ret, "failed to add power notifier\n");
762 		goto cleanup_provider;
763 	}
764 
765 	if (bc_data->probe) {
766 		ret = bc_data->probe(bc);
767 		if (ret)
768 			goto cleanup_provider;
769 	}
770 
771 	dev_set_drvdata(dev, bc);
772 
773 	return 0;
774 
775 cleanup_provider:
776 	of_genpd_del_provider(dev->of_node);
777 cleanup_pds:
778 	for (i--; i >= 0; i--) {
779 		pm_genpd_remove(&bc->domains[i].genpd);
780 		dev_pm_genpd_remove_notifier(bc->domains[i].power_dev);
781 		dev_pm_domain_detach(bc->domains[i].power_dev, true);
782 	}
783 
784 	dev_pm_domain_detach(bc->bus_power_dev, true);
785 
786 	return ret;
787 }
788 
imx8mp_blk_ctrl_remove(struct platform_device * pdev)789 static void imx8mp_blk_ctrl_remove(struct platform_device *pdev)
790 {
791 	struct imx8mp_blk_ctrl *bc = dev_get_drvdata(&pdev->dev);
792 	int i;
793 
794 	of_genpd_del_provider(pdev->dev.of_node);
795 
796 	for (i = 0; i < bc->onecell_data.num_domains; i++) {
797 		struct imx8mp_blk_ctrl_domain *domain = &bc->domains[i];
798 
799 		pm_genpd_remove(&domain->genpd);
800 		dev_pm_genpd_remove_notifier(domain->power_dev);
801 		dev_pm_domain_detach(domain->power_dev, true);
802 	}
803 
804 	dev_pm_genpd_remove_notifier(bc->bus_power_dev);
805 
806 	dev_pm_domain_detach(bc->bus_power_dev, true);
807 }
808 
809 #ifdef CONFIG_PM_SLEEP
imx8mp_blk_ctrl_suspend(struct device * dev)810 static int imx8mp_blk_ctrl_suspend(struct device *dev)
811 {
812 	struct imx8mp_blk_ctrl *bc = dev_get_drvdata(dev);
813 	int ret, i;
814 
815 	/*
816 	 * This may look strange, but is done so the generic PM_SLEEP code
817 	 * can power down our domains and more importantly power them up again
818 	 * after resume, without tripping over our usage of runtime PM to
819 	 * control the upstream GPC domains. Things happen in the right order
820 	 * in the system suspend/resume paths due to the device parent/child
821 	 * hierarchy.
822 	 */
823 	ret = pm_runtime_get_sync(bc->bus_power_dev);
824 	if (ret < 0) {
825 		pm_runtime_put_noidle(bc->bus_power_dev);
826 		return ret;
827 	}
828 
829 	for (i = 0; i < bc->onecell_data.num_domains; i++) {
830 		struct imx8mp_blk_ctrl_domain *domain = &bc->domains[i];
831 
832 		ret = pm_runtime_get_sync(domain->power_dev);
833 		if (ret < 0) {
834 			pm_runtime_put_noidle(domain->power_dev);
835 			goto out_fail;
836 		}
837 	}
838 
839 	return 0;
840 
841 out_fail:
842 	for (i--; i >= 0; i--)
843 		pm_runtime_put(bc->domains[i].power_dev);
844 
845 	pm_runtime_put(bc->bus_power_dev);
846 
847 	return ret;
848 }
849 
imx8mp_blk_ctrl_resume(struct device * dev)850 static int imx8mp_blk_ctrl_resume(struct device *dev)
851 {
852 	struct imx8mp_blk_ctrl *bc = dev_get_drvdata(dev);
853 	int i;
854 
855 	for (i = 0; i < bc->onecell_data.num_domains; i++)
856 		pm_runtime_put(bc->domains[i].power_dev);
857 
858 	pm_runtime_put(bc->bus_power_dev);
859 
860 	return 0;
861 }
862 #endif
863 
864 static const struct dev_pm_ops imx8mp_blk_ctrl_pm_ops = {
865 	SET_SYSTEM_SLEEP_PM_OPS(imx8mp_blk_ctrl_suspend,
866 				imx8mp_blk_ctrl_resume)
867 };
868 
869 static const struct of_device_id imx8mp_blk_ctrl_of_match[] = {
870 	{
871 		.compatible = "fsl,imx8mp-hsio-blk-ctrl",
872 		.data = &imx8mp_hsio_blk_ctl_dev_data,
873 	}, {
874 		.compatible = "fsl,imx8mp-hdmi-blk-ctrl",
875 		.data = &imx8mp_hdmi_blk_ctl_dev_data,
876 	}, {
877 		/* Sentinel */
878 	}
879 };
880 MODULE_DEVICE_TABLE(of, imx8mp_blk_ctrl_of_match);
881 
882 static struct platform_driver imx8mp_blk_ctrl_driver = {
883 	.probe = imx8mp_blk_ctrl_probe,
884 	.remove = imx8mp_blk_ctrl_remove,
885 	.driver = {
886 		.name = "imx8mp-blk-ctrl",
887 		.pm = &imx8mp_blk_ctrl_pm_ops,
888 		.of_match_table = imx8mp_blk_ctrl_of_match,
889 		.suppress_bind_attrs = true,
890 	},
891 };
892 module_platform_driver(imx8mp_blk_ctrl_driver);
893 MODULE_LICENSE("GPL");
894