[PATCH v4 3/3] usb: cdns3: cdnsp: Enable eUSB2v2 1KB bulk packet capability

From: Pawel Laszczak via B4 Relay

Date: Fri Oct 09 2026 - 02:39:24 EST


From: Pawel Laszczak <pawell@xxxxxxxxxxx>

Implement peripheral-side changes in the Cadence (cdnsp) driver
to support eUSB2v2 1024-byte Bulk MaxPacketSize.

Check the HCC2_E2V2C bit in HCCPARAMS2 during setup and set
'pdev->gadget.is_eusb2v2 = 1' if supported. Delegate the incoming
USB_DEVICE_BULK_MAX_PACKET_UPDATE setup request from ep0 to the
composite layer.

Update cdnsp_endpoint_init() to check the 'eusb2v2_mps_active' flag
set by the gadget framework. If active, dynamically configure the
hardware endpoint for 1024-byte maximum packet size, overriding
the 512-byte value reported in the endpoint descriptor.

Signed-off-by: Pawel Laszczak <pawell@xxxxxxxxxxx>
---
Changes in v4:
- No changes.

Changes in v3:
- cdnsp-mem.c: Use the new gadget->eusb2v2_mps_active flag instead of modifying
ep->desc.wMaxPacketSize. This allows the UDC to determine the correct HS bulk
maximum packet size while letting the composite framework report 512 bytes in
the endpoint descriptor per eUSB2v2 spec section 5.2.

Changes in v2:
- cdnsp-mem.c: simplified HS bulk clamp logic to: if (max_packet != 1024)
max_packet = 512, consistent with xhci-mem.c.
---
drivers/usb/cdns3/cdnsp-ep0.c | 2 ++
drivers/usb/cdns3/cdnsp-gadget.c | 4 ++++
drivers/usb/cdns3/cdnsp-gadget.h | 8 ++++++++
drivers/usb/cdns3/cdnsp-mem.c | 9 +++++++--
drivers/usb/common/debug.c | 2 ++
5 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/cdns3/cdnsp-ep0.c b/drivers/usb/cdns3/cdnsp-ep0.c
index 5cd9b898ce97..090d20b307ee 100644
--- a/drivers/usb/cdns3/cdnsp-ep0.c
+++ b/drivers/usb/cdns3/cdnsp-ep0.c
@@ -253,6 +253,8 @@ static int cdnsp_ep0_handle_feature_device(struct cdnsp_device *pdev,
*/
cdnsp_enter_test_mode(pdev);
break;
+ case USB_DEVICE_BULK_MAX_PACKET_UPDATE:
+ return cdnsp_ep0_delegate_req(pdev, ctrl);
default:
return -EINVAL;
}
diff --git a/drivers/usb/cdns3/cdnsp-gadget.c b/drivers/usb/cdns3/cdnsp-gadget.c
index a5275c2fb43b..ac1dde43ce1d 100644
--- a/drivers/usb/cdns3/cdnsp-gadget.c
+++ b/drivers/usb/cdns3/cdnsp-gadget.c
@@ -1853,6 +1853,10 @@ static int cdnsp_gen_setup(struct cdnsp_device *pdev)
pdev->hcc_params = readl(&pdev->cap_regs->hc_capbase);
pdev->hci_version = HC_VERSION(pdev->hcc_params);
pdev->hcc_params = readl(&pdev->cap_regs->hcc_params);
+ pdev->hcc_params2 = readl(&pdev->cap_regs->hcc_params2);
+
+ if (pdev->hcc_params2 & HCC2_E2V2C)
+ pdev->gadget.is_eusb2v2 = 1;

/*
* Override the APB timeout value to give the controller more time for
diff --git a/drivers/usb/cdns3/cdnsp-gadget.h b/drivers/usb/cdns3/cdnsp-gadget.h
index c44bca348a41..75bc3f15bde5 100644
--- a/drivers/usb/cdns3/cdnsp-gadget.h
+++ b/drivers/usb/cdns3/cdnsp-gadget.h
@@ -89,6 +89,12 @@ struct cdnsp_cap_regs {

#define CTX_SIZE(_hcc) (HCC_64BYTE_CONTEXT(_hcc) ? 64 : 32)

+/* HCCPARAMS2 - hcc_params2 - bitmasks */
+/* bit 11 - DC support Double BW on a eUSB2 HS ISOC EP */
+#define HCC2_EUSB2_DIC BIT(11)
+/* bit 12 - DC support eUSB2V2 capability */
+#define HCC2_E2V2C BIT(12)
+
/* db_off bitmask - bits 0:1 reserved. */
#define DBOFF_MASK GENMASK(31, 2)

@@ -1370,6 +1376,7 @@ struct cdnsp_port {
* @rev_cap: Controller Capabilities Registers.
* @hcs_params1: Cached register copies of read-only HCSPARAMS1
* @hcc_params: Cached register copies of read-only HCCPARAMS1
+ * @hcc_params2: Cached register copies of read-only HCCPARAMS2
* @rtl_revision: Cached controller rtl revision.
* @setup: Temporary buffer for setup packet.
* @ep0_preq: Internal allocated request used during enumeration.
@@ -1425,6 +1432,7 @@ struct cdnsp_device {
__u32 hcs_params1;
__u32 hcs_params3;
__u32 hcc_params;
+ __u32 hcc_params2;
#define RTL_REVISION_NEW_LPM 0x2700
__u32 rtl_revision;
/* Lock used in interrupt thread context. */
diff --git a/drivers/usb/cdns3/cdnsp-mem.c b/drivers/usb/cdns3/cdnsp-mem.c
index 5d8cdc91927d..8892767942a7 100644
--- a/drivers/usb/cdns3/cdnsp-mem.c
+++ b/drivers/usb/cdns3/cdnsp-mem.c
@@ -978,8 +978,13 @@ int cdnsp_endpoint_init(struct cdnsp_device *pdev,
if (!usb_endpoint_xfer_isoc(pep->endpoint.desc))
err_count = 3;
if (usb_endpoint_xfer_bulk(pep->endpoint.desc) &&
- pdev->gadget.speed == USB_SPEED_HIGH)
- max_packet = 512;
+ pdev->gadget.speed == USB_SPEED_HIGH) {
+ if (pdev->gadget.eusb2v2_mps_active)
+ max_packet = 1024;
+ else
+ max_packet = 512;
+ }
+
/* Controller spec indicates that ctrl ep avg TRB Length should be 8. */
if (usb_endpoint_xfer_control(pep->endpoint.desc))
avg_trb_len = 8;
diff --git a/drivers/usb/common/debug.c b/drivers/usb/common/debug.c
index f204cec8d380..b9696fae7ef5 100644
--- a/drivers/usb/common/debug.c
+++ b/drivers/usb/common/debug.c
@@ -46,6 +46,8 @@ static const char *usb_decode_device_feature(u16 wValue)
return "U2 Enable";
case USB_DEVICE_LTM_ENABLE:
return "LTM Enable";
+ case USB_DEVICE_BULK_MAX_PACKET_UPDATE:
+ return "Bulk mps update";
default:
return "UNKNOWN";
}

--
2.43.0