From: "Peter Chen (CIX)" <peter.chen@kernel.org>
To: Pawel Laszczak <pawell@cadence.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
"linux-usb@vger.kernel.org" <linux-usb@vger.kernel.org>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH] usb: cdnsp: add support for eUSB2v2 port
Date: Mon, 20 Apr 2026 17:01:55 +0800 [thread overview]
Message-ID: <aeXrg/JVB0ys6zsV@nchen-desktop> (raw)
In-Reply-To: <PH7PR07MB95385E1B5FCF45ABE48987CADD2F2@PH7PR07MB9538.namprd07.prod.outlook.com>
On 26-04-20 06:31:59, Pawel Laszczak wrote:
> >On 26-04-17 10:37:31, Pawel Laszczak via B4 Relay wrote:
> >> From: Pawel Laszczak <pawell@cadence.com>
> >>
> >> The Cadence CDNSP controller optionally supports eUSB2 (embedded USB2)
> >> port. While this port type operates logically like high-speed USB 2.0,
> >> it utilizes a different physical layer signaling.
> >>
> >> This patch:
> >> - Extends the port detection logic to recognize the eUSB2 protocol.
> >> - Tracks the eUSB2 port offset in the cdnsp_device structure.
> >> - Ensures that eUSB2 ports are correctly handled during Link State
> >> transitions, specifically forcing L0 when LPM is capable, similar
> >> to standard USB 2.0 ports.
> >>
> >> Signed-off-by: Pawel Laszczak <pawell@cadence.com>
Except one extra blank space, others are okay for me.
Acked-by: Peter Chen <peter.chen@kernel.org>
Peter
> >
> >Pawel, I would like double confirm if you have tested current USB2 and
> >USB3 device mode, basically, I think you did it.
>
> Yes, I've tested.
> >
> >> ---
> >> drivers/usb/cdns3/cdnsp-gadget.c | 49 ++++++++++++++++++---------
> >> drivers/usb/cdns3/cdnsp-gadget.h | 1 +
> >> drivers/usb/cdns3/cdnsp-mem.c | 73 +++++++++++++++++++++++++++-----
> >--------
> >> drivers/usb/cdns3/cdnsp-ring.c | 9 +++--
> >> 4 files changed, 90 insertions(+), 42 deletions(-)
> >>
> >> diff --git a/drivers/usb/cdns3/cdnsp-gadget.c b/drivers/usb/cdns3/cdnsp-
> >gadget.c
> >> index 6b3815f8a6e5..2c71c77e6ec3 100644
> >> --- a/drivers/usb/cdns3/cdnsp-gadget.c
> >> +++ b/drivers/usb/cdns3/cdnsp-gadget.c
> >> @@ -124,20 +124,28 @@ void cdnsp_set_link_state(struct cdnsp_device
> >*pdev,
> >> }
> >>
> >> static void cdnsp_disable_port(struct cdnsp_device *pdev,
> >> - __le32 __iomem *port_regs)
> >> + struct cdnsp_port *port)
> >> {
> >> - u32 temp = cdnsp_port_state_to_neutral(readl(port_regs));
> >> + u32 temp;
> >> +
> >> + if (!port->exist)
> >> + return;
> >>
> >> - writel(temp | PORT_PED, port_regs);
> >> + temp = cdnsp_port_state_to_neutral(readl(&port->regs->portsc));
> >> + writel(temp | PORT_PED, &port->regs->portsc);
> >> }
> >
> >Why above changes are added, is it related to this change?
>
> Changed the function argument allows the function to verify the port's
> existence before accessing registers that might have been removed.
>
> Although the driver can detect three ports (eusb2, USB2.0, and USB3.0),
> either the USB2.0 or the eusb2 port will likely be "removed" from the
> controller, depending on the controller configuration.
> These two ports (eusb2 and USB2.0) will not work simultaneously
> on a single SoC because this two port uses different voltage.
>
> By 'removed', I mean that while the register map remains unchanged,
> the underlying logic will be stripped out to reduce the controller size.
> Both eUSB2 and USB2.0 ports have their own dedicated register groups.
>
>
> >>
> >> @@ -1133,6 +1131,18 @@ static void cdnsp_add_in_port(struct cdnsp_device
> >*pdev,
> >> port_offset = CDNSP_EXT_PORT_OFF(temp);
> >> port_count = CDNSP_EXT_PORT_COUNT(temp);
> >>
> >> + if (port == &pdev->eusb_port) {
> >> + /*
> >> + * If controller has usb2 + eusb port then eusb is as
> >> + * second port
> >> + */
> >
> >What kinds of topology like below usb2 + eusb?
>
> In the case of eUSB2, both USB2.0 and eUSB2 ports will be visible.
> The USB2.0 port appears first. As I mentioned earlier, for eUSB2 SoCs,
> the USB2.0 logic will likely be stripped out, but the port will remain
> visible in the configuration.
>
> >
> >> + if (port_count == 2)
> >> + port_offset++;
> >> +
> >> + if (port_count == 1 && pdev->usb2_port.exist)
> >> + return;
> >> + }
> >> +
> >> trace_cdnsp_port_info(addr, port_offset, port_count, port->maj_rev);
> >>
> >> port->port_num = port_offset;
> >> @@ -1152,13 +1162,10 @@ static int cdnsp_setup_port_arrays(struct
> >cdnsp_device *pdev)
> >> base = &pdev->cap_regs->hc_capbase;
> >> offset = cdnsp_find_next_ext_cap(base, 0,
> >> EXT_CAP_CFG_DEV_20PORT_CAP_ID);
> >> - pdev->port20_regs = base + offset;
> >> -
> >> - offset = cdnsp_find_next_ext_cap(base, 0, D_XEC_CFG_3XPORT_CAP);
> >> - pdev->port3x_regs = base + offset;
> >> + if (offset)
> >> + pdev->port20_regs = base + offset;
> >>
> >> offset = 0;
> >> - base = &pdev->cap_regs->hc_capbase;
> >>
> >> /* Driver expects max 2 extended protocol capability. */
> >> for (i = 0; i < 2; i++) {
> >> @@ -1173,26 +1180,46 @@ static int cdnsp_setup_port_arrays(struct
> >cdnsp_device *pdev)
> >> cdnsp_add_in_port(pdev, &pdev->usb3_port,
> >> base + offset);
> >>
> >> - if (CDNSP_EXT_PORT_MAJOR(temp) == 0x02 &&
> >> - !pdev->usb2_port.port_num)
> >> - cdnsp_add_in_port(pdev, &pdev->usb2_port,
> >> - base + offset);
> >> + if (CDNSP_EXT_PORT_MAJOR(temp) == 0x02) {
> >> + if (!pdev->usb2_port.port_num && pdev->port20_regs)
> >
> >Why "&& pdev->port20_regs" is added?
>
> This additional check for the pdev->port20_regs register group occurs
> only for the USB 2.0 port.
>
> >
> >> + cdnsp_add_in_port(pdev, &pdev->usb2_port,
> >> + base + offset);
> >> +
> >> + if (!pdev->eusb_port.port_num)
> >> + cdnsp_add_in_port(pdev, &pdev->eusb_port,
> >> + base + offset);
> >> + }
> >> }
> >>
> >> - if (!pdev->usb2_port.exist || !pdev->usb3_port.exist) {
> >> - dev_err(pdev->dev, "Error: Only one port detected\n");
> >> + if (!pdev->usb2_port.exist && !pdev->eusb_port.exist &&
> >> + !pdev->usb3_port.exist) {
> >> + dev_err(pdev->dev, "Error: No port detected\n");
> >> return -ENODEV;
> >> }
> >>
> >> - trace_cdnsp_init("Found USB 2.0 ports and USB 3.0 ports.");
> >> + if (pdev->usb2_port.exist) {
> >> + pdev->usb2_port.regs = (struct cdnsp_port_regs __iomem *)
> >> + (&pdev->op_regs->port_reg_base +
> >NUM_PORT_REGS *
> >> + (pdev->usb2_port.port_num - 1));
> >> + trace_cdnsp_init("Found USB 2.0 port.");
> >> + }
> >>
> >> - pdev->usb2_port.regs = (struct cdnsp_port_regs __iomem *)
> >> - (&pdev->op_regs->port_reg_base +
> >NUM_PORT_REGS *
> >> - (pdev->usb2_port.port_num - 1));
> >> + if (pdev->eusb_port.exist) {
> >> + pdev->eusb_port.regs = (struct cdnsp_port_regs __iomem *)
> >> + (&pdev->op_regs->port_reg_base +
> >NUM_PORT_REGS *
> >> + (pdev->eusb_port.port_num - 1));
> >> + trace_cdnsp_init("Found eUSB 2.0 port.");
> >> + }
> >> +
> >> + if (pdev->usb3_port.exist) {
> >> + offset = cdnsp_find_next_ext_cap(base, 0,
> >D_XEC_CFG_3XPORT_CAP);
> >> + pdev->port3x_regs = base + offset;
> >>
> >> - pdev->usb3_port.regs = (struct cdnsp_port_regs __iomem *)
> >> - (&pdev->op_regs->port_reg_base +
> >NUM_PORT_REGS *
> >> - (pdev->usb3_port.port_num - 1));
> >> + pdev->usb3_port.regs = (struct cdnsp_port_regs __iomem *)
> >> + (&pdev->op_regs->port_reg_base +
> >NUM_PORT_REGS *
> >> + (pdev->usb3_port.port_num - 1));
> >> + trace_cdnsp_init("Found USB 3.x port.");
> >
> >One More blank space after "Found"
> >
> >Peter
> >> + }
> >>
> >> return 0;
> >> }
> >> diff --git a/drivers/usb/cdns3/cdnsp-ring.c b/drivers/usb/cdns3/cdnsp-ring.c
> >> index 0758f171f73e..715658c981ff 100644
> >> --- a/drivers/usb/cdns3/cdnsp-ring.c
> >> +++ b/drivers/usb/cdns3/cdnsp-ring.c
> >> @@ -259,7 +259,7 @@ static bool cdnsp_room_on_ring(struct cdnsp_device
> >*pdev,
> >> */
> >> static void cdnsp_force_l0_go(struct cdnsp_device *pdev)
> >> {
> >> - if (pdev->active_port == &pdev->usb2_port && pdev-
> >>gadget.lpm_capable)
> >> + if (pdev->active_port != &pdev->usb3_port && pdev-
> >>gadget.lpm_capable)
> >> cdnsp_set_link_state(pdev, &pdev->active_port->regs->portsc,
> >XDEV_U0);
> >> }
> >>
> >> @@ -763,6 +763,8 @@ static int cdnsp_update_port_id(struct cdnsp_device
> >*pdev, u32 port_id)
> >>
> >> if (port_id == pdev->usb2_port.port_num) {
> >> port = &pdev->usb2_port;
> >> + } else if (port_id == pdev->eusb_port.port_num) {
> >> + port = &pdev->eusb_port;
> >> } else if (port_id == pdev->usb3_port.port_num) {
> >> port = &pdev->usb3_port;
> >> } else {
> >> @@ -779,7 +781,8 @@ static int cdnsp_update_port_id(struct cdnsp_device
> >*pdev, u32 port_id)
> >> cdnsp_enable_slot(pdev);
> >> }
> >>
> >> - if (port_id == pdev->usb2_port.port_num)
> >> + if ((pdev->usb2_port.exist && port_id == pdev->usb2_port.port_num) ||
> >> + (pdev->eusb_port.exist && port_id == pdev->eusb_port.port_num))
> >> cdnsp_set_usb2_hardware_lpm(pdev, NULL, 1);
> >> else
> >> writel(PORT_U1_TIMEOUT(1) | PORT_U2_TIMEOUT(1),
> >> @@ -808,7 +811,7 @@ static void cdnsp_handle_port_status(struct
> >cdnsp_device *pdev,
> >>
> >> port_regs = pdev->active_port->regs;
> >>
> >> - if (port_id == pdev->usb2_port.port_num)
> >> + if (port_id == pdev->usb2_port.port_num || port_id == pdev-
> >>eusb_port.port_num)
> >> port2 = true;
> >>
> >> new_event:
> >>
> >> ---
> >> base-commit: 1c7cc4904160c6fc6377564140062d68a3dc93a0
> >> change-id: 20260417-eusb2v2_upstream-80c5b29a7bba
> >>
> >> Best regards,
> >> --
> >> Pawel Laszczak <pawell@cadence.com>
> >>
> >>
> >
> >--
> >
> >Best regards,
> >Peter
--
Best regards,
Peter
prev parent reply other threads:[~2026-04-20 9:01 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-17 8:37 [PATCH] usb: cdnsp: add support for eUSB2v2 port Pawel Laszczak via B4 Relay
2026-04-18 1:38 ` Peter Chen (CIX)
2026-04-20 6:31 ` Pawel Laszczak
2026-04-20 9:01 ` Peter Chen (CIX) [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aeXrg/JVB0ys6zsV@nchen-desktop \
--to=peter.chen@kernel.org \
--cc=gregkh@linuxfoundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=pawell@cadence.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox