diff options
author | Tom Rini | 2024-03-11 13:40:06 -0400 |
---|---|---|
committer | Tom Rini | 2024-03-11 15:27:20 -0400 |
commit | 20a0ce574d6642e0dfe651467159039fac48cc4f (patch) | |
tree | 9a76dcd90a2e27e65963b4a74d1621cd10fe91f0 /drivers | |
parent | beedf675b36841ce1e077779157a87a6505317e6 (diff) | |
parent | f3c979dd0053c082d2df170446923e7ce5edbc2d (diff) |
Merge tag 'v2024.04-rc4' into next
Prepare v2024.04-rc4
Diffstat (limited to 'drivers')
33 files changed, 1010 insertions, 68 deletions
diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig index e9296ed9fe2..a093027eb0e 100644 --- a/drivers/clk/renesas/Kconfig +++ b/drivers/clk/renesas/Kconfig @@ -1,6 +1,6 @@ config CLK_RENESAS bool "Renesas clock drivers" - depends on CLK && ARCH_RMOBILE + depends on CLK && ARCH_RENESAS help Enable support for clock present on Renesas SoCs. diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c index e54508c35ce..dba009997a8 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 @@ static int rzg2l_cpg_clk_set(struct clk *clk, bool enable) 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 @@ static int rzg2l_cpg_rst_set(struct reset_ctl *reset_ctl, bool asserted) 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/gpio/Kconfig b/drivers/gpio/Kconfig index 27df5d88d40..2df3dc42d0f 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -333,7 +333,7 @@ config PCF8575_GPIO config RCAR_GPIO bool "Renesas RCar GPIO driver" - depends on DM_GPIO && ARCH_RMOBILE + depends on DM_GPIO && ARCH_RENESAS help This driver supports the GPIO banks on Renesas RCar SoCs. diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index 4f42200f392..59c635af80b 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -524,6 +524,13 @@ config SYS_I2C_ROCKCHIP 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 @@ -544,7 +551,7 @@ config SPL_SYS_I2C_SANDBOX config SYS_I2C_SH bool "Legacy SuperH I2C interface" - depends on ARCH_RMOBILE && SYS_I2C_LEGACY + depends on ARCH_RENESAS && SYS_I2C_LEGACY help Enable the legacy SuperH I2C interface. diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index a96a8c7e955..692f63bafd0 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile @@ -40,6 +40,7 @@ obj-$(CONFIG_SYS_I2C_QUP) += qup_i2c.o 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 00000000000..5f3f8d1b24b --- /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/mmc/Kconfig b/drivers/mmc/Kconfig index 17618c3bdcc..cef05790dd9 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -393,7 +393,7 @@ config HSMMC2_8BIT config SH_MMCIF bool "SuperH/Renesas ARM SoCs on-chip MMCIF host controller support" - depends on ARCH_RMOBILE || SH + depends on ARCH_RENESAS || SH help Support for the on-chip MMCIF host controller on SuperH/Renesas ARM SoCs platform @@ -408,7 +408,7 @@ config MMC_UNIPHIER config RENESAS_SDHI bool "Renesas R-Car SD/MMC Host Controller support" - depends on ARCH_RMOBILE + depends on ARCH_RENESAS depends on BLK && DM_MMC depends on OF_CONTROL select BOUNCE_BUFFER diff --git a/drivers/mmc/renesas-sdhi.c b/drivers/mmc/renesas-sdhi.c index a74559ca686..20b1e9277eb 100644 --- a/drivers/mmc/renesas-sdhi.c +++ b/drivers/mmc/renesas-sdhi.c @@ -92,7 +92,7 @@ static const u8 r8a77990_calib_table[2][CALIB_TABLE_MAX] = { 11, 12, 13, 15, 16, 17, 17, 18, 18, 19, 20, 22, 24, 25, 26, 26 } }; -static int rmobile_is_gen3_mmc0(struct tmio_sd_priv *priv) +static int rcar_is_gen3_mmc0(struct tmio_sd_priv *priv) { /* On R-Car Gen3, MMC0 is at 0xee140000 */ return (uintptr_t)(priv->regbase) == 0xee140000; @@ -885,80 +885,80 @@ static void renesas_sdhi_filter_caps(struct udevice *dev) struct tmio_sd_plat *plat = dev_get_plat(dev); /* HS400 is not supported on H3 ES1.x, M3W ES1.[012], V3M, V3H ES1.x, D3 */ - if (((rmobile_get_cpu_type() == RMOBILE_CPU_TYPE_R8A7795) && - (rmobile_get_cpu_rev_integer() <= 1)) || - ((rmobile_get_cpu_type() == RMOBILE_CPU_TYPE_R8A7796) && - (rmobile_get_cpu_rev_integer() == 1) && - (rmobile_get_cpu_rev_fraction() <= 2)) || - (rmobile_get_cpu_type() == RMOBILE_CPU_TYPE_R8A77970) || - ((rmobile_get_cpu_type() == RMOBILE_CPU_TYPE_R8A77980) && - (rmobile_get_cpu_rev_integer() <= 1)) || - (rmobile_get_cpu_type() == RMOBILE_CPU_TYPE_R8A77995)) + if (((renesas_get_cpu_type() == RENESAS_CPU_TYPE_R8A7795) && + (renesas_get_cpu_rev_integer() <= 1)) || + ((renesas_get_cpu_type() == RENESAS_CPU_TYPE_R8A7796) && + (renesas_get_cpu_rev_integer() == 1) && + (renesas_get_cpu_rev_fraction() <= 2)) || + (renesas_get_cpu_type() == RENESAS_CPU_TYPE_R8A77970) || + ((renesas_get_cpu_type() == RENESAS_CPU_TYPE_R8A77980) && + (renesas_get_cpu_rev_integer() <= 1)) || + (renesas_get_cpu_type() == RENESAS_CPU_TYPE_R8A77995)) plat->cfg.host_caps &= ~MMC_MODE_HS400; /* H3 ES2.0, ES3.0 and M3W ES1.2 and M3N bad taps */ - if (((rmobile_get_cpu_type() == RMOBILE_CPU_TYPE_R8A7795) && - (rmobile_get_cpu_rev_integer() >= 2)) || - ((rmobile_get_cpu_type() == RMOBILE_CPU_TYPE_R8A7796) && - (rmobile_get_cpu_rev_integer() == 1) && - (rmobile_get_cpu_rev_fraction() == 2)) || - (rmobile_get_cpu_type() == RMOBILE_CPU_TYPE_R8A77965)) + if (((renesas_get_cpu_type() == RENESAS_CPU_TYPE_R8A7795) && + (renesas_get_cpu_rev_integer() >= 2)) || + ((renesas_get_cpu_type() == RENESAS_CPU_TYPE_R8A7796) && + (renesas_get_cpu_rev_integer() == 1) && + (renesas_get_cpu_rev_fraction() == 2)) || + (renesas_get_cpu_type() == RENESAS_CPU_TYPE_R8A77965)) priv->hs400_bad_tap = BIT(2) | BIT(3) | BIT(6) | BIT(7); /* M3W ES1.x for x>2 can use HS400 with manual adjustment and taps */ - if ((rmobile_get_cpu_type() == RMOBILE_CPU_TYPE_R8A7796) && - (rmobile_get_cpu_rev_integer() == 1) && - (rmobile_get_cpu_rev_fraction() > 2)) { + if ((renesas_get_cpu_type() == RENESAS_CPU_TYPE_R8A7796) && + (renesas_get_cpu_rev_integer() == 1) && + (renesas_get_cpu_rev_fraction() > 2)) { priv->adjust_hs400_enable = true; priv->adjust_hs400_offset = 3; priv->hs400_bad_tap = BIT(1) | BIT(3) | BIT(5) | BIT(7); priv->adjust_hs400_calib_table = - r8a7796_rev13_calib_table[!rmobile_is_gen3_mmc0(priv)]; + r8a7796_rev13_calib_table[!rcar_is_gen3_mmc0(priv)]; } /* M3W+ bad taps */ - if ((rmobile_get_cpu_type() == RMOBILE_CPU_TYPE_R8A7796) && - (rmobile_get_cpu_rev_integer() == 3)) + if ((renesas_get_cpu_type() == RENESAS_CPU_TYPE_R8A7796) && + (renesas_get_cpu_rev_integer() == 3)) priv->hs400_bad_tap = BIT(1) | BIT(3) | BIT(5) | BIT(7); /* M3N can use HS400 with manual adjustment */ - if (rmobile_get_cpu_type() == RMOBILE_CPU_TYPE_R8A77965) { + if (renesas_get_cpu_type() == RENESAS_CPU_TYPE_R8A77965) { priv->adjust_hs400_enable = true; priv->adjust_hs400_offset = 3; priv->adjust_hs400_calib_table = - r8a77965_calib_table[!rmobile_is_gen3_mmc0(priv)]; + r8a77965_calib_table[!rcar_is_gen3_mmc0(priv)]; } /* E3 can use HS400 with manual adjustment */ - if (rmobile_get_cpu_type() == RMOBILE_CPU_TYPE_R8A77990) { + if (renesas_get_cpu_type() == RENESAS_CPU_TYPE_R8A77990) { priv->adjust_hs400_enable = true; priv->adjust_hs400_offset = 3; priv->adjust_hs400_calib_table = - r8a77990_calib_table[!rmobile_is_gen3_mmc0(priv)]; + r8a77990_calib_table[!rcar_is_gen3_mmc0(priv)]; } /* H3 ES1.x, ES2.0 and M3W ES1.[0123] uses 4 tuning taps */ - if (((rmobile_get_cpu_type() == RMOBILE_CPU_TYPE_R8A7795) && - (rmobile_get_cpu_rev_integer() <= 2)) || - ((rmobile_get_cpu_type() == RMOBILE_CPU_TYPE_R8A7796) && - (rmobile_get_cpu_rev_integer() == 1) && - (rmobile_get_cpu_rev_fraction() <= 3))) + if (((renesas_get_cpu_type() == RENESAS_CPU_TYPE_R8A7795) && + (renesas_get_cpu_rev_integer() <= 2)) || + ((renesas_get_cpu_type() == RENESAS_CPU_TYPE_R8A7796) && + (renesas_get_cpu_rev_integer() == 1) && + (renesas_get_cpu_rev_fraction() <= 3))) priv->nrtaps = 4; else priv->nrtaps = 8; #endif /* H3 ES1.x and M3W ES1.0 uses bit 17 for DTRAEND */ - if (((rmobile_get_cpu_type() == RMOBILE_CPU_TYPE_R8A7795) && - (rmobile_get_cpu_rev_integer() <= 1)) || - ((rmobile_get_cpu_type() == RMOBILE_CPU_TYPE_R8A7796) && - (rmobile_get_cpu_rev_integer() == 1) && - (rmobile_get_cpu_rev_fraction() == 0))) + if (((renesas_get_cpu_type() == RENESAS_CPU_TYPE_R8A7795) && + (renesas_get_cpu_rev_integer() <= 1)) || + ((renesas_get_cpu_type() == RENESAS_CPU_TYPE_R8A7796) && + (renesas_get_cpu_rev_integer() == 1) && + (renesas_get_cpu_rev_fraction() == 0))) priv->read_poll_flag = TMIO_SD_DMA_INFO1_END_RD; else priv->read_poll_flag = TMIO_SD_DMA_INFO1_END_RD2; /* V3M handles SD0H differently than other Gen3 SoCs */ - if (rmobile_get_cpu_type() == RMOBILE_CPU_TYPE_R8A77970) + if (renesas_get_cpu_type() == RENESAS_CPU_TYPE_R8A77970) priv->needs_clkh_fallback = true; else priv->needs_clkh_fallback = false; diff --git a/drivers/mmc/sh_mmcif.h b/drivers/mmc/sh_mmcif.h index 66341e51d26..b131b8c2833 100644 --- a/drivers/mmc/sh_mmcif.h +++ b/drivers/mmc/sh_mmcif.h @@ -195,7 +195,7 @@ struct sh_mmcif_regs { #define SOFT_RST_OFF (0 << 31) #define CLKDEV_EMMC_DATA 52000000 /* 52MHz */ -#ifdef CONFIG_ARCH_RMOBILE +#ifdef CONFIG_ARCH_RENESAS #define MMC_CLK_DIV_MIN(clk) (clk / (1 << 9)) #define MMC_CLK_DIV_MAX(clk) (clk / (1 << 1)) #else diff --git a/drivers/net/mv88e6xxx.c b/drivers/net/mv88e6xxx.c index c073f81e72d..8fbbc1cacca 100644 --- a/drivers/net/mv88e6xxx.c +++ b/drivers/net/mv88e6xxx.c @@ -745,6 +745,7 @@ static int mv88e6xxx_probe(struct udevice *dev) { struct dsa_pdata *dsa_pdata = dev_get_uclass_plat(dev); struct mv88e6xxx_priv *priv = dev_get_priv(dev); + fdt_addr_t smi_addr; int val, ret; if (ofnode_valid(dev_ofnode(dev)) && @@ -753,6 +754,13 @@ static int mv88e6xxx_probe(struct udevice *dev) return -ENODEV; } + smi_addr = dev_read_addr(dev); + if (smi_addr == FDT_ADDR_T_NONE) { + dev_err(dev, "Missing SMI address\n"); + return -EINVAL; + } + priv->smi_addr = smi_addr; + /* probe internal mdio bus */ ret = mv88e6xxx_probe_mdio(dev); if (ret) diff --git a/drivers/net/phy/ethernet_id.c b/drivers/net/phy/ethernet_id.c index 877a51c3d00..6cb1fd4453e 100644 --- a/drivers/net/phy/ethernet_id.c +++ b/drivers/net/phy/ethernet_id.c @@ -71,6 +71,9 @@ struct phy_device *phy_connect_phy_id(struct mii_dev *bus, struct udevice *dev, } } + if (phyaddr == -1) + phyaddr = ofnode_read_u32_default(phandle_args.node, "reg", -1); + id = vendor << 16 | device; phydev = phy_device_create(bus, phyaddr, id, false); if (phydev) diff --git a/drivers/net/ravb.c b/drivers/net/ravb.c index 0bcd6cfd3f3..4764bca7082 100644 --- a/drivers/net/ravb.c +++ b/drivers/net/ravb.c @@ -392,8 +392,8 @@ static int ravb_dmac_init(struct udevice *dev) writel(0x00222210, eth->iobase + RAVB_REG_TGC); /* Delay CLK: 2ns (not applicable on R-Car E3/D3) */ - if ((rmobile_get_cpu_type() == RMOBILE_CPU_TYPE_R8A77990) || - (rmobile_get_cpu_type() == RMOBILE_CPU_TYPE_R8A77995)) + if ((renesas_get_cpu_type() == RENESAS_CPU_TYPE_R8A77990) || + (renesas_get_cpu_type() == RENESAS_CPU_TYPE_R8A77995)) return 0; if (!dev_read_u32(dev, "rx-internal-delay-ps", &delay)) { diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index 0e929d8ca04..6d7b7cd9051 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -14,7 +14,7 @@ obj-$(CONFIG_PINCTRL_INTEL) += intel/ obj-$(CONFIG_ARCH_MTMIPS) += mtmips/ obj-$(CONFIG_ARCH_NPCM) += nuvoton/ obj-$(CONFIG_PINCTRL_QCOM) += qcom/ -obj-$(CONFIG_ARCH_RMOBILE) += renesas/ +obj-$(CONFIG_ARCH_RENESAS) += renesas/ obj-$(CONFIG_ARCH_RZN1) += renesas/ obj-$(CONFIG_PINCTRL_SANDBOX) += pinctrl-sandbox.o obj-$(CONFIG_PINCTRL_SUNXI) += sunxi/ diff --git a/drivers/pinctrl/renesas/Kconfig b/drivers/pinctrl/renesas/Kconfig index 171cd374b81..57e88604aa2 100644 --- a/drivers/pinctrl/renesas/Kconfig +++ b/drivers/pinctrl/renesas/Kconfig @@ -1,8 +1,8 @@ -if ARCH_RMOBILE +if ARCH_RENESAS config PINCTRL_PFC bool "Renesas pin control drivers" - depends on DM && ARCH_RMOBILE + depends on DM && ARCH_RENESAS default n if CPU_RZA1 help Support pin multiplexing control on Renesas SoCs. diff --git a/drivers/pinctrl/renesas/pfc-r8a7790.c b/drivers/pinctrl/renesas/pfc-r8a7790.c index e1811c4c908..acd6b01f497 100644 --- a/drivers/pinctrl/renesas/pfc-r8a7790.c +++ b/drivers/pinctrl/renesas/pfc-r8a7790.c @@ -6117,8 +6117,8 @@ static const struct pinmux_bias_reg pinmux_bias_regs[] = { static int r8a7790_pinmux_soc_init(struct sh_pfc *pfc) { /* Initialize TDSEL on old revisions */ - if ((rmobile_get_cpu_rev_integer() == 1) && - (rmobile_get_cpu_rev_fraction() == 0)) + if ((renesas_get_cpu_rev_integer() == 1) && + (renesas_get_cpu_rev_fraction() == 0)) sh_pfc_write(pfc, 0xe6060088, 0x00155554); return 0; diff --git a/drivers/pinctrl/renesas/pfc-r8a7794.c b/drivers/pinctrl/renesas/pfc-r8a7794.c index 29eab2610c1..2f550218182 100644 --- a/drivers/pinctrl/renesas/pfc-r8a7794.c +++ b/drivers/pinctrl/renesas/pfc-r8a7794.c @@ -5818,8 +5818,8 @@ static const struct pinmux_bias_reg pinmux_bias_regs[] = { static int r8a7794_pinmux_soc_init(struct sh_pfc *pfc) { /* Initialize TDSEL on old revisions */ - if ((rmobile_get_cpu_rev_integer() == 1) && - (rmobile_get_cpu_rev_fraction() == 0)) + if ((renesas_get_cpu_rev_integer() == 1) && + (renesas_get_cpu_rev_fraction() == 0)) sh_pfc_write(pfc, 0xe6060068, 0x55555500); return 0; diff --git a/drivers/power/pmic/Kconfig b/drivers/power/pmic/Kconfig index 454a6e0cf87..9b61b18e11f 100644 --- a/drivers/power/pmic/Kconfig +++ b/drivers/power/pmic/Kconfig @@ -404,6 +404,15 @@ config PMIC_TPS65219 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 55ee614364b..a2d59deeed8 100644 --- a/drivers/power/pmic/Makefile +++ b/drivers/power/pmic/Makefile @@ -35,6 +35,7 @@ obj-$(CONFIG_PMIC_STPMIC1) += stpmic1.o 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 00000000000..a581a1f6dc1 --- /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/ram/Makefile b/drivers/ram/Makefile index 985990ab5ac..c9c46cc17a8 100644 --- a/drivers/ram/Makefile +++ b/drivers/ram/Makefile @@ -28,5 +28,5 @@ obj-$(CONFIG_DRAM_SUN20I_D1) += sunxi/ obj-$(CONFIG_ARCH_OCTEON) += octeon/ -obj-$(CONFIG_ARCH_RMOBILE) += renesas/ +obj-$(CONFIG_ARCH_RENESAS) += renesas/ obj-$(CONFIG_CADENCE_DDR_CTRL) += cadence/ diff --git a/drivers/rng/Kconfig b/drivers/rng/Kconfig index a89c8995682..cd72852a479 100644 --- a/drivers/rng/Kconfig +++ b/drivers/rng/Kconfig @@ -105,4 +105,12 @@ config RNG_JH7110 help Enable True Random Number Generator in StarFive JH7110 SoCs. +config RNG_TURRIS_RWTM + bool "Turris Mox TRNG in Secure Processor" + depends on DM_RNG && ARMADA_3700 + help + Use TRNG in Turris Mox Secure Processor Firmware. Can be used + on other Armada-3700 devices (like EspressoBin) if Secure + Firmware from CZ.NIC is used. + endif diff --git a/drivers/rng/Makefile b/drivers/rng/Makefile index 7e64c4cdfc3..ecae1a3da33 100644 --- a/drivers/rng/Makefile +++ b/drivers/rng/Makefile @@ -17,3 +17,4 @@ obj-$(CONFIG_RNG_SMCCC_TRNG) += smccc_trng.o obj-$(CONFIG_RNG_ARM_RNDR) += arm_rndr.o obj-$(CONFIG_TPM_RNG) += tpm_rng.o obj-$(CONFIG_RNG_JH7110) += jh7110_rng.o +obj-$(CONFIG_RNG_TURRIS_RWTM) += turris_rwtm_rng.o diff --git a/drivers/rng/turris_rwtm_rng.c b/drivers/rng/turris_rwtm_rng.c new file mode 100644 index 00000000000..ca808c45797 --- /dev/null +++ b/drivers/rng/turris_rwtm_rng.c @@ -0,0 +1,123 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause +/* + * Copyright (c) 2024, Max Resch + */ + +#include <dm.h> +#include <malloc.h> +#include <rng.h> +#include <asm/dma-mapping.h> +#include <asm/types.h> +#include <mach/mbox.h> + +/* size of entropy buffer */ +#define RNG_BUFFER_SIZE 128U + +struct turris_rwtm_rng_priv { + phys_addr_t buffer; +}; + +static int turris_rwtm_rng_fill_entropy(phys_addr_t entropy, size_t size) +{ + u32 args[3] = { 1, (u32)entropy, size }; + int ret; + + /* flush data cache */ + flush_dcache_range(entropy, entropy + size); + + /* + * get entropy + * args[0] = 1 copies BYTES array in args[1] of length args[2] + */ + ret = mbox_do_cmd(MBOX_CMD_GET_RANDOM, args, 3, NULL, 0); + if (ret < 0) + return ret; + + /* invalidate data cache */ + invalidate_dcache_range(entropy, entropy + size); + + return 0; +} + +static int turris_rwtm_rng_random_read(struct udevice *dev, void *data, size_t count) +{ + struct turris_rwtm_rng_priv *priv = dev_get_priv(dev); + phys_addr_t phys; + size_t size; + int ret; + + phys = priv->buffer; + + while (count) { + size = min_t(size_t, RNG_BUFFER_SIZE, count); + + ret = turris_rwtm_rng_fill_entropy(phys, size); + if (ret < 0) + return ret; + + memcpy(data, (void *)phys, size); + count -= size; + data = (u8 *)data + size; + } + + return 0; +} + +static int turris_rwtm_rng_probe(struct udevice *dev) +{ + struct turris_rwtm_rng_priv *priv = dev_get_priv(dev); + u32 args[] = { 0 }; + int ret; + + /* + * check if the random command is supported + * args[0] = 0 would copy 16 DWORDS entropy to out but we ignore them + */ + ret = mbox_do_cmd(MBOX_CMD_GET_RANDOM, args, ARRAY_SIZE(args), NULL, 0); + if (ret < 0) + return ret; + + /* entropy buffer */ + priv->buffer = 0; + + /* buffer address need to be aligned */ + dma_alloc_coherent(RNG_BUFFER_SIZE, (unsigned long *)&priv->buffer); + if (!priv->buffer) + return -ENOMEM; + + return 0; +} + +static int turris_rwtm_rng_remove(struct udevice *dev) +{ + struct turris_rwtm_rng_priv *priv = dev_get_priv(dev); + phys_addr_t phys = priv->buffer; + + dma_free_coherent((void *)phys); + + return 0; +} + +static const struct dm_rng_ops turris_rwtm_rng_ops = { + .read = turris_rwtm_rng_random_read, +}; + +/* + * only Turris MOX firmware has the RNG but allow all probable devices to be + * probed the default firmware will just reject the probe + */ +static const struct udevice_id turris_rwtm_rng_match[] = { + { .compatible = "cznic,turris-mox-rwtm" }, + { .compatible = "marvell,armada-3700-rwtm-firmware" }, + {}, +}; + +U_BOOT_DRIVER(turris_rwtm_rng) = { + .name = "turris-rwtm-rng", + .id = UCLASS_RNG, + .of_match = turris_rwtm_rng_match, + .ops = &turris_rwtm_rng_ops, + .probe = turris_rwtm_rng_probe, + .remove = turris_rwtm_rng_remove, + .priv_auto = sizeof(struct turris_rwtm_rng_priv), +}; diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index fbd351a4785..8b19e2684e5 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -441,7 +441,7 @@ config DEBUG_UART_SEMIHOSTING config DEBUG_UART_SCIF bool "Renesas SCIF UART" - depends on SH || ARCH_RMOBILE + depends on SH || ARCH_RENESAS help Select this to enable a debug UART using the serial_sh driver. You will need to provide parameters to make this work. The driver will @@ -901,7 +901,7 @@ config SANDBOX_SERIAL config SCIF_CONSOLE bool "Renesas SCIF UART support" - depends on SH || ARCH_RMOBILE + depends on SH || ARCH_RENESAS help Select this to enable Renesas SCIF UART. To operate serial ports on systems with RCar or SH SoCs, say Y to this option. If unsure, diff --git a/drivers/spi/renesas_rpc_spi.c b/drivers/spi/renesas_rpc_spi.c index 3eb14061c81..8aff2238645 100644 --- a/drivers/spi/renesas_rpc_spi.c +++ b/drivers/spi/renesas_rpc_spi.c @@ -203,7 +203,7 @@ static void rpc_spi_flush_read_cache(struct udevice *dev) static u32 rpc_spi_get_strobe_delay(void) { #ifndef CONFIG_RZA1 - u32 cpu_type = rmobile_get_cpu_type(); + u32 cpu_type = renesas_get_cpu_type(); /* * NOTE: RPC_PHYCNT_STRTIM value: @@ -212,11 +212,11 @@ static u32 rpc_spi_get_strobe_delay(void) * 7: On other R-Car Gen3 * 15: On R-Car Gen4 */ - if (cpu_type == RMOBILE_CPU_TYPE_R8A7796 && rmobile_get_cpu_rev_integer() == 1) + if (cpu_type == RENESAS_CPU_TYPE_R8A7796 && renesas_get_cpu_rev_integer() == 1) return RPC_PHYCNT_STRTIM(6); - else if (cpu_type == RMOBILE_CPU_TYPE_R8A779F0 || - cpu_type == RMOBILE_CPU_TYPE_R8A779G0 || - cpu_type == RMOBILE_CPU_TYPE_R8A779H0) + else if (cpu_type == RENESAS_CPU_TYPE_R8A779F0 || + cpu_type == RENESAS_CPU_TYPE_R8A779G0 || + cpu_type == RENESAS_CPU_TYPE_R8A779H0) return RPC_PHYCNT_STRTIM2(15); else #endif diff --git a/drivers/spi/sh_qspi.c b/drivers/spi/sh_qspi.c index 7dd1fe75e04..72594993853 100644 --- a/drivers/spi/sh_qspi.c +++ b/drivers/spi/sh_qspi.c @@ -13,7 +13,7 @@ #include <malloc.h> #include <spi.h> #include <wait_bit.h> -#include <asm/arch/rmobile.h> +#include <asm/arch/renesas.h> #include <asm/io.h> #include <linux/bitops.h> diff --git a/drivers/spi/spi-sunxi.c b/drivers/spi/spi-sunxi.c index c56d82d998a..9ec6b359e22 100644 --- a/drivers/spi/spi-sunxi.c +++ b/drivers/spi/spi-sunxi.c @@ -117,6 +117,8 @@ enum sun4i_spi_bits { SPI_TCR_XCH, SPI_TCR_CS_MANUAL, SPI_TCR_CS_LEVEL, + SPI_TCR_SDC, + SPI_TCR_SDM, SPI_FCR_TF_RST, SPI_FCR_RF_RST, SPI_FSR_RF_CNT_MASK, @@ -128,6 +130,7 @@ struct sun4i_spi_variant { u32 fifo_depth; bool has_soft_reset; bool has_burst_ctl; + bool has_clk_ctl; }; struct sun4i_spi_plat { @@ -302,7 +305,19 @@ static int sun4i_spi_claim_bus(struct udevice *dev) setbits_le32(SPI_REG(priv, SPI_TCR), SPI_BIT(priv, SPI_TCR_CS_MANUAL) | SPI_BIT(priv, SPI_TCR_CS_ACTIVE_LOW)); - sun4i_spi_set_speed_mode(dev->parent); + if (priv->variant->has_clk_ctl) { + sun4i_spi_set_speed_mode(dev->parent); + } else { + /* + * At this moment there is no ability to change input clock. + * Therefore, we can only use default HOSC@24MHz clock and + * set SPI sampling mode to normal + */ + clrsetbits_le32(SPI_REG(priv, SPI_TCR), + SPI_BIT(priv, SPI_TCR_SDC) | + SPI_BIT(priv, SPI_TCR_SDM), + SPI_BIT(priv, SPI_TCR_SDM)); + } return 0; } @@ -516,6 +531,8 @@ static const u32 sun6i_spi_bits[] = { [SPI_TCR_CS_MASK] = 0x30, [SPI_TCR_CS_MANUAL] = BIT(6), [SPI_TCR_CS_LEVEL] = BIT(7), + [SPI_TCR_SDC] = BIT(11), + [SPI_TCR_SDM] = BIT(13), [SPI_TCR_XCH] = BIT(31), [SPI_FCR_RF_RST] = BIT(15), [SPI_FCR_TF_RST] = BIT(31), @@ -526,6 +543,7 @@ static const struct sun4i_spi_variant sun4i_a10_spi_variant = { .regs = sun4i_spi_regs, .bits = sun4i_spi_bits, .fifo_depth = 64, + .has_clk_ctl = true, }; static const struct sun4i_spi_variant sun6i_a31_spi_variant = { @@ -534,6 +552,7 @@ static const struct sun4i_spi_variant sun6i_a31_spi_variant = { .fifo_depth = 128, .has_soft_reset = true, .has_burst_ctl = true, + .has_clk_ctl = true, }; static const struct sun4i_spi_variant sun8i_h3_spi_variant = { @@ -542,6 +561,15 @@ static const struct sun4i_spi_variant sun8i_h3_spi_variant = { .fifo_depth = 64, .has_soft_reset = true, .has_burst_ctl = true, + .has_clk_ctl = true, +}; + +static const struct sun4i_spi_variant sun50i_r329_spi_variant = { + .regs = sun6i_spi_regs, + .bits = sun6i_spi_bits, + .fifo_depth = 64, + .has_soft_reset = true, + .has_burst_ctl = true, }; static const struct udevice_id sun4i_spi_ids[] = { @@ -557,6 +585,10 @@ static const struct udevice_id sun4i_spi_ids[] = { .compatible = "allwinner,sun8i-h3-spi", .data = (ulong)&sun8i_h3_spi_variant, }, + { + .compatible = "allwinner,sun50i-r329-spi", + .data = (ulong)&sun50i_r329_spi_variant, + }, { /* sentinel */ } }; diff --git a/drivers/sysreset/Kconfig b/drivers/sysreset/Kconfig index 0e52f996283..49c0787b26d 100644 --- a/drivers/sysreset/Kconfig +++ b/drivers/sysreset/Kconfig @@ -229,6 +229,12 @@ config SYSRESET_MPC83XX 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 c9f1c625aeb..e0e732205df 100644 --- a/drivers/sysreset/Makefile +++ b/drivers/sysreset/Makefile @@ -27,4 +27,5 @@ obj-$(CONFIG_SYSRESET_WATCHDOG) += sysreset_watchdog.o 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 00000000000..32dfcb0aec8 --- /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, +}; diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index f96027d7bd2..6e10b629a3c 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -97,7 +97,7 @@ config USB_XHCI_PCI config USB_XHCI_RCAR bool "Renesas RCar USB 3.0 support" default y - depends on ARCH_RMOBILE + depends on ARCH_RENESAS help Choose this option to add support for USB 3.0 driver on Renesas RCar Gen3 SoCs. diff --git a/drivers/usb/host/xhci-dwc3.c b/drivers/usb/host/xhci-dwc3.c index 1dbd65dfaa3..6cebe1cc30c 100644 --- a/drivers/usb/host/xhci-dwc3.c +++ b/drivers/usb/host/xhci-dwc3.c @@ -197,7 +197,7 @@ static int xhci_dwc3_probe(struct udevice *dev) reg |= DWC3_GUSB2PHYCFG_USBTRDTIM_16BIT; } - if (dev_read_bool(dev, "snps,dis_enblslpm-quirk")) + if (dev_read_bool(dev, "snps,dis_enblslpm_quirk")) reg &= ~DWC3_GUSB2PHYCFG_ENBLSLPM; if (dev_read_bool(dev, "snps,dis-u2-freeclk-exists-quirk")) diff --git a/drivers/video/mxsfb.c b/drivers/video/mxsfb.c index 10433949bb8..515363f6a49 100644 --- a/drivers/video/mxsfb.c +++ b/drivers/video/mxsfb.c @@ -387,6 +387,7 @@ static int mxs_video_remove(struct udevice *dev) static const struct udevice_id mxs_video_ids[] = { { .compatible = "fsl,imx23-lcdif" }, { .compatible = "fsl,imx28-lcdif" }, + { .compatible = "fsl,imx6sx-lcdif" }, { .compatible = "fsl,imx7ulp-lcdif" }, { .compatible = "fsl,imxrt-lcdif" }, { /* sentinel */ } |