[U-Boot] [PATCH 1/6] misc: Add JZ47xx efuse driver

Marek Vasut marex at denx.de
Mon Dec 10 20:56:53 UTC 2018


On 12/10/2018 09:35 PM, Ezequiel Garcia wrote:
> From: Paul Burton <paul.burton at imgtec.com>
> 
> Add driver for the efuse block in the JZ47xx SOC.
> 
> Cc: Daniel Schwierzeck <daniel.schwierzeck at gmail.com>
> Signed-off-by: Paul Burton <paul.burton at imgtec.com>
> Signed-off-by: Marek Vasut <marek.vasut at gmail.com>

[...]

> +static void jz4780_efuse_read_chunk(size_t addr, size_t count, u8 *buf)
> +{
> +	void __iomem *regs = (void __iomem *)NEMC_BASE;
> +	size_t i;
> +	u32 val;
> +
> +	val = EFUSE_EFUCTRL_RD_EN |
> +	      ((count - 1) << EFUSE_EFUCTRL_LEN_BIT) |
> +	      (addr << EFUSE_EFUCTRL_ADDR_BIT) |
> +	      ((addr > 0x200) ? EFUSE_EFUCTRL_CS : 0);
> +	writel(val, regs + EFUSE_EFUCTRL);
> +	/* FIXME -- wait_bit() */
> +	while (!(readl(regs + EFUSE_EFUSTATE) & EFUSE_EFUSTATE_RD_DONE))
> +		;

Does wait_for_bit_le32() fit into the SPL if you use it here ?

> +	if ((count % 4) == 0) {
> +		for (i = 0; i < count / 4; i++) {
> +			val = readl(regs + EFUSE_EFUDATA(i));
> +			put_unaligned(val, (u32 *)(buf + (i * 4)));
> +		}

I thought we had something like ioread*_rep(), but I guess not.

> +	} else {
> +		val = readl(regs + EFUSE_EFUDATA(0));
> +		if (count > 2)
> +			buf[2] = (val >> 16) & 0xff;
> +		if (count > 1)
> +			buf[1] = (val >> 8) & 0xff;
> +		buf[0] = val & 0xff;
> +	}
> +}
> +
> +static inline int jz4780_efuse_chunk_size(size_t count)
> +{
> +	if (count >= 32)
> +		return 32;
> +	else if ((count / 4) > 0)
> +		return (count / 4) * 4;
> +	else
> +		return count % 4;
> +}
> +
> +void jz4780_efuse_read(size_t addr, size_t count, u8 *buf)
> +{
> +	size_t chunk;
> +
> +	while (count > 0) {
> +		chunk = jz4780_efuse_chunk_size(count);
> +		jz4780_efuse_read_chunk(addr, chunk, buf);
> +		addr += chunk;
> +		buf += chunk;
> +		count -= chunk;
> +	}
> +}
> +
> +void jz4780_efuse_init(u32 ahb2_rate)
> +{
> +	void __iomem *regs = (void __iomem *)NEMC_BASE;
> +	u32 rd_adj, rd_strobe, tmp;
> +
> +	rd_adj = (((6500 * (ahb2_rate / 1000000)) / 1000000) + 0xf) / 2;
> +	tmp = (((35000 * (ahb2_rate / 1000000)) / 1000000) - 4) - rd_adj;
> +	rd_strobe = ((tmp + 0xf) / 2 < 7) ? 7 : (tmp + 0xf) / 2;

Can you turn those magic numbers into macros ? Or if they really come
from the datasheet, well ... at least add a comment.

> +	tmp = (rd_adj << EFUSE_EFUCFG_RD_ADJ_BIT) |
> +	      (rd_strobe << EFUSE_EFUCFG_RD_STROBE_BIT);
> +	writel(tmp, regs + EFUSE_EFUCFG);
> +}
> 


-- 
Best regards,
Marek Vasut


More information about the U-Boot mailing list