Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7efda99e authored by Mayank Rana's avatar Mayank Rana Committed by Jack Pham
Browse files

dwc3-msm: Readback USB GSI wrapper register after updating



In some of cases, it has been observed that USB GSI wrapper
is trying to access IPA GSI doorbell register which is pending
at bus level whereas USB software has detached SMMU and power
collapse controller. This results into global SMMU page fault.
Fix this issue by reading back USB GSI wrapper register after
updating it to make sure that register write has not buffered
at bus level or cache level. To achieve this, remove
dwc3_msm_write_readback() API usage, readback updated register
with dwc3_msm_write_reg_field() API and replace references of
dwc3_msm_write_readback() API.

Change-Id: Ib77e23d3430cb69a47478618d79851acea5c3c56
Signed-off-by: default avatarMayank Rana <mrana@codeaurora.org>
parent 0ee2387c
Loading
Loading
Loading
Loading
+6 −34
Original line number Diff line number Diff line
@@ -373,34 +373,9 @@ static inline void dwc3_msm_write_reg_field(void __iomem *base, u32 offset,
	tmp &= ~mask;		/* clear written bits */
	val = tmp | (val << shift);
	iowrite32(val, base + offset);
}

/**
 * Write register and read back masked value to confirm it is written
 *
 * @base - DWC3 base virtual address.
 * @offset - register offset.
 * @mask - register bitmask specifying what should be updated
 * @val - value to write.
 *
 */
static inline void dwc3_msm_write_readback(void __iomem *base, u32 offset,
					    const u32 mask, u32 val)
{
	u32 write_val, tmp = ioread32(base + offset);

	tmp &= ~mask;		/* retain other bits */
	write_val = tmp | val;

	iowrite32(write_val, base + offset);

	/* Read back to see if val was written */
	tmp = ioread32(base + offset);
	tmp &= mask;		/* clear other bits */

	if (tmp != val)
		pr_err("%s: write: %x to QSCRATCH: %x FAILED\n",
			__func__, val, offset);
	/* Read back to make sure that previous write goes through */
	ioread32(base + offset);
}

static bool dwc3_msm_is_ss_rhport_connected(struct dwc3_msm *mdwc)
@@ -4033,17 +4008,14 @@ static void dwc3_override_vbus_status(struct dwc3_msm *mdwc, bool vbus_present)
	struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3);

	/* Update OTG VBUS Valid from HSPHY to controller */
	dwc3_msm_write_readback(mdwc->base, HS_PHY_CTRL_REG,
		vbus_present ? UTMI_OTG_VBUS_VALID | SW_SESSVLD_SEL :
		UTMI_OTG_VBUS_VALID,
		vbus_present ? UTMI_OTG_VBUS_VALID | SW_SESSVLD_SEL : 0);
	dwc3_msm_write_reg_field(mdwc->base, HS_PHY_CTRL_REG,
			UTMI_OTG_VBUS_VALID, !!vbus_present);

	/* Update only if Super Speed is supported */
	if (dwc->maximum_speed >= USB_SPEED_SUPER) {
		/* Update VBUS Valid from SSPHY to controller */
		dwc3_msm_write_readback(mdwc->base, SS_PHY_CTRL_REG,
			LANE0_PWR_PRESENT,
			vbus_present ? LANE0_PWR_PRESENT : 0);
		dwc3_msm_write_reg_field(mdwc->base, SS_PHY_CTRL_REG,
			LANE0_PWR_PRESENT, !!vbus_present);
	}
}