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 "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
30 static int rmobile_pd_power_down(struct generic_pm_domain
*genpd
)
32 struct rmobile_pm_domain
*rmobile_pd
= to_rmobile_pd(genpd
);
33 unsigned int mask
= 1 << rmobile_pd
->bit_shift
;
35 if (rmobile_pd
->suspend
) {
36 int ret
= rmobile_pd
->suspend();
42 if (__raw_readl(PSTR
) & mask
) {
43 unsigned int retry_count
;
44 __raw_writel(mask
, SPDCR
);
46 for (retry_count
= PSTR_RETRIES
; retry_count
; retry_count
--) {
47 if (!(__raw_readl(SPDCR
) & mask
))
53 if (!rmobile_pd
->no_debug
)
54 pr_debug("%s: Power off, 0x%08x -> PSTR = 0x%08x\n",
55 genpd
->name
, mask
, __raw_readl(PSTR
));
60 static int __rmobile_pd_power_up(struct rmobile_pm_domain
*rmobile_pd
,
63 unsigned int mask
= 1 << rmobile_pd
->bit_shift
;
64 unsigned int retry_count
;
67 if (__raw_readl(PSTR
) & mask
)
70 __raw_writel(mask
, SWUCR
);
72 for (retry_count
= 2 * PSTR_RETRIES
; retry_count
; retry_count
--) {
73 if (!(__raw_readl(SWUCR
) & mask
))
75 if (retry_count
> PSTR_RETRIES
)
76 udelay(PSTR_DELAY_US
);
83 if (!rmobile_pd
->no_debug
)
84 pr_debug("%s: Power on, 0x%08x -> PSTR = 0x%08x\n",
85 rmobile_pd
->genpd
.name
, mask
, __raw_readl(PSTR
));
88 if (ret
== 0 && rmobile_pd
->resume
&& do_resume
)
94 static int rmobile_pd_power_up(struct generic_pm_domain
*genpd
)
96 return __rmobile_pd_power_up(to_rmobile_pd(genpd
), true);
99 static bool rmobile_pd_active_wakeup(struct device
*dev
)
104 static int rmobile_pd_attach_dev(struct generic_pm_domain
*domain
,
109 error
= pm_clk_create(dev
);
111 dev_err(dev
, "pm_clk_create failed %d\n", error
);
115 error
= pm_clk_add(dev
, NULL
);
117 dev_err(dev
, "pm_clk_add failed %d\n", error
);
128 static void rmobile_pd_detach_dev(struct generic_pm_domain
*domain
,
134 static void rmobile_init_pm_domain(struct rmobile_pm_domain
*rmobile_pd
)
136 struct generic_pm_domain
*genpd
= &rmobile_pd
->genpd
;
137 struct dev_power_governor
*gov
= rmobile_pd
->gov
;
139 genpd
->flags
= GENPD_FLAG_PM_CLK
;
140 pm_genpd_init(genpd
, gov
? : &simple_qos_governor
, false);
141 genpd
->dev_ops
.active_wakeup
= rmobile_pd_active_wakeup
;
142 genpd
->power_off
= rmobile_pd_power_down
;
143 genpd
->power_on
= rmobile_pd_power_up
;
144 genpd
->attach_dev
= rmobile_pd_attach_dev
;
145 genpd
->detach_dev
= rmobile_pd_detach_dev
;
146 __rmobile_pd_power_up(rmobile_pd
, false);
149 void rmobile_init_domains(struct rmobile_pm_domain domains
[], int num
)
153 for (j
= 0; j
< num
; j
++)
154 rmobile_init_pm_domain(&domains
[j
]);
157 void rmobile_add_device_to_domain_td(const char *domain_name
,
158 struct platform_device
*pdev
,
159 struct gpd_timing_data
*td
)
161 struct device
*dev
= &pdev
->dev
;
163 __pm_genpd_name_add_device(domain_name
, dev
, td
);
166 void rmobile_add_devices_to_domains(struct pm_domain_device data
[],
169 struct gpd_timing_data latencies
= {
170 .stop_latency_ns
= DEFAULT_DEV_LATENCY_NS
,
171 .start_latency_ns
= DEFAULT_DEV_LATENCY_NS
,
172 .save_state_latency_ns
= DEFAULT_DEV_LATENCY_NS
,
173 .restore_state_latency_ns
= DEFAULT_DEV_LATENCY_NS
,
177 for (j
= 0; j
< size
; j
++)
178 rmobile_add_device_to_domain_td(data
[j
].domain_name
,
179 data
[j
].pdev
, &latencies
);