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

Commit 375bf771 authored by Hemant Kumar's avatar Hemant Kumar
Browse files

usb: dwc3: Add API to read back after register write



Write memory barrier can be used to ensure that the write buffer
on the processor has completed its operation before subsequent
operations can be started. However, it does not check the status
of the bus level write buffers. In case a device memory write
needs to complete an operation without waiting for next write to
same device memory region (which flushes previous write), it is
recommended to perform a read back right after write operation.
This eliminates the need to add memory barrier and also makes
sure bus level write buffer gets flushed.

Change-Id: I3af062be6eab65bb264f1a4d030672aa0c5f6b9a
Signed-off-by: default avatarHemant Kumar <hemantk@codeaurora.org>
parent 6f1c8202
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -64,4 +64,28 @@ static inline void dwc3_writel(void __iomem *base, u32 offset, u32 value)
			base - DWC3_GLOBALS_REGS_START + offset, value);
}

static inline void dwc3_masked_write_readback(void __iomem *base,
	u32 offset, const u32 mask, u32 value)
{
	u32 write_val, tmp;

	tmp = readl_relaxed(base + offset - DWC3_GLOBALS_REGS_START);
	tmp &= ~mask;		/* retain other bits */
	write_val = tmp | value;

	writel_relaxed(write_val, base + offset - DWC3_GLOBALS_REGS_START);

	/* Read back to see if value was written */
	tmp = readl_relaxed(base + offset);

	dwc3_trace(trace_dwc3_masked_write_readback,
			"addr %p readback val %08x",
			base - DWC3_GLOBALS_REGS_START + offset, tmp);

	tmp &= mask;		/* clear other bits */
	if (tmp != value)
		pr_err("%s: write: %x to %x FAILED\n",
			__func__, value, offset);
}

#endif /* __DRIVERS_USB_DWC3_IO_H */
+5 −0
Original line number Diff line number Diff line
@@ -47,6 +47,11 @@ DEFINE_EVENT(dwc3_log_msg, dwc3_writel,
	TP_ARGS(vaf)
);

DEFINE_EVENT(dwc3_log_msg, dwc3_masked_write_readback,
	TP_PROTO(struct va_format *vaf),
	TP_ARGS(vaf)
);

DEFINE_EVENT(dwc3_log_msg, dwc3_gadget,
	TP_PROTO(struct va_format *vaf),
	TP_ARGS(vaf)