2 * Copyright 2015-2017 Pengutronix, Lucas Stach <kernel@pengutronix.de>
3 * Copyright 2011-2013 Freescale Semiconductor, Inc.
5 * The code contained herein is licensed under the GNU General Public
6 * License. You may obtain a copy of the GNU General Public License
7 * Version 2 or later at the following locations:
9 * http://www.opensource.org/licenses/gpl-license.html
10 * http://www.gnu.org/copyleft/gpl.html
13 #include <linux/clk.h>
14 #include <linux/delay.h>
16 #include <linux/of_device.h>
17 #include <linux/platform_device.h>
18 #include <linux/pm_domain.h>
19 #include <linux/regmap.h>
20 #include <linux/regulator/consumer.h>
22 #define GPC_CNTR 0x000
24 #define GPC_PGC_CTRL_OFFS 0x0
25 #define GPC_PGC_PUPSCR_OFFS 0x4
26 #define GPC_PGC_PDNSCR_OFFS 0x8
27 #define GPC_PGC_SW2ISO_SHIFT 0x8
28 #define GPC_PGC_SW_SHIFT 0x0
30 #define GPC_PGC_GPU_PDN 0x260
31 #define GPC_PGC_GPU_PUPSCR 0x264
32 #define GPC_PGC_GPU_PDNSCR 0x268
34 #define GPU_VPU_PUP_REQ BIT(1)
35 #define GPU_VPU_PDN_REQ BIT(0)
39 #define PGC_DOMAIN_FLAG_NO_PD BIT(0)
41 struct imx_pm_domain
{
42 struct generic_pm_domain base
;
43 struct regmap
*regmap
;
44 struct regulator
*supply
;
45 struct clk
*clk
[GPC_CLK_MAX
];
47 unsigned int reg_offs
;
48 signed char cntr_pdn_bit
;
49 unsigned int ipg_rate_mhz
;
53 static inline struct imx_pm_domain
*
54 to_imx_pm_domain(struct generic_pm_domain
*genpd
)
56 return container_of(genpd
, struct imx_pm_domain
, base
);
59 static int imx6_pm_domain_power_off(struct generic_pm_domain
*genpd
)
61 struct imx_pm_domain
*pd
= to_imx_pm_domain(genpd
);
65 if (pd
->flags
& PGC_DOMAIN_FLAG_NO_PD
)
68 /* Read ISO and ISO2SW power down delays */
69 regmap_read(pd
->regmap
, pd
->reg_offs
+ GPC_PGC_PUPSCR_OFFS
, &val
);
71 iso2sw
= (val
>> 8) & 0x3f;
73 /* Gate off domain when powered down */
74 regmap_update_bits(pd
->regmap
, pd
->reg_offs
+ GPC_PGC_CTRL_OFFS
,
77 /* Request GPC to power down domain */
78 val
= BIT(pd
->cntr_pdn_bit
);
79 regmap_update_bits(pd
->regmap
, GPC_CNTR
, val
, val
);
81 /* Wait ISO + ISO2SW IPG clock cycles */
82 udelay(DIV_ROUND_UP(iso
+ iso2sw
, pd
->ipg_rate_mhz
));
85 regulator_disable(pd
->supply
);
90 static int imx6_pm_domain_power_on(struct generic_pm_domain
*genpd
)
92 struct imx_pm_domain
*pd
= to_imx_pm_domain(genpd
);
93 int i
, ret
, sw
, sw2iso
;
97 ret
= regulator_enable(pd
->supply
);
99 pr_err("%s: failed to enable regulator: %d\n",
105 /* Enable reset clocks for all devices in the domain */
106 for (i
= 0; i
< pd
->num_clks
; i
++)
107 clk_prepare_enable(pd
->clk
[i
]);
109 /* Gate off domain when powered down */
110 regmap_update_bits(pd
->regmap
, pd
->reg_offs
+ GPC_PGC_CTRL_OFFS
,
113 /* Read ISO and ISO2SW power up delays */
114 regmap_read(pd
->regmap
, pd
->reg_offs
+ GPC_PGC_PUPSCR_OFFS
, &val
);
116 sw2iso
= (val
>> 8) & 0x3f;
118 /* Request GPC to power up domain */
119 val
= BIT(pd
->cntr_pdn_bit
+ 1);
120 regmap_update_bits(pd
->regmap
, GPC_CNTR
, val
, val
);
122 /* Wait ISO + ISO2SW IPG clock cycles */
123 udelay(DIV_ROUND_UP(sw
+ sw2iso
, pd
->ipg_rate_mhz
));
125 /* Disable reset clocks for all devices in the domain */
126 for (i
= 0; i
< pd
->num_clks
; i
++)
127 clk_disable_unprepare(pd
->clk
[i
]);
132 static int imx_pgc_get_clocks(struct device
*dev
, struct imx_pm_domain
*domain
)
137 struct clk
*clk
= of_clk_get(dev
->of_node
, i
);
140 if (i
>= GPC_CLK_MAX
) {
141 dev_err(dev
, "more than %d clocks\n", GPC_CLK_MAX
);
145 domain
->clk
[i
] = clk
;
147 domain
->num_clks
= i
;
153 clk_put(domain
->clk
[i
]);
158 static void imx_pgc_put_clocks(struct imx_pm_domain
*domain
)
162 for (i
= domain
->num_clks
- 1; i
>= 0; i
--)
163 clk_put(domain
->clk
[i
]);
166 static int imx_pgc_parse_dt(struct device
*dev
, struct imx_pm_domain
*domain
)
168 /* try to get the domain supply regulator */
169 domain
->supply
= devm_regulator_get_optional(dev
, "power");
170 if (IS_ERR(domain
->supply
)) {
171 if (PTR_ERR(domain
->supply
) == -ENODEV
)
172 domain
->supply
= NULL
;
174 return PTR_ERR(domain
->supply
);
177 /* try to get all clocks needed for reset propagation */
178 return imx_pgc_get_clocks(dev
, domain
);
181 static int imx_pgc_power_domain_probe(struct platform_device
*pdev
)
183 struct imx_pm_domain
*domain
= pdev
->dev
.platform_data
;
184 struct device
*dev
= &pdev
->dev
;
187 /* if this PD is associated with a DT node try to parse it */
189 ret
= imx_pgc_parse_dt(dev
, domain
);
194 /* initially power on the domain */
195 if (domain
->base
.power_on
)
196 domain
->base
.power_on(&domain
->base
);
198 if (IS_ENABLED(CONFIG_PM_GENERIC_DOMAINS
)) {
199 pm_genpd_init(&domain
->base
, NULL
, false);
200 ret
= of_genpd_add_provider_simple(dev
->of_node
, &domain
->base
);
205 device_link_add(dev
, dev
->parent
, DL_FLAG_AUTOREMOVE
);
210 pm_genpd_remove(&domain
->base
);
211 imx_pgc_put_clocks(domain
);
216 static int imx_pgc_power_domain_remove(struct platform_device
*pdev
)
218 struct imx_pm_domain
*domain
= pdev
->dev
.platform_data
;
220 if (IS_ENABLED(CONFIG_PM_GENERIC_DOMAINS
)) {
221 of_genpd_del_provider(pdev
->dev
.of_node
);
222 pm_genpd_remove(&domain
->base
);
223 imx_pgc_put_clocks(domain
);
229 static const struct platform_device_id imx_pgc_power_domain_id
[] = {
230 { "imx-pgc-power-domain"},
234 static struct platform_driver imx_pgc_power_domain_driver
= {
236 .name
= "imx-pgc-pd",
238 .probe
= imx_pgc_power_domain_probe
,
239 .remove
= imx_pgc_power_domain_remove
,
240 .id_table
= imx_pgc_power_domain_id
,
242 builtin_platform_driver(imx_pgc_power_domain_driver
)
244 #define GPC_PGC_DOMAIN_ARM 0
245 #define GPC_PGC_DOMAIN_PU 1
246 #define GPC_PGC_DOMAIN_DISPLAY 2
248 static struct genpd_power_state imx6_pm_domain_pu_state
= {
249 .power_off_latency_ns
= 25000,
250 .power_on_latency_ns
= 2000000,
253 static struct imx_pm_domain imx_gpc_domains
[] = {
257 .flags
= GENPD_FLAG_ALWAYS_ON
,
262 .power_off
= imx6_pm_domain_power_off
,
263 .power_on
= imx6_pm_domain_power_on
,
264 .states
= &imx6_pm_domain_pu_state
,
272 .power_off
= imx6_pm_domain_power_off
,
273 .power_on
= imx6_pm_domain_power_on
,
280 .power_off
= imx6_pm_domain_power_off
,
281 .power_on
= imx6_pm_domain_power_on
,
288 struct imx_gpc_dt_data
{
290 bool err009619_present
;
293 static const struct imx_gpc_dt_data imx6q_dt_data
= {
295 .err009619_present
= false,
298 static const struct imx_gpc_dt_data imx6qp_dt_data
= {
300 .err009619_present
= true,
303 static const struct imx_gpc_dt_data imx6sl_dt_data
= {
305 .err009619_present
= false,
308 static const struct imx_gpc_dt_data imx6sx_dt_data
= {
310 .err009619_present
= false,
313 static const struct of_device_id imx_gpc_dt_ids
[] = {
314 { .compatible
= "fsl,imx6q-gpc", .data
= &imx6q_dt_data
},
315 { .compatible
= "fsl,imx6qp-gpc", .data
= &imx6qp_dt_data
},
316 { .compatible
= "fsl,imx6sl-gpc", .data
= &imx6sl_dt_data
},
317 { .compatible
= "fsl,imx6sx-gpc", .data
= &imx6sx_dt_data
},
321 static const struct regmap_config imx_gpc_regmap_config
= {
325 .max_register
= 0x2ac,
328 static struct generic_pm_domain
*imx_gpc_onecell_domains
[] = {
329 &imx_gpc_domains
[0].base
,
330 &imx_gpc_domains
[1].base
,
333 static struct genpd_onecell_data imx_gpc_onecell_data
= {
334 .domains
= imx_gpc_onecell_domains
,
338 static int imx_gpc_old_dt_init(struct device
*dev
, struct regmap
*regmap
,
339 unsigned int num_domains
)
341 struct imx_pm_domain
*domain
;
344 for (i
= 0; i
< num_domains
; i
++) {
345 domain
= &imx_gpc_domains
[i
];
346 domain
->regmap
= regmap
;
347 domain
->ipg_rate_mhz
= 66;
350 domain
->supply
= devm_regulator_get(dev
, "pu");
351 if (IS_ERR(domain
->supply
))
352 return PTR_ERR(domain
->supply
);
354 ret
= imx_pgc_get_clocks(dev
, domain
);
358 domain
->base
.power_on(&domain
->base
);
362 for (i
= 0; i
< num_domains
; i
++)
363 pm_genpd_init(&imx_gpc_domains
[i
].base
, NULL
, false);
365 if (IS_ENABLED(CONFIG_PM_GENERIC_DOMAINS
)) {
366 ret
= of_genpd_add_provider_onecell(dev
->of_node
,
367 &imx_gpc_onecell_data
);
375 for (i
= 0; i
< num_domains
; i
++)
376 pm_genpd_remove(&imx_gpc_domains
[i
].base
);
377 imx_pgc_put_clocks(&imx_gpc_domains
[GPC_PGC_DOMAIN_PU
]);
382 static int imx_gpc_probe(struct platform_device
*pdev
)
384 const struct of_device_id
*of_id
=
385 of_match_device(imx_gpc_dt_ids
, &pdev
->dev
);
386 const struct imx_gpc_dt_data
*of_id_data
= of_id
->data
;
387 struct device_node
*pgc_node
;
388 struct regmap
*regmap
;
389 struct resource
*res
;
393 pgc_node
= of_get_child_by_name(pdev
->dev
.of_node
, "pgc");
395 /* bail out if DT too old and doesn't provide the necessary info */
396 if (!of_property_read_bool(pdev
->dev
.of_node
, "#power-domain-cells") &&
400 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
401 base
= devm_ioremap_resource(&pdev
->dev
, res
);
403 return PTR_ERR(base
);
405 regmap
= devm_regmap_init_mmio_clk(&pdev
->dev
, NULL
, base
,
406 &imx_gpc_regmap_config
);
407 if (IS_ERR(regmap
)) {
408 ret
= PTR_ERR(regmap
);
409 dev_err(&pdev
->dev
, "failed to init regmap: %d\n",
414 /* Disable PU power down in normal operation if ERR009619 is present */
415 if (of_id_data
->err009619_present
)
416 imx_gpc_domains
[GPC_PGC_DOMAIN_PU
].flags
|=
417 PGC_DOMAIN_FLAG_NO_PD
;
420 ret
= imx_gpc_old_dt_init(&pdev
->dev
, regmap
,
421 of_id_data
->num_domains
);
425 struct imx_pm_domain
*domain
;
426 struct platform_device
*pd_pdev
;
427 struct device_node
*np
;
429 unsigned int ipg_rate_mhz
;
432 ipg_clk
= devm_clk_get(&pdev
->dev
, "ipg");
434 return PTR_ERR(ipg_clk
);
435 ipg_rate_mhz
= clk_get_rate(ipg_clk
) / 1000000;
437 for_each_child_of_node(pgc_node
, np
) {
438 ret
= of_property_read_u32(np
, "reg", &domain_index
);
443 if (domain_index
>= of_id_data
->num_domains
)
446 pd_pdev
= platform_device_alloc("imx-pgc-power-domain",
453 ret
= platform_device_add_data(pd_pdev
,
454 &imx_gpc_domains
[domain_index
],
455 sizeof(imx_gpc_domains
[domain_index
]));
457 platform_device_put(pd_pdev
);
461 domain
= pd_pdev
->dev
.platform_data
;
462 domain
->regmap
= regmap
;
463 domain
->ipg_rate_mhz
= ipg_rate_mhz
;
465 pd_pdev
->dev
.parent
= &pdev
->dev
;
466 pd_pdev
->dev
.of_node
= np
;
468 ret
= platform_device_add(pd_pdev
);
470 platform_device_put(pd_pdev
);
480 static int imx_gpc_remove(struct platform_device
*pdev
)
482 struct device_node
*pgc_node
;
485 pgc_node
= of_get_child_by_name(pdev
->dev
.of_node
, "pgc");
487 /* bail out if DT too old and doesn't provide the necessary info */
488 if (!of_property_read_bool(pdev
->dev
.of_node
, "#power-domain-cells") &&
493 * If the old DT binding is used the toplevel driver needs to
494 * de-register the power domains
497 of_genpd_del_provider(pdev
->dev
.of_node
);
499 ret
= pm_genpd_remove(&imx_gpc_domains
[GPC_PGC_DOMAIN_PU
].base
);
502 imx_pgc_put_clocks(&imx_gpc_domains
[GPC_PGC_DOMAIN_PU
]);
504 ret
= pm_genpd_remove(&imx_gpc_domains
[GPC_PGC_DOMAIN_ARM
].base
);
512 static struct platform_driver imx_gpc_driver
= {
515 .of_match_table
= imx_gpc_dt_ids
,
517 .probe
= imx_gpc_probe
,
518 .remove
= imx_gpc_remove
,
520 builtin_platform_driver(imx_gpc_driver
)