[PATCH] misc: Add RZG2L OTP support

Marek Vasut marek.vasut at mailbox.org
Wed Apr 15 00:18:55 CEST 2026


On 4/14/26 11:14 AM, Mathieu Othacehe wrote:

[...]

> +/*
> + * XXX: To enable direct fusing through U-Boot, the trusted-firmware must
> + * allow the non-secure world to perform fusing operations. This is controlled
> + * by the SYS_SLVACCCTL7 register.

Is there some SMC call to perform the fusing via TFA ?

> + */
> +#define RZG2L_OTP_BASE      0x11860000
> +#define RZG2L_SYSC_BASE     0x11020000

Can this be parsed out of DT ?

> +#define RZ_SYS_BASE_DEVID   (RZG2L_SYSC_BASE + 0x0A04)
> +#define RZ_OTP_BASE_DEVID   (RZG2L_OTP_BASE + 0x1178)
> +#define RZ_OTP_BASE_CHIPID  (RZG2L_OTP_BASE + 0x1140)
> +
> +#define RZ_OTP_PWR          (RZG2L_OTP_BASE + 0x0000)
> +#define RZ_OTP_STR          (RZG2L_OTP_BASE + 0x0004)
> +#define RZ_OTP_STAWR        (RZG2L_OTP_BASE + 0x0008)
> +#define RZ_OTP_ADRWR        (RZG2L_OTP_BASE + 0x000c)
> +#define RZ_OTP_DATAWR       (RZG2L_OTP_BASE + 0x0010)
> +
> +#define RZ_OTP_ADRRD        (RZG2L_OTP_BASE + 0x0014)
> +#define RZ_OTP_DATARD       (RZG2L_OTP_BASE + 0x0018)
> +
> +#define RZ_OTP_FLAG         (RZG2L_OTP_BASE + 0x001c)
> +
> +#define OTP_PWR		    BIT(0)
> +#define ERR_WR_1	    BIT(1)
> +#define ERR_WR_2	    BIT(2)
> +#define ERR_WP		    BIT(3)
> +#define OTP_ACCL	    BIT(4)
> +#define ERR_RDY_WR	    BIT(8)
> +#define OTP_DUMMY_READ	    (0x400 >> 2)

What does 0x400 >> 2 mean ?

> +static int rzg2l_otp_open(void)
> +{
> +	int i = 0;
> +
> +	if (readl(RZ_OTP_PWR) & 1) {

What does this magic value 1 mean ? Please add macro for it.

> +		debug("OTP already powered up\n");
> +		return 0;
> +	}
> +
> +	while ((readl(RZ_OTP_STR) & 1) ||
> +	       ((readl(RZ_OTP_FLAG) & 1) == 0)) {

read_poll_*() .

> +		if (i++ > 1000) {
> +			printf("OTP power-up timeout\n");
> +			return -ETIMEDOUT;
> +		}
> +
> +		mdelay(1);
> +	}
> +
> +	writel(readl(RZ_OTP_PWR) | OTP_PWR | OTP_ACCL, RZ_OTP_PWR);
> +
> +	return 0;
> +}
> +
> +static int rzg2l_otp_dummy_read(void)
> +{
> +	int i = 0;
> +
> +	while ((readl(RZ_OTP_STR) & 1) == 0) {

readl_poll_*()

> +		if (i++ > 1000) {
> +			printf("Timeout polling ready for OTP read\n");
> +			return -ETIMEDOUT;
> +		}
> +		mdelay(1);
> +	}
> +
> +	writel(RZG2L_OTP_BASE + OTP_DUMMY_READ, RZ_OTP_ADRRD);
> +	readl(RZ_OTP_DATARD);
> +
> +	return 0;
> +}
> +
> +static int rzg2l_otp_close(void)
> +{
> +	int i = 0;
> +	u32 val;
> +
> +	rzg2l_otp_dummy_read();
> +
> +	val = readl(RZ_OTP_PWR);
> +	val = val & OTP_PWR & OTP_ACCL;
> +	writel(val, RZ_OTP_PWR);

clrsetbits_le32()

> +	while (readl(RZ_OTP_STR) & 1) {

readl_poll ...

[...]


More information about the U-Boot mailing list