[PATCH RFC 07/22] usb: dwc3: apple: Adjust vendor-specific registers during init

Sven Peter posted 22 patches 5 months, 2 weeks ago
There is a newer version of this series
[PATCH RFC 07/22] usb: dwc3: apple: Adjust vendor-specific registers during init
Posted by Sven Peter 5 months, 2 weeks ago
From: Hector Martin <marcan@marcan.st>

When tracing Apple's dwc3 driver under our hypervisor and comparing its
MMIO access with their kernel debug output these vendor-specific
registers have been identified. We don't know exactly what these do
or why they are required but without changing these parameters sometimes
USB3 devices don't work or take an additional 5 seconds to be recognized.

Signed-off-by: Hector Martin <marcan@marcan.st>
Co-developed-by: Sven Peter <sven@kernel.org>
Signed-off-by: Sven Peter <sven@kernel.org>
---
 drivers/usb/dwc3/core.c | 17 +++++++++++++++++
 drivers/usb/dwc3/core.h | 18 ++++++++++++++++++
 2 files changed, 35 insertions(+)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index f8013ba2bdc22fa5e719df0841b12b84d9465b62..e018e80778cf39a9981d438c7e54534b26cddf63 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -1366,6 +1366,23 @@ static int dwc3_core_init(struct dwc3 *dwc)
 	 */
 	dwc3_writel(dwc->regs, DWC3_GUID, LINUX_VERSION_CODE);
 
+	/* Apply Apple quirks */
+	if (of_device_is_compatible(dwc->dev->of_node, "apple,t8103-dwc3")) {
+		dwc3_writel(dwc->regs,
+			    APPLE_DWC3_CIO_LFPS_OFFSET,
+			    APPLE_DWC3_CIO_LFPS_OFFSET_VALUE);
+		dwc3_writel(dwc->regs,
+			    APPLE_DWC3_CIO_BW_NGT_OFFSET,
+			    APPLE_DWC3_CIO_BW_NGT_OFFSET_VALUE);
+
+		u32 link_timer = dwc3_readl(dwc->regs, APPLE_DWC3_CIO_LINK_TIMER);
+
+		link_timer &= ~APPLE_DWC3_CIO_PENDING_HP_TIMER;
+		link_timer |= FIELD_PREP(APPLE_DWC3_CIO_PENDING_HP_TIMER,
+					 APPLE_DWC3_CIO_PENDING_HP_TIMER_VALUE);
+		dwc3_writel(dwc->regs, APPLE_DWC3_CIO_LINK_TIMER, link_timer);
+	}
+
 	ret = dwc3_phy_setup(dwc);
 	if (ret)
 		return ret;
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 98e748cc348dfd9de1962c93fcf9f6a6690c2388..1caa46ca8b2ffb74dd3e58b174122e8f8216dd48 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -181,6 +181,24 @@
 
 #define DWC3_LLUCTL(n)		(0xd024 + ((n) * 0x80))
 
+/*
+ * Apple Silicon dwc3 vendor-specific registers
+ *
+ * These registers were identified by tracing XNU's memory access patterns
+ * and correlating them with debug output over serial to determine their names.
+ * We don't exactly know what these do but without these USB3 devices sometimes
+ * don't work.
+ */
+#define APPLE_DWC3_CIO_LFPS_OFFSET 0xcd38
+#define APPLE_DWC3_CIO_LFPS_OFFSET_VALUE 0xf800f80
+
+#define APPLE_DWC3_CIO_BW_NGT_OFFSET 0xcd3c
+#define APPLE_DWC3_CIO_BW_NGT_OFFSET_VALUE 0xfc00fc0
+
+#define APPLE_DWC3_CIO_LINK_TIMER 0xcd40
+#define APPLE_DWC3_CIO_PENDING_HP_TIMER GENMASK(23, 16)
+#define APPLE_DWC3_CIO_PENDING_HP_TIMER_VALUE 0x14
+
 /* Bit fields */
 
 /* Global SoC Bus Configuration INCRx Register 0 */

-- 
2.34.1
Re: [PATCH RFC 07/22] usb: dwc3: apple: Adjust vendor-specific registers during init
Posted by Thinh Nguyen 5 months, 2 weeks ago
Hi,

On Thu, Aug 21, 2025, Sven Peter wrote:
> From: Hector Martin <marcan@marcan.st>
> 
> When tracing Apple's dwc3 driver under our hypervisor and comparing its
> MMIO access with their kernel debug output these vendor-specific
> registers have been identified. We don't know exactly what these do
> or why they are required but without changing these parameters sometimes
> USB3 devices don't work or take an additional 5 seconds to be recognized.
> 
> Signed-off-by: Hector Martin <marcan@marcan.st>
> Co-developed-by: Sven Peter <sven@kernel.org>
> Signed-off-by: Sven Peter <sven@kernel.org>
> ---
>  drivers/usb/dwc3/core.c | 17 +++++++++++++++++
>  drivers/usb/dwc3/core.h | 18 ++++++++++++++++++
>  2 files changed, 35 insertions(+)
> 
> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
> index f8013ba2bdc22fa5e719df0841b12b84d9465b62..e018e80778cf39a9981d438c7e54534b26cddf63 100644
> --- a/drivers/usb/dwc3/core.c
> +++ b/drivers/usb/dwc3/core.c
> @@ -1366,6 +1366,23 @@ static int dwc3_core_init(struct dwc3 *dwc)
>  	 */
>  	dwc3_writel(dwc->regs, DWC3_GUID, LINUX_VERSION_CODE);
>  
> +	/* Apply Apple quirks */
> +	if (of_device_is_compatible(dwc->dev->of_node, "apple,t8103-dwc3")) {
> +		dwc3_writel(dwc->regs,
> +			    APPLE_DWC3_CIO_LFPS_OFFSET,
> +			    APPLE_DWC3_CIO_LFPS_OFFSET_VALUE);
> +		dwc3_writel(dwc->regs,
> +			    APPLE_DWC3_CIO_BW_NGT_OFFSET,
> +			    APPLE_DWC3_CIO_BW_NGT_OFFSET_VALUE);
> +
> +		u32 link_timer = dwc3_readl(dwc->regs, APPLE_DWC3_CIO_LINK_TIMER);
> +
> +		link_timer &= ~APPLE_DWC3_CIO_PENDING_HP_TIMER;
> +		link_timer |= FIELD_PREP(APPLE_DWC3_CIO_PENDING_HP_TIMER,
> +					 APPLE_DWC3_CIO_PENDING_HP_TIMER_VALUE);
> +		dwc3_writel(dwc->regs, APPLE_DWC3_CIO_LINK_TIMER, link_timer);
> +	}
> +
>  	ret = dwc3_phy_setup(dwc);
>  	if (ret)
>  		return ret;
> diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
> index 98e748cc348dfd9de1962c93fcf9f6a6690c2388..1caa46ca8b2ffb74dd3e58b174122e8f8216dd48 100644
> --- a/drivers/usb/dwc3/core.h
> +++ b/drivers/usb/dwc3/core.h
> @@ -181,6 +181,24 @@
>  
>  #define DWC3_LLUCTL(n)		(0xd024 + ((n) * 0x80))
>  
> +/*
> + * Apple Silicon dwc3 vendor-specific registers
> + *
> + * These registers were identified by tracing XNU's memory access patterns
> + * and correlating them with debug output over serial to determine their names.
> + * We don't exactly know what these do but without these USB3 devices sometimes
> + * don't work.
> + */
> +#define APPLE_DWC3_CIO_LFPS_OFFSET 0xcd38
> +#define APPLE_DWC3_CIO_LFPS_OFFSET_VALUE 0xf800f80
> +
> +#define APPLE_DWC3_CIO_BW_NGT_OFFSET 0xcd3c
> +#define APPLE_DWC3_CIO_BW_NGT_OFFSET_VALUE 0xfc00fc0
> +
> +#define APPLE_DWC3_CIO_LINK_TIMER 0xcd40
> +#define APPLE_DWC3_CIO_PENDING_HP_TIMER GENMASK(23, 16)
> +#define APPLE_DWC3_CIO_PENDING_HP_TIMER_VALUE 0x14
> +
>  /* Bit fields */
>  
>  /* Global SoC Bus Configuration INCRx Register 0 */
> 
> -- 
> 2.34.1
> 
> 

This is really great that you got to this point!

For this patch, however, I'd prefer these vendor-specific settings to be
in their own glue driver. I can only imagine more changes will be
introduced in the future with this vendor. See if we can use the new
glue interface in glue.h (some call this the new "flatten" model) when
creating a glue driver.

Thanks,
Thinh
Re: [PATCH RFC 07/22] usb: dwc3: apple: Adjust vendor-specific registers during init
Posted by Sven Peter 5 months, 2 weeks ago
Hi Thinh,

On 22.08.25 00:18, Thinh Nguyen wrote:
> For this patch, however, I'd prefer these vendor-specific settings to be
> in their own glue driver. I can only imagine more changes will be
> introduced in the future with this vendor. See if we can use the new
> glue interface in glue.h (some call this the new "flatten" model) when
> creating a glue driver.

Nice, thanks! Hints like that are exactly what I was hoping for when
I sent this RFC.

When I originally started working on this I tried to use the 
parent/child model but didn't really get anywhere. This flattened model 
looks very useful though.

I think I can even move some of logic from the previous commits to 
dwc3-apple.c if I extend the glue a little bit. I'll see how that works 
out and maybe do that for the next version then.

Thanks,

Sven
Re: [PATCH RFC 07/22] usb: dwc3: apple: Adjust vendor-specific registers during init
Posted by Thinh Nguyen 5 months, 1 week ago
On Sat, Aug 23, 2025, Sven Peter wrote:
> Hi Thinh,
> 
> On 22.08.25 00:18, Thinh Nguyen wrote:
> > For this patch, however, I'd prefer these vendor-specific settings to be
> > in their own glue driver. I can only imagine more changes will be
> > introduced in the future with this vendor. See if we can use the new
> > glue interface in glue.h (some call this the new "flatten" model) when
> > creating a glue driver.
> 
> Nice, thanks! Hints like that are exactly what I was hoping for when
> I sent this RFC.
> 
> When I originally started working on this I tried to use the parent/child
> model but didn't really get anywhere. This flattened model looks very useful
> though.
> 
> I think I can even move some of logic from the previous commits to
> dwc3-apple.c if I extend the glue a little bit. I'll see how that works out
> and maybe do that for the next version then.
> 

That's great! I'll look forward to your updates.

Check this change for inspirations for extending the glue interface:
https://lore.kernel.org/linux-usb/20250815004207.xwv4n6xsat44bydi@synopsys.com/T/#u

Thanks,
Thinh