Skip to content
Snippets Groups Projects
Unverified Commit ae8f7048 authored by AngeloGioacchino Del Regno's avatar AngeloGioacchino Del Regno
Browse files

TODO: soc: mediatek: mtk-pm-domains: Support CPU Power Domains

Some SoCs need support for powering up CPU power domains before
secondary bringup.
TODO: Test this on mt6795 and other older gen MTK SoCs.
parent ae1db121
No related merge requests found
......@@ -4,6 +4,7 @@
*/
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/cpu.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/iopoll.h>
......@@ -655,6 +656,7 @@ static int scpsys_probe(struct platform_device *pdev)
struct device_node *node;
struct device *parent;
struct scpsys *scpsys;
bool cpu_pd_found = false;
int ret;
soc = of_device_get_match_data(&pdev->dev);
......@@ -688,6 +690,7 @@ static int scpsys_probe(struct platform_device *pdev)
ret = -ENODEV;
for_each_available_child_of_node(np, node) {
struct generic_pm_domain *domain;
struct scpsys_domain *pd;
domain = scpsys_add_one_domain(scpsys, node);
if (IS_ERR(domain)) {
......@@ -701,6 +704,10 @@ static int scpsys_probe(struct platform_device *pdev)
of_node_put(node);
goto err_cleanup_domains;
}
pd = to_scpsys_domain(domain);
if (MTK_SCPD_CAPS(pd, MTK_SCPD_CPU_DOMAIN))
cpu_pd_found = true;
}
if (ret) {
......@@ -714,6 +721,14 @@ static int scpsys_probe(struct platform_device *pdev)
goto err_cleanup_domains;
}
/*
* If we have found a CPU power domain this means that, during early
* init, we have disabled CPU hotplug: since we can now control power
* to bring up secondary CPUs now, enable it again here.
*/
if (cpu_pd_found)
cpu_hotplug_enable();
return 0;
err_cleanup_domains:
......@@ -730,3 +745,55 @@ static struct platform_driver scpsys_pm_domain_driver = {
},
};
builtin_platform_driver(scpsys_pm_domain_driver);
static int scpsys_early_init(void)
{
const struct scpsys_soc_data *soc;
const struct of_device_id *match;
bool cpu_pd_found = false;
struct device_node *np;
int i;
np = of_find_matching_node_and_match(NULL, scpsys_of_match, &match);
if (IS_ERR_OR_NULL(np))
return -ENODEV;
soc = match->data;
for (i = 0; i < soc->num_domains; i++) {
if (soc->domains_data[i].caps & MTK_SCPD_CPU_DOMAIN) {
cpu_pd_found = true;
break;
}
}
/* If there's no CPU Power Domain we have nothing to do here */
if (!cpu_pd_found)
goto end;
/*
* This function always runs after SMP is prepared, so the CPU maps
* are populated but no secondary CPU is booted yet: in order to
* avoid forcing powerup of all processors in the systems at this
* early stage and to keep using the regular power domains on/off
* flow provided in this driver (using regmap), we temporarily
* disable CPU hotplug here and re-enable it after initializing
* all of the power domains for the CPUs.
*/
cpu_hotplug_disable();
/* we set all of the
* secondary processors as not present in this function (not good)
*/
/*
base = of_iomap(np, 0);
if (!base) {
ret = -ENODEV;
goto end;
};
*/
end:
of_node_put(np);
return 0;
}
early_initcall(scpsys_early_init);
......@@ -13,6 +13,7 @@
#define MTK_SCPD_EXT_BUCK_ISO BIT(6)
#define MTK_SCPD_HAS_INFRA_NAO BIT(7)
#define MTK_SCPD_STRICT_BUS_PROTECTION BIT(8)
#define MTK_SCPD_CPU_DOMAIN BIT(9)
#define MTK_SCPD_CAPS(_scpd, _x) ((_scpd)->data->caps & (_x))
#define SPM_VDE_PWR_CON 0x0210
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment