drivers/ufs/host/ufs-amd-versal2.c

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

File Facts

System
Linux kernel
Corpus path
drivers/ufs/host/ufs-amd-versal2.c
Extension
.c
Size
13224 bytes
Lines
562
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_versal2_host {
	struct ufs_hba *hba;
	struct reset_control *rstc;
	struct reset_control *rstphy;
	u32 phy_mode;
	unsigned long host_clk;
	u8 attcompval0;
	u8 attcompval1;
	u8 ctlecompval0;
	u8 ctlecompval1;
};

static int ufs_versal2_phy_reg_write(struct ufs_hba *hba, u32 addr, u32 val)
{
	static struct ufshcd_dme_attr_val phy_write_attrs[] = {
		{ UIC_ARG_MIB(CBCREGADDRLSB), 0, DME_LOCAL },
		{ UIC_ARG_MIB(CBCREGADDRMSB), 0, DME_LOCAL },
		{ UIC_ARG_MIB(CBCREGWRLSB), 0, DME_LOCAL },
		{ UIC_ARG_MIB(CBCREGWRMSB), 0, DME_LOCAL },
		{ UIC_ARG_MIB(CBCREGRDWRSEL), 1, DME_LOCAL },
		{ UIC_ARG_MIB(VS_MPHYCFGUPDT), 1, DME_LOCAL }
	};

	phy_write_attrs[0].mib_val = (u8)addr;
	phy_write_attrs[1].mib_val = (u8)(addr >> 8);
	phy_write_attrs[2].mib_val = (u8)val;
	phy_write_attrs[3].mib_val = (u8)(val >> 8);

	return ufshcd_dwc_dme_set_attrs(hba, phy_write_attrs, ARRAY_SIZE(phy_write_attrs));
}

static int ufs_versal2_phy_reg_read(struct ufs_hba *hba, u32 addr, u32 *val)
{
	u32 mib_val;
	int ret;
	static struct ufshcd_dme_attr_val phy_read_attrs[] = {
		{ UIC_ARG_MIB(CBCREGADDRLSB), 0, DME_LOCAL },
		{ UIC_ARG_MIB(CBCREGADDRMSB), 0, DME_LOCAL },
		{ UIC_ARG_MIB(CBCREGRDWRSEL), 0, DME_LOCAL },
		{ UIC_ARG_MIB(VS_MPHYCFGUPDT), 1, DME_LOCAL }
	};

	phy_read_attrs[0].mib_val = (u8)addr;
	phy_read_attrs[1].mib_val = (u8)(addr >> 8);

	ret = ufshcd_dwc_dme_set_attrs(hba, phy_read_attrs, ARRAY_SIZE(phy_read_attrs));
	if (ret)
		return ret;

	ret = ufshcd_dme_get(hba, UIC_ARG_MIB(CBCREGRDLSB), &mib_val);
	if (ret)
		return ret;

	*val = mib_val;
	ret = ufshcd_dme_get(hba, UIC_ARG_MIB(CBCREGRDMSB), &mib_val);
	if (ret)
		return ret;

	*val |= (mib_val << 8);

	return 0;
}

static int ufs_versal2_enable_phy(struct ufs_hba *hba)
{
	u32 offset, reg;
	int ret;

	ret = ufshcd_dme_set(hba, UIC_ARG_MIB(VS_MPHYDISABLE), 0);
	if (ret)
		return ret;

	ret = ufshcd_dme_set(hba, UIC_ARG_MIB(VS_MPHYCFGUPDT), 1);
	if (ret)
		return ret;

	/* Check Tx/Rx FSM states */
	for (offset = 0; offset < 2; offset++) {
		u32 time_left, mibsel;

		time_left = TIMEOUT_MICROSEC;
		mibsel = UIC_ARG_MIB_SEL(MTX_FSM_STATE, UIC_ARG_MPHY_TX_GEN_SEL_INDEX(offset));
		do {
			ret = ufshcd_dme_get(hba, mibsel, &reg);
			if (ret)
				return ret;

			if (reg == TX_STATE_HIBERN8 || reg == TX_STATE_SLEEP ||
			    reg == TX_STATE_LSBURST)
				break;

Annotation

Implementation Notes