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_PCI_PDN 0x200
31 #define GPC_PGC_PCI_SR 0x20c
33 #define GPC_PGC_GPU_PDN 0x260
34 #define GPC_PGC_GPU_PUPSCR 0x264
35 #define GPC_PGC_GPU_PDNSCR 0x268
36 #define GPC_PGC_GPU_SR 0x26c
38 #define GPC_PGC_DISP_PDN 0x240
39 #define GPC_PGC_DISP_SR 0x24c
41 #define GPU_VPU_PUP_REQ BIT(1)
42 #define GPU_VPU_PDN_REQ BIT(0)
46 #define PGC_DOMAIN_FLAG_NO_PD BIT(0)
48 struct imx_pm_domain
{
49 struct generic_pm_domain base
;
50 struct regmap
*regmap
;
51 struct regulator
*supply
;
52 struct clk
*clk
[GPC_CLK_MAX
];
54 unsigned int reg_offs
;
55 signed char cntr_pdn_bit
;
56 unsigned int ipg_rate_mhz
;
59 static inline struct imx_pm_domain
*
60 to_imx_pm_domain(struct generic_pm_domain
*genpd
)
62 return container_of(genpd
, struct imx_pm_domain
, base
);
65 static int imx6_pm_domain_power_off(struct generic_pm_domain
*genpd
)
67 struct imx_pm_domain
*pd
= to_imx_pm_domain(genpd
);
71 /* Read ISO and ISO2SW power down delays */
72 regmap_read(pd
->regmap
, pd
->reg_offs
+ GPC_PGC_PDNSCR_OFFS
, &val
);
74 iso2sw
= (val
>> 8) & 0x3f;
76 /* Gate off domain when powered down */
77 regmap_update_bits(pd
->regmap
, pd
->reg_offs
+ GPC_PGC_CTRL_OFFS
,
80 /* Request GPC to power down domain */
81 val
= BIT(pd
->cntr_pdn_bit
);
82 regmap_update_bits(pd
->regmap
, GPC_CNTR
, val
, val
);
84 /* Wait ISO + ISO2SW IPG clock cycles */
85 udelay(DIV_ROUND_UP(iso
+ iso2sw
, pd
->ipg_rate_mhz
));
88 regulator_disable(pd
->supply
);
93 static int imx6_pm_domain_power_on(struct generic_pm_domain
*genpd
)
95 struct imx_pm_domain
*pd
= to_imx_pm_domain(genpd
);
100 ret
= regulator_enable(pd
->supply
);
102 pr_err("%s: failed to enable regulator: %d\n",
108 /* Enable reset clocks for all devices in the domain */
109 for (i
= 0; i
< pd
->num_clks
; i
++)
110 clk_prepare_enable(pd
->clk
[i
]);
112 /* Gate off domain when powered down */
113 regmap_update_bits(pd
->regmap
, pd
->reg_offs
+ GPC_PGC_CTRL_OFFS
,
116 /* Request GPC to power up domain */
117 req
= BIT(pd
->cntr_pdn_bit
+ 1);
118 regmap_update_bits(pd
->regmap
, GPC_CNTR
, req
, req
);
120 /* Wait for the PGC to handle the request */
121 ret
= regmap_read_poll_timeout(pd
->regmap
, GPC_CNTR
, val
, !(val
& req
),
124 pr_err("powerup request on domain %s timed out\n", genpd
->name
);
126 /* Wait for reset to propagate through peripherals */
129 /* Disable reset clocks for all devices in the domain */
130 for (i
= 0; i
< pd
->num_clks
; i
++)
131 clk_disable_unprepare(pd
->clk
[i
]);
136 static int imx_pgc_get_clocks(struct device
*dev
, struct imx_pm_domain
*domain
)
141 struct clk
*clk
= of_clk_get(dev
->of_node
, i
);
144 if (i
>= GPC_CLK_MAX
) {
145 dev_err(dev
, "more than %d clocks\n", GPC_CLK_MAX
);
149 domain
->clk
[i
] = clk
;
151 domain
->num_clks
= i
;
157 clk_put(domain
->clk
[i
]);
162 static void imx_pgc_put_clocks(struct imx_pm_domain
*domain
)
166 for (i
= domain
->num_clks
- 1; i
>= 0; i
--)
167 clk_put(domain
->clk
[i
]);
170 static int imx_pgc_parse_dt(struct device
*dev
, struct imx_pm_domain
*domain
)
172 /* try to get the domain supply regulator */
173 domain
->supply
= devm_regulator_get_optional(dev
, "power");
174 if (IS_ERR(domain
->supply
)) {
175 if (PTR_ERR(domain
->supply
) == -ENODEV
)
176 domain
->supply
= NULL
;
178 return PTR_ERR(domain
->supply
);
181 /* try to get all clocks needed for reset propagation */
182 return imx_pgc_get_clocks(dev
, domain
);
185 static int imx_pgc_power_domain_probe(struct platform_device
*pdev
)
187 struct imx_pm_domain
*domain
= pdev
->dev
.platform_data
;
188 struct device
*dev
= &pdev
->dev
;
191 /* if this PD is associated with a DT node try to parse it */
193 ret
= imx_pgc_parse_dt(dev
, domain
);
198 /* initially power on the domain */
199 if (domain
->base
.power_on
)
200 domain
->base
.power_on(&domain
->base
);
202 if (IS_ENABLED(CONFIG_PM_GENERIC_DOMAINS
)) {
203 pm_genpd_init(&domain
->base
, NULL
, false);
204 ret
= of_genpd_add_provider_simple(dev
->of_node
, &domain
->base
);
209 device_link_add(dev
, dev
->parent
, DL_FLAG_AUTOREMOVE_CONSUMER
);
214 pm_genpd_remove(&domain
->base
);
215 imx_pgc_put_clocks(domain
);
220 static int imx_pgc_power_domain_remove(struct platform_device
*pdev
)
222 struct imx_pm_domain
*domain
= pdev
->dev
.platform_data
;
224 if (IS_ENABLED(CONFIG_PM_GENERIC_DOMAINS
)) {
225 of_genpd_del_provider(pdev
->dev
.of_node
);
226 pm_genpd_remove(&domain
->base
);
227 imx_pgc_put_clocks(domain
);
233 static const struct platform_device_id imx_pgc_power_domain_id
[] = {
234 { "imx-pgc-power-domain"},
238 static struct platform_driver imx_pgc_power_domain_driver
= {
240 .name
= "imx-pgc-pd",
242 .probe
= imx_pgc_power_domain_probe
,
243 .remove
= imx_pgc_power_domain_remove
,
244 .id_table
= imx_pgc_power_domain_id
,
246 builtin_platform_driver(imx_pgc_power_domain_driver
)
248 #define GPC_PGC_DOMAIN_ARM 0
249 #define GPC_PGC_DOMAIN_PU 1
250 #define GPC_PGC_DOMAIN_DISPLAY 2
252 static struct genpd_power_state imx6_pm_domain_pu_state
= {
253 .power_off_latency_ns
= 25000,
254 .power_on_latency_ns
= 2000000,
257 static struct imx_pm_domain imx_gpc_domains
[] = {
261 .flags
= GENPD_FLAG_ALWAYS_ON
,
266 .power_off
= imx6_pm_domain_power_off
,
267 .power_on
= imx6_pm_domain_power_on
,
268 .states
= &imx6_pm_domain_pu_state
,
276 .power_off
= imx6_pm_domain_power_off
,
277 .power_on
= imx6_pm_domain_power_on
,
284 .power_off
= imx6_pm_domain_power_off
,
285 .power_on
= imx6_pm_domain_power_on
,
292 struct imx_gpc_dt_data
{
294 bool err009619_present
;
295 bool err006287_present
;
298 static const struct imx_gpc_dt_data imx6q_dt_data
= {
300 .err009619_present
= false,
301 .err006287_present
= false,
304 static const struct imx_gpc_dt_data imx6qp_dt_data
= {
306 .err009619_present
= true,
307 .err006287_present
= false,
310 static const struct imx_gpc_dt_data imx6sl_dt_data
= {
312 .err009619_present
= false,
313 .err006287_present
= true,
316 static const struct imx_gpc_dt_data imx6sx_dt_data
= {
318 .err009619_present
= false,
319 .err006287_present
= false,
322 static const struct of_device_id imx_gpc_dt_ids
[] = {
323 { .compatible
= "fsl,imx6q-gpc", .data
= &imx6q_dt_data
},
324 { .compatible
= "fsl,imx6qp-gpc", .data
= &imx6qp_dt_data
},
325 { .compatible
= "fsl,imx6sl-gpc", .data
= &imx6sl_dt_data
},
326 { .compatible
= "fsl,imx6sx-gpc", .data
= &imx6sx_dt_data
},
330 static const struct regmap_range yes_ranges
[] = {
331 regmap_reg_range(GPC_CNTR
, GPC_CNTR
),
332 regmap_reg_range(GPC_PGC_PCI_PDN
, GPC_PGC_PCI_SR
),
333 regmap_reg_range(GPC_PGC_GPU_PDN
, GPC_PGC_GPU_SR
),
334 regmap_reg_range(GPC_PGC_DISP_PDN
, GPC_PGC_DISP_SR
),
337 static const struct regmap_access_table access_table
= {
338 .yes_ranges
= yes_ranges
,
339 .n_yes_ranges
= ARRAY_SIZE(yes_ranges
),
342 static const struct regmap_config imx_gpc_regmap_config
= {
346 .rd_table
= &access_table
,
347 .wr_table
= &access_table
,
348 .max_register
= 0x2ac,
352 static struct generic_pm_domain
*imx_gpc_onecell_domains
[] = {
353 &imx_gpc_domains
[0].base
,
354 &imx_gpc_domains
[1].base
,
357 static struct genpd_onecell_data imx_gpc_onecell_data
= {
358 .domains
= imx_gpc_onecell_domains
,
362 static int imx_gpc_old_dt_init(struct device
*dev
, struct regmap
*regmap
,
363 unsigned int num_domains
)
365 struct imx_pm_domain
*domain
;
368 for (i
= 0; i
< num_domains
; i
++) {
369 domain
= &imx_gpc_domains
[i
];
370 domain
->regmap
= regmap
;
371 domain
->ipg_rate_mhz
= 66;
374 domain
->supply
= devm_regulator_get(dev
, "pu");
375 if (IS_ERR(domain
->supply
))
376 return PTR_ERR(domain
->supply
);
378 ret
= imx_pgc_get_clocks(dev
, domain
);
382 domain
->base
.power_on(&domain
->base
);
386 for (i
= 0; i
< num_domains
; i
++)
387 pm_genpd_init(&imx_gpc_domains
[i
].base
, NULL
, false);
389 if (IS_ENABLED(CONFIG_PM_GENERIC_DOMAINS
)) {
390 ret
= of_genpd_add_provider_onecell(dev
->of_node
,
391 &imx_gpc_onecell_data
);
399 for (i
= 0; i
< num_domains
; i
++)
400 pm_genpd_remove(&imx_gpc_domains
[i
].base
);
401 imx_pgc_put_clocks(&imx_gpc_domains
[GPC_PGC_DOMAIN_PU
]);
406 static int imx_gpc_probe(struct platform_device
*pdev
)
408 const struct of_device_id
*of_id
=
409 of_match_device(imx_gpc_dt_ids
, &pdev
->dev
);
410 const struct imx_gpc_dt_data
*of_id_data
= of_id
->data
;
411 struct device_node
*pgc_node
;
412 struct regmap
*regmap
;
413 struct resource
*res
;
417 pgc_node
= of_get_child_by_name(pdev
->dev
.of_node
, "pgc");
419 /* bail out if DT too old and doesn't provide the necessary info */
420 if (!of_property_read_bool(pdev
->dev
.of_node
, "#power-domain-cells") &&
424 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
425 base
= devm_ioremap_resource(&pdev
->dev
, res
);
427 return PTR_ERR(base
);
429 regmap
= devm_regmap_init_mmio_clk(&pdev
->dev
, NULL
, base
,
430 &imx_gpc_regmap_config
);
431 if (IS_ERR(regmap
)) {
432 ret
= PTR_ERR(regmap
);
433 dev_err(&pdev
->dev
, "failed to init regmap: %d\n",
438 /* Disable PU power down in normal operation if ERR009619 is present */
439 if (of_id_data
->err009619_present
)
440 imx_gpc_domains
[GPC_PGC_DOMAIN_PU
].base
.flags
|=
441 GENPD_FLAG_ALWAYS_ON
;
443 /* Keep DISP always on if ERR006287 is present */
444 if (of_id_data
->err006287_present
)
445 imx_gpc_domains
[GPC_PGC_DOMAIN_DISPLAY
].base
.flags
|=
446 GENPD_FLAG_ALWAYS_ON
;
449 ret
= imx_gpc_old_dt_init(&pdev
->dev
, regmap
,
450 of_id_data
->num_domains
);
454 struct imx_pm_domain
*domain
;
455 struct platform_device
*pd_pdev
;
456 struct device_node
*np
;
458 unsigned int ipg_rate_mhz
;
461 ipg_clk
= devm_clk_get(&pdev
->dev
, "ipg");
463 return PTR_ERR(ipg_clk
);
464 ipg_rate_mhz
= clk_get_rate(ipg_clk
) / 1000000;
466 for_each_child_of_node(pgc_node
, np
) {
467 ret
= of_property_read_u32(np
, "reg", &domain_index
);
472 if (domain_index
>= of_id_data
->num_domains
)
475 pd_pdev
= platform_device_alloc("imx-pgc-power-domain",
482 ret
= platform_device_add_data(pd_pdev
,
483 &imx_gpc_domains
[domain_index
],
484 sizeof(imx_gpc_domains
[domain_index
]));
486 platform_device_put(pd_pdev
);
490 domain
= pd_pdev
->dev
.platform_data
;
491 domain
->regmap
= regmap
;
492 domain
->ipg_rate_mhz
= ipg_rate_mhz
;
494 pd_pdev
->dev
.parent
= &pdev
->dev
;
495 pd_pdev
->dev
.of_node
= np
;
497 ret
= platform_device_add(pd_pdev
);
499 platform_device_put(pd_pdev
);
509 static int imx_gpc_remove(struct platform_device
*pdev
)
511 struct device_node
*pgc_node
;
514 pgc_node
= of_get_child_by_name(pdev
->dev
.of_node
, "pgc");
516 /* bail out if DT too old and doesn't provide the necessary info */
517 if (!of_property_read_bool(pdev
->dev
.of_node
, "#power-domain-cells") &&
522 * If the old DT binding is used the toplevel driver needs to
523 * de-register the power domains
526 of_genpd_del_provider(pdev
->dev
.of_node
);
528 ret
= pm_genpd_remove(&imx_gpc_domains
[GPC_PGC_DOMAIN_PU
].base
);
531 imx_pgc_put_clocks(&imx_gpc_domains
[GPC_PGC_DOMAIN_PU
]);
533 ret
= pm_genpd_remove(&imx_gpc_domains
[GPC_PGC_DOMAIN_ARM
].base
);
541 static struct platform_driver imx_gpc_driver
= {
544 .of_match_table
= imx_gpc_dt_ids
,
546 .probe
= imx_gpc_probe
,
547 .remove
= imx_gpc_remove
,
549 builtin_platform_driver(imx_gpc_driver
)