summaryrefslogtreecommitdiff
path: root/drivers/soc/sunxi
diff options
context:
space:
mode:
authorUlf Hansson <ulf.hansson@linaro.org>2023-07-05 18:26:45 +0200
committerUlf Hansson <ulf.hansson@linaro.org>2023-07-14 10:40:56 +0200
commitfd697e2160401530dfe43074bbdcbb7d63b87b60 (patch)
treeb4c3867ef41e4f0c68cc4bdc05bf18fb8792a2d3 /drivers/soc/sunxi
parentf3fb16291f48638e9eda4f249970d34061906ba3 (diff)
soc: sunxi: Move power-domain driver to the genpd dir
To simplify with maintenance let's move the sunxi power-domain driver to the new genpd directory. Going forward, patches are intended to be managed through a separate git tree, according to MAINTAINERS. Cc: Chen-Yu Tsai <wens@csie.org> Cc: Jernej Skrabec <jernej.skrabec@gmail.com> Cc: Samuel Holland <samuel@sholland.org> Cc: <linux-sunxi@lists.linux.dev> Acked-by: Jernej Skrabec <jernej.skrabec@gmail.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Diffstat (limited to 'drivers/soc/sunxi')
-rw-r--r--drivers/soc/sunxi/Makefile1
-rw-r--r--drivers/soc/sunxi/sun20i-ppu.c207
2 files changed, 0 insertions, 208 deletions
diff --git a/drivers/soc/sunxi/Makefile b/drivers/soc/sunxi/Makefile
index 90ff2ebe7655..549159571d4f 100644
--- a/drivers/soc/sunxi/Makefile
+++ b/drivers/soc/sunxi/Makefile
@@ -1,4 +1,3 @@
# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_SUNXI_MBUS) += sunxi_mbus.o
obj-$(CONFIG_SUNXI_SRAM) += sunxi_sram.o
-obj-$(CONFIG_SUN20I_PPU) += sun20i-ppu.o
diff --git a/drivers/soc/sunxi/sun20i-ppu.c b/drivers/soc/sunxi/sun20i-ppu.c
deleted file mode 100644
index 98cb41d36560..000000000000
--- a/drivers/soc/sunxi/sun20i-ppu.c
+++ /dev/null
@@ -1,207 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-
-#include <linux/bitfield.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/iopoll.h>
-#include <linux/module.h>
-#include <linux/of_device.h>
-#include <linux/platform_device.h>
-#include <linux/pm_domain.h>
-#include <linux/reset.h>
-
-#define PD_STATE_ON 1
-#define PD_STATE_OFF 2
-
-#define PD_RSTN_REG 0x00
-#define PD_CLK_GATE_REG 0x04
-#define PD_PWROFF_GATE_REG 0x08
-#define PD_PSW_ON_REG 0x0c
-#define PD_PSW_OFF_REG 0x10
-#define PD_PSW_DELAY_REG 0x14
-#define PD_OFF_DELAY_REG 0x18
-#define PD_ON_DELAY_REG 0x1c
-#define PD_COMMAND_REG 0x20
-#define PD_STATUS_REG 0x24
-#define PD_STATUS_COMPLETE BIT(1)
-#define PD_STATUS_BUSY BIT(3)
-#define PD_STATUS_STATE GENMASK(17, 16)
-#define PD_ACTIVE_CTRL_REG 0x2c
-#define PD_GATE_STATUS_REG 0x30
-#define PD_RSTN_STATUS BIT(0)
-#define PD_CLK_GATE_STATUS BIT(1)
-#define PD_PWROFF_GATE_STATUS BIT(2)
-#define PD_PSW_STATUS_REG 0x34
-
-#define PD_REGS_SIZE 0x80
-
-struct sun20i_ppu_desc {
- const char *const *names;
- unsigned int num_domains;
-};
-
-struct sun20i_ppu_pd {
- struct generic_pm_domain genpd;
- void __iomem *base;
-};
-
-#define to_sun20i_ppu_pd(_genpd) \
- container_of(_genpd, struct sun20i_ppu_pd, genpd)
-
-static bool sun20i_ppu_pd_is_on(const struct sun20i_ppu_pd *pd)
-{
- u32 status = readl(pd->base + PD_STATUS_REG);
-
- return FIELD_GET(PD_STATUS_STATE, status) == PD_STATE_ON;
-}
-
-static int sun20i_ppu_pd_set_power(const struct sun20i_ppu_pd *pd, bool power_on)
-{
- u32 state, status;
- int ret;
-
- if (sun20i_ppu_pd_is_on(pd) == power_on)
- return 0;
-
- /* Wait for the power controller to be idle. */
- ret = readl_poll_timeout(pd->base + PD_STATUS_REG, status,
- !(status & PD_STATUS_BUSY), 100, 1000);
- if (ret)
- return ret;
-
- state = power_on ? PD_STATE_ON : PD_STATE_OFF;
- writel(state, pd->base + PD_COMMAND_REG);
-
- /* Wait for the state transition to complete. */
- ret = readl_poll_timeout(pd->base + PD_STATUS_REG, status,
- FIELD_GET(PD_STATUS_STATE, status) == state &&
- (status & PD_STATUS_COMPLETE), 100, 1000);
- if (ret)
- return ret;
-
- /* Clear the completion flag. */
- writel(status, pd->base + PD_STATUS_REG);
-
- return 0;
-}
-
-static int sun20i_ppu_pd_power_on(struct generic_pm_domain *genpd)
-{
- const struct sun20i_ppu_pd *pd = to_sun20i_ppu_pd(genpd);
-
- return sun20i_ppu_pd_set_power(pd, true);
-}
-
-static int sun20i_ppu_pd_power_off(struct generic_pm_domain *genpd)
-{
- const struct sun20i_ppu_pd *pd = to_sun20i_ppu_pd(genpd);
-
- return sun20i_ppu_pd_set_power(pd, false);
-}
-
-static int sun20i_ppu_probe(struct platform_device *pdev)
-{
- const struct sun20i_ppu_desc *desc;
- struct device *dev = &pdev->dev;
- struct genpd_onecell_data *ppu;
- struct sun20i_ppu_pd *pds;
- struct reset_control *rst;
- void __iomem *base;
- struct clk *clk;
- int ret;
-
- desc = of_device_get_match_data(dev);
- if (!desc)
- return -EINVAL;
-
- pds = devm_kcalloc(dev, desc->num_domains, sizeof(*pds), GFP_KERNEL);
- if (!pds)
- return -ENOMEM;
-
- ppu = devm_kzalloc(dev, sizeof(*ppu), GFP_KERNEL);
- if (!ppu)
- return -ENOMEM;
-
- ppu->domains = devm_kcalloc(dev, desc->num_domains,
- sizeof(*ppu->domains), GFP_KERNEL);
- if (!ppu->domains)
- return -ENOMEM;
-
- ppu->num_domains = desc->num_domains;
- platform_set_drvdata(pdev, ppu);
-
- base = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(base))
- return PTR_ERR(base);
-
- clk = devm_clk_get_enabled(dev, NULL);
- if (IS_ERR(clk))
- return PTR_ERR(clk);
-
- rst = devm_reset_control_get_exclusive(dev, NULL);
- if (IS_ERR(rst))
- return PTR_ERR(rst);
-
- ret = reset_control_deassert(rst);
- if (ret)
- return ret;
-
- for (unsigned int i = 0; i < ppu->num_domains; ++i) {
- struct sun20i_ppu_pd *pd = &pds[i];
-
- pd->genpd.name = desc->names[i];
- pd->genpd.power_off = sun20i_ppu_pd_power_off;
- pd->genpd.power_on = sun20i_ppu_pd_power_on;
- pd->base = base + PD_REGS_SIZE * i;
-
- ret = pm_genpd_init(&pd->genpd, NULL, sun20i_ppu_pd_is_on(pd));
- if (ret) {
- dev_warn(dev, "Failed to add '%s' domain: %d\n",
- pd->genpd.name, ret);
- continue;
- }
-
- ppu->domains[i] = &pd->genpd;
- }
-
- ret = of_genpd_add_provider_onecell(dev->of_node, ppu);
- if (ret)
- dev_warn(dev, "Failed to add provider: %d\n", ret);
-
- return 0;
-}
-
-static const char *const sun20i_d1_ppu_pd_names[] = {
- "CPU",
- "VE",
- "DSP",
-};
-
-static const struct sun20i_ppu_desc sun20i_d1_ppu_desc = {
- .names = sun20i_d1_ppu_pd_names,
- .num_domains = ARRAY_SIZE(sun20i_d1_ppu_pd_names),
-};
-
-static const struct of_device_id sun20i_ppu_of_match[] = {
- {
- .compatible = "allwinner,sun20i-d1-ppu",
- .data = &sun20i_d1_ppu_desc,
- },
- { }
-};
-MODULE_DEVICE_TABLE(of, sun20i_ppu_of_match);
-
-static struct platform_driver sun20i_ppu_driver = {
- .probe = sun20i_ppu_probe,
- .driver = {
- .name = "sun20i-ppu",
- .of_match_table = sun20i_ppu_of_match,
- /* Power domains cannot be removed while they are in use. */
- .suppress_bind_attrs = true,
- },
-};
-module_platform_driver(sun20i_ppu_driver);
-
-MODULE_AUTHOR("Samuel Holland <samuel@sholland.org>");
-MODULE_DESCRIPTION("Allwinner D1 PPU power domain driver");
-MODULE_LICENSE("GPL");