2 * rmobile power management support
4 * Copyright (C) 2012 Renesas Solutions Corp.
5 * Copyright (C) 2012 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
8 * Copyright (C) 2011 Magnus Damm
10 * This file is subject to the terms and conditions of the GNU General Public
11 * License. See the file "COPYING" in the main directory of this archive
14 #include <linux/console.h>
15 #include <linux/delay.h>
16 #include <linux/platform_device.h>
18 #include <linux/pm_clock.h>
20 #include <mach/pm-rmobile.h>
23 #define SPDCR IOMEM(0xe6180008)
24 #define SWUCR IOMEM(0xe6180014)
25 #define PSTR IOMEM(0xe6180080)
27 #define PSTR_RETRIES 100
28 #define PSTR_DELAY_US 10
31 static int rmobile_pd_power_down(struct generic_pm_domain
*genpd
)
33 struct rmobile_pm_domain
*rmobile_pd
= to_rmobile_pd(genpd
);
34 unsigned int mask
= 1 << rmobile_pd
->bit_shift
;
36 if (rmobile_pd
->suspend
) {
37 int ret
= rmobile_pd
->suspend();
43 if (__raw_readl(PSTR
) & mask
) {
44 unsigned int retry_count
;
45 __raw_writel(mask
, SPDCR
);
47 for (retry_count
= PSTR_RETRIES
; retry_count
; retry_count
--) {
48 if (!(__raw_readl(SPDCR
) & mask
))
54 if (!rmobile_pd
->no_debug
)
55 pr_debug("%s: Power off, 0x%08x -> PSTR = 0x%08x\n",
56 genpd
->name
, mask
, __raw_readl(PSTR
));
61 static int __rmobile_pd_power_up(struct rmobile_pm_domain
*rmobile_pd
,
64 unsigned int mask
= 1 << rmobile_pd
->bit_shift
;
65 unsigned int retry_count
;
68 if (__raw_readl(PSTR
) & mask
)
71 __raw_writel(mask
, SWUCR
);
73 for (retry_count
= 2 * PSTR_RETRIES
; retry_count
; retry_count
--) {
74 if (!(__raw_readl(SWUCR
) & mask
))
76 if (retry_count
> PSTR_RETRIES
)
77 udelay(PSTR_DELAY_US
);
84 if (!rmobile_pd
->no_debug
)
85 pr_debug("%s: Power on, 0x%08x -> PSTR = 0x%08x\n",
86 rmobile_pd
->genpd
.name
, mask
, __raw_readl(PSTR
));
89 if (ret
== 0 && rmobile_pd
->resume
&& do_resume
)
95 static int rmobile_pd_power_up(struct generic_pm_domain
*genpd
)
97 return __rmobile_pd_power_up(to_rmobile_pd(genpd
), true);
100 static bool rmobile_pd_active_wakeup(struct device
*dev
)
105 static void rmobile_init_pm_domain(struct rmobile_pm_domain
*rmobile_pd
)
107 struct generic_pm_domain
*genpd
= &rmobile_pd
->genpd
;
108 struct dev_power_governor
*gov
= rmobile_pd
->gov
;
110 pm_genpd_init(genpd
, gov
? : &simple_qos_governor
, false);
111 genpd
->dev_ops
.stop
= pm_clk_suspend
;
112 genpd
->dev_ops
.start
= pm_clk_resume
;
113 genpd
->dev_ops
.active_wakeup
= rmobile_pd_active_wakeup
;
114 genpd
->dev_irq_safe
= true;
115 genpd
->power_off
= rmobile_pd_power_down
;
116 genpd
->power_on
= rmobile_pd_power_up
;
117 __rmobile_pd_power_up(rmobile_pd
, false);
120 void rmobile_init_domains(struct rmobile_pm_domain domains
[], int num
)
124 for (j
= 0; j
< num
; j
++)
125 rmobile_init_pm_domain(&domains
[j
]);
128 void rmobile_add_device_to_domain_td(const char *domain_name
,
129 struct platform_device
*pdev
,
130 struct gpd_timing_data
*td
)
132 struct device
*dev
= &pdev
->dev
;
134 __pm_genpd_name_add_device(domain_name
, dev
, td
);
135 if (pm_clk_no_clocks(dev
))
136 pm_clk_add(dev
, NULL
);
139 void rmobile_add_devices_to_domains(struct pm_domain_device data
[],
142 struct gpd_timing_data latencies
= {
143 .stop_latency_ns
= DEFAULT_DEV_LATENCY_NS
,
144 .start_latency_ns
= DEFAULT_DEV_LATENCY_NS
,
145 .save_state_latency_ns
= DEFAULT_DEV_LATENCY_NS
,
146 .restore_state_latency_ns
= DEFAULT_DEV_LATENCY_NS
,
150 for (j
= 0; j
< size
; j
++)
151 rmobile_add_device_to_domain_td(data
[j
].domain_name
,
152 data
[j
].pdev
, &latencies
);
154 #endif /* CONFIG_PM */