blob: 8b6870c8646335194cdc8edae34b944fde078f56 [file] [log] [blame]
Patrick Wildt8bd56562019-10-03 15:51:50 +02001// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright 2017 NXP
4 */
5
Marek Vasute5481a82022-04-13 00:42:51 +02006#include <clk.h>
Patrick Wildt8bd56562019-10-03 15:51:50 +02007#include <dm.h>
Simon Glass9bc15642020-02-03 07:36:16 -07008#include <malloc.h>
Patrick Wildt8bd56562019-10-03 15:51:50 +02009#include <power-domain-uclass.h>
Simon Glass3ba929a2020-10-30 21:38:53 -060010#include <asm/global_data.h>
Patrick Wildt8bd56562019-10-03 15:51:50 +020011#include <asm/io.h>
Patrick Wildt8bd56562019-10-03 15:51:50 +020012#include <asm/mach-imx/sys_proto.h>
13#include <dm/device-internal.h>
14#include <dm/device.h>
Marek Vasute5481a82022-04-13 00:42:51 +020015#include <dm/device_compat.h>
Patrick Wildt8bd56562019-10-03 15:51:50 +020016#include <imx_sip.h>
Marek Vasute5481a82022-04-13 00:42:51 +020017#include <linux/bitmap.h>
18#include <wait_bit.h>
19
20#include <dt-bindings/power/imx8mm-power.h>
21#include <dt-bindings/power/imx8mn-power.h>
Marek Vasut2e1405e2022-04-13 00:42:53 +020022#include <dt-bindings/power/imx8mp-power.h>
Marek Vasute5481a82022-04-13 00:42:51 +020023#include <dt-bindings/power/imx8mq-power.h>
Patrick Wildt8bd56562019-10-03 15:51:50 +020024
25DECLARE_GLOBAL_DATA_PTR;
26
Marek Vasute5481a82022-04-13 00:42:51 +020027#define GPC_PGC_CPU_MAPPING 0x0ec
Marek Vasut2e1405e2022-04-13 00:42:53 +020028#define IMX8MP_GPC_PGC_CPU_MAPPING 0x1cc
Marek Vasute5481a82022-04-13 00:42:51 +020029
30#define IMX8M_PCIE2_A53_DOMAIN BIT(15)
31#define IMX8M_OTG2_A53_DOMAIN BIT(5)
32#define IMX8M_OTG1_A53_DOMAIN BIT(4)
33#define IMX8M_PCIE1_A53_DOMAIN BIT(3)
34
35#define IMX8MM_OTG2_A53_DOMAIN BIT(5)
36#define IMX8MM_OTG1_A53_DOMAIN BIT(4)
37#define IMX8MM_PCIE_A53_DOMAIN BIT(3)
38
39#define IMX8MN_OTG1_A53_DOMAIN BIT(4)
40#define IMX8MN_MIPI_A53_DOMAIN BIT(2)
41
Marek Vasut2e1405e2022-04-13 00:42:53 +020042#define IMX8MP_HSIOMIX_A53_DOMAIN BIT(19)
43#define IMX8MP_USB2_PHY_A53_DOMAIN BIT(5)
44#define IMX8MP_USB1_PHY_A53_DOMAIN BIT(4)
45#define IMX8MP_PCIE_PHY_A53_DOMAIN BIT(3)
46
47#define IMX8MP_GPC_PU_PGC_SW_PUP_REQ 0x0d8
48#define IMX8MP_GPC_PU_PGC_SW_PDN_REQ 0x0e4
49
Marek Vasute5481a82022-04-13 00:42:51 +020050#define GPC_PU_PGC_SW_PUP_REQ 0x0f8
51#define GPC_PU_PGC_SW_PDN_REQ 0x104
52
53#define IMX8M_PCIE2_SW_Pxx_REQ BIT(13)
54#define IMX8M_OTG2_SW_Pxx_REQ BIT(3)
55#define IMX8M_OTG1_SW_Pxx_REQ BIT(2)
56#define IMX8M_PCIE1_SW_Pxx_REQ BIT(1)
57
58#define IMX8MM_OTG2_SW_Pxx_REQ BIT(3)
59#define IMX8MM_OTG1_SW_Pxx_REQ BIT(2)
60#define IMX8MM_PCIE_SW_Pxx_REQ BIT(1)
61
62#define IMX8MN_OTG1_SW_Pxx_REQ BIT(2)
63#define IMX8MN_MIPI_SW_Pxx_REQ BIT(0)
64
Marek Vasut2e1405e2022-04-13 00:42:53 +020065#define IMX8MP_HSIOMIX_Pxx_REQ BIT(17)
66#define IMX8MP_USB2_PHY_Pxx_REQ BIT(3)
67#define IMX8MP_USB1_PHY_Pxx_REQ BIT(2)
68#define IMX8MP_PCIE_PHY_SW_Pxx_REQ BIT(1)
69
Marek Vasute5481a82022-04-13 00:42:51 +020070#define GPC_M4_PU_PDN_FLG 0x1bc
71
Marek Vasut2e1405e2022-04-13 00:42:53 +020072#define IMX8MP_GPC_PU_PWRHSK 0x190
Marek Vasute5481a82022-04-13 00:42:51 +020073#define GPC_PU_PWRHSK 0x1fc
74
75#define IMX8MM_HSIO_HSK_PWRDNACKN (BIT(23) | BIT(24))
76#define IMX8MM_HSIO_HSK_PWRDNREQN (BIT(5) | BIT(6))
77
78#define IMX8MN_HSIO_HSK_PWRDNACKN BIT(23)
79#define IMX8MN_HSIO_HSK_PWRDNREQN BIT(5)
80
Marek Vasut2e1405e2022-04-13 00:42:53 +020081#define IMX8MP_HSIOMIX_PWRDNACKN BIT(28)
82#define IMX8MP_HSIOMIX_PWRDNREQN BIT(12)
83
Marek Vasute5481a82022-04-13 00:42:51 +020084/*
85 * The PGC offset values in Reference Manual
86 * (Rev. 1, 01/2018 and the older ones) GPC chapter's
87 * GPC_PGC memory map are incorrect, below offset
88 * values are from design RTL.
89 */
90#define IMX8M_PGC_PCIE1 17
91#define IMX8M_PGC_OTG1 18
92#define IMX8M_PGC_OTG2 19
93#define IMX8M_PGC_PCIE2 29
94
95#define IMX8MM_PGC_PCIE 17
96#define IMX8MM_PGC_OTG1 18
97#define IMX8MM_PGC_OTG2 19
98
99#define IMX8MN_PGC_OTG1 18
100
Marek Vasut2e1405e2022-04-13 00:42:53 +0200101#define IMX8MP_PGC_PCIE 13
102#define IMX8MP_PGC_USB1 14
103#define IMX8MP_PGC_USB2 15
104#define IMX8MP_PGC_HSIOMIX 29
105
Marek Vasute5481a82022-04-13 00:42:51 +0200106#define GPC_PGC_CTRL(n) (0x800 + (n) * 0x40)
107#define GPC_PGC_SR(n) (GPC_PGC_CTRL(n) + 0xc)
108
109#define GPC_PGC_CTRL_PCR BIT(0)
110
111struct imx_pgc_regs {
112 u16 map;
113 u16 pup;
114 u16 pdn;
115 u16 hsk;
116};
117
118struct imx_pgc_domain {
119 unsigned long pgc;
120
121 const struct {
122 u32 pxx;
123 u32 map;
124 u32 hskreq;
125 u32 hskack;
126 } bits;
127
128 const bool keep_clocks;
129};
130
131struct imx_pgc_domain_data {
132 const struct imx_pgc_domain *domains;
133 size_t domains_num;
134 const struct imx_pgc_regs *pgc_regs;
135};
136
Marek Vasut93d1d8b2022-04-13 00:42:50 +0200137struct imx8m_power_domain_plat {
Marek Vasute5481a82022-04-13 00:42:51 +0200138 struct power_domain pd;
139 const struct imx_pgc_domain *domain;
140 const struct imx_pgc_regs *regs;
141 struct clk_bulk clk;
142 void __iomem *base;
Marek Vasut93d1d8b2022-04-13 00:42:50 +0200143 int resource_id;
144 int has_pd;
Marek Vasute5481a82022-04-13 00:42:51 +0200145};
146
147#if defined(CONFIG_IMX8MM) || defined(CONFIG_IMX8MN) || defined(CONFIG_IMX8MQ)
148static const struct imx_pgc_regs imx7_pgc_regs = {
149 .map = GPC_PGC_CPU_MAPPING,
150 .pup = GPC_PU_PGC_SW_PUP_REQ,
151 .pdn = GPC_PU_PGC_SW_PDN_REQ,
152 .hsk = GPC_PU_PWRHSK,
153};
154#endif
155
156#ifdef CONFIG_IMX8MQ
157static const struct imx_pgc_domain imx8m_pgc_domains[] = {
158 [IMX8M_POWER_DOMAIN_PCIE1] = {
159 .bits = {
160 .pxx = IMX8M_PCIE1_SW_Pxx_REQ,
161 .map = IMX8M_PCIE1_A53_DOMAIN,
162 },
163 .pgc = BIT(IMX8M_PGC_PCIE1),
164 },
165
166 [IMX8M_POWER_DOMAIN_USB_OTG1] = {
167 .bits = {
168 .pxx = IMX8M_OTG1_SW_Pxx_REQ,
169 .map = IMX8M_OTG1_A53_DOMAIN,
170 },
171 .pgc = BIT(IMX8M_PGC_OTG1),
172 },
173
174 [IMX8M_POWER_DOMAIN_USB_OTG2] = {
175 .bits = {
176 .pxx = IMX8M_OTG2_SW_Pxx_REQ,
177 .map = IMX8M_OTG2_A53_DOMAIN,
178 },
179 .pgc = BIT(IMX8M_PGC_OTG2),
180 },
181
182 [IMX8M_POWER_DOMAIN_PCIE2] = {
183 .bits = {
184 .pxx = IMX8M_PCIE2_SW_Pxx_REQ,
185 .map = IMX8M_PCIE2_A53_DOMAIN,
186 },
187 .pgc = BIT(IMX8M_PGC_PCIE2),
188 },
189};
190
191static const struct imx_pgc_domain_data imx8m_pgc_domain_data = {
192 .domains = imx8m_pgc_domains,
193 .domains_num = ARRAY_SIZE(imx8m_pgc_domains),
194 .pgc_regs = &imx7_pgc_regs,
195};
196#endif
197
198#ifdef CONFIG_IMX8MM
199static const struct imx_pgc_domain imx8mm_pgc_domains[] = {
200 [IMX8MM_POWER_DOMAIN_HSIOMIX] = {
201 .bits = {
202 .pxx = 0, /* no power sequence control */
203 .map = 0, /* no power sequence control */
204 .hskreq = IMX8MM_HSIO_HSK_PWRDNREQN,
205 .hskack = IMX8MM_HSIO_HSK_PWRDNACKN,
206 },
207 .keep_clocks = true,
208 },
209
210 [IMX8MM_POWER_DOMAIN_PCIE] = {
211 .bits = {
212 .pxx = IMX8MM_PCIE_SW_Pxx_REQ,
213 .map = IMX8MM_PCIE_A53_DOMAIN,
214 },
215 .pgc = BIT(IMX8MM_PGC_PCIE),
216 },
217
218 [IMX8MM_POWER_DOMAIN_OTG1] = {
219 .bits = {
220 .pxx = IMX8MM_OTG1_SW_Pxx_REQ,
221 .map = IMX8MM_OTG1_A53_DOMAIN,
222 },
223 .pgc = BIT(IMX8MM_PGC_OTG1),
224 },
225
226 [IMX8MM_POWER_DOMAIN_OTG2] = {
227 .bits = {
228 .pxx = IMX8MM_OTG2_SW_Pxx_REQ,
229 .map = IMX8MM_OTG2_A53_DOMAIN,
230 },
231 .pgc = BIT(IMX8MM_PGC_OTG2),
232 },
Marek Vasut93d1d8b2022-04-13 00:42:50 +0200233};
234
Marek Vasute5481a82022-04-13 00:42:51 +0200235static const struct imx_pgc_domain_data imx8mm_pgc_domain_data = {
236 .domains = imx8mm_pgc_domains,
237 .domains_num = ARRAY_SIZE(imx8mm_pgc_domains),
238 .pgc_regs = &imx7_pgc_regs,
239};
240#endif
241
242#ifdef CONFIG_IMX8MN
243static const struct imx_pgc_domain imx8mn_pgc_domains[] = {
244 [IMX8MN_POWER_DOMAIN_HSIOMIX] = {
245 .bits = {
246 .pxx = 0, /* no power sequence control */
247 .map = 0, /* no power sequence control */
248 .hskreq = IMX8MN_HSIO_HSK_PWRDNREQN,
249 .hskack = IMX8MN_HSIO_HSK_PWRDNACKN,
250 },
251 .keep_clocks = true,
252 },
253
254 [IMX8MN_POWER_DOMAIN_OTG1] = {
255 .bits = {
256 .pxx = IMX8MN_OTG1_SW_Pxx_REQ,
257 .map = IMX8MN_OTG1_A53_DOMAIN,
258 },
259 .pgc = BIT(IMX8MN_PGC_OTG1),
260 },
261};
262
263static const struct imx_pgc_domain_data imx8mn_pgc_domain_data = {
264 .domains = imx8mn_pgc_domains,
265 .domains_num = ARRAY_SIZE(imx8mn_pgc_domains),
266 .pgc_regs = &imx7_pgc_regs,
267};
268#endif
269
Marek Vasut2e1405e2022-04-13 00:42:53 +0200270#ifdef CONFIG_IMX8MP
271static const struct imx_pgc_domain imx8mp_pgc_domains[] = {
272 [IMX8MP_POWER_DOMAIN_PCIE_PHY] = {
273 .bits = {
274 .pxx = IMX8MP_PCIE_PHY_SW_Pxx_REQ,
275 .map = IMX8MP_PCIE_PHY_A53_DOMAIN,
276 },
277 .pgc = BIT(IMX8MP_PGC_PCIE),
278 },
279
280 [IMX8MP_POWER_DOMAIN_USB1_PHY] = {
281 .bits = {
282 .pxx = IMX8MP_USB1_PHY_Pxx_REQ,
283 .map = IMX8MP_USB1_PHY_A53_DOMAIN,
284 },
285 .pgc = BIT(IMX8MP_PGC_USB1),
286 },
287
288 [IMX8MP_POWER_DOMAIN_USB2_PHY] = {
289 .bits = {
290 .pxx = IMX8MP_USB2_PHY_Pxx_REQ,
291 .map = IMX8MP_USB2_PHY_A53_DOMAIN,
292 },
293 .pgc = BIT(IMX8MP_PGC_USB2),
294 },
295
296 [IMX8MP_POWER_DOMAIN_HSIOMIX] = {
297 .bits = {
298 .pxx = IMX8MP_HSIOMIX_Pxx_REQ,
299 .map = IMX8MP_HSIOMIX_A53_DOMAIN,
300 .hskreq = IMX8MP_HSIOMIX_PWRDNREQN,
301 .hskack = IMX8MP_HSIOMIX_PWRDNACKN,
302 },
303 .pgc = BIT(IMX8MP_PGC_HSIOMIX),
304 .keep_clocks = true,
305 },
306};
307
308static const struct imx_pgc_regs imx8mp_pgc_regs = {
309 .map = IMX8MP_GPC_PGC_CPU_MAPPING,
310 .pup = IMX8MP_GPC_PU_PGC_SW_PUP_REQ,
311 .pdn = IMX8MP_GPC_PU_PGC_SW_PDN_REQ,
312 .hsk = IMX8MP_GPC_PU_PWRHSK,
313};
314
315static const struct imx_pgc_domain_data imx8mp_pgc_domain_data = {
316 .domains = imx8mp_pgc_domains,
317 .domains_num = ARRAY_SIZE(imx8mp_pgc_domains),
318 .pgc_regs = &imx8mp_pgc_regs,
319};
320#endif
321
Patrick Wildt8bd56562019-10-03 15:51:50 +0200322static int imx8m_power_domain_on(struct power_domain *power_domain)
323{
324 struct udevice *dev = power_domain->dev;
Marek Vasute5481a82022-04-13 00:42:51 +0200325 struct imx8m_power_domain_plat *pdata = dev_get_plat(dev);
326 const struct imx_pgc_domain *domain = pdata->domain;
327 const struct imx_pgc_regs *regs = pdata->regs;
328 void __iomem *base = pdata->base;
329 u32 pgc;
330 int ret;
Peng Fanaae33562020-05-11 15:16:37 +0800331
Marek Vasute5481a82022-04-13 00:42:51 +0200332 if (pdata->clk.count) {
333 ret = clk_enable_bulk(&pdata->clk);
334 if (ret) {
335 dev_err(dev, "failed to enable reset clocks\n");
336 return ret;
337 }
338 }
Patrick Wildt8bd56562019-10-03 15:51:50 +0200339
Fabio Estevam24d8f572023-05-06 13:14:02 -0300340 /* delay for reset to propagate */
341 udelay(5);
342
Marek Vasute5481a82022-04-13 00:42:51 +0200343 if (domain->bits.pxx) {
344 /* request the domain to power up */
345 setbits_le32(base + regs->pup, domain->bits.pxx);
Patrick Wildt8bd56562019-10-03 15:51:50 +0200346
Marek Vasute5481a82022-04-13 00:42:51 +0200347 /*
348 * As per "5.5.9.4 Example Code 4" in IMX7DRM.pdf wait
349 * for PUP_REQ/PDN_REQ bit to be cleared
350 */
351 ret = wait_for_bit_le32(base + regs->pup, domain->bits.pxx,
352 false, 1000, false);
353 if (ret) {
354 dev_err(dev, "failed to command PGC\n");
355 goto out_clk_disable;
356 }
357
358 /* disable power control */
359 for_each_set_bit(pgc, &domain->pgc, 32) {
360 clrbits_le32(base + GPC_PGC_CTRL(pgc),
361 GPC_PGC_CTRL_PCR);
362 }
363 }
364
365 /* delay for reset to propagate */
366 udelay(5);
Patrick Wildt8bd56562019-10-03 15:51:50 +0200367
Marek Vasute5481a82022-04-13 00:42:51 +0200368 /* request the ADB400 to power up */
369 if (domain->bits.hskreq)
370 setbits_le32(base + regs->hsk, domain->bits.hskreq);
371
372 /* Disable reset clocks for all devices in the domain */
373 if (!domain->keep_clocks && pdata->clk.count)
374 clk_disable_bulk(&pdata->clk);
Patrick Wildt8bd56562019-10-03 15:51:50 +0200375
376 return 0;
Marek Vasute5481a82022-04-13 00:42:51 +0200377
378out_clk_disable:
379 if (pdata->clk.count)
380 clk_disable_bulk(&pdata->clk);
381 return ret;
Patrick Wildt8bd56562019-10-03 15:51:50 +0200382}
383
384static int imx8m_power_domain_off(struct power_domain *power_domain)
385{
386 struct udevice *dev = power_domain->dev;
Marek Vasute5481a82022-04-13 00:42:51 +0200387 struct imx8m_power_domain_plat *pdata = dev_get_plat(dev);
388 const struct imx_pgc_domain *domain = pdata->domain;
389 const struct imx_pgc_regs *regs = pdata->regs;
390 void __iomem *base = pdata->base;
391 u32 pgc;
392 int ret;
393
394 /* Enable reset clocks for all devices in the domain */
395 if (!domain->keep_clocks && pdata->clk.count) {
396 ret = clk_enable_bulk(&pdata->clk);
397 if (ret)
398 return ret;
399 }
400
401 /* request the ADB400 to power down */
402 if (domain->bits.hskreq) {
403 clrbits_le32(base + regs->hsk, domain->bits.hskreq);
404
405 ret = wait_for_bit_le32(base + regs->hsk, domain->bits.hskack,
406 false, 1000, false);
407 if (ret) {
408 dev_err(dev, "failed to power down ADB400\n");
409 goto out_clk_disable;
410 }
411 }
Patrick Wildt8bd56562019-10-03 15:51:50 +0200412
Marek Vasute5481a82022-04-13 00:42:51 +0200413 if (domain->bits.pxx) {
414 /* enable power control */
415 for_each_set_bit(pgc, &domain->pgc, 32) {
416 setbits_le32(base + GPC_PGC_CTRL(pgc),
417 GPC_PGC_CTRL_PCR);
418 }
Patrick Wildt8bd56562019-10-03 15:51:50 +0200419
Marek Vasute5481a82022-04-13 00:42:51 +0200420 /* request the domain to power down */
421 setbits_le32(base + regs->pdn, domain->bits.pxx);
422
423 /*
424 * As per "5.5.9.4 Example Code 4" in IMX7DRM.pdf wait
425 * for PUP_REQ/PDN_REQ bit to be cleared
426 */
427 ret = wait_for_bit_le32(base + regs->pdn, domain->bits.pxx,
428 false, 1000, false);
429 if (ret) {
430 dev_err(dev, "failed to command PGC\n");
431 goto out_clk_disable;
432 }
433 }
434
435 /* Disable reset clocks for all devices in the domain */
436 if (pdata->clk.count)
437 clk_disable_bulk(&pdata->clk);
Patrick Wildt8bd56562019-10-03 15:51:50 +0200438
439 if (pdata->has_pd)
440 power_domain_off(&pdata->pd);
441
442 return 0;
Marek Vasute5481a82022-04-13 00:42:51 +0200443
444out_clk_disable:
445 if (!domain->keep_clocks && pdata->clk.count)
446 clk_disable_bulk(&pdata->clk);
447
448 return ret;
Patrick Wildt8bd56562019-10-03 15:51:50 +0200449}
450
451static int imx8m_power_domain_of_xlate(struct power_domain *power_domain,
452 struct ofnode_phandle_args *args)
453{
454 return 0;
455}
456
457static int imx8m_power_domain_bind(struct udevice *dev)
458{
459 int offset;
460 const char *name;
461 int ret = 0;
462
463 offset = dev_of_offset(dev);
464 for (offset = fdt_first_subnode(gd->fdt_blob, offset); offset > 0;
465 offset = fdt_next_subnode(gd->fdt_blob, offset)) {
466 /* Bind the subnode to this driver */
467 name = fdt_get_name(gd->fdt_blob, offset, NULL);
468
Marek Vasut78fb0072022-04-13 00:42:49 +0200469 /* Descend into 'pgc' subnode */
470 if (!strstr(name, "power-domain")) {
471 offset = fdt_first_subnode(gd->fdt_blob, offset);
472 name = fdt_get_name(gd->fdt_blob, offset, NULL);
473 }
474
Patrick Wildt8bd56562019-10-03 15:51:50 +0200475 ret = device_bind_with_driver_data(dev, dev->driver, name,
476 dev->driver_data,
477 offset_to_ofnode(offset),
478 NULL);
479
480 if (ret == -ENODEV)
481 printf("Driver '%s' refuses to bind\n",
482 dev->driver->name);
483
484 if (ret)
485 printf("Error binding driver '%s': %d\n",
486 dev->driver->name, ret);
487 }
488
Patrick Wildt8bd56562019-10-03 15:51:50 +0200489 return 0;
490}
491
Marek Vasute5481a82022-04-13 00:42:51 +0200492static int imx8m_power_domain_probe(struct udevice *dev)
493{
494 struct imx8m_power_domain_plat *pdata = dev_get_plat(dev);
495 int ret;
496
497 /* Nothing to do for non-"power-domain" driver instances. */
498 if (!strstr(dev->name, "power-domain"))
499 return 0;
500
501 /* Grab optional power domain clock. */
502 ret = clk_get_bulk(dev, &pdata->clk);
503 if (ret && ret != -ENOENT) {
504 dev_err(dev, "Failed to get domain clock (%d)\n", ret);
505 return ret;
506 }
507
508 return 0;
509}
510
Simon Glassaad29ae2020-12-03 16:55:21 -0700511static int imx8m_power_domain_of_to_plat(struct udevice *dev)
Patrick Wildt8bd56562019-10-03 15:51:50 +0200512{
Simon Glassb75b15b2020-12-03 16:55:23 -0700513 struct imx8m_power_domain_plat *pdata = dev_get_plat(dev);
Marek Vasute5481a82022-04-13 00:42:51 +0200514 struct imx_pgc_domain_data *domain_data =
515 (struct imx_pgc_domain_data *)dev_get_driver_data(dev);
Patrick Wildt8bd56562019-10-03 15:51:50 +0200516
517 pdata->resource_id = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
518 "reg", -1);
Marek Vasute5481a82022-04-13 00:42:51 +0200519 pdata->domain = &domain_data->domains[pdata->resource_id];
520 pdata->regs = domain_data->pgc_regs;
521 pdata->base = dev_read_addr_ptr(dev->parent);
Patrick Wildt8bd56562019-10-03 15:51:50 +0200522
523 if (!power_domain_get(dev, &pdata->pd))
524 pdata->has_pd = 1;
525
526 return 0;
527}
528
529static const struct udevice_id imx8m_power_domain_ids[] = {
Marek Vasute5481a82022-04-13 00:42:51 +0200530#ifdef CONFIG_IMX8MQ
531 { .compatible = "fsl,imx8mq-gpc", .data = (long)&imx8m_pgc_domain_data },
532#endif
533#ifdef CONFIG_IMX8MM
534 { .compatible = "fsl,imx8mm-gpc", .data = (long)&imx8mm_pgc_domain_data },
535#endif
536#ifdef CONFIG_IMX8MN
537 { .compatible = "fsl,imx8mn-gpc", .data = (long)&imx8mn_pgc_domain_data },
538#endif
Marek Vasut2e1405e2022-04-13 00:42:53 +0200539#ifdef CONFIG_IMX8MP
540 { .compatible = "fsl,imx8mp-gpc", .data = (long)&imx8mp_pgc_domain_data },
541#endif
Patrick Wildt8bd56562019-10-03 15:51:50 +0200542 { }
543};
544
545struct power_domain_ops imx8m_power_domain_ops = {
Patrick Wildt8bd56562019-10-03 15:51:50 +0200546 .on = imx8m_power_domain_on,
547 .off = imx8m_power_domain_off,
548 .of_xlate = imx8m_power_domain_of_xlate,
549};
550
551U_BOOT_DRIVER(imx8m_power_domain) = {
552 .name = "imx8m_power_domain",
553 .id = UCLASS_POWER_DOMAIN,
554 .of_match = imx8m_power_domain_ids,
555 .bind = imx8m_power_domain_bind,
Marek Vasute5481a82022-04-13 00:42:51 +0200556 .probe = imx8m_power_domain_probe,
Simon Glassaad29ae2020-12-03 16:55:21 -0700557 .of_to_plat = imx8m_power_domain_of_to_plat,
Simon Glassb75b15b2020-12-03 16:55:23 -0700558 .plat_auto = sizeof(struct imx8m_power_domain_plat),
Patrick Wildt8bd56562019-10-03 15:51:50 +0200559 .ops = &imx8m_power_domain_ops,
560};