Skip to content

Commit 0cd454a

Browse files
Paullo612mdrjr
authored andcommitted
WIP: soc: samsung: pm_domains: Bring back old driver implementation
Using new implementation decreases Mali GPU performance significantly (with both KBase and Panfrost drivers). Signed-off-by: Pavel Golikov <[email protected]>
1 parent 6ba8d45 commit 0cd454a

File tree

1 file changed

+50
-47
lines changed

1 file changed

+50
-47
lines changed

drivers/pmdomain/samsung/exynos-pm-domains.c

Lines changed: 50 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#include <linux/of.h>
1919
#include <linux/of_address.h>
2020
#include <linux/pm_runtime.h>
21+
#include <linux/of_platform.h>
22+
#include <linux/sched.h>
2123

2224
struct exynos_pm_domain_config {
2325
/* Value for LOCAL_PWR_CFG and STATUS fields for each domain */
@@ -73,15 +75,15 @@ static int exynos_pd_power_off(struct generic_pm_domain *domain)
7375
return exynos_pd_power(domain, false);
7476
}
7577

76-
static const struct exynos_pm_domain_config exynos4210_cfg = {
78+
static const struct exynos_pm_domain_config exynos4210_cfg __initconst = {
7779
.local_pwr_cfg = 0x7,
7880
};
7981

80-
static const struct exynos_pm_domain_config exynos5433_cfg = {
82+
static const struct exynos_pm_domain_config exynos5433_cfg __initconst = {
8183
.local_pwr_cfg = 0xf,
8284
};
8385

84-
static const struct of_device_id exynos_pm_domain_of_match[] = {
86+
static const struct of_device_id exynos_pm_domain_of_match[] __initconst = {
8587
{
8688
.compatible = "samsung,exynos4210-pd",
8789
.data = &exynos4210_cfg,
@@ -92,7 +94,7 @@ static const struct of_device_id exynos_pm_domain_of_match[] = {
9294
{ },
9395
};
9496

95-
static const char *exynos_get_domain_name(struct device_node *node)
97+
static __init const char *exynos_get_domain_name(struct device_node *node)
9698
{
9799
const char *name;
98100

@@ -101,44 +103,60 @@ static const char *exynos_get_domain_name(struct device_node *node)
101103
return kstrdup_const(name, GFP_KERNEL);
102104
}
103105

104-
static int exynos_pd_probe(struct platform_device *pdev)
106+
static __init int exynos4_pm_init_power_domain(void)
105107
{
106-
const struct exynos_pm_domain_config *pm_domain_cfg;
107-
struct device *dev = &pdev->dev;
108-
struct device_node *np = dev->of_node;
109-
struct of_phandle_args child, parent;
110-
struct exynos_pm_domain *pd;
111-
int on, ret;
108+
struct device_node *np;
109+
const struct of_device_id *match;
112110

113-
pm_domain_cfg = of_device_get_match_data(dev);
114-
pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
115-
if (!pd)
116-
return -ENOMEM;
111+
for_each_matching_node_and_match(np, exynos_pm_domain_of_match, &match) {
112+
const struct exynos_pm_domain_config *pm_domain_cfg;
113+
struct exynos_pm_domain *pd;
114+
int on;
117115

118-
pd->pd.name = exynos_get_domain_name(np);
119-
if (!pd->pd.name)
120-
return -ENOMEM;
116+
pm_domain_cfg = match->data;
121117

122-
pd->base = of_iomap(np, 0);
123-
if (!pd->base) {
124-
kfree_const(pd->pd.name);
125-
return -ENODEV;
126-
}
118+
pd = kzalloc(sizeof(*pd), GFP_KERNEL);
119+
if (!pd) {
120+
of_node_put(np);
121+
return -ENOMEM;
122+
}
123+
pd->pd.name = exynos_get_domain_name(np);
124+
if (!pd->pd.name) {
125+
kfree(pd);
126+
of_node_put(np);
127+
return -ENOMEM;
128+
}
127129

128-
pd->pd.power_off = exynos_pd_power_off;
129-
pd->pd.power_on = exynos_pd_power_on;
130-
pd->local_pwr_cfg = pm_domain_cfg->local_pwr_cfg;
130+
pd->base = of_iomap(np, 0);
131+
if (!pd->base) {
132+
pr_warn("%s: failed to map memory\n", __func__);
133+
kfree_const(pd->pd.name);
134+
kfree(pd);
135+
continue;
136+
}
137+
138+
pd->pd.power_off = exynos_pd_power_off;
139+
pd->pd.power_on = exynos_pd_power_on;
140+
pd->local_pwr_cfg = pm_domain_cfg->local_pwr_cfg;
131141

132-
on = readl_relaxed(pd->base + 0x4) & pd->local_pwr_cfg;
142+
on = readl_relaxed(pd->base + 0x4) & pd->local_pwr_cfg;
143+
144+
pm_genpd_init(&pd->pd, NULL, !on);
145+
of_genpd_add_provider_simple(np, &pd->pd);
146+
}
133147

134-
pm_genpd_init(&pd->pd, NULL, !on);
135-
ret = of_genpd_add_provider_simple(np, &pd->pd);
148+
/* Assign the child power domains to their parents */
149+
for_each_matching_node(np, exynos_pm_domain_of_match) {
150+
struct of_phandle_args child, parent;
136151

137-
if (ret == 0 && of_parse_phandle_with_args(np, "power-domains",
138-
"#power-domain-cells", 0, &parent) == 0) {
139152
child.np = np;
140153
child.args_count = 0;
141154

155+
if (of_parse_phandle_with_args(np, "power-domains",
156+
"#power-domain-cells", 0,
157+
&parent) != 0)
158+
continue;
159+
142160
if (of_genpd_add_subdomain(&parent, &child))
143161
pr_warn("%pOF failed to add subdomain: %pOF\n",
144162
parent.np, child.np);
@@ -147,21 +165,6 @@ static int exynos_pd_probe(struct platform_device *pdev)
147165
parent.np, child.np);
148166
}
149167

150-
pm_runtime_enable(dev);
151-
return ret;
152-
}
153-
154-
static struct platform_driver exynos_pd_driver = {
155-
.probe = exynos_pd_probe,
156-
.driver = {
157-
.name = "exynos-pd",
158-
.of_match_table = exynos_pm_domain_of_match,
159-
.suppress_bind_attrs = true,
160-
}
161-
};
162-
163-
static __init int exynos4_pm_init_power_domain(void)
164-
{
165-
return platform_driver_register(&exynos_pd_driver);
168+
return 0;
166169
}
167170
core_initcall(exynos4_pm_init_power_domain);

0 commit comments

Comments
 (0)