mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Michael Grzeschik <m.grzeschik@pengutronix.de>
To: Sascha Hauer <s.hauer@pengutronix.de>,
	 BAREBOX <barebox@lists.infradead.org>
Subject: [PATCH 1/2] soc: imx: imx93: add ported source driver for pmdomain from linux
Date: Wed, 19 Nov 2025 16:25:07 +0100	[thread overview]
Message-ID: <20251119-imx93-pd-v1-1-2b114723a734@pengutronix.de> (raw)
In-Reply-To: <20251119-imx93-pd-v1-0-2b114723a734@pengutronix.de>

The src driver is populating all power domains that are controlled by
the system reset controller. Currently supported power domain is the
mediamix power domain.

Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
---
 arch/arm/mach-imx/imx9.c        |   3 +
 drivers/pmdomain/imx/Makefile   |   1 +
 drivers/pmdomain/imx/imx93-pd.c | 151 ++++++++++++++++++++++++++++++++++++++++
 drivers/soc/imx/Makefile        |   1 +
 drivers/soc/imx/imx93-src.c     |  30 ++++++++
 5 files changed, 186 insertions(+)

diff --git a/arch/arm/mach-imx/imx9.c b/arch/arm/mach-imx/imx9.c
index dd4fbf099e601dda3c01a4e2d64a9552d2f616e5..25ba7e444843ea5ae817dd8103074e5a50fb48f0 100644
--- a/arch/arm/mach-imx/imx9.c
+++ b/arch/arm/mach-imx/imx9.c
@@ -2,6 +2,7 @@
 
 #include <init.h>
 #include <common.h>
+#include <pm_domain.h>
 #include <linux/clk.h>
 #include <mach/imx/generic.h>
 #include <mach/imx/ele.h>
@@ -184,5 +185,7 @@ int imx93_init(void)
 		of_register_fixup(of_optee_fixup, &optee_fixup_data);
 	}
 
+	genpd_activate();
+
 	return 0;
 }
diff --git a/drivers/pmdomain/imx/Makefile b/drivers/pmdomain/imx/Makefile
index 1364944d5ac52dd2faf7002a9df1f3263d48891c..f35ac69f70cd0f403b20c32638f93bbdb34f6b9a 100644
--- a/drivers/pmdomain/imx/Makefile
+++ b/drivers/pmdomain/imx/Makefile
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-$(CONFIG_IMX_GPCV2_PM_DOMAINS) += gpcv2.o
 obj-$(CONFIG_IMX8M_BLK_CTRL) += imx8mp-blk-ctrl.o
+obj-$(CONFIG_ARCH_IMX93) += imx93-pd.o
diff --git a/drivers/pmdomain/imx/imx93-pd.c b/drivers/pmdomain/imx/imx93-pd.c
new file mode 100644
index 0000000000000000000000000000000000000000..3222fc17e9d02adbb6792df27d5a0fb97fc5c305
--- /dev/null
+++ b/drivers/pmdomain/imx/imx93-pd.c
@@ -0,0 +1,151 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2022 NXP
+ */
+
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/iopoll.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <pm_domain.h>
+
+#define MIX_SLICE_SW_CTRL_OFF		0x20
+#define SLICE_SW_CTRL_PSW_CTRL_OFF_MASK	BIT(4)
+#define SLICE_SW_CTRL_PDN_SOFT_MASK	BIT(31)
+
+#define MIX_FUNC_STAT_OFF		0xB4
+
+#define FUNC_STAT_PSW_STAT_MASK		BIT(0)
+#define FUNC_STAT_RST_STAT_MASK		BIT(2)
+#define FUNC_STAT_ISO_STAT_MASK		BIT(4)
+#define FUNC_STAT_SSAR_STAT_MASK	BIT(8)
+
+struct imx93_power_domain {
+	struct generic_pm_domain genpd;
+	struct device *dev;
+	void __iomem *addr;
+	struct clk_bulk_data *clks;
+	int num_clks;
+};
+
+#define to_imx93_pd(_genpd) container_of(_genpd, struct imx93_power_domain, genpd)
+
+static int imx93_pd_on(struct generic_pm_domain *genpd)
+{
+	struct imx93_power_domain *domain = to_imx93_pd(genpd);
+	void __iomem *addr = domain->addr;
+	u32 val;
+	int ret;
+
+	ret = clk_bulk_prepare_enable(domain->num_clks, domain->clks);
+	if (ret) {
+		dev_err(domain->dev, "failed to enable clocks for domain: %s\n", genpd->name);
+		return ret;
+	}
+
+	val = readl(addr + MIX_SLICE_SW_CTRL_OFF);
+	val &= ~SLICE_SW_CTRL_PDN_SOFT_MASK;
+	writel(val, addr + MIX_SLICE_SW_CTRL_OFF);
+
+	ret = readl_poll_timeout(addr + MIX_FUNC_STAT_OFF, val,
+				 !(val & FUNC_STAT_SSAR_STAT_MASK), 10000);
+	if (ret) {
+		dev_err(domain->dev, "pd_on timeout: name: %s, stat: %x\n", genpd->name, val);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int imx93_pd_off(struct generic_pm_domain *genpd)
+{
+	struct imx93_power_domain *domain = to_imx93_pd(genpd);
+	void __iomem *addr = domain->addr;
+	int ret;
+	u32 val;
+
+	/* Power off MIX */
+	val = readl(addr + MIX_SLICE_SW_CTRL_OFF);
+	val |= SLICE_SW_CTRL_PDN_SOFT_MASK;
+	writel(val, addr + MIX_SLICE_SW_CTRL_OFF);
+
+	ret = readl_poll_timeout(addr + MIX_FUNC_STAT_OFF, val,
+				 val & FUNC_STAT_PSW_STAT_MASK, 10000);
+	if (ret) {
+		dev_err(domain->dev, "pd_off timeout: name: %s, stat: %x\n", genpd->name, val);
+		return ret;
+	}
+
+	clk_bulk_disable_unprepare(domain->num_clks, domain->clks);
+
+	return 0;
+};
+
+static int imx93_pd_probe(struct device *dev)
+{
+	struct device_node *np = dev->of_node;
+	struct imx93_power_domain *domain;
+	bool init_off;
+	int ret;
+
+	domain = devm_kzalloc(dev, sizeof(*domain), GFP_KERNEL);
+	if (!domain)
+		return -ENOMEM;
+
+	domain->addr = dev_platform_ioremap_resource(dev, 0);
+	if (IS_ERR(domain->addr))
+		return PTR_ERR(domain->addr);
+
+	domain->num_clks = clk_bulk_get_all(dev, &domain->clks);
+	if (domain->num_clks < 0)
+		return dev_err_probe(dev, domain->num_clks, "Failed to get domain's clocks\n");
+
+	domain->genpd.name = dev_name(dev);
+	domain->genpd.power_off = imx93_pd_off;
+	domain->genpd.power_on = imx93_pd_on;
+	domain->dev = dev;
+
+	init_off = readl(domain->addr + MIX_FUNC_STAT_OFF) & FUNC_STAT_ISO_STAT_MASK;
+	/* Just to sync the status of hardware */
+	if (!init_off) {
+		ret = clk_bulk_prepare_enable(domain->num_clks, domain->clks);
+		if (ret)
+			return dev_err_probe(domain->dev, ret,
+					     "failed to enable clocks for domain: %s\n",
+					     domain->genpd.name);
+	}
+
+	ret = pm_genpd_init(&domain->genpd, NULL, init_off);
+	if (ret)
+		goto err_clk_unprepare;
+
+	ret = of_genpd_add_provider_simple(np, &domain->genpd);
+	if (ret)
+		goto err_genpd_remove;
+
+	return 0;
+
+err_genpd_remove:
+	pm_genpd_remove(&domain->genpd);
+
+err_clk_unprepare:
+	if (!init_off)
+		clk_bulk_disable_unprepare(domain->num_clks, domain->clks);
+
+	return ret;
+}
+
+static const struct of_device_id imx93_pd_ids[] = {
+	{ .compatible = "fsl,imx93-src-slice" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, imx93_pd_ids);
+
+static struct driver imx93_power_domain_driver = {
+	.name	= "imx93_power_domain",
+	.of_match_table = imx93_pd_ids,
+	.probe = imx93_pd_probe,
+};
+coredevice_platform_driver(imx93_power_domain_driver);
+MODULE_LICENSE("GPL");
diff --git a/drivers/soc/imx/Makefile b/drivers/soc/imx/Makefile
index 65b2677f7ad5e3826655424efbc3ecd9e2ac5604..53ee0b8f5b3c7451083bdbbd47a76744ebc2b7c5 100644
--- a/drivers/soc/imx/Makefile
+++ b/drivers/soc/imx/Makefile
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-$(CONFIG_IMX8M_FEATCTRL) += imx8m-featctrl.o
 obj-$(CONFIG_ARCH_IMX8M) += soc-imx8m.o
+obj-$(CONFIG_ARCH_IMX93) += imx93-src.o
diff --git a/drivers/soc/imx/imx93-src.c b/drivers/soc/imx/imx93-src.c
new file mode 100644
index 0000000000000000000000000000000000000000..4889948141b0f669259306d52862158894557569
--- /dev/null
+++ b/drivers/soc/imx/imx93-src.c
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2022 NXP
+ */
+
+#include <init.h>
+#include <driver.h>
+#include <linux/module.h>
+
+static int imx93_src_probe(struct device *dev)
+{
+	return of_platform_populate(dev->of_node, NULL, dev);
+}
+
+static const struct of_device_id imx93_src_ids[] = {
+	{ .compatible = "fsl,imx93-src" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, imx93_src_ids);
+
+static struct driver imx93_src_driver = {
+	.name	= "imx93_src",
+	.probe = imx93_src_probe,
+	.of_compatible = imx93_src_ids,
+};
+core_platform_driver(imx93_src_driver);
+
+MODULE_AUTHOR("Peng Fan <peng.fan@nxp.com>");
+MODULE_DESCRIPTION("NXP i.MX93 src driver");
+MODULE_LICENSE("GPL");

-- 
2.47.3




  reply	other threads:[~2025-11-19 15:25 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-11-19 15:25 [PATCH 0/2] imx93-pmdomain: add imx93-src, imx93-pd and media-blk-ctrl drivers " Michael Grzeschik
2025-11-19 15:25 ` Michael Grzeschik [this message]
2025-11-19 15:25 ` [PATCH 2/2] pmdomain: imx: imx93-blk-ctrl: add ported driver " Michael Grzeschik
2025-11-20  8:00 ` [PATCH 0/2] imx93-pmdomain: add imx93-src, imx93-pd and media-blk-ctrl drivers " Sascha Hauer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20251119-imx93-pd-v1-1-2b114723a734@pengutronix.de \
    --to=m.grzeschik@pengutronix.de \
    --cc=barebox@lists.infradead.org \
    --cc=s.hauer@pengutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox