1 From bb53ca75f9e3631e753f397ccab704a8f975658b Mon Sep 17 00:00:00 2001
2 From: Jonathan Bell <jonathan@raspberrypi.com>
3 Date: Wed, 6 Nov 2024 10:45:24 +0000
4 Subject: [PATCH] usb: dwc3: core: add support for setting NAK enhancement bits
7 If a device frequently NAKs, it can exhaust the scheduled handshakes in
8 a frame. It will then not get polled by the controller until the next
9 frame interval. This is most noticeable on FS devices as the controller
10 schedules a small set of transactions only once per full-speed frame.
12 Setting the ENH_PER_NAK_FS/LS bits in the GUCTL1 register increases the
13 number of transactions that can be scheduled to Async (Control/Bulk)
14 endpoints in the respective frame time. In the FS case, this only
15 applies to FS devices directly connected to root ports.
17 Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
19 drivers/usb/dwc3/core.c | 10 ++++++++++
20 drivers/usb/dwc3/core.h | 6 ++++++
21 2 files changed, 16 insertions(+)
23 --- a/drivers/usb/dwc3/core.c
24 +++ b/drivers/usb/dwc3/core.c
25 @@ -1366,6 +1366,12 @@ static int dwc3_core_init(struct dwc3 *d
26 if (dwc->dis_tx_ipgap_linecheck_quirk)
27 reg |= DWC3_GUCTL1_TX_IPGAP_LINECHECK_DIS;
29 + if (dwc->enh_nak_fs_quirk)
30 + reg |= DWC3_GUCTL1_NAK_PER_ENH_FS;
32 + if (dwc->enh_nak_hs_quirk)
33 + reg |= DWC3_GUCTL1_NAK_PER_ENH_HS;
35 if (dwc->parkmode_disable_ss_quirk)
36 reg |= DWC3_GUCTL1_PARKMODE_DISABLE_SS;
38 @@ -1669,6 +1675,10 @@ static void dwc3_get_properties(struct d
39 "snps,resume-hs-terminations");
40 dwc->ulpi_ext_vbus_drv = device_property_read_bool(dev,
41 "snps,ulpi-ext-vbus-drv");
42 + dwc->enh_nak_fs_quirk = device_property_read_bool(dev,
43 + "snps,enhanced-nak-fs-quirk");
44 + dwc->enh_nak_hs_quirk = device_property_read_bool(dev,
45 + "snps,enhanced-nak-hs-quirk");
46 dwc->parkmode_disable_ss_quirk = device_property_read_bool(dev,
47 "snps,parkmode-disable-ss-quirk");
48 dwc->parkmode_disable_hs_quirk = device_property_read_bool(dev,
49 --- a/drivers/usb/dwc3/core.h
50 +++ b/drivers/usb/dwc3/core.h
52 #define DWC3_GUCTL1_TX_IPGAP_LINECHECK_DIS BIT(28)
53 #define DWC3_GUCTL1_DEV_FORCE_20_CLK_FOR_30_CLK BIT(26)
54 #define DWC3_GUCTL1_DEV_L1_EXIT_BY_HW BIT(24)
55 +#define DWC3_GUCTL1_NAK_PER_ENH_FS BIT(19)
56 +#define DWC3_GUCTL1_NAK_PER_ENH_HS BIT(18)
57 #define DWC3_GUCTL1_PARKMODE_DISABLE_SS BIT(17)
58 #define DWC3_GUCTL1_PARKMODE_DISABLE_HS BIT(16)
59 #define DWC3_GUCTL1_PARKMODE_DISABLE_FSLS BIT(15)
60 @@ -1118,6 +1120,8 @@ struct dwc3_scratchpad_array {
61 * generation after resume from suspend.
62 * @ulpi_ext_vbus_drv: Set to confiure the upli chip to drives CPEN pin
63 * VBUS with an external supply.
64 + * @enh_nak_fs_quirk: Set to schedule more handshakes to Async FS endpoints.
65 + * @enh_nak_hs_quirk: Set to schedule more handshakes to Async HS endpoints.
66 * @parkmode_disable_ss_quirk: If set, disable park mode feature for all
67 * Superspeed instances.
68 * @parkmode_disable_hs_quirk: If set, disable park mode feature for all
69 @@ -1348,6 +1352,8 @@ struct dwc3 {
70 unsigned dis_tx_ipgap_linecheck_quirk:1;
71 unsigned resume_hs_terminations:1;
72 unsigned ulpi_ext_vbus_drv:1;
73 + unsigned enh_nak_fs_quirk:1;
74 + unsigned enh_nak_hs_quirk:1;
75 unsigned parkmode_disable_ss_quirk:1;
76 unsigned parkmode_disable_hs_quirk:1;
77 unsigned parkmode_disable_fsls_quirk:1;