[RFC PATCH v1 07/14] soc: thead: power-domain: Add skeleton power-domain driver for TH1520

Krzysztof Kozlowski krzk at kernel.org
Tue Dec 3 07:58:24 PST 2024


On 03/12/2024 14:41, Michal Wilczynski wrote:
> The T-Head TH1520 SoC contains multiple power islands that can be
> programmatically turned on and off using the AON (Always-On) protocol
> and a hardware mailbox [1]. The relevant mailbox driver has already been
> merged into the mainline kernel in commit 5d4d263e1c6b ("mailbox:
> Introduce support for T-head TH1520 Mailbox driver"); however, the AON
> implementation is still under development.
> 
> This commit introduces a skeleton power-domain driver for the TH1520
> SoC, designed to be easily extended to work with the AON protocol in the
> future.  Currently, it only supports the GPU. Since there is no
> mechanism yet to turn the GPU power island on, the driver will only set
> the relevant registers to bring the GPU out of the reset state.  This
> should be done after the power-up sequence requested through the mailbox
> is completed.
> 
> Link: https://openbeagle.org/beaglev-ahead/beaglev-ahead/-/blob/main/docs/TH1520%20System%20User%20Manual.pdf [1]
> 
> Signed-off-by: Michal Wilczynski <m.wilczynski at samsung.com>
> ---
>  MAINTAINERS                                   |   2 +
>  drivers/pmdomain/Kconfig                      |   1 +
>  drivers/pmdomain/Makefile                     |   1 +
>  drivers/pmdomain/thead/Kconfig                |  12 ++
>  drivers/pmdomain/thead/Makefile               |   2 +
>  drivers/pmdomain/thead/th1520-pm-domains.c    | 195 ++++++++++++++++++
>  .../dt-bindings/power/thead,th1520-power.h    |  19 ++
>  7 files changed, 232 insertions(+)


Please run scripts/checkpatch.pl and fix reported warnings. Then please
run `scripts/checkpatch.pl --strict` and (probably) fix more warnings.


>  create mode 100644 drivers/pmdomain/thead/Kconfig
>  create mode 100644 drivers/pmdomain/thead/Makefile
>  create mode 100644 drivers/pmdomain/thead/th1520-pm-domains.c
>  create mode 100644 include/dt-bindings/power/thead,th1520-power.h
> 


...

> +
> +static int th1520_pd_power_off(struct generic_pm_domain *domain)
> +{
> +	struct th1520_power_domain *pd = to_th1520_power_domain(domain);
> +
> +	/* The missing component here is the call to E902 core through the

Use Linux coding style comments (see coding style). This applies to
multiple places in your code.

> +	 * AON protocol using hardware mailbox.
> +	 */
> +
> +	/* Put the GPU into reset state after powering it off */
> +	th1520_rst_gpu_disable(pd->reg);
> +
> +	return 0;
> +}
> +
> +static struct generic_pm_domain *th1520_pd_xlate(const struct of_phandle_args *spec,
> +						 void *data)
> +{
> +	struct generic_pm_domain *domain = ERR_PTR(-ENOENT);
> +	struct genpd_onecell_data *pd_data = data;
> +	unsigned int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(th1520_pd_ranges); i++) {
> +		struct th1520_power_domain *pd;
> +
> +		pd = to_th1520_power_domain(pd_data->domains[i]);
> +		if (pd->rsrc == spec->args[0]) {
> +			domain = &pd->genpd;
> +			break;
> +		}
> +	}
> +
> +	return domain;
> +}
> +
> +static struct th1520_power_domain *
> +th1520_add_pm_domain(struct device *dev, const struct th1520_power_info *pi)
> +{
> +	struct th1520_power_domain *pd;
> +	int ret;
> +
> +	pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
> +	if (!pd)
> +		return ERR_PTR(-ENOMEM);
> +
> +	pd->rsrc = pi->rsrc;
> +	pd->genpd.power_on = th1520_pd_power_on;
> +	pd->genpd.power_off = th1520_pd_power_off;
> +	pd->genpd.name = pi->name;
> +
> +	ret = pm_genpd_init(&pd->genpd, NULL, true);
> +	if (ret) {
> +		devm_kfree(dev, pd);

You should rather fail the probe. Failures of power domains are important.

> +		return ERR_PTR(ret);
> +	}
> +
> +	return pd;
> +}
> +
> +static int th1520_pd_probe(struct platform_device *pdev)
> +{
> +	struct generic_pm_domain **domains;
> +	struct genpd_onecell_data *pd_data;
> +	struct device *dev = &pdev->dev;
> +	struct device_node *np = dev->of_node;
> +	struct regmap *reg;
> +	int i;
> +
> +	reg = syscon_regmap_lookup_by_phandle(np, "thead,vosys-regmap");
> +	if (IS_ERR(reg))
> +		return PTR_ERR(reg);
> +
> +	domains = devm_kcalloc(dev, ARRAY_SIZE(th1520_pd_ranges),
> +			       sizeof(*domains), GFP_KERNEL);
> +	if (!domains)
> +		return -ENOMEM;
> +
> +	pd_data = devm_kzalloc(dev, sizeof(*pd_data), GFP_KERNEL);
> +	if (!pd_data)
> +		return -ENOMEM;
> +
> +	for (i = 0; i < ARRAY_SIZE(th1520_pd_ranges); i++) {
> +		struct th1520_power_domain *pd;
> +
> +		pd = th1520_add_pm_domain(dev, &th1520_pd_ranges[i]);
> +		if (IS_ERR_OR_NULL(pd))
> +			continue;
> +
> +		pd->reg = reg;
> +		domains[i] = &pd->genpd;
> +		dev_dbg(dev, "added power domain %s\n", pd->genpd.name);
> +	}
> +
> +	pd_data->domains = domains;
> +	pd_data->num_domains = ARRAY_SIZE(th1520_pd_ranges);
> +	pd_data->xlate = th1520_pd_xlate;
> +
> +	return of_genpd_add_provider_onecell(dev->of_node, pd_data);
> +}
> +
> +static const struct of_device_id th1520_pd_match[] = {
> +	{ .compatible = "thead,th1520-pd",},
> +	{ /* sentinel */ }
> +};
> +


Make the driver tristate and module. There is nothing here which
prevents it being a module.


> +builtin_platform_driver(th1520_pd_driver);
> diff --git a/include/dt-bindings/power/thead,th1520-power.h b/include/dt-bindings/power/thead,th1520-power.h
> new file mode 100644
> index 000000000000..30fb4e9892e7
> --- /dev/null
> +++ b/include/dt-bindings/power/thead,th1520-power.h
> @@ -0,0 +1,19 @@
> +// SPDX-License-Identifier: GPL-2.0+


Wrong license. See checkpatch.



Best regards,
Krzysztof



More information about the linux-riscv mailing list