clk: renesas: rzg2l: Drop MSTOP based power domain support
Since the configuration order between the individual MSTOP and CLKON bits cannot be preserved with the power domain abstraction, drop the power domain core code. Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> Link: https://lore.kernel.org/20250527112403.1254122-7-claudiu.beznea.uj@bp.renesas.com Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
This commit is contained in:
committed by
Geert Uytterhoeven
parent
c496959527
commit
26a301a244
+17
-191
@@ -148,6 +148,7 @@ struct rzg2l_pll5_mux_dsi_div_param {
|
||||
* @num_resets: Number of Module Resets in info->resets[]
|
||||
* @last_dt_core_clk: ID of the last Core Clock exported to DT
|
||||
* @info: Pointer to platform data
|
||||
* @genpd: PM domain
|
||||
* @mux_dsi_div_params: pll5 mux and dsi div parameters
|
||||
*/
|
||||
struct rzg2l_cpg_priv {
|
||||
@@ -164,6 +165,8 @@ struct rzg2l_cpg_priv {
|
||||
|
||||
const struct rzg2l_cpg_info *info;
|
||||
|
||||
struct generic_pm_domain genpd;
|
||||
|
||||
struct rzg2l_pll5_mux_dsi_div_param mux_dsi_div_params;
|
||||
};
|
||||
|
||||
@@ -1763,39 +1766,14 @@ static int rzg2l_cpg_reset_controller_register(struct rzg2l_cpg_priv *priv)
|
||||
return devm_reset_controller_register(priv->dev, &priv->rcdev);
|
||||
}
|
||||
|
||||
/**
|
||||
* struct rzg2l_cpg_pm_domains - RZ/G2L PM domains data structure
|
||||
* @onecell_data: cell data
|
||||
* @domains: generic PM domains
|
||||
*/
|
||||
struct rzg2l_cpg_pm_domains {
|
||||
struct genpd_onecell_data onecell_data;
|
||||
struct generic_pm_domain *domains[];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct rzg2l_cpg_pd - RZ/G2L power domain data structure
|
||||
* @genpd: generic PM domain
|
||||
* @priv: pointer to CPG private data structure
|
||||
* @conf: CPG PM domain configuration info
|
||||
* @id: RZ/G2L power domain ID
|
||||
*/
|
||||
struct rzg2l_cpg_pd {
|
||||
struct generic_pm_domain genpd;
|
||||
struct rzg2l_cpg_priv *priv;
|
||||
struct rzg2l_cpg_pm_domain_conf conf;
|
||||
u16 id;
|
||||
};
|
||||
|
||||
static bool rzg2l_cpg_is_pm_clk(struct rzg2l_cpg_pd *pd,
|
||||
static bool rzg2l_cpg_is_pm_clk(struct rzg2l_cpg_priv *priv,
|
||||
const struct of_phandle_args *clkspec)
|
||||
{
|
||||
if (clkspec->np != pd->genpd.dev.of_node || clkspec->args_count != 2)
|
||||
if (clkspec->np != priv->genpd.dev.of_node || clkspec->args_count != 2)
|
||||
return false;
|
||||
|
||||
switch (clkspec->args[0]) {
|
||||
case CPG_MOD: {
|
||||
struct rzg2l_cpg_priv *priv = pd->priv;
|
||||
const struct rzg2l_cpg_info *info = priv->info;
|
||||
unsigned int id = clkspec->args[1];
|
||||
|
||||
@@ -1820,7 +1798,7 @@ static bool rzg2l_cpg_is_pm_clk(struct rzg2l_cpg_pd *pd,
|
||||
|
||||
static int rzg2l_cpg_attach_dev(struct generic_pm_domain *domain, struct device *dev)
|
||||
{
|
||||
struct rzg2l_cpg_pd *pd = container_of(domain, struct rzg2l_cpg_pd, genpd);
|
||||
struct rzg2l_cpg_priv *priv = container_of(domain, struct rzg2l_cpg_priv, genpd);
|
||||
struct device_node *np = dev->of_node;
|
||||
struct of_phandle_args clkspec;
|
||||
bool once = true;
|
||||
@@ -1829,7 +1807,7 @@ static int rzg2l_cpg_attach_dev(struct generic_pm_domain *domain, struct device
|
||||
int error;
|
||||
|
||||
for (i = 0; !of_parse_phandle_with_args(np, "clocks", "#clock-cells", i, &clkspec); i++) {
|
||||
if (!rzg2l_cpg_is_pm_clk(pd, &clkspec)) {
|
||||
if (!rzg2l_cpg_is_pm_clk(priv, &clkspec)) {
|
||||
of_node_put(clkspec.np);
|
||||
continue;
|
||||
}
|
||||
@@ -1874,183 +1852,31 @@ static void rzg2l_cpg_detach_dev(struct generic_pm_domain *unused, struct device
|
||||
}
|
||||
|
||||
static void rzg2l_cpg_genpd_remove(void *data)
|
||||
{
|
||||
struct genpd_onecell_data *celldata = data;
|
||||
|
||||
for (unsigned int i = 0; i < celldata->num_domains; i++)
|
||||
pm_genpd_remove(celldata->domains[i]);
|
||||
}
|
||||
|
||||
static void rzg2l_cpg_genpd_remove_simple(void *data)
|
||||
{
|
||||
pm_genpd_remove(data);
|
||||
}
|
||||
|
||||
static int rzg2l_cpg_power_on(struct generic_pm_domain *domain)
|
||||
{
|
||||
struct rzg2l_cpg_pd *pd = container_of(domain, struct rzg2l_cpg_pd, genpd);
|
||||
struct rzg2l_cpg_reg_conf mstop = pd->conf.mstop;
|
||||
struct rzg2l_cpg_priv *priv = pd->priv;
|
||||
|
||||
/* Set MSTOP. */
|
||||
if (mstop.mask)
|
||||
writel(mstop.mask << 16, priv->base + mstop.off);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rzg2l_cpg_power_off(struct generic_pm_domain *domain)
|
||||
{
|
||||
struct rzg2l_cpg_pd *pd = container_of(domain, struct rzg2l_cpg_pd, genpd);
|
||||
struct rzg2l_cpg_reg_conf mstop = pd->conf.mstop;
|
||||
struct rzg2l_cpg_priv *priv = pd->priv;
|
||||
|
||||
/* Set MSTOP. */
|
||||
if (mstop.mask)
|
||||
writel(mstop.mask | (mstop.mask << 16), priv->base + mstop.off);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init rzg2l_cpg_pd_setup(struct rzg2l_cpg_pd *pd)
|
||||
{
|
||||
bool always_on = !!(pd->genpd.flags & GENPD_FLAG_ALWAYS_ON);
|
||||
struct dev_power_governor *governor;
|
||||
int ret;
|
||||
|
||||
if (always_on)
|
||||
governor = &pm_domain_always_on_gov;
|
||||
else
|
||||
governor = &simple_qos_governor;
|
||||
|
||||
pd->genpd.flags |= GENPD_FLAG_PM_CLK | GENPD_FLAG_ACTIVE_WAKEUP;
|
||||
pd->genpd.attach_dev = rzg2l_cpg_attach_dev;
|
||||
pd->genpd.detach_dev = rzg2l_cpg_detach_dev;
|
||||
pd->genpd.power_on = rzg2l_cpg_power_on;
|
||||
pd->genpd.power_off = rzg2l_cpg_power_off;
|
||||
|
||||
ret = pm_genpd_init(&pd->genpd, governor, !always_on);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (always_on)
|
||||
ret = rzg2l_cpg_power_on(&pd->genpd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __init rzg2l_cpg_add_clk_domain(struct rzg2l_cpg_priv *priv)
|
||||
{
|
||||
struct device *dev = priv->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
struct rzg2l_cpg_pd *pd;
|
||||
struct generic_pm_domain *genpd = &priv->genpd;
|
||||
int ret;
|
||||
|
||||
pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
|
||||
if (!pd)
|
||||
return -ENOMEM;
|
||||
|
||||
pd->genpd.name = np->name;
|
||||
pd->genpd.flags = GENPD_FLAG_ALWAYS_ON;
|
||||
pd->priv = priv;
|
||||
ret = rzg2l_cpg_pd_setup(pd);
|
||||
genpd->name = np->name;
|
||||
genpd->flags = GENPD_FLAG_PM_CLK | GENPD_FLAG_ALWAYS_ON |
|
||||
GENPD_FLAG_ACTIVE_WAKEUP;
|
||||
genpd->attach_dev = rzg2l_cpg_attach_dev;
|
||||
genpd->detach_dev = rzg2l_cpg_detach_dev;
|
||||
ret = pm_genpd_init(genpd, &pm_domain_always_on_gov, false);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = devm_add_action_or_reset(dev, rzg2l_cpg_genpd_remove_simple, &pd->genpd);
|
||||
ret = devm_add_action_or_reset(dev, rzg2l_cpg_genpd_remove, genpd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return of_genpd_add_provider_simple(np, &pd->genpd);
|
||||
}
|
||||
|
||||
static struct generic_pm_domain *
|
||||
rzg2l_cpg_pm_domain_xlate(const struct of_phandle_args *spec, void *data)
|
||||
{
|
||||
struct generic_pm_domain *domain = ERR_PTR(-ENOENT);
|
||||
struct genpd_onecell_data *genpd = data;
|
||||
|
||||
if (spec->args_count != 1)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
for (unsigned int i = 0; i < genpd->num_domains; i++) {
|
||||
struct rzg2l_cpg_pd *pd = container_of(genpd->domains[i], struct rzg2l_cpg_pd,
|
||||
genpd);
|
||||
|
||||
if (pd->id == spec->args[0]) {
|
||||
domain = &pd->genpd;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return domain;
|
||||
}
|
||||
|
||||
static int __init rzg2l_cpg_add_pm_domains(struct rzg2l_cpg_priv *priv)
|
||||
{
|
||||
const struct rzg2l_cpg_info *info = priv->info;
|
||||
struct device *dev = priv->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
struct rzg2l_cpg_pm_domains *domains;
|
||||
struct generic_pm_domain *parent;
|
||||
u32 ncells;
|
||||
int ret;
|
||||
|
||||
ret = of_property_read_u32(np, "#power-domain-cells", &ncells);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* For backward compatibility. */
|
||||
if (!ncells)
|
||||
return rzg2l_cpg_add_clk_domain(priv);
|
||||
|
||||
domains = devm_kzalloc(dev, struct_size(domains, domains, info->num_pm_domains),
|
||||
GFP_KERNEL);
|
||||
if (!domains)
|
||||
return -ENOMEM;
|
||||
|
||||
domains->onecell_data.domains = domains->domains;
|
||||
domains->onecell_data.num_domains = info->num_pm_domains;
|
||||
domains->onecell_data.xlate = rzg2l_cpg_pm_domain_xlate;
|
||||
|
||||
ret = devm_add_action_or_reset(dev, rzg2l_cpg_genpd_remove, &domains->onecell_data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
for (unsigned int i = 0; i < info->num_pm_domains; i++) {
|
||||
struct rzg2l_cpg_pd *pd;
|
||||
|
||||
pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
|
||||
if (!pd)
|
||||
return -ENOMEM;
|
||||
|
||||
pd->genpd.name = info->pm_domains[i].name;
|
||||
pd->genpd.flags = info->pm_domains[i].genpd_flags;
|
||||
pd->conf = info->pm_domains[i].conf;
|
||||
pd->id = info->pm_domains[i].id;
|
||||
pd->priv = priv;
|
||||
|
||||
ret = rzg2l_cpg_pd_setup(pd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
domains->domains[i] = &pd->genpd;
|
||||
/* Parent should be on the very first entry of info->pm_domains[]. */
|
||||
if (!i) {
|
||||
parent = &pd->genpd;
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = pm_genpd_add_subdomain(parent, &pd->genpd);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = of_genpd_add_provider_onecell(np, &domains->onecell_data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
return of_genpd_add_provider_simple(np, genpd);
|
||||
}
|
||||
|
||||
static int __init rzg2l_cpg_probe(struct platform_device *pdev)
|
||||
@@ -2113,7 +1939,7 @@ static int __init rzg2l_cpg_probe(struct platform_device *pdev)
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
error = rzg2l_cpg_add_pm_domains(priv);
|
||||
error = rzg2l_cpg_add_clk_domain(priv);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
|
||||
@@ -257,51 +257,6 @@ struct rzg2l_reset {
|
||||
#define DEF_RST(_id, _off, _bit) \
|
||||
DEF_RST_MON(_id, _off, _bit, -1)
|
||||
|
||||
/**
|
||||
* struct rzg2l_cpg_reg_conf - RZ/G2L register configuration data structure
|
||||
* @off: register offset
|
||||
* @mask: register mask
|
||||
*/
|
||||
struct rzg2l_cpg_reg_conf {
|
||||
u16 off;
|
||||
u16 mask;
|
||||
};
|
||||
|
||||
#define DEF_REG_CONF(_off, _mask) ((struct rzg2l_cpg_reg_conf) { .off = (_off), .mask = (_mask) })
|
||||
|
||||
/**
|
||||
* struct rzg2l_cpg_pm_domain_conf - PM domain configuration data structure
|
||||
* @mstop: MSTOP register configuration
|
||||
*/
|
||||
struct rzg2l_cpg_pm_domain_conf {
|
||||
struct rzg2l_cpg_reg_conf mstop;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct rzg2l_cpg_pm_domain_init_data - PM domain init data
|
||||
* @name: PM domain name
|
||||
* @conf: PM domain configuration
|
||||
* @genpd_flags: genpd flags (see GENPD_FLAG_*)
|
||||
* @id: PM domain ID (similar to the ones defined in
|
||||
* include/dt-bindings/clock/<soc-id>-cpg.h)
|
||||
*/
|
||||
struct rzg2l_cpg_pm_domain_init_data {
|
||||
const char * const name;
|
||||
struct rzg2l_cpg_pm_domain_conf conf;
|
||||
u32 genpd_flags;
|
||||
u16 id;
|
||||
};
|
||||
|
||||
#define DEF_PD(_name, _id, _mstop_conf, _flags) \
|
||||
{ \
|
||||
.name = (_name), \
|
||||
.id = (_id), \
|
||||
.conf = { \
|
||||
.mstop = (_mstop_conf), \
|
||||
}, \
|
||||
.genpd_flags = (_flags), \
|
||||
}
|
||||
|
||||
/**
|
||||
* struct rzg2l_cpg_info - SoC-specific CPG Description
|
||||
*
|
||||
@@ -320,8 +275,6 @@ struct rzg2l_cpg_pm_domain_init_data {
|
||||
* @crit_mod_clks: Array with Module Clock IDs of critical clocks that
|
||||
* should not be disabled without a knowledgeable driver
|
||||
* @num_crit_mod_clks: Number of entries in crit_mod_clks[]
|
||||
* @pm_domains: PM domains init data array
|
||||
* @num_pm_domains: Number of PM domains
|
||||
* @has_clk_mon_regs: Flag indicating whether the SoC has CLK_MON registers
|
||||
*/
|
||||
struct rzg2l_cpg_info {
|
||||
@@ -348,10 +301,6 @@ struct rzg2l_cpg_info {
|
||||
const unsigned int *crit_mod_clks;
|
||||
unsigned int num_crit_mod_clks;
|
||||
|
||||
/* Power domain. */
|
||||
const struct rzg2l_cpg_pm_domain_init_data *pm_domains;
|
||||
unsigned int num_pm_domains;
|
||||
|
||||
bool has_clk_mon_regs;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user