diff options
author | Krzysztof Kozlowski <k.kozlowski@samsung.com> | 2016-05-10 09:52:21 -0400 |
---|---|---|
committer | Krzysztof Kozlowski <k.kozlowski@samsung.com> | 2016-05-30 03:12:53 -0400 |
commit | c028e175713698b88694c2075853963d07c81c13 (patch) | |
tree | 4755cc690a542a0aa173bbc72d4ce5ce0e03c37f /drivers/soc/samsung/pm_domains.c | |
parent | e465007a7a7ca745f018fdcacb0a5a911a5c50d9 (diff) |
soc: samsung: pm_domains: Prepare for supporting ARMv8 Exynos
The ARMv8 Exynos family (Exynos5433 and Exynos7420) uses different value
(0xf instead of 0x7) for controlling the power domain on/off registers
(both for control and for status).
Choose the value depending on the compatible. This prepares the driver
for supporting ARMv8 SoCs.
Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
Reviewed-by: Javier Martinez Canillas <javier@osg.samsung.com>
Diffstat (limited to 'drivers/soc/samsung/pm_domains.c')
-rw-r--r-- | drivers/soc/samsung/pm_domains.c | 34 |
1 files changed, 28 insertions, 6 deletions
diff --git a/drivers/soc/samsung/pm_domains.c b/drivers/soc/samsung/pm_domains.c index 875a2bab64f6..f60515eefb66 100644 --- a/drivers/soc/samsung/pm_domains.c +++ b/drivers/soc/samsung/pm_domains.c | |||
@@ -23,9 +23,13 @@ | |||
23 | #include <linux/of_platform.h> | 23 | #include <linux/of_platform.h> |
24 | #include <linux/sched.h> | 24 | #include <linux/sched.h> |
25 | 25 | ||
26 | #define INT_LOCAL_PWR_EN 0x7 | ||
27 | #define MAX_CLK_PER_DOMAIN 4 | 26 | #define MAX_CLK_PER_DOMAIN 4 |
28 | 27 | ||
28 | struct exynos_pm_domain_config { | ||
29 | /* Value for LOCAL_PWR_CFG and STATUS fields for each domain */ | ||
30 | u32 local_pwr_cfg; | ||
31 | }; | ||
32 | |||
29 | /* | 33 | /* |
30 | * Exynos specific wrapper around the generic power domain | 34 | * Exynos specific wrapper around the generic power domain |
31 | */ | 35 | */ |
@@ -38,6 +42,7 @@ struct exynos_pm_domain { | |||
38 | struct clk *clk[MAX_CLK_PER_DOMAIN]; | 42 | struct clk *clk[MAX_CLK_PER_DOMAIN]; |
39 | struct clk *pclk[MAX_CLK_PER_DOMAIN]; | 43 | struct clk *pclk[MAX_CLK_PER_DOMAIN]; |
40 | struct clk *asb_clk[MAX_CLK_PER_DOMAIN]; | 44 | struct clk *asb_clk[MAX_CLK_PER_DOMAIN]; |
45 | u32 local_pwr_cfg; | ||
41 | }; | 46 | }; |
42 | 47 | ||
43 | static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on) | 48 | static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on) |
@@ -69,13 +74,13 @@ static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on) | |||
69 | } | 74 | } |
70 | } | 75 | } |
71 | 76 | ||
72 | pwr = power_on ? INT_LOCAL_PWR_EN : 0; | 77 | pwr = power_on ? pd->local_pwr_cfg : 0; |
73 | __raw_writel(pwr, base); | 78 | __raw_writel(pwr, base); |
74 | 79 | ||
75 | /* Wait max 1ms */ | 80 | /* Wait max 1ms */ |
76 | timeout = 10; | 81 | timeout = 10; |
77 | 82 | ||
78 | while ((__raw_readl(base + 0x4) & INT_LOCAL_PWR_EN) != pwr) { | 83 | while ((__raw_readl(base + 0x4) & pd->local_pwr_cfg) != pwr) { |
79 | if (!timeout) { | 84 | if (!timeout) { |
80 | op = (power_on) ? "enable" : "disable"; | 85 | op = (power_on) ? "enable" : "disable"; |
81 | pr_err("Power domain %s %s failed\n", domain->name, op); | 86 | pr_err("Power domain %s %s failed\n", domain->name, op); |
@@ -119,14 +124,30 @@ static int exynos_pd_power_off(struct generic_pm_domain *domain) | |||
119 | return exynos_pd_power(domain, false); | 124 | return exynos_pd_power(domain, false); |
120 | } | 125 | } |
121 | 126 | ||
127 | static const struct exynos_pm_domain_config exynos4210_cfg __initconst = { | ||
128 | .local_pwr_cfg = 0x7, | ||
129 | }; | ||
130 | |||
131 | static const struct of_device_id exynos_pm_domain_of_match[] __initconst = { | ||
132 | { | ||
133 | .compatible = "samsung,exynos4210-pd", | ||
134 | .data = &exynos4210_cfg, | ||
135 | }, | ||
136 | { }, | ||
137 | }; | ||
138 | |||
122 | static __init int exynos4_pm_init_power_domain(void) | 139 | static __init int exynos4_pm_init_power_domain(void) |
123 | { | 140 | { |
124 | struct device_node *np; | 141 | struct device_node *np; |
142 | const struct of_device_id *match; | ||
125 | 143 | ||
126 | for_each_compatible_node(np, NULL, "samsung,exynos4210-pd") { | 144 | for_each_matching_node_and_match(np, exynos_pm_domain_of_match, &match) { |
145 | const struct exynos_pm_domain_config *pm_domain_cfg; | ||
127 | struct exynos_pm_domain *pd; | 146 | struct exynos_pm_domain *pd; |
128 | int on, i; | 147 | int on, i; |
129 | 148 | ||
149 | pm_domain_cfg = match->data; | ||
150 | |||
130 | pd = kzalloc(sizeof(*pd), GFP_KERNEL); | 151 | pd = kzalloc(sizeof(*pd), GFP_KERNEL); |
131 | if (!pd) { | 152 | if (!pd) { |
132 | pr_err("%s: failed to allocate memory for domain\n", | 153 | pr_err("%s: failed to allocate memory for domain\n", |
@@ -153,6 +174,7 @@ static __init int exynos4_pm_init_power_domain(void) | |||
153 | 174 | ||
154 | pd->pd.power_off = exynos_pd_power_off; | 175 | pd->pd.power_off = exynos_pd_power_off; |
155 | pd->pd.power_on = exynos_pd_power_on; | 176 | pd->pd.power_on = exynos_pd_power_on; |
177 | pd->local_pwr_cfg = pm_domain_cfg->local_pwr_cfg; | ||
156 | 178 | ||
157 | for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) { | 179 | for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) { |
158 | char clk_name[8]; | 180 | char clk_name[8]; |
@@ -185,14 +207,14 @@ static __init int exynos4_pm_init_power_domain(void) | |||
185 | clk_put(pd->oscclk); | 207 | clk_put(pd->oscclk); |
186 | 208 | ||
187 | no_clk: | 209 | no_clk: |
188 | on = __raw_readl(pd->base + 0x4) & INT_LOCAL_PWR_EN; | 210 | on = __raw_readl(pd->base + 0x4) & pd->local_pwr_cfg; |
189 | 211 | ||
190 | pm_genpd_init(&pd->pd, NULL, !on); | 212 | pm_genpd_init(&pd->pd, NULL, !on); |
191 | of_genpd_add_provider_simple(np, &pd->pd); | 213 | of_genpd_add_provider_simple(np, &pd->pd); |
192 | } | 214 | } |
193 | 215 | ||
194 | /* Assign the child power domains to their parents */ | 216 | /* Assign the child power domains to their parents */ |
195 | for_each_compatible_node(np, NULL, "samsung,exynos4210-pd") { | 217 | for_each_matching_node(np, exynos_pm_domain_of_match) { |
196 | struct generic_pm_domain *child_domain, *parent_domain; | 218 | struct generic_pm_domain *child_domain, *parent_domain; |
197 | struct of_phandle_args args; | 219 | struct of_phandle_args args; |
198 | 220 | ||