Merge branch 'master-riic' of https://source.denx.de/u-boot/custodians/u-boot-sh

- New renesas I2C controller driver and new PMIC driver along with
  enablement of them.
diff --git a/arch/arm/dts/r9a07g044.dtsi b/arch/arm/dts/r9a07g044.dtsi
index 232910e..66f68fc 100644
--- a/arch/arm/dts/r9a07g044.dtsi
+++ b/arch/arm/dts/r9a07g044.dtsi
@@ -223,20 +223,20 @@
 				     <GIC_SPI 212 IRQ_TYPE_EDGE_RISING>,
 				     <GIC_SPI 213 IRQ_TYPE_EDGE_RISING>;
 			interrupt-names = "tgia0", "tgib0", "tgic0", "tgid0",
-					  "tgiv0", "tgie0", "tgif0",
-					  "tgia1", "tgib1", "tgiv1", "tgiu1",
-					  "tgia2", "tgib2", "tgiv2", "tgiu2",
+					  "tciv0", "tgie0", "tgif0",
+					  "tgia1", "tgib1", "tciv1", "tciu1",
+					  "tgia2", "tgib2", "tciv2", "tciu2",
 					  "tgia3", "tgib3", "tgic3", "tgid3",
-					  "tgiv3",
+					  "tciv3",
 					  "tgia4", "tgib4", "tgic4", "tgid4",
-					  "tgiv4",
+					  "tciv4",
 					  "tgiu5", "tgiv5", "tgiw5",
 					  "tgia6", "tgib6", "tgic6", "tgid6",
-					  "tgiv6",
+					  "tciv6",
 					  "tgia7", "tgib7", "tgic7", "tgid7",
-					  "tgiv7",
+					  "tciv7",
 					  "tgia8", "tgib8", "tgic8", "tgid8",
-					  "tgiv8", "tgiu8";
+					  "tciv8", "tciu8";
 			clocks = <&cpg CPG_MOD R9A07G044_MTU_X_MCK_MTU3>;
 			power-domains = <&cpg>;
 			resets = <&cpg R9A07G044_MTU_X_PRESET_MTU3>;
diff --git a/arch/arm/dts/r9a07g044l2-smarc.dts b/arch/arm/dts/r9a07g044l2-smarc.dts
index bc2af6c..568d49c 100644
--- a/arch/arm/dts/r9a07g044l2-smarc.dts
+++ b/arch/arm/dts/r9a07g044l2-smarc.dts
@@ -6,6 +6,27 @@
  */
 
 /dts-v1/;
+
+/* Enable SCIF2 (SER0) on PMOD1 (CN7) */
+#define PMOD1_SER0	1
+
+/*
+ * To enable MTU3a PWM on PMOD0,
+ * Disable PMOD1_SER0 by setting "#define PMOD1_SER0	0" above and
+ * enable PMOD_MTU3 by setting "#define PMOD_MTU3	1" below.
+ */
+#define PMOD_MTU3	0
+
+#if (PMOD_MTU3 && PMOD1_SER0)
+#error "Cannot set as PMOD_MTU3 and PMOD1_SER0 are mutually exclusive "
+#endif
+
+#define MTU3_COUNTER_Z_PHASE_SIGNAL	0
+
+#if (!PMOD_MTU3 && MTU3_COUNTER_Z_PHASE_SIGNAL)
+#error "Cannot set 1 to MTU3_COUNTER_Z_PHASE_SIGNAL as PMOD_MTU3=0"
+#endif
+
 #include "r9a07g044l2.dtsi"
 #include "rzg2l-smarc-som.dtsi"
 #include "rzg2l-smarc-pinfunction.dtsi"
diff --git a/arch/arm/dts/rz-smarc-common.dtsi b/arch/arm/dts/rz-smarc-common.dtsi
index 3962d47..b7a3e6c 100644
--- a/arch/arm/dts/rz-smarc-common.dtsi
+++ b/arch/arm/dts/rz-smarc-common.dtsi
@@ -32,12 +32,6 @@
 		stdout-path = "serial0:115200n8";
 	};
 
-	audio_mclock: audio_mclock {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <11289600>;
-	};
-
 	snd_rzg2l: sound {
 		compatible = "simple-audio-card";
 		simple-audio-card,format = "i2s";
@@ -55,7 +49,7 @@
 		};
 
 		codec_dai: simple-audio-card,codec {
-			clocks = <&audio_mclock>;
+			clocks = <&versa3 2>;
 			sound-dai = <&wm8978>;
 		};
 	};
@@ -76,13 +70,19 @@
 		gpios-states = <1>;
 		states = <3300000 1>, <1800000 0>;
 	};
+
+	x1: x1-clock {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+	};
 };
 
-&audio_clk1{
+&audio_clk1 {
 	clock-frequency = <11289600>;
 };
 
-&audio_clk2{
+&audio_clk2 {
 	clock-frequency = <12288000>;
 };
 
diff --git a/arch/arm/dts/rzg2l-smarc-pinfunction.dtsi b/arch/arm/dts/rzg2l-smarc-pinfunction.dtsi
index 9085d8c..18c526c 100644
--- a/arch/arm/dts/rzg2l-smarc-pinfunction.dtsi
+++ b/arch/arm/dts/rzg2l-smarc-pinfunction.dtsi
@@ -53,6 +53,26 @@
 			 <RZG2L_PORT_PINMUX(18, 1, 3)>; /* SCL */
 	};
 
+	mtu3_pins: mtu3 {
+		mtu3-ext-clk-input-pin {
+			pinmux = <RZG2L_PORT_PINMUX(48, 0, 4)>, /* MTCLKA */
+				 <RZG2L_PORT_PINMUX(48, 1, 4)>; /* MTCLKB */
+		};
+
+		mtu3-pwm {
+			pinmux = <RZG2L_PORT_PINMUX(44, 0, 4)>, /* MTIOC3A */
+				 <RZG2L_PORT_PINMUX(44, 1, 4)>, /* MTIOC3B */
+				 <RZG2L_PORT_PINMUX(44, 2, 4)>, /* MTIOC3C */
+				 <RZG2L_PORT_PINMUX(44, 3, 4)>; /* MTIOC3D */
+		};
+
+#if MTU3_COUNTER_Z_PHASE_SIGNAL
+		mtu3-zphase-clk {
+			pinmux = <RZG2L_PORT_PINMUX(19, 0, 3)>; /* MTIOC1A */
+		};
+#endif /* MTU3_COUNTER_Z_PHASE_SIGNAL */
+	};
+
 	scif0_pins: scif0 {
 		pinmux = <RZG2L_PORT_PINMUX(38, 0, 1)>,	/* TxD */
 			 <RZG2L_PORT_PINMUX(38, 1, 1)>;	/* RxD */
diff --git a/arch/arm/dts/rzg2l-smarc-som.dtsi b/arch/arm/dts/rzg2l-smarc-som.dtsi
index fbbb4f0..547859c 100644
--- a/arch/arm/dts/rzg2l-smarc-som.dtsi
+++ b/arch/arm/dts/rzg2l-smarc-som.dtsi
@@ -73,6 +73,13 @@
 		gpios = <&pinctrl RZG2L_GPIO(39, 0) GPIO_ACTIVE_HIGH>;
 		regulator-always-on;
 	};
+
+	/* 32.768kHz crystal */
+	x2: x2-clock {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <32768>;
+	};
 };
 
 &adc {
@@ -100,7 +107,7 @@
 		rxc-skew-psec = <2400>;
 		txc-skew-psec = <2400>;
 		rxdv-skew-psec = <0>;
-		txdv-skew-psec = <0>;
+		txen-skew-psec = <0>;
 		rxd0-skew-psec = <0>;
 		rxd1-skew-psec = <0>;
 		rxd2-skew-psec = <0>;
@@ -128,7 +135,7 @@
 		rxc-skew-psec = <2400>;
 		txc-skew-psec = <2400>;
 		rxdv-skew-psec = <0>;
-		txdv-skew-psec = <0>;
+		txen-skew-psec = <0>;
 		rxd0-skew-psec = <0>;
 		rxd1-skew-psec = <0>;
 		rxd2-skew-psec = <0>;
@@ -148,6 +155,17 @@
 	mali-supply = <&reg_1p1v>;
 };
 
+&i2c3 {
+	raa215300: pmic@12 {
+		compatible = "renesas,raa215300";
+		reg = <0x12>, <0x6f>;
+		reg-names = "main", "rtc";
+
+		clocks = <&x2>;
+		clock-names = "xin";
+	};
+};
+
 &ostm1 {
 	status = "okay";
 };
diff --git a/arch/arm/dts/rzg2l-smarc.dtsi b/arch/arm/dts/rzg2l-smarc.dtsi
index 2a158a9..37807f1 100644
--- a/arch/arm/dts/rzg2l-smarc.dtsi
+++ b/arch/arm/dts/rzg2l-smarc.dtsi
@@ -8,9 +8,6 @@
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/pinctrl/rzg2l-pinctrl.h>
 
-/* comment the #define statement to disable SCIF2 (SER0) on PMOD1 (CN7) */
-#define PMOD1_SER0	1
-
 / {
 	aliases {
 		serial1 = &scif2;
@@ -113,7 +110,47 @@
 		#sound-dai-cells = <0>;
 		reg = <0x1a>;
 	};
+
+	versa3: clock-generator@68 {
+		compatible = "renesas,5p35023";
+		reg = <0x68>;
+		#clock-cells = <1>;
+		clocks = <&x1>;
+
+		renesas,settings = [
+			80 00 11 19 4c 02 23 7f 83 19 08 a9 5f 25 24 bf
+			00 14 7a e1 00 00 00 00 01 55 59 bb 3f 30 90 b6
+			80 b0 45 c4 95
+		];
+
+		assigned-clocks = <&versa3 0>, <&versa3 1>,
+				  <&versa3 2>, <&versa3 3>,
+				  <&versa3 4>, <&versa3 5>;
+		assigned-clock-rates = <24000000>, <11289600>,
+				       <11289600>, <12000000>,
+				       <25000000>, <12288000>;
+	};
+};
+
+#if PMOD_MTU3
+&mtu3 {
+	pinctrl-0 = <&mtu3_pins>;
+	pinctrl-names = "default";
+
+	status = "okay";
+};
+
+#if MTU3_COUNTER_Z_PHASE_SIGNAL
+/* SDHI cd pin is muxed with counter Z phase signal */
+&sdhi1 {
+	status = "disabled";
+};
+#endif /* MTU3_COUNTER_Z_PHASE_SIGNAL */
+
+&spi1 {
+	status = "disabled";
 };
+#endif /* PMOD_MTU3 */
 
 /*
  * To enable SCIF2 (SER0) on PMOD1 (CN7)
diff --git a/arch/arm/mach-rmobile/Kconfig b/arch/arm/mach-rmobile/Kconfig
index 2bb9674..38ede6e 100644
--- a/arch/arm/mach-rmobile/Kconfig
+++ b/arch/arm/mach-rmobile/Kconfig
@@ -78,6 +78,7 @@
 	imply RENESAS_SDHI
 	imply RZG2L_GPIO
 	imply SCIF_CONSOLE
+	imply SYS_I2C_RZ_RIIC
 	imply SYS_MALLOC_F
 	help
 	  Enable support for the Renesas RZ/G2L family of SoCs. Currently
diff --git a/board/renesas/rzg2l/rzg2l.c b/board/renesas/rzg2l/rzg2l.c
index 73201a8..0f6d6e7 100644
--- a/board/renesas/rzg2l/rzg2l.c
+++ b/board/renesas/rzg2l/rzg2l.c
@@ -56,11 +56,3 @@
 {
 	return 0;
 }
-
-void reset_cpu(void)
-{
-	/*
-	 * TODO: Implement reset support once TrustedFirmware supports
-	 * the appropriate call.
-	 */
-}
diff --git a/configs/renesas_rzg2l_smarc_defconfig b/configs/renesas_rzg2l_smarc_defconfig
index e928697..7f22795 100644
--- a/configs/renesas_rzg2l_smarc_defconfig
+++ b/configs/renesas_rzg2l_smarc_defconfig
@@ -23,8 +23,10 @@
 CONFIG_HUSH_PARSER=y
 CONFIG_CMD_CLK=y
 CONFIG_CMD_GPIO=y
+CONFIG_CMD_I2C=y
 CONFIG_CMD_MMC=y
 CONFIG_CMD_PART=y
+CONFIG_CMD_PMIC=y
 CONFIG_CMD_EXT2=y
 CONFIG_CMD_EXT4=y
 CONFIG_CMD_EXT4_WRITE=y
@@ -43,9 +45,14 @@
 CONFIG_CLK_RENESAS=y
 # CONFIG_CLK_RCAR_GEN3 is not set
 CONFIG_GPIO_HOG=y
+CONFIG_DM_I2C=y
 CONFIG_MMC_IO_VOLTAGE=y
 CONFIG_MMC_UHS_SUPPORT=y
 CONFIG_MMC_HS400_SUPPORT=y
+CONFIG_DM_PMIC=y
+CONFIG_PMIC_RAA215300=y
 CONFIG_DM_REGULATOR=y
 CONFIG_DM_REGULATOR_FIXED=y
 CONFIG_DM_REGULATOR_GPIO=y
+CONFIG_SYSRESET=y
+CONFIG_SYSRESET_RAA215300=y
diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c
index e54508c..dba0099 100644
--- a/drivers/clk/renesas/rzg2l-cpg.c
+++ b/drivers/clk/renesas/rzg2l-cpg.c
@@ -23,10 +23,18 @@
 #include <linux/iopoll.h>
 #include <reset-uclass.h>
 #include <reset.h>
+#include <wait_bit.h>
 
 #include "rzg2l-cpg.h"
 
+/*
+ * Monitor registers for both clock and reset signals are offset by 0x180 from
+ * the corresponding control registers.
+ */
 #define CLK_MON_R(reg)		(0x180 + (reg))
+#define RST_MON_R(reg)		(0x180 + (reg))
+
+#define CPG_TIMEOUT_MSEC	100
 
 static ulong rzg2l_cpg_clk_get_rate_by_id(struct udevice *dev, unsigned int id);
 static ulong rzg2l_cpg_clk_get_rate_by_name(struct udevice *dev, const char *name);
@@ -83,9 +91,9 @@
 		value |= BIT(mod_clk->bit);
 	writel(value, data->base + mod_clk->off);
 
-	if (enable && readl_poll_timeout(data->base + CLK_MON_R(mod_clk->off),
-					 value, (value & BIT(mod_clk->bit)),
-					 10)) {
+	if (enable && wait_for_bit_32(data->base + CLK_MON_R(mod_clk->off),
+				      BIT(mod_clk->bit), enable,
+				      CPG_TIMEOUT_MSEC, false)) {
 		dev_err(clk->dev, "Timeout\n");
 		return -ETIMEDOUT;
 	}
@@ -420,7 +428,8 @@
 		value |= BIT(rst->bit);
 	writel(value, data->base + rst->off);
 
-	return 0;
+	return wait_for_bit_32(data->base + RST_MON_R(rst->off), BIT(rst->bit),
+			       asserted, CPG_TIMEOUT_MSEC, false);
 }
 
 static int rzg2l_cpg_rst_assert(struct reset_ctl *reset_ctl)
diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
index 4f42200..d2a3a13 100644
--- a/drivers/i2c/Kconfig
+++ b/drivers/i2c/Kconfig
@@ -524,6 +524,13 @@
 	  have several I2C ports and all are provided, controlled by the
 	  device tree.
 
+config SYS_I2C_RZ_RIIC
+	bool "Renesas RZ/G2L RIIC driver"
+	depends on RZG2L && DM_I2C
+	help
+	  Support for the I2C controller (RIIC) on the Renesas RZ/G2L SoC
+	  family.
+
 config SYS_I2C_SANDBOX
 	bool "Sandbox I2C driver"
 	depends on SANDBOX && DM_I2C
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
index a96a8c7..692f63b 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -40,6 +40,7 @@
 obj-$(CONFIG_SYS_I2C_RCAR_I2C) += rcar_i2c.o
 obj-$(CONFIG_SYS_I2C_RCAR_IIC) += rcar_iic.o
 obj-$(CONFIG_SYS_I2C_ROCKCHIP) += rk_i2c.o
+obj-$(CONFIG_SYS_I2C_RZ_RIIC) += rz_riic.o
 obj-$(CONFIG_SYS_I2C_S3C24X0) += s3c24x0_i2c.o exynos_hs_i2c.o
 obj-$(CONFIG_SYS_I2C_SANDBOX) += sandbox_i2c.o i2c-emul-uclass.o
 obj-$(CONFIG_SYS_I2C_SH) += sh_i2c.o
diff --git a/drivers/i2c/rz_riic.c b/drivers/i2c/rz_riic.c
new file mode 100644
index 0000000..5f3f8d1
--- /dev/null
+++ b/drivers/i2c/rz_riic.c
@@ -0,0 +1,624 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * RZ/G2L I2C (RIIC) driver
+ *
+ * Copyright (C) 2021-2023 Renesas Electronics Corp.
+ */
+
+#include <asm/io.h>
+#include <clk.h>
+#include <dm.h>
+#include <dm/device_compat.h>
+#include <errno.h>
+#include <i2c.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <reset.h>
+#include <wait_bit.h>
+
+#define RIIC_ICCR1	0x00
+#define RIIC_ICCR2	0x04
+#define RIIC_ICMR1	0x08
+#define RIIC_ICMR2	0x0c
+#define RIIC_ICMR3	0x10
+#define RIIC_ICFER	0x14
+#define RIIC_ICSER	0x18
+#define RIIC_ICIER	0x1c
+#define RIIC_ICSR1	0x20
+#define RIIC_ICSR2	0x24
+#define RIIC_ICSAR0	0x28
+#define RIIC_ICBRL	0x34
+#define RIIC_ICBRH	0x38
+#define RIIC_ICDRT	0x3c
+#define RIIC_ICDRR	0x40
+
+/* ICCR1 */
+#define ICCR1_ICE	BIT(7)
+#define ICCR1_IICRST	BIT(6)
+#define ICCR1_CLO	BIT(5)
+#define ICCR1_SOWP	BIT(4)
+#define ICCR1_SCLO	BIT(3)
+#define ICCR1_SDAO	BIT(2)
+#define ICCR1_SCLI	BIT(1)
+#define ICCR1_SDAI	BIT(0)
+
+/* ICCR2 */
+#define ICCR2_BBSY	BIT(7)
+#define ICCR2_MST	BIT(6)
+#define ICCR2_TRS	BIT(5)
+#define ICCR2_SP	BIT(3)
+#define ICCR2_RS	BIT(2)
+#define ICCR2_ST	BIT(1)
+
+/* ICMR1 */
+#define ICMR1_MTWP	BIT(7)
+#define ICMR1_CKS_MASK	GENMASK(6, 4)
+#define ICMR1_BCWP	BIT(3)
+#define ICMR1_BC_MASK	GENMASK(2, 0)
+
+#define ICMR1_CKS(x)	(((x) << 4) & ICMR1_CKS_MASK)
+#define ICMR1_BC(x)	((x) & ICMR1_BC_MASK)
+
+/* ICMR2 */
+#define ICMR2_DLCS	BIT(7)
+#define ICMR2_SDDL_MASK	GENMASK(6, 4)
+#define ICMR2_TMOH	BIT(2)
+#define ICMR2_TMOL	BIT(1)
+#define ICMR2_TMOS	BIT(0)
+
+/* ICMR3 */
+#define ICMR3_SMBS	BIT(7)
+#define ICMR3_WAIT	BIT(6)
+#define ICMR3_RDRFS	BIT(5)
+#define ICMR3_ACKWP	BIT(4)
+#define ICMR3_ACKBT	BIT(3)
+#define ICMR3_ACKBR	BIT(2)
+#define ICMR3_NF_MASK	GENMASK(1, 0)
+
+/* ICFER */
+#define ICFER_FMPE	BIT(7)
+#define ICFER_SCLE	BIT(6)
+#define ICFER_NFE	BIT(5)
+#define ICFER_NACKE	BIT(4)
+#define ICFER_SALE	BIT(3)
+#define ICFER_NALE	BIT(2)
+#define ICFER_MALE	BIT(1)
+#define ICFER_TMOE	BIT(0)
+
+/* ICSER */
+#define ICSER_HOAE	BIT(7)
+#define ICSER_DIDE	BIT(5)
+#define ICSER_GCAE	BIT(3)
+#define ICSER_SAR2E	BIT(2)
+#define ICSER_SAR1E	BIT(1)
+#define ICSER_SAR0E	BIT(0)
+
+/* ICIER */
+#define ICIER_TIE	BIT(7)
+#define ICIER_TEIE	BIT(6)
+#define ICIER_RIE	BIT(5)
+#define ICIER_NAKIE	BIT(4)
+#define ICIER_SPIE	BIT(3)
+#define ICIER_STIE	BIT(2)
+#define ICIER_ALIE	BIT(1)
+#define ICIER_TMOIE	BIT(0)
+
+/* ICSR1 */
+#define ICSR1_HOA	BIT(7)
+#define ICSR1_DID	BIT(5)
+#define ICSR1_GCA	BIT(3)
+#define ICSR1_AAS2	BIT(2)
+#define ICSR1_AAS1	BIT(1)
+#define ICSR1_AAS0	BIT(0)
+
+/* ICSR2 */
+#define ICSR2_TDRE	BIT(7)
+#define ICSR2_TEND	BIT(6)
+#define ICSR2_RDRF	BIT(5)
+#define ICSR2_NACKF	BIT(4)
+#define ICSR2_STOP	BIT(3)
+#define ICSR2_START	BIT(2)
+#define ICSR2_AL	BIT(1)
+#define ICSR2_TMOF	BIT(0)
+
+/* ICBRH */
+#define ICBRH_RESERVED	GENMASK(7, 5)	/* The write value should always be 1 */
+#define ICBRH_BRH_MASK	GENMASK(4, 0)
+
+/* ICBRL */
+#define ICBRL_RESERVED	GENMASK(7, 5)	/* The write value should always be 1 */
+#define ICBRL_BRL_MASK	GENMASK(4, 0)
+
+#define RIIC_TIMEOUT_MSEC	100
+
+#define RIIC_FLAG_DEFAULT_SCL_RISE_TIME		BIT(0)
+#define RIIC_FLAG_DEFAULT_SCL_FALL_TIME		BIT(1)
+
+/*
+ * If SDA is stuck in a low state, the I2C spec says up to 9 clock cycles on SCL
+ * may be needed to unblock whichever other device on the bus is holding SDA low.
+ */
+#define I2C_DEBLOCK_MAX_CYCLES 9
+
+struct riic_priv {
+	void __iomem *base;
+	struct clk clk;
+	uint bus_speed;
+	u32 scl_rise_ns;
+	u32 scl_fall_ns;
+	u32 flags;
+};
+
+static int riic_check_busy(struct udevice *dev)
+{
+	struct riic_priv *priv = dev_get_priv(dev);
+	int ret;
+
+	ret = wait_for_bit_8(priv->base + RIIC_ICCR2, ICCR2_BBSY, 0,
+			     RIIC_TIMEOUT_MSEC, 0);
+	if (ret == -ETIMEDOUT) {
+		dev_dbg(dev, "bus is busy!\n");
+		return -EBUSY;
+	}
+
+	return ret;
+}
+
+static int riic_wait_for_icsr2(struct udevice *dev, u8 bit)
+{
+	struct riic_priv *priv = dev_get_priv(dev);
+	ulong start = get_timer(0);
+	u8 icsr2;
+
+	/* We can't use wait_for_bit_8() here as we need to check for NACK. */
+	while (!((icsr2 = readb(priv->base + RIIC_ICSR2)) & bit)) {
+		if (icsr2 & ICSR2_NACKF)
+			return -EIO;
+		if (get_timer(start) > RIIC_TIMEOUT_MSEC) {
+			dev_dbg(dev, "timeout! (bit=%x, icsr2=%x, iccr2=%x)\n",
+				bit, icsr2, readb(priv->base + RIIC_ICCR2));
+			return -ETIMEDOUT;
+		}
+		udelay(1);
+		schedule();
+	}
+
+	return 0;
+}
+
+static int riic_check_nack_receive(struct udevice *dev)
+{
+	struct riic_priv *priv = dev_get_priv(dev);
+
+	if (readb(priv->base + RIIC_ICSR2) & ICSR2_NACKF) {
+		dev_dbg(dev, "received nack!\n");
+		/* received NACK */
+		clrbits_8(priv->base + RIIC_ICSR2, ICSR2_NACKF);
+		setbits_8(priv->base + RIIC_ICCR2, ICCR2_SP);
+		readb(priv->base + RIIC_ICDRR);	/* dummy read */
+		return -EIO;
+	}
+	return 0;
+}
+
+static int riic_i2c_raw_write(struct udevice *dev, u8 *buf, size_t len)
+{
+	struct riic_priv *priv = dev_get_priv(dev);
+	size_t i;
+	int ret;
+
+	for (i = 0; i < len; i++) {
+		ret = riic_check_nack_receive(dev);
+		if (ret < 0)
+			return ret;
+
+		ret = riic_wait_for_icsr2(dev, ICSR2_TDRE);
+		if (ret < 0)
+			return ret;
+
+		writeb(buf[i], priv->base + RIIC_ICDRT);
+	}
+
+	return riic_check_nack_receive(dev);
+}
+
+static int riic_send_start_cond(struct udevice *dev, int restart)
+{
+	struct riic_priv *priv = dev_get_priv(dev);
+	int ret;
+
+	if (restart)
+		setbits_8(priv->base + RIIC_ICCR2, ICCR2_RS);
+	else
+		setbits_8(priv->base + RIIC_ICCR2, ICCR2_ST);
+
+	ret = riic_wait_for_icsr2(dev, ICSR2_START);
+	if (ret < 0)
+		return ret;
+	clrbits_8(priv->base + RIIC_ICSR2, ICSR2_START);
+
+	return ret;
+}
+
+static int riic_receive_data(struct udevice *dev, struct i2c_msg *msg)
+{
+	struct riic_priv *priv = dev_get_priv(dev);
+	int ret, stop_ret, i;
+
+	ret = riic_wait_for_icsr2(dev, ICSR2_RDRF);
+	if (ret < 0)
+		goto send_stop;
+
+	ret = riic_check_nack_receive(dev);
+	if (ret < 0)
+		goto send_stop;
+
+	setbits_8(priv->base + RIIC_ICMR3, ICMR3_WAIT | ICMR3_ACKWP | ICMR3_RDRFS);
+
+	/* A dummy read must be performed to trigger data reception */
+	readb(priv->base + RIIC_ICDRR);
+
+	for (i = 0; i < msg->len; i++) {
+		ret = riic_wait_for_icsr2(dev, ICSR2_RDRF);
+		if (ret < 0)
+			goto send_stop;
+
+		if (i == (msg->len - 1)) {
+			clrbits_8(priv->base + RIIC_ICSR2, ICSR2_STOP);
+			setbits_8(priv->base + RIIC_ICCR2, ICCR2_SP);
+			setbits_8(priv->base + RIIC_ICMR3, ICMR3_ACKBT);
+		} else {
+			clrbits_8(priv->base + RIIC_ICMR3, ICMR3_ACKBT);
+		}
+
+		msg->buf[i] = readb(priv->base + RIIC_ICDRR);
+	};
+
+send_stop:
+	if (ret) {
+		/*
+		 * We got here due to an error condition, so we need to perform
+		 * a dummy read to issue the stop bit.
+		 */
+		clrbits_8(priv->base + RIIC_ICSR2, ICSR2_STOP);
+		setbits_8(priv->base + RIIC_ICCR2, ICCR2_SP);
+		readb(priv->base + RIIC_ICDRR);
+	}
+	stop_ret = riic_wait_for_icsr2(dev, ICSR2_STOP);
+	clrbits_8(priv->base + RIIC_ICSR2, ICSR2_STOP | ICSR2_NACKF);
+	clrbits_8(priv->base + RIIC_ICMR3, ICMR3_WAIT | ICMR3_ACKWP | ICMR3_RDRFS);
+	return ret ? ret : stop_ret;
+}
+
+static int riic_transmit_stop(struct udevice *dev)
+{
+	struct riic_priv *priv = dev_get_priv(dev);
+	int ret;
+
+	clrbits_8(priv->base + RIIC_ICSR2, ICSR2_STOP);
+	setbits_8(priv->base + RIIC_ICCR2, ICCR2_SP);
+
+	ret = riic_wait_for_icsr2(dev, ICSR2_STOP);
+	clrbits_8(priv->base + RIIC_ICSR2, ICSR2_STOP | ICSR2_NACKF);
+	return ret;
+}
+
+static int riic_transmit_data(struct udevice *dev, struct i2c_msg *msg)
+{
+	int ret, stop_ret;
+
+	ret = riic_i2c_raw_write(dev, msg->buf, msg->len);
+	if (ret < 0)
+		goto send_stop;
+
+	ret = riic_wait_for_icsr2(dev, ICSR2_TEND);
+	if (ret < 0)
+		goto send_stop;
+
+	if (!ret && !(msg->flags & I2C_M_STOP))
+		return 0;
+
+send_stop:
+	stop_ret = riic_transmit_stop(dev);
+	return ret ? ret : stop_ret;
+}
+
+static int riic_xfer_one(struct udevice *dev, struct i2c_msg *msg, int first_msg)
+{
+	u8 addr_byte = ((msg->addr << 1) | (msg->flags & I2C_M_RD));
+	int ret;
+
+	if (!(msg->flags & I2C_M_NOSTART)) {
+		/*
+		 * Send a start for the first message and a restart for
+		 * subsequent messages.
+		 */
+		ret = riic_send_start_cond(dev, !first_msg);
+		if (ret < 0)
+			return ret;
+	}
+
+	ret = riic_i2c_raw_write(dev, &addr_byte, 1);
+	if (ret < 0) {
+		/*
+		 * We're aborting the transfer while still in master transmit
+		 * mode.
+		 */
+		riic_transmit_stop(dev);
+		return ret;
+	}
+
+	if (msg->flags & I2C_M_RD)
+		return riic_receive_data(dev, msg);
+
+	return riic_transmit_data(dev, msg);
+}
+
+static int riic_xfer(struct udevice *dev, struct i2c_msg *msg, int nmsgs)
+{
+	int ret, i;
+
+	ret = riic_check_busy(dev);
+	if (ret < 0)
+		return ret;
+
+	/* Ensure that the last message is terminated with a stop bit. */
+	msg[nmsgs - 1].flags |= I2C_M_STOP;
+
+	for (i = 0; i < nmsgs; i++) {
+		ret = riic_xfer_one(dev, &msg[i], !i);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int riic_deblock(struct udevice *dev)
+{
+	struct riic_priv *priv = dev_get_priv(dev);
+	int i = 0;
+
+	/*
+	 * Issue clock cycles on SCL to hopefully unblock whatever is holding
+	 * SDA low. These clock cycles may trigger error conditions such as
+	 * Arbitration Lost, so we clear the status bits in ICSR2 after each
+	 * cycle.
+	 */
+	while (!(readb(priv->base + RIIC_ICCR1) & ICCR1_SDAI)) {
+		if (i++ == I2C_DEBLOCK_MAX_CYCLES)
+			return -EIO;
+
+		setbits_8(priv->base + RIIC_ICCR1, ICCR1_CLO);
+		if (wait_for_bit_8(priv->base + RIIC_ICCR1, ICCR1_CLO, 0,
+				   RIIC_TIMEOUT_MSEC, false))
+			return -ETIMEDOUT;
+		writeb(0, priv->base + RIIC_ICSR2);
+	}
+
+	/*
+	 * We have released SDA, but the I2C module is now out of sync
+	 * with the bus state, so we need to reset its state machine.
+	 */
+	setbits_8(priv->base + RIIC_ICCR1, ICCR1_IICRST);
+	clrbits_8(priv->base + RIIC_ICCR1, ICCR1_IICRST);
+
+	return 0;
+}
+
+static int riic_set_bus_speed(struct udevice *dev, uint bus_speed)
+{
+	struct riic_priv *priv = dev_get_priv(dev);
+	ulong refclk;
+	uint total_ticks, cks, brl, brh;
+
+	if (bus_speed > I2C_SPEED_FAST_PLUS_RATE) {
+		dev_err(dev, "unsupported bus speed (%dHz). %d max\n", bus_speed,
+			I2C_SPEED_FAST_PLUS_RATE);
+		return -EINVAL;
+	}
+
+	/*
+	 * Assume the default register settings:
+	 *  FER.SCLE = 1 (SCL sync circuit enabled, adds 2 or 3 cycles)
+	 *  FER.NFE = 1 (noise circuit enabled)
+	 *  MR3.NF = 0 (1 cycle of noise filtered out)
+	 *
+	 * Freq (CKS=000) = (I2CCLK + tr + tf)/ (BRH + 3 + 1) + (BRL + 3 + 1)
+	 * Freq (CKS!=000) = (I2CCLK + tr + tf)/ (BRH + 2 + 1) + (BRL + 2 + 1)
+	 */
+
+	/*
+	 * Determine reference clock rate. We must be able to get the desired
+	 * frequency with only 62 clock ticks max (31 high, 31 low).
+	 * Aim for a duty of 60% LOW, 40% HIGH.
+	 */
+	refclk = clk_get_rate(&priv->clk);
+	total_ticks = DIV_ROUND_UP(refclk, bus_speed ?: 1);
+
+	for (cks = 0; cks < 7; cks++) {
+		/*
+		 * 60% low time must be less than BRL + 2 + 1
+		 * BRL max register value is 0x1F.
+		 */
+		brl = ((total_ticks * 6) / 10);
+		if (brl <= (0x1f + 3))
+			break;
+
+		total_ticks /= 2;
+		refclk /= 2;
+	}
+
+	if (brl > (0x1f + 3)) {
+		dev_err(dev, "invalid speed (%u). Too slow.\n", bus_speed);
+		return -EINVAL;
+	}
+
+	brh = total_ticks - brl;
+
+	/* Remove automatic clock ticks for sync circuit and NF */
+	if (cks == 0) {
+		brl -= 4;
+		brh -= 4;
+	} else {
+		brl -= 3;
+		brh -= 3;
+	}
+
+	/*
+	 * If SCL rise and fall times weren't set in the device tree, set them
+	 * based on the desired bus speed and the maximum timings given in the
+	 * I2C specification.
+	 */
+	if (priv->flags & RIIC_FLAG_DEFAULT_SCL_RISE_TIME)
+		priv->scl_rise_ns = bus_speed <= I2C_SPEED_STANDARD_RATE ? 1000 :
+				    bus_speed <= I2C_SPEED_FAST_RATE ? 300 : 120;
+	if (priv->flags & RIIC_FLAG_DEFAULT_SCL_FALL_TIME)
+		priv->scl_fall_ns = bus_speed <= I2C_SPEED_FAST_RATE ? 300 : 120;
+
+	/*
+	 * Remove clock ticks for rise and fall times. Convert ns to clock
+	 * ticks.
+	 */
+	brl -= priv->scl_fall_ns / (1000000000 / refclk);
+	brh -= priv->scl_rise_ns / (1000000000 / refclk);
+
+	/* Adjust for min register values for when SCLE=1 and NFE=1 */
+	if (brl < 1)
+		brl = 1;
+	if (brh < 1)
+		brh = 1;
+
+	priv->bus_speed = refclk / total_ticks;
+	dev_dbg(dev, "freq=%u, duty=%d, fall=%lu, rise=%lu, cks=%d, brl=%d, brh=%d\n",
+		priv->bus_speed, ((brl + 3) * 100) / (brl + brh + 6),
+		priv->scl_fall_ns / (1000000000 / refclk),
+		priv->scl_rise_ns / (1000000000 / refclk), cks, brl, brh);
+
+	setbits_8(priv->base + RIIC_ICCR1, ICCR1_IICRST);
+	writeb(ICMR1_CKS(cks), priv->base + RIIC_ICMR1);
+	writeb(brh | ICBRH_RESERVED, priv->base + RIIC_ICBRH);
+	writeb(brl | ICBRL_RESERVED, priv->base + RIIC_ICBRL);
+	clrbits_8(priv->base + RIIC_ICCR1, ICCR1_IICRST);
+
+	return 0;
+}
+
+static int riic_get_bus_speed(struct udevice *dev)
+{
+	struct riic_priv *priv = dev_get_priv(dev);
+
+	return priv->bus_speed;
+}
+
+static const struct dm_i2c_ops riic_ops = {
+	.xfer           = riic_xfer,
+	.deblock        = riic_deblock,
+	.set_bus_speed	= riic_set_bus_speed,
+	.get_bus_speed	= riic_get_bus_speed,
+};
+
+static int riic_init_setting(struct udevice *dev)
+{
+	struct riic_priv *priv = dev_get_priv(dev);
+	int ret;
+
+	clrbits_8(priv->base + RIIC_ICCR1, ICCR1_ICE);
+	setbits_8(priv->base + RIIC_ICCR1, ICCR1_IICRST);
+	setbits_8(priv->base + RIIC_ICCR1, ICCR1_ICE);
+
+	/*
+	 * Set a default bitrate. The rate may be overridden based on the device
+	 * tree as part of i2c_post_probe().
+	 */
+	ret = riic_set_bus_speed(dev, I2C_SPEED_STANDARD_RATE);
+	if (ret < 0)
+		goto err;
+
+	clrbits_8(priv->base + RIIC_ICCR1, ICCR1_IICRST);
+
+	/* Make sure the bus is not stuck. */
+	if (!(readb(priv->base + RIIC_ICCR1) & ICCR1_SDAI)) {
+		dev_dbg(dev, "clearing SDA low state\n");
+		ret = riic_deblock(dev);
+		if (ret) {
+			dev_err(dev, "failed to clear SDA low state!\n");
+			goto err;
+		}
+	}
+	return 0;
+
+err:
+	clrbits_8(priv->base + RIIC_ICCR1, ICCR1_ICE | ICCR1_IICRST);
+	return ret;
+}
+
+static int riic_probe(struct udevice *dev)
+{
+	struct riic_priv *priv = dev_get_priv(dev);
+	struct reset_ctl rst;
+	int ret;
+
+	priv->base = dev_read_addr_ptr(dev);
+
+	ret = dev_read_u32(dev, "i2c-scl-rising-time-ns", &priv->scl_rise_ns);
+	if (ret)
+		priv->flags |= RIIC_FLAG_DEFAULT_SCL_RISE_TIME;
+	ret = dev_read_u32(dev, "i2c-scl-falling-time-ns", &priv->scl_fall_ns);
+	if (ret)
+		priv->flags |= RIIC_FLAG_DEFAULT_SCL_FALL_TIME;
+
+	ret = clk_get_by_index(dev, 0, &priv->clk);
+	if (ret) {
+		dev_err(dev, "failed to get clock\n");
+		return ret;
+	}
+
+	ret = clk_enable(&priv->clk);
+	if (ret) {
+		dev_err(dev, "failed to enable clock\n");
+		return ret;
+	}
+
+	ret = reset_get_by_index(dev, 0, &rst);
+	if (ret < 0) {
+		dev_err(dev, "failed to get reset line\n");
+		goto err_get_reset;
+	}
+
+	ret = reset_deassert(&rst);
+	if (ret < 0) {
+		dev_err(dev, "failed to de-assert reset line\n");
+		goto err_reset;
+	}
+
+	ret = riic_init_setting(dev);
+	if (ret < 0) {
+		dev_err(dev, "failed to init i2c bus interface\n");
+		goto err_init;
+	}
+
+	return 0;
+
+err_init:
+	reset_assert(&rst);
+err_reset:
+	reset_free(&rst);
+err_get_reset:
+	clk_disable(&priv->clk);
+	return ret;
+}
+
+static const struct udevice_id riic_ids[] = {
+	{ .compatible = "renesas,riic-rz", },
+	{ /* sentinel */ }
+};
+
+U_BOOT_DRIVER(riic_i2c) = {
+	.name           = "riic-i2c",
+	.id             = UCLASS_I2C,
+	.of_match       = riic_ids,
+	.probe          = riic_probe,
+	.priv_auto	= sizeof(struct riic_priv),
+	.ops            = &riic_ops,
+};
diff --git a/drivers/power/pmic/Kconfig b/drivers/power/pmic/Kconfig
index 454a6e0..9b61b18 100644
--- a/drivers/power/pmic/Kconfig
+++ b/drivers/power/pmic/Kconfig
@@ -404,6 +404,15 @@
 	help
 	The TPS65219 is a PMIC containing a bunch of SMPS & LDOs.
 	This driver binds the pmic children.
+
+config PMIC_RAA215300
+	bool "Renesas RAA215300 PMIC driver"
+	depends on DM_PMIC
+	help
+	  The Renesas RAA215300 PMIC driver includes RTC support, system reset
+	  support and several voltage regulators. For now, this driver simply
+	  allows register access and will bind the sysreset driver
+	  (CONFIG_SYSRESET_RAA215300) if it is enabled.
 endif
 
 config PMIC_TPS65217
diff --git a/drivers/power/pmic/Makefile b/drivers/power/pmic/Makefile
index 55ee614..a2d59de 100644
--- a/drivers/power/pmic/Makefile
+++ b/drivers/power/pmic/Makefile
@@ -35,6 +35,7 @@
 obj-$(CONFIG_PMIC_TPS65217) += pmic_tps65217.o
 obj-$(CONFIG_PMIC_TPS65219) += tps65219.o
 obj-$(CONFIG_PMIC_TPS65941) += tps65941.o
+obj-$(CONFIG_PMIC_RAA215300) += raa215300.o
 obj-$(CONFIG_POWER_TPS65218) += pmic_tps65218.o
 
 ifeq ($(CONFIG_$(SPL_)POWER_LEGACY),y)
diff --git a/drivers/power/pmic/raa215300.c b/drivers/power/pmic/raa215300.c
new file mode 100644
index 0000000..a581a1f
--- /dev/null
+++ b/drivers/power/pmic/raa215300.c
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2023 Renesas Electronics Corporation
+ */
+
+#include <dm.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+#include <i2c.h>
+#include <power/pmic.h>
+
+#define RAA215300_REG_COUNT 0x80
+
+static int raa215300_reg_count(struct udevice *dev)
+{
+	return RAA215300_REG_COUNT;
+}
+
+static struct dm_pmic_ops raa215300_ops = {
+	.reg_count = raa215300_reg_count,
+	.read = dm_i2c_read,
+	.write = dm_i2c_write,
+};
+
+static const struct udevice_id raa215300_ids[] = {
+	{ .compatible = "renesas,raa215300" },
+	{ /* sentinel */ }
+};
+
+static int raa215300_bind(struct udevice *dev)
+{
+	if (IS_ENABLED(CONFIG_SYSRESET_RAA215300)) {
+		struct driver *drv = lists_driver_lookup_name("raa215300_sysreset");
+		if (!drv)
+			return -ENOENT;
+
+		return device_bind(dev, drv, dev->name, NULL, dev_ofnode(dev),
+				   NULL);
+	}
+
+	return 0;
+}
+
+U_BOOT_DRIVER(raa215300_pmic) = {
+	.name = "raa215300_pmic",
+	.id = UCLASS_PMIC,
+	.of_match = raa215300_ids,
+	.bind = raa215300_bind,
+	.ops = &raa215300_ops,
+};
diff --git a/drivers/sysreset/Kconfig b/drivers/sysreset/Kconfig
index 0e52f99..49c0787 100644
--- a/drivers/sysreset/Kconfig
+++ b/drivers/sysreset/Kconfig
@@ -229,6 +229,12 @@
 	help
 	  Reboot support for NXP MPC83xx SoCs.
 
+config SYSRESET_RAA215300
+	bool "Support sysreset via Renesas RAA215300 PMIC"
+	depends on PMIC_RAA215300
+	help
+	  Add support for the system reboot via the Renesas RAA215300 PMIC.
+
 endif
 
 endmenu
diff --git a/drivers/sysreset/Makefile b/drivers/sysreset/Makefile
index c9f1c62..e0e7322 100644
--- a/drivers/sysreset/Makefile
+++ b/drivers/sysreset/Makefile
@@ -27,4 +27,5 @@
 obj-$(CONFIG_SYSRESET_RESETCTL) += sysreset_resetctl.o
 obj-$(CONFIG_$(SPL_TPL_)SYSRESET_AT91) += sysreset_at91.o
 obj-$(CONFIG_$(SPL_TPL_)SYSRESET_X86) += sysreset_x86.o
+obj-$(CONFIG_SYSRESET_RAA215300) += sysreset_raa215300.o
 obj-$(CONFIG_TARGET_XTFPGA) += sysreset_xtfpga.o
diff --git a/drivers/sysreset/sysreset_raa215300.c b/drivers/sysreset/sysreset_raa215300.c
new file mode 100644
index 0000000..32dfcb0
--- /dev/null
+++ b/drivers/sysreset/sysreset_raa215300.c
@@ -0,0 +1,58 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2023 Renesas Electronics Corporation
+ */
+
+#include <dm.h>
+#include <power/pmic.h>
+#include <sysreset.h>
+
+#define RAA215300_REG_SWRESET	0x6D
+#define RAA215300_COLD_RESET	BIT(0)
+#define RAA215300_WARM_RESET	BIT(1)
+
+static int raa215300_sysreset_request(struct udevice *dev, enum sysreset_t type)
+{
+	struct udevice *pmic = dev_get_parent(dev);
+	int ret;
+	u8 val;
+
+	/*
+	 * The RAA215300 documentation names the available reset types
+	 * differently to u-boot:
+	 *
+	 *   - A "warm" reset via the RAA215300 PMIC will fully reset the SoC
+	 *     (CPU & GPIOs), so this corresponds to SYSRESET_COLD.
+	 *
+	 *   - A "cold" reset via the RAA215300 PMIC will cycle all power supply
+	 *     rails, so this corresponds to SYSRESET_POWER.
+	 */
+	switch (type) {
+	case SYSRESET_COLD:
+		val = RAA215300_WARM_RESET;
+		break;
+
+	case SYSRESET_POWER:
+		val = RAA215300_COLD_RESET;
+		break;
+
+	default:
+		return -EPROTONOSUPPORT;
+	}
+
+	ret = pmic_reg_write(pmic, RAA215300_REG_SWRESET, val);
+	if (ret)
+		return ret;
+
+	return -EINPROGRESS;
+}
+
+static struct sysreset_ops raa215300_sysreset_ops = {
+	.request = raa215300_sysreset_request,
+};
+
+U_BOOT_DRIVER(raa215300_sysreset) = {
+	.name = "raa215300_sysreset",
+	.id = UCLASS_SYSRESET,
+	.ops = &raa215300_sysreset_ops,
+};