summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBiju Das <biju.das.jz@bp.renesas.com>2026-08-26 13:27:25 +0100
committerBartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>2026-09-02 12:46:21 +0200
commit3b04e9b8056e868c3e9a04cc74168c7c9a18746a (patch)
tree6e0c117177973f3360cbf37ffee649d68c73626f
parentcee9395acd8043be0644b25c34bfa86623f2b935 (diff)
downloadlinux-next-3b04e9b8056e868c3e9a04cc74168c7c9a18746a.tar.gz
linux-next-3b04e9b8056e868c3e9a04cc74168c7c9a18746a.zip
power: sequencing: Add Renesas RZ/G3L Power Ready driver
Add a power sequencing driver for the Renesas RZ/G3L PWRRDY module, which signals power readiness for various IPs (USB, DSI, CSI etc.) on the SoC. The driver binds as an auxiliary device to the parent SYSC driver, using its regmap to toggle the SYS_PWRRDY_N register bits, and exposes {usb,dsi,csi}-pwrrdy pwrseq targets. Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com> Link: https://patch.msgid.link/20260826122742.153643-4-biju.das.jz@bp.renesas.com Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
-rw-r--r--drivers/power/sequencing/Kconfig9
-rw-r--r--drivers/power/sequencing/Makefile1
-rw-r--r--drivers/power/sequencing/pwrseq-renesas-pwrrdy.c142
3 files changed, 152 insertions, 0 deletions
diff --git a/drivers/power/sequencing/Kconfig b/drivers/power/sequencing/Kconfig
index 1c5f5820f5b7..286d4e300845 100644
--- a/drivers/power/sequencing/Kconfig
+++ b/drivers/power/sequencing/Kconfig
@@ -27,6 +27,15 @@ config POWER_SEQUENCING_QCOM_WCN
this driver is needed for correct power control or else we'd risk not
respecting the required delays between enabling Bluetooth and WLAN.
+config POWER_SEQUENCING_RENESAS_PWRRDY
+ tristate "Renesas Power Ready sequencing driver"
+ depends on SYSC_RZ || COMPILE_TEST
+ select AUXILIARY_BUS
+ help
+ Say Y here to enable the power sequencing driver for the Renesas
+ Power Ready signals. This driver handles the power ready signals
+ required to power on the various IP's on RZ/G3L platform.
+
config POWER_SEQUENCING_TH1520_GPU
tristate "T-HEAD TH1520 GPU power sequencing driver"
depends on (ARCH_THEAD && AUXILIARY_BUS) || COMPILE_TEST
diff --git a/drivers/power/sequencing/Makefile b/drivers/power/sequencing/Makefile
index 0911d4618298..b33d08d82f43 100644
--- a/drivers/power/sequencing/Makefile
+++ b/drivers/power/sequencing/Makefile
@@ -4,5 +4,6 @@ obj-$(CONFIG_POWER_SEQUENCING) += pwrseq-core.o
pwrseq-core-y := core.o
obj-$(CONFIG_POWER_SEQUENCING_QCOM_WCN) += pwrseq-qcom-wcn.o
+obj-$(CONFIG_POWER_SEQUENCING_RENESAS_PWRRDY) += pwrseq-renesas-pwrrdy.o
obj-$(CONFIG_POWER_SEQUENCING_TH1520_GPU) += pwrseq-thead-gpu.o
obj-$(CONFIG_POWER_SEQUENCING_PCIE_M2) += pwrseq-pcie-m2.o
diff --git a/drivers/power/sequencing/pwrseq-renesas-pwrrdy.c b/drivers/power/sequencing/pwrseq-renesas-pwrrdy.c
new file mode 100644
index 000000000000..743855620501
--- /dev/null
+++ b/drivers/power/sequencing/pwrseq-renesas-pwrrdy.c
@@ -0,0 +1,142 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Renesas RZ/G3L Power Ready driver
+ *
+ */
+
+#include <linux/auxiliary_bus.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/pwrseq/provider.h>
+#include <linux/regmap.h>
+
+#define SYS_PWRRDY_N 0xd70
+#define SYS_PWRRDY_N_USB_MASK BIT(0)
+#define SYS_PWRRDY_N_DSI_MASK BIT(1)
+#define SYS_PWRRDY_N_CSI_MASK BIT(2)
+
+static int pwrseq_rzg3l_set_pwrrdy(struct pwrseq_device *pwrseq, u32 mask,
+ bool val)
+{
+ struct regmap *regmap = pwrseq_device_get_drvdata(pwrseq);
+
+ return regmap_assign_bits(regmap, SYS_PWRRDY_N, mask, val);
+}
+
+static int pwrseq_rzg3l_usb_pwrrdy_enable(struct pwrseq_device *pwrseq)
+{
+ return pwrseq_rzg3l_set_pwrrdy(pwrseq, SYS_PWRRDY_N_USB_MASK, 0);
+}
+
+static int pwrseq_rzg3l_usb_pwrrdy_disable(struct pwrseq_device *pwrseq)
+{
+ return pwrseq_rzg3l_set_pwrrdy(pwrseq, SYS_PWRRDY_N_USB_MASK, 1);
+}
+
+static const struct pwrseq_unit_data pwrseq_rzg3l_usb_pwrrdy_unit = {
+ .name = "usb-pwrrdy-power-sequence",
+ .enable = pwrseq_rzg3l_usb_pwrrdy_enable,
+ .disable = pwrseq_rzg3l_usb_pwrrdy_disable,
+};
+
+static int pwrseq_rzg3l_dsi_pwrrdy_enable(struct pwrseq_device *pwrseq)
+{
+ return pwrseq_rzg3l_set_pwrrdy(pwrseq, SYS_PWRRDY_N_DSI_MASK, 0);
+}
+
+static int pwrseq_rzg3l_dsi_pwrrdy_disable(struct pwrseq_device *pwrseq)
+{
+ return pwrseq_rzg3l_set_pwrrdy(pwrseq, SYS_PWRRDY_N_DSI_MASK, 1);
+}
+
+static const struct pwrseq_unit_data pwrseq_rzg3l_dsi_pwrrdy_unit = {
+ .name = "dsi-pwrrdy-sequence",
+ .enable = pwrseq_rzg3l_dsi_pwrrdy_enable,
+ .disable = pwrseq_rzg3l_dsi_pwrrdy_disable,
+};
+
+static int pwrseq_rzg3l_csi_pwrrdy_enable(struct pwrseq_device *pwrseq)
+{
+ return pwrseq_rzg3l_set_pwrrdy(pwrseq, SYS_PWRRDY_N_CSI_MASK, 0);
+}
+
+static int pwrseq_rzg3l_csi_pwrrdy_disable(struct pwrseq_device *pwrseq)
+{
+ return pwrseq_rzg3l_set_pwrrdy(pwrseq, SYS_PWRRDY_N_CSI_MASK, 1);
+}
+
+static const struct pwrseq_unit_data pwrseq_rzg3l_csi_pwrrdy_unit = {
+ .name = "csi-pwrrdy-power-sequence",
+ .enable = pwrseq_rzg3l_csi_pwrrdy_enable,
+ .disable = pwrseq_rzg3l_csi_pwrrdy_disable,
+};
+
+static const struct pwrseq_target_data pwrseq_rzg3l_usb_pwrrdy_target = {
+ .name = "usb-pwrrdy",
+ .unit = &pwrseq_rzg3l_usb_pwrrdy_unit,
+};
+
+static const struct pwrseq_target_data pwrseq_rzg3l_dsi_pwrrdy_target = {
+ .name = "dsi-pwrrdy",
+ .unit = &pwrseq_rzg3l_dsi_pwrrdy_unit,
+};
+
+static const struct pwrseq_target_data pwrseq_rzg3l_csi_pwrrdy_target = {
+ .name = "csi-pwrrdy",
+ .unit = &pwrseq_rzg3l_csi_pwrrdy_unit,
+};
+
+static const struct pwrseq_target_data *pwrseq_rzg3l_pwrrdy_targets[] = {
+ &pwrseq_rzg3l_usb_pwrrdy_target,
+ &pwrseq_rzg3l_dsi_pwrrdy_target,
+ &pwrseq_rzg3l_csi_pwrrdy_target,
+ NULL
+};
+
+static const char * const pwrseq_rzg3l_pwrrdy_compats[] = {
+ "renesas,r9a08g046-usbphy-ctrl",
+ "renesas,r9a08g046-mipi-dsi",
+ NULL
+};
+
+static int pwrseq_rzg3l_pwrrdy_match(struct pwrseq_device *pwrseq,
+ struct device *dev)
+{
+ if (of_device_compatible_match(dev->of_node, pwrseq_rzg3l_pwrrdy_compats))
+ return PWRSEQ_MATCH_OK;
+
+ return PWRSEQ_NO_MATCH;
+}
+
+static int pwrseq_rzg3l_pwrrdy_probe(struct auxiliary_device *adev,
+ const struct auxiliary_device_id *id)
+{
+ struct pwrseq_config config = {
+ .parent = &adev->dev,
+ .owner = THIS_MODULE,
+ .drvdata = adev->dev.platform_data,
+ .match = pwrseq_rzg3l_pwrrdy_match,
+ .targets = pwrseq_rzg3l_pwrrdy_targets,
+ };
+
+ return PTR_ERR_OR_ZERO(devm_pwrseq_device_register(&adev->dev, &config));
+}
+
+static const struct auxiliary_device_id pwrseq_rzg3l_pwrrdy_id_table[] = {
+ { .name = "rz_sysc.pwrseq-pwrrdy" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(auxiliary, pwrseq_rzg3l_pwrrdy_id_table);
+
+static struct auxiliary_driver pwrseq_rzg3l_pwrrdy_driver = {
+ .driver = {
+ .name = "pwrseq-rzg3l-pwrrdy",
+ },
+ .probe = pwrseq_rzg3l_pwrrdy_probe,
+ .id_table = pwrseq_rzg3l_pwrrdy_id_table,
+};
+module_auxiliary_driver(pwrseq_rzg3l_pwrrdy_driver);
+
+MODULE_AUTHOR("Biju Das <biju.das.jz@bp.renesas.com>");
+MODULE_DESCRIPTION("Renesas RZ/G3L Power Ready Driver");
+MODULE_LICENSE("GPL");