This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TDA4VM: USB 2.0 host test mode / USB 3.0 host compliance pattern

Part Number: TDA4VM

Hi TI members,

We are using PSDKLA 06.02.

On our custom board, we connect USB0 to an M.2 connector, and SERDES1_LANE1 to another M.2 connector.

Here are some questions:

  1. Is there any command (e.g. devmem2) that can set USB 2.0 host (USB0) to test mode in linux?

      I cannot find related register in TRM.

  2. During compliance test, there is no CP0 or CP1 from the M.2 connector connected to USB 3.0 host (SERDES1_LANE1).

      After connecting M.2 to our test fixture, since USB 3.0 host cannot detect any USB 3.0 device, shouldn't it enter compliance mode and start to generate CP0?

Best regards,

Eric Chen

  • Hi Eric,

    We are checking with the USB developer and will get back to you. 

    Thanks.

  • Hi Praveen,

    Thank you for the reply.

    We will keep trying on our side too.

    Best regards,

    Eric Chen

  • Hi Eric

    What mode is the controller set to in device tree? If dr_mode is to "otg" then controller will not enter host mode till ID pin goes low.
    Can you first force the controller to host mode by setting dr_mode to "host"?

    According to HCCPARAMS2 bit 3 (CTC) of Cadence USB programming guide
    "This bit indicates whether the xHC USB3 Root Hub
    ports support the Compliance Transition Enabled
    (CTE) flag. When this bit is 1 USB3 Root Hub port
    state machine transitions to the Compliance substate
    shall be explicitly enabled software. When this bit is 0.
    USB3 Root Hub port state machine transitions to the
    Compliance substate are automatically enabled."

    On TDAV4, CTS is set to 1 which means Compliance state needs to be triggered by SW.

    From XHCI spec
    "The PORTSC register with the PLS field set to Compliance Mode and LWS set to ‘1’ shall set CTE to ‘1’.
    If the Compliance Transition Capability (CTC) flag in the HCCPARAMS2 register = ‘1’, then the xHC
    supports software control of the transition to the Compliance state and Compliance Transition Enabled
    (CTE) flags. The CTE flag is an internal xHCI flag associated with each Root Hub port, i.e. CTE is not
    software visible. If CTE = ‘1’ then the transition path to the Compliance substate shall be enabled,
    otherwise the transition is disabled. Upon Chip Hardware Reset, the assertion of HCRST = ‘1’, or a Warm
    Reset (WPR = ‘1’), CTE shall be cleared to ‘0’. Only if the port is in the Disconnected state, then a write to
    the PORTSC register with the PLS field set to Compliance Mode and LWS set to ‘1’ shall set CTE to ‘1’.
    If CTE = ‘1’, then the detection of the first LFPS Timeout shall transition the substate to the Compliance
    state."


    In Linux the compliance mode can be enabled through debugfs.

    e.g.

    echo compliance > /sys/kernel/debug/usb/xhci/xhci-hcd.x.auto/ports/port0y/portsc


    Make sure x and y match the super speed port in your case. There will be 2 ports per controller one is for high-speed and one is for super-speed.

    regards,
    Roger.

  • Hi Roger,

    Thank you for the reply.

    We use SERDES1 LANE1 as USB 3.0 host.

    In our dtsi file:

    ...
                    usb1: usb@6400000 {
                            compatible = "cdns,usb3";
                            reg = <0x00 0x6400000 0x00 0x10000>,
                                  <0x00 0x6410000 0x00 0x10000>,
                                  <0x00 0x6420000 0x00 0x10000>;
                            reg-names = "otg", "xhci", "dev";
                            interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>, /* irq.0 */
                                         <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>, /* irq.6 */
                                         <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>; /* otgirq.0 */
                            interrupt-names = "host",
                                              "peripheral",
                                              "otg";
                            maximum-speed = "super-speed";
                            dr_mode = "otg";
                    };
    ...

    And in our dts file:

    ...
    &usb1 {
            dr_mode = "host";
            maximum-speed = "super-speed";
            phys = <&serdes1_pcie_link>;
            phy-names = "cdns3,usb3-phy";
    };
    ...

    It seems that the dr_mode is already set to "host".

    Before I plug the USB 3.0 module in the M.2 connector:

    root@j7-evm:~# cat /sys/kernel/debug/usb/xhci/xhci-hcd.3.auto/ports/port02/portsc
    Powered Not-connected Disabled Link:RxDetect PortSpeed:0 Change: Wake: WCE WOE

    After I plug the USB 3.0 module in the M.2 connector:

    root@j7-evm:~# cat /sys/kernel/debug/usb/xhci/xhci-hcd.3.auto/ports/port02/portsc
    Powered Connected Enabled Link:U3 PortSpeed:4 Change: Wake: WDE WOE

    I tried the command when the USB 3.0 module is disconnected, but it seems that nothing is changed.

    root@j7-evm:~# echo compliance > /sys/kernel/debug/usb/xhci/xhci-hcd.3.auto/ports/port02/portsc
    root@j7-evm:~# cat /sys/kernel/debug/usb/xhci/xhci-hcd.3.auto/ports/port02/portsc
    Powered Not-connected Disabled Link:RxDetect PortSpeed:0 Change: Wake: WCE WOE

    Am I missing something here?

    Best regards,

    Eric Chen

  • Hi Eric,

    On TI EVM we use USB0 but you seem to be using USB1. That is fine but we need to ensure that you have made all required changes in the device tree.

    Can you please attach your full device tree file? We need to look for something like below.

    &usb_serdes_mux {
            idle-states = <1>, <0>; /* USB0 to SERDES3, USB1 to SERDES1 */
    };
    
    &serdes_ln_ctrl {
            idle-states = ..
                          <SERDES1_LANE0_USB3_1_SWAP>, <SERDES1_LANE1_USB3_1>,
    ..
    };

    What about port power for the USB device. Is the device on M.2 self powered?

    Are you able to check enumeration of the USB device on Linux?

  • Hi Roger,

    Thank you for the quick reply.

    I might not be able to post the whole file here.

    Can I directly mail you the files?

    If you need other information, please let me know.

    Here are the nodes you are looking for.

    &usb_serdes_mux {
            idle-states = <1>, <0>; /* USB0 to SERDES3, USB1 to SERDES1 */
    };
    
    ...
    
    &serdes_ln_ctrl {
            idle-states = <SERDES0_LANE0_PCIE0_LANE0>, <SERDES0_LANE1_QSGMII_LANE2>,
                          <SERDES1_LANE0_PCIE1_LANE0>, <SERDES1_LANE1_USB3_1>,
                          <SERDES2_LANE0_PCIE2_LANE0>, <SERDES2_LANE1_PCIE2_LANE1>,
                          <SERDES3_LANE0_USB3_0_SWAP>, <SERDES3_LANE1_USB3_0>,
                          <SERDES4_LANE0_EDP_LANE0>, <SERDES4_LANE1_EDP_LANE1>, <SERDES4_LANE2_EDP_LANE2>, <SERDES4_LANE3_EDP_LANE3>;
    };

    The USB device is powered by TDA4.

    The result of lsusb is as below.

    root@j7-evm:~# lsusb
    Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
    Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
    Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
    Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

    If the USB device is plugged in, it will be on Bus 004.

    Best regards,

    Eric Chen

  • Eric,

    I'm sorry I'm a bit confused. Do you want to test USB0 or USB1?

    For debugging let's first focus on just one USB controller. You can disable the other controller by adding status = "disabled" in the device tree node.

    On TI EVMs we have used USB0 instance for USB3.0. Are you able to first test on USB0?

    Please email me the device tree and schematics for USB section to rogerq@ti.com .

    Your serdes_ln_ctrl is wrong on the 2nd row.

    It should be

    <SERDES1_LANE0_USB3_1_SWAP>, <SERDES1_LANE1_USB3_1>,

    instead of

    <SERDES1_LANE0_PCIE1_LANE0>, <SERDES1_LANE1_USB3_1>,

    cheers,

    -roger

  • Hi Roger,

    I am sorry for not clarifying.

    We want to test USB1 only.

    We are not using USB0 on the custom board as you can see in the partial schematics attached in the mail.

    I will try to correct the serdes_ln_ctrl first.

    Thank you.

    Best regards,

    Eric Chen

  • Hi Roger,

    I summarize the status so far as below.

      - USB0 is connected to a M.2 connector though USB port, not SERDES3.

      - USB1 is connected to another M.2 connector through SERDES1.

    With the unmodified dts file (USB0 is not fixed to 2.0 only mode and PCIe on SERDES1 is not disabled):

      - USB0 works fine in high-speed and seems to be able to enter test mode successfully.

      - USB1 works fine in super-speed but cannot enter test mode.

      - We are not attempt to use PCIe and USB1 on SERDES1 at the same time so far.

        We just didn't disable PCIe on SERDES1, and somehow USB1 still works.

    With the modified dts file (USB0 is fixed to 2.0 only mode and PCIe on SERDES1 is disabled)

      - To be test

    If there is anything confusing, please let me know.

    Thank you.

    Best regards,

    Eric Chen

  • Here is the reply from USB IP team

    "Compliance state entry differs for Device and Host modes as per the spec.

    Procedure to follow to enter Compliance mode:
     
    Device:

        Power-On the Device (Compliance entry is enabled only for the very first Polling.LFPS handshake fail after power-on)
        Connect Scope that is able to perform USB3 Compliance Testing
            Scope has implemented sequence described in USB3 spec (e.g. provide VBUS, enable Rx termination, force LFPS handshake fail)

    Host:

        Power-On the Host (nothing should be connected to Host’s USB3 Port)
        Enable Compliance mode transition by writing PLS=0xa, LWS=1, PP=1 to PORTSC register
        Connect Scope that is able to perform USB3 Compliance Testing
            Scope has implemented sequence described in USB3 spec (e.g. enable Rx termination, force LFPS handshake fail)
    "

    Since you are using Host mode, writing "compliance" to portsc via debugfs should set PLS to 0xa and LWS to 1.
    I suppose PP will be already be set to 1 by XHCI hub driver.

    Is your Scope implementing the right sequence as per USB3 spec i.e. (e.g. provide VBUS, enable Rx termination, force LFPS handshake fail)?

    cheers,
    -roger

  • Hi Roger,

    Thank you for the reply.

    I will check the scope with our RF team.

    Is there a way to check the value of PLS, LWS and PP?

    I tried below command with the patch, but it still looks like nothing has changed.

    root@j7-evm:~# cat /sys/kernel/debug/usb/xhci/xhci-hcd.3.auto/ports/port02/portsc
    Powered Not-connected Disabled Link:RxDetect PortSpeed:0 Change: Wake: WCE WOE
    root@j7-evm:~# echo compliance > /sys/kernel/debug/usb/xhci/xhci-hcd.3.auto/ports/port02/portsc
    root@j7-evm:~# cat /sys/kernel/debug/usb/xhci/xhci-hcd.3.auto/ports/port02/portsc
    Powered Not-connected Disabled Link:RxDetect PortSpeed:0 Change: Wake: WCE WOE

    Best regards,

    Eric Chen

  • Eric,

    Reading portsc doesn't show PLS. But we can see raw PORTSC with attached patch. Can you please try it out?

    Also how do you know you are setting the right portsc, Can you set compliance on all ports just to be sure?

    portsc-show.patch.gz

  • Hi Roger,

    Thanks for the patch.

    I will try it.

    As I mentioned in this post, only this portsc changed if I plug in our USB 3.0 module.

    Does this mean the portsc is the right one?

    Just in case, I also wrote "compliance" to the other three portsc, but the result seems to be the same.

    Best regards,

    Eric Chen

  • Hi Roger,

    Here are the values from portsc, and the modified dts you sent is applied.

    Both USB 2.0 and 3.0 modules are plug in the M.2 connectors respectively.

    The USB 3.0 module is detected on xhci-hcd.3.auto port02.

    The USB 2.0 module is not detected.

    root@j7-evm:~# cat /sys/kernel/debug/usb/xhci/xhci-hcd.2.auto/ports/port01/portsc
    PORTSC = 0xa0002a0
    Powered Not-connected Disabled Link:RxDetect PortSpeed:0 Change: Wake: WCE WOE
    
    root@j7-evm:~# cat /sys/kernel/debug/usb/xhci/xhci-hcd.2.auto/ports/port02/portsc
    PORTSC = 0xa0002a0
    Powered Not-connected Disabled Link:RxDetect PortSpeed:0 Change: Wake: WCE WOE
    
    root@j7-evm:~# cat /sys/kernel/debug/usb/xhci/xhci-hcd.3.auto/ports/port01/portsc
    PORTSC = 0xa0002a0
    Powered Not-connected Disabled Link:RxDetect PortSpeed:0 Change: Wake: WCE WOE
    
    root@j7-evm:~# cat /sys/kernel/debug/usb/xhci/xhci-hcd.3.auto/ports/port02/portsc
    PORTSC = 0xc001263
    Powered Connected Enabled Link:U3 PortSpeed:4 Change: Wake: WDE WOE

    Both USB 2.0 and 3.0 modules are disconnected from the M.2 connectors.

    root@j7-evm:~# cat /sys/kernel/debug/usb/xhci/xhci-hcd.2.auto/ports/port01/portsc
    PORTSC = 0xa0002a0
    Powered Not-connected Disabled Link:RxDetect PortSpeed:0 Change: Wake: WCE WOE
    
    root@j7-evm:~# cat /sys/kernel/debug/usb/xhci/xhci-hcd.2.auto/ports/port02/portsc
    PORTSC = 0xa0002a0
    Powered Not-connected Disabled Link:RxDetect PortSpeed:0 Change: Wake: WCE WOE
    
    root@j7-evm:~# cat /sys/kernel/debug/usb/xhci/xhci-hcd.3.auto/ports/port01/portsc
    PORTSC = 0xa0002a0
    Powered Not-connected Disabled Link:RxDetect PortSpeed:0 Change: Wake: WCE WOE
    
    root@j7-evm:~# cat /sys/kernel/debug/usb/xhci/xhci-hcd.3.auto/ports/port02/portsc
    PORTSC = 0xa0002a0
    Powered Not-connected Disabled Link:RxDetect PortSpeed:0 Change: Wake: WCE WOE

    And writing "compliance" to all 4 portsc still makes no difference.

    The values are still all 0xa0002a0.

    I have 2 questions here.

      1. "ti,usb2-only" is already in the usbss0 DT node when you sent me the modified dts file.

          Why is USB 2.0 module undetected?

          If I use the original dts file, the value from xhci-hcd.2.auto port01 will be as below.

    root@j7-evm:/boot# cat /sys/kernel/debug/usb/xhci/xhci-hcd.2.auto/ports/port01/portsc
    PORTSC = 0x603
    Powered Connected Enabled Link:U0 PortSpeed:1 Change: Wake:

      2. In the modified dts file, all PCIe instances are disabled.

          Does this mean that, for example, PCIe on SERDES0 might influence USB function on SERDES1?

          If it does not, why not just disable PCIe on SERDES1?

    Best regards,

    Eric Chen

  • Hi Eric,

    Sorry for the delay. I'm not sure why USB2.0 module is not being detected in one case but being detected in the other. Maybe looking at diff of dtb converted to DT using dtc will give some idea?

    SERDES0 and SERDES1 are independent so you can disable PCIe on SERDES that is not being used for USB.

    Did you have any luck with this?

    regards,
    Roger

  • Hi Roger,

    Thanks for the reply.

    I will check the dtb and try to make some adjustment.

    SERDES0 and SERDES1 are independent so you can disable PCIe on SERDES that is not being used for USB.

    Does this mean that I can disable PCIe1 on SERDES1 only? Since we need the PCIe0 function on SERDES0 at the same time.

    Best regards,

    Eric Chen

  • Eric,

    Yes PCIe0 can use SERDES0 and PCIe1 is disabled. To summarize you are using the below configuration

    SERDES0 -> PCIe0

    SERDES1 -> USB1

    SERDES2 -> unused

    SERDES3 -> unused

    PCIE1 -> disabled

    can you please send me your working and non working dtb for USB0 in 2.0 mode?

    regards,
    Roger

  • Hi Roger,

    Thanks for the reply.

    Actually, we use SERDES2 as PCIe too.

    I didn't mention the usage of SERDES2 before since I think it doesn't matter.

    The other parts of your summary are correct.

    I will send you the dtb by mail.

    Thank you.

    Best regards,

    Eric Chen

  • Eric,

    We are working on getting compliance pattern on Linux. We were relying on baremetal code for this so far. I will post some updates by next week.

    cheers,
    -roger