aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-shmobile
diff options
context:
space:
mode:
authorMagnus Damm <damm@opensource.se>2011-07-10 04:39:32 -0400
committerRafael J. Wysocki <rjw@sisk.pl>2011-07-10 04:39:32 -0400
commit775b8ae8707592af9275b8b216c2bf056b3f5d82 (patch)
tree45547ece2b4012199e1a51f4cde3f9de640398fc /arch/arm/mach-shmobile
parent18b4f3f5d058b590e7189027eeb5d897742ade0a (diff)
ARM: mach-shmobile: sh7372 A3RV requires A4LC
Add a power domain workaround for the VPU and A3RV on sh7372. The sh7372 data sheet mentions that the VPU is located in the A3RV power domain. The A3RV power domain is not related to A4LC in any way, but testing shows that unless A3RV _and_ A4LC are powered on the VPU test program will bomb out. This issue may be caused by a more or less undocumented dependency on the MERAM block that happens to be located in A4LC. So now we know that the out-of-reset requirement of the VPU is that the MERAM is powered on. This patch adds a workaround for A3RV to make sure A4LC is powered on - this so we can use the VPU even though the LCDCs are in blanking state and A4LC is supposed to be off. Signed-off-by: Magnus Damm <damm@opensource.se> Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Diffstat (limited to 'arch/arm/mach-shmobile')
-rw-r--r--arch/arm/mach-shmobile/pm-sh7372.c45
1 files changed, 42 insertions, 3 deletions
diff --git a/arch/arm/mach-shmobile/pm-sh7372.c b/arch/arm/mach-shmobile/pm-sh7372.c
index 9ad3b610f0fe..71400eae2b68 100644
--- a/arch/arm/mach-shmobile/pm-sh7372.c
+++ b/arch/arm/mach-shmobile/pm-sh7372.c
@@ -91,6 +91,36 @@ static int pd_power_up(struct generic_pm_domain *genpd)
91 return ret; 91 return ret;
92} 92}
93 93
94static int pd_power_up_a3rv(struct generic_pm_domain *genpd)
95{
96 int ret = pd_power_up(genpd);
97
98 /* force A4LC on after A3RV has been requested on */
99 pm_genpd_poweron(&sh7372_a4lc.genpd);
100
101 return ret;
102}
103
104static int pd_power_down_a3rv(struct generic_pm_domain *genpd)
105{
106 int ret = pd_power_down(genpd);
107
108 /* try to power down A4LC after A3RV is requested off */
109 pm_genpd_poweron(&sh7372_a4lc.genpd);
110 queue_work(pm_wq, &sh7372_a4lc.genpd.power_off_work);
111
112 return ret;
113}
114
115static int pd_power_down_a4lc(struct generic_pm_domain *genpd)
116{
117 /* only power down A4LC if A3RV is off */
118 if (!(__raw_readl(PSTR) & (1 << sh7372_a3rv.bit_shift)))
119 return pd_power_down(genpd);
120
121 return 0;
122}
123
94static bool pd_active_wakeup(struct device *dev) 124static bool pd_active_wakeup(struct device *dev)
95{ 125{
96 return true; 126 return true;
@@ -115,9 +145,18 @@ void sh7372_init_pm_domain(struct sh7372_pm_domain *sh7372_pd)
115 genpd->stop_device = pm_clk_suspend; 145 genpd->stop_device = pm_clk_suspend;
116 genpd->start_device = pm_clk_resume; 146 genpd->start_device = pm_clk_resume;
117 genpd->active_wakeup = pd_active_wakeup; 147 genpd->active_wakeup = pd_active_wakeup;
118 genpd->power_off = pd_power_down; 148
119 genpd->power_on = pd_power_up; 149 if (sh7372_pd == &sh7372_a4lc) {
120 pd_power_up(&sh7372_pd->genpd); 150 genpd->power_off = pd_power_down_a4lc;
151 genpd->power_on = pd_power_up;
152 } else if (sh7372_pd == &sh7372_a3rv) {
153 genpd->power_off = pd_power_down_a3rv;
154 genpd->power_on = pd_power_up_a3rv;
155 } else {
156 genpd->power_off = pd_power_down;
157 genpd->power_on = pd_power_up;
158 }
159 genpd->power_on(&sh7372_pd->genpd);
121 160
122 shmobile_runtime_pm_late_init = sh7372_late_pm_domain_off; 161 shmobile_runtime_pm_late_init = sh7372_late_pm_domain_off;
123} 162}