2 * rmobile power management support
4 * Copyright (C) 2012 Renesas Solutions Corp.
5 * Copyright (C) 2012 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6 * Copyright (C) 2014 Glider bvba
9 * Copyright (C) 2011 Magnus Damm
11 * This file is subject to the terms and conditions of the GNU General Public
12 * License. See the file "COPYING" in the main directory of this archive
15 #include <linux/console.h>
16 #include <linux/delay.h>
18 #include <linux/of_address.h>
19 #include <linux/of_platform.h>
20 #include <linux/platform_device.h>
22 #include <linux/pm_clock.h>
23 #include <linux/slab.h>
27 #include "pm-rmobile.h"
30 #define SPDCR 0x08 /* SYS Power Down Control Register */
31 #define SWUCR 0x14 /* SYS Wakeup Control Register */
32 #define PSTR 0x80 /* Power Status Register */
34 #define PSTR_RETRIES 100
35 #define PSTR_DELAY_US 10
38 struct rmobile_pm_domain
*to_rmobile_pd(struct generic_pm_domain
*d
)
40 return container_of(d
, struct rmobile_pm_domain
, genpd
);
43 static int rmobile_pd_power_down(struct generic_pm_domain
*genpd
)
45 struct rmobile_pm_domain
*rmobile_pd
= to_rmobile_pd(genpd
);
48 if (rmobile_pd
->bit_shift
== ~0)
51 mask
= BIT(rmobile_pd
->bit_shift
);
52 if (rmobile_pd
->suspend
) {
53 int ret
= rmobile_pd
->suspend();
59 if (__raw_readl(rmobile_pd
->base
+ PSTR
) & mask
) {
60 unsigned int retry_count
;
61 __raw_writel(mask
, rmobile_pd
->base
+ SPDCR
);
63 for (retry_count
= PSTR_RETRIES
; retry_count
; retry_count
--) {
64 if (!(__raw_readl(rmobile_pd
->base
+ SPDCR
) & mask
))
70 if (!rmobile_pd
->no_debug
)
71 pr_debug("%s: Power off, 0x%08x -> PSTR = 0x%08x\n",
73 __raw_readl(rmobile_pd
->base
+ PSTR
));
78 static int __rmobile_pd_power_up(struct rmobile_pm_domain
*rmobile_pd
,
82 unsigned int retry_count
;
85 if (rmobile_pd
->bit_shift
== ~0)
88 mask
= BIT(rmobile_pd
->bit_shift
);
89 if (__raw_readl(rmobile_pd
->base
+ PSTR
) & mask
)
92 __raw_writel(mask
, rmobile_pd
->base
+ SWUCR
);
94 for (retry_count
= 2 * PSTR_RETRIES
; retry_count
; retry_count
--) {
95 if (!(__raw_readl(rmobile_pd
->base
+ SWUCR
) & mask
))
97 if (retry_count
> PSTR_RETRIES
)
98 udelay(PSTR_DELAY_US
);
105 if (!rmobile_pd
->no_debug
)
106 pr_debug("%s: Power on, 0x%08x -> PSTR = 0x%08x\n",
107 rmobile_pd
->genpd
.name
, mask
,
108 __raw_readl(rmobile_pd
->base
+ PSTR
));
111 if (ret
== 0 && rmobile_pd
->resume
&& do_resume
)
112 rmobile_pd
->resume();
117 static int rmobile_pd_power_up(struct generic_pm_domain
*genpd
)
119 return __rmobile_pd_power_up(to_rmobile_pd(genpd
), true);
122 static bool rmobile_pd_active_wakeup(struct device
*dev
)
127 static int rmobile_pd_attach_dev(struct generic_pm_domain
*domain
,
132 error
= pm_clk_create(dev
);
134 dev_err(dev
, "pm_clk_create failed %d\n", error
);
138 error
= pm_clk_add(dev
, NULL
);
140 dev_err(dev
, "pm_clk_add failed %d\n", error
);
151 static void rmobile_pd_detach_dev(struct generic_pm_domain
*domain
,
157 static void rmobile_init_pm_domain(struct rmobile_pm_domain
*rmobile_pd
)
159 struct generic_pm_domain
*genpd
= &rmobile_pd
->genpd
;
160 struct dev_power_governor
*gov
= rmobile_pd
->gov
;
162 genpd
->flags
= GENPD_FLAG_PM_CLK
;
163 pm_genpd_init(genpd
, gov
? : &simple_qos_governor
, false);
164 genpd
->dev_ops
.active_wakeup
= rmobile_pd_active_wakeup
;
165 genpd
->power_off
= rmobile_pd_power_down
;
166 genpd
->power_on
= rmobile_pd_power_up
;
167 genpd
->attach_dev
= rmobile_pd_attach_dev
;
168 genpd
->detach_dev
= rmobile_pd_detach_dev
;
169 __rmobile_pd_power_up(rmobile_pd
, false);
172 static int rmobile_pd_suspend_busy(void)
175 * This domain should not be turned off.
180 static int rmobile_pd_suspend_console(void)
183 * Serial consoles make use of SCIF hardware located in this domain,
184 * hence keep the power domain on if "no_console_suspend" is set.
186 return console_suspend_enabled
? 0 : -EBUSY
;
197 #define MAX_NUM_SPECIAL_PDS 16
199 static struct special_pd
{
200 struct device_node
*pd
;
202 } special_pds
[MAX_NUM_SPECIAL_PDS
] __initdata
;
204 static unsigned int num_special_pds __initdata
;
206 static const struct of_device_id special_ids
[] __initconst
= {
207 { .compatible
= "arm,coresight-etm3x", .data
= (void *)PD_DEBUG
},
208 { .compatible
= "renesas,dbsc-r8a73a4", .data
= (void *)PD_MEMCTL
, },
209 { .compatible
= "renesas,dbsc3-r8a7740", .data
= (void *)PD_MEMCTL
, },
210 { .compatible
= "renesas,sbsc-sh73a0", .data
= (void *)PD_MEMCTL
, },
214 static void __init
add_special_pd(struct device_node
*np
, enum pd_types type
)
217 struct device_node
*pd
;
219 pd
= of_parse_phandle(np
, "power-domains", 0);
223 for (i
= 0; i
< num_special_pds
; i
++)
224 if (pd
== special_pds
[i
].pd
&& type
== special_pds
[i
].type
) {
229 if (num_special_pds
== ARRAY_SIZE(special_pds
)) {
230 pr_warn("Too many special PM domains\n");
235 pr_debug("Special PM domain %s type %d for %s\n", pd
->name
, type
,
238 special_pds
[num_special_pds
].pd
= pd
;
239 special_pds
[num_special_pds
].type
= type
;
243 static void __init
get_special_pds(void)
245 struct device_node
*np
;
246 const struct of_device_id
*id
;
248 /* PM domains containing CPUs */
249 for_each_node_by_type(np
, "cpu")
250 add_special_pd(np
, PD_CPU
);
252 /* PM domain containing console */
254 add_special_pd(of_stdout
, PD_CONSOLE
);
256 /* PM domains containing other special devices */
257 for_each_matching_node_and_match(np
, special_ids
, &id
)
258 add_special_pd(np
, (enum pd_types
)id
->data
);
261 static void __init
put_special_pds(void)
265 for (i
= 0; i
< num_special_pds
; i
++)
266 of_node_put(special_pds
[i
].pd
);
269 static enum pd_types __init
pd_type(const struct device_node
*pd
)
273 for (i
= 0; i
< num_special_pds
; i
++)
274 if (pd
== special_pds
[i
].pd
)
275 return special_pds
[i
].type
;
280 static void __init
rmobile_setup_pm_domain(struct device_node
*np
,
281 struct rmobile_pm_domain
*pd
)
283 const char *name
= pd
->genpd
.name
;
285 switch (pd_type(np
)) {
288 * This domain contains the CPU core and therefore it should
289 * only be turned off if the CPU is not in use.
291 pr_debug("PM domain %s contains CPU\n", name
);
292 pd
->gov
= &pm_domain_always_on_gov
;
293 pd
->suspend
= rmobile_pd_suspend_busy
;
297 pr_debug("PM domain %s contains serial console\n", name
);
298 pd
->gov
= &pm_domain_always_on_gov
;
299 pd
->suspend
= rmobile_pd_suspend_console
;
304 * This domain contains the Coresight-ETM hardware block and
305 * therefore it should only be turned off if the debug module
308 pr_debug("PM domain %s contains Coresight-ETM\n", name
);
309 pd
->gov
= &pm_domain_always_on_gov
;
310 pd
->suspend
= rmobile_pd_suspend_busy
;
315 * This domain contains a memory-controller and therefore it
316 * should only be turned off if memory is not in use.
318 pr_debug("PM domain %s contains MEMCTL\n", name
);
319 pd
->gov
= &pm_domain_always_on_gov
;
320 pd
->suspend
= rmobile_pd_suspend_busy
;
327 rmobile_init_pm_domain(pd
);
330 static int __init
rmobile_add_pm_domains(void __iomem
*base
,
331 struct device_node
*parent
,
332 struct generic_pm_domain
*genpd_parent
)
334 struct device_node
*np
;
336 for_each_child_of_node(parent
, np
) {
337 struct rmobile_pm_domain
*pd
;
340 if (of_property_read_u32(np
, "reg", &idx
)) {
341 /* always-on domain */
344 pd
= kzalloc(sizeof(*pd
), GFP_KERNEL
);
348 pd
->genpd
.name
= np
->name
;
352 rmobile_setup_pm_domain(np
, pd
);
354 pm_genpd_add_subdomain(genpd_parent
, &pd
->genpd
);
355 of_genpd_add_provider_simple(np
, &pd
->genpd
);
357 rmobile_add_pm_domains(base
, np
, &pd
->genpd
);
362 static int __init
rmobile_init_pm_domains(void)
364 struct device_node
*np
, *pmd
;
365 bool scanned
= false;
369 for_each_compatible_node(np
, NULL
, "renesas,sysc-rmobile") {
370 base
= of_iomap(np
, 0);
372 pr_warn("%s cannot map reg 0\n", np
->full_name
);
376 pmd
= of_get_child_by_name(np
, "pm-domains");
378 pr_warn("%s lacks pm-domains node\n", np
->full_name
);
383 /* Find PM domains containing special blocks */
388 ret
= rmobile_add_pm_domains(base
, pmd
, NULL
);
401 core_initcall(rmobile_init_pm_domains
);