drivers/ufs/host/ufs-renesas.c

Source file repositories/reference/linux-study-clean/drivers/ufs/host/ufs-renesas.c

File Facts

System
Linux kernel
Corpus path
drivers/ufs/host/ufs-renesas.c
Extension
.c
Size
17442 bytes
Lines
559
Domain
Driver Families
Bucket
drivers/ufs
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct ufs_renesas_priv {
	const struct firmware *fw;
	void (*pre_init)(struct ufs_hba *hba);
	bool initialized;	/* The hardware needs initialization once */
	u8 calib[EFUSE_CALIB_SIZE];
};

#define UFS_RENESAS_FIRMWARE_NAME "r8a779f0_ufs.bin"
MODULE_FIRMWARE(UFS_RENESAS_FIRMWARE_NAME);

static void ufs_renesas_dbg_register_dump(struct ufs_hba *hba)
{
	ufshcd_dump_regs(hba, 0xc0, 0x40, "regs: 0xc0 + ");
}

static void ufs_renesas_poll(struct ufs_hba *hba, u32 reg, u32 expected, u32 mask)
{
	int ret;
	u32 val;

	ret = readl_poll_timeout_atomic(hba->mmio_base + reg,
					val, (val & mask) == expected,
					10, 1000);
	if (ret)
		dev_err(hba->dev, "%s: poll failed %d (%08x, %08x, %08x)\n",
			__func__, ret, val, mask, expected);
}

static u32 ufs_renesas_read(struct ufs_hba *hba, u32 reg)
{
	return ufshcd_readl(hba, reg);
}

static void ufs_renesas_write(struct ufs_hba *hba, u32 reg, u32 value)
{
	ufshcd_writel(hba, value, reg);
}

static void ufs_renesas_write_d0_d4(struct ufs_hba *hba, u32 data_d0, u32 data_d4)
{
	ufs_renesas_write(hba, 0xd0, data_d0);
	ufs_renesas_write(hba, 0xd4, data_d4);
}

static void ufs_renesas_write_800_80c_poll(struct ufs_hba *hba, u32 addr,
					   u32 data_800)
{
	ufs_renesas_write_d0_d4(hba, 0x0000080c, 0x00000100);
	ufs_renesas_write_d0_d4(hba, 0x00000800, (data_800 << 16) | BIT(8) | addr);
	ufs_renesas_write(hba, 0xd0, 0x0000080c);
	ufs_renesas_poll(hba, 0xd4, BIT(8), BIT(8));
}

static void ufs_renesas_write_804_80c_poll(struct ufs_hba *hba, u32 addr, u32 data_804)
{
	ufs_renesas_write_d0_d4(hba, 0x0000080c, 0x00000100);
	ufs_renesas_write_d0_d4(hba, 0x00000804, (data_804 << 16) | BIT(8) | addr);
	ufs_renesas_write(hba, 0xd0, 0x0000080c);
	ufs_renesas_poll(hba, 0xd4, BIT(8), BIT(8));
}

static void ufs_renesas_write_828_82c_poll(struct ufs_hba *hba, u32 data_828)
{
	ufs_renesas_write_d0_d4(hba, 0x0000082c, 0x0f000000);
	ufs_renesas_write_d0_d4(hba, 0x00000828, data_828);
	ufs_renesas_write(hba, 0xd0, 0x0000082c);
	ufs_renesas_poll(hba, 0xd4, data_828, data_828);
}

static void ufs_renesas_write_phy(struct ufs_hba *hba, u32 addr16, u32 data16)
{
	ufs_renesas_write(hba, 0xf0, 1);
	ufs_renesas_write_800_80c_poll(hba, 0x16, addr16 & 0xff);
	ufs_renesas_write_800_80c_poll(hba, 0x17, (addr16 >> 8) & 0xff);
	ufs_renesas_write_800_80c_poll(hba, 0x18, data16 & 0xff);
	ufs_renesas_write_800_80c_poll(hba, 0x19, (data16 >> 8) & 0xff);
	ufs_renesas_write_800_80c_poll(hba, 0x1c, 0x01);
	ufs_renesas_write_828_82c_poll(hba, 0x0f000000);
	ufs_renesas_write(hba, 0xf0, 0);
}

static void ufs_renesas_set_phy(struct ufs_hba *hba, u32 addr16, u32 data16)
{
	u32 low, high;

	ufs_renesas_write(hba, 0xf0, 1);
	ufs_renesas_write_800_80c_poll(hba, 0x16, addr16 & 0xff);
	ufs_renesas_write_800_80c_poll(hba, 0x17, (addr16 >> 8) & 0xff);
	ufs_renesas_write_800_80c_poll(hba, 0x1c, 0x01);
	ufs_renesas_write_828_82c_poll(hba, 0x0f000000);

Annotation

Implementation Notes