usb: mtu3: add feature to disable device's usb3 port
authorChunfeng Yun <chunfeng.yun@mediatek.com>
Fri, 8 Jul 2022 07:19:01 +0000 (15:19 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 8 Jul 2022 12:53:23 +0000 (14:53 +0200)
We may want to disable device's usb3 port when the combo phy is switched
from usb3 mode to pcie mode for some projects.
Meanwhile rename member @is_u3_ip to @u3_capable to avoid misleading, due
to the member's value may be changed when disable usb3 port, but the
controller is still a usb3 IP which also tells us how to manage the fifo.

Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
Link: https://lore.kernel.org/r/20220708071903.25752-3-chunfeng.yun@mediatek.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/mtu3/mtu3.h
drivers/usb/mtu3/mtu3_core.c
drivers/usb/mtu3/mtu3_plat.c

index 8408e1b..2d7b57e 100644 (file)
@@ -317,6 +317,7 @@ static inline struct ssusb_mtk *dev_to_ssusb(struct device *dev)
  * @ep0_req: dummy request used while handling standard USB requests
  *             for GET_STATUS and SET_SEL
  * @setup_buf: ep0 response buffer for GET_STATUS and SET_SEL requests
+ * @u3_capable: is capable of supporting USB3
  */
 struct mtu3 {
        spinlock_t lock;
@@ -353,11 +354,12 @@ struct mtu3 {
        unsigned softconnect:1;
        unsigned u1_enable:1;
        unsigned u2_enable:1;
-       unsigned is_u3_ip:1;
+       unsigned u3_capable:1;
        unsigned delayed_status:1;
        unsigned gen2cp:1;
        unsigned connected:1;
        unsigned async_callbacks:1;
+       unsigned separate_fifo:1;
 
        u8 address;
        u8 test_mode_nr;
index 3c6a670..0ca173a 100644 (file)
@@ -100,7 +100,7 @@ static int mtu3_device_enable(struct mtu3 *mtu)
 
        mtu3_clrbits(ibase, U3D_SSUSB_IP_PW_CTRL2, SSUSB_IP_DEV_PDN);
 
-       if (mtu->is_u3_ip) {
+       if (mtu->u3_capable) {
                check_clk = SSUSB_U3_MAC_RST_B_STS;
                mtu3_clrbits(ibase, SSUSB_U3_CTRL(0),
                        (SSUSB_U3_PORT_DIS | SSUSB_U3_PORT_PDN |
@@ -112,7 +112,7 @@ static int mtu3_device_enable(struct mtu3 *mtu)
 
        if (mtu->ssusb->dr_mode == USB_DR_MODE_OTG) {
                mtu3_setbits(ibase, SSUSB_U2_CTRL(0), SSUSB_U2_PORT_OTG_SEL);
-               if (mtu->is_u3_ip)
+               if (mtu->u3_capable)
                        mtu3_setbits(ibase, SSUSB_U3_CTRL(0),
                                     SSUSB_U3_PORT_DUAL_MODE);
        }
@@ -124,7 +124,7 @@ static void mtu3_device_disable(struct mtu3 *mtu)
 {
        void __iomem *ibase = mtu->ippc_base;
 
-       if (mtu->is_u3_ip)
+       if (mtu->u3_capable)
                mtu3_setbits(ibase, SSUSB_U3_CTRL(0),
                        (SSUSB_U3_PORT_DIS | SSUSB_U3_PORT_PDN));
 
@@ -133,7 +133,7 @@ static void mtu3_device_disable(struct mtu3 *mtu)
 
        if (mtu->ssusb->dr_mode == USB_DR_MODE_OTG) {
                mtu3_clrbits(ibase, SSUSB_U2_CTRL(0), SSUSB_U2_PORT_OTG_SEL);
-               if (mtu->is_u3_ip)
+               if (mtu->u3_capable)
                        mtu3_clrbits(ibase, SSUSB_U3_CTRL(0),
                                     SSUSB_U3_PORT_DUAL_MODE);
        }
@@ -146,7 +146,7 @@ static void mtu3_dev_power_on(struct mtu3 *mtu)
        void __iomem *ibase = mtu->ippc_base;
 
        mtu3_clrbits(ibase, U3D_SSUSB_IP_PW_CTRL2, SSUSB_IP_DEV_PDN);
-       if (mtu->is_u3_ip)
+       if (mtu->u3_capable)
                mtu3_clrbits(ibase, SSUSB_U3_CTRL(0), SSUSB_U3_PORT_PDN);
 
        mtu3_clrbits(ibase, SSUSB_U2_CTRL(0), SSUSB_U2_PORT_PDN);
@@ -156,7 +156,7 @@ static void mtu3_dev_power_down(struct mtu3 *mtu)
 {
        void __iomem *ibase = mtu->ippc_base;
 
-       if (mtu->is_u3_ip)
+       if (mtu->u3_capable)
                mtu3_setbits(ibase, SSUSB_U3_CTRL(0), SSUSB_U3_PORT_PDN);
 
        mtu3_setbits(ibase, SSUSB_U2_CTRL(0), SSUSB_U2_PORT_PDN);
@@ -213,7 +213,7 @@ static void mtu3_intr_enable(struct mtu3 *mtu)
        value = SUSPEND_INTR | RESUME_INTR | RESET_INTR;
        mtu3_writel(mbase, U3D_COMMON_USB_INTR_ENABLE, value);
 
-       if (mtu->is_u3_ip) {
+       if (mtu->u3_capable) {
                /* Enable U3 LTSSM interrupts */
                value = HOT_RST_INTR | WARM_RST_INTR |
                        ENTER_U3_INTR | EXIT_U3_INTR;
@@ -273,7 +273,7 @@ static void mtu3_csr_init(struct mtu3 *mtu)
 {
        void __iomem *mbase = mtu->mac_base;
 
-       if (mtu->is_u3_ip) {
+       if (mtu->u3_capable) {
                /* disable LGO_U1/U2 by default */
                mtu3_clrbits(mbase, U3D_LINK_POWER_CONTROL,
                                SW_U1_REQUEST_ENABLE | SW_U2_REQUEST_ENABLE);
@@ -341,7 +341,7 @@ void mtu3_ep_stall_set(struct mtu3_ep *mep, bool set)
 
 void mtu3_dev_on_off(struct mtu3 *mtu, int is_on)
 {
-       if (mtu->is_u3_ip && mtu->speed >= USB_SPEED_SUPER)
+       if (mtu->u3_capable && mtu->speed >= USB_SPEED_SUPER)
                mtu3_ss_func_set(mtu, is_on);
        else
                mtu3_hs_softconn_set(mtu, is_on);
@@ -544,7 +544,7 @@ static void get_ep_fifo_config(struct mtu3 *mtu)
        struct mtu3_fifo_info *rx_fifo;
        u32 fifosize;
 
-       if (mtu->is_u3_ip) {
+       if (mtu->separate_fifo) {
                fifosize = mtu3_readl(mtu->mac_base, U3D_CAP_EPNTXFFSZ);
                tx_fifo = &mtu->tx_fifo;
                tx_fifo->base = 0;
@@ -821,6 +821,10 @@ static irqreturn_t mtu3_irq(int irq, void *data)
 
 static void mtu3_check_params(struct mtu3 *mtu)
 {
+       /* device's u3 port (port0) is disabled */
+       if (mtu->u3_capable && (mtu->ssusb->u3p_dis_msk & BIT(0)))
+               mtu->u3_capable = 0;
+
        /* check the max_speed parameter */
        switch (mtu->max_speed) {
        case USB_SPEED_FULL:
@@ -838,7 +842,7 @@ static void mtu3_check_params(struct mtu3 *mtu)
                break;
        }
 
-       if (!mtu->is_u3_ip && (mtu->max_speed > USB_SPEED_HIGH))
+       if (!mtu->u3_capable && (mtu->max_speed > USB_SPEED_HIGH))
                mtu->max_speed = USB_SPEED_HIGH;
 
        mtu->speed = mtu->max_speed;
@@ -857,10 +861,12 @@ static int mtu3_hw_init(struct mtu3 *mtu)
        mtu->gen2cp = !!(mtu->hw_version >= MTU3_TRUNK_VERS_1003);
 
        value = mtu3_readl(mtu->ippc_base, U3D_SSUSB_IP_DEV_CAP);
-       mtu->is_u3_ip = !!SSUSB_IP_DEV_U3_PORT_NUM(value);
+       mtu->u3_capable = !!SSUSB_IP_DEV_U3_PORT_NUM(value);
+       /* usb3 ip uses separate fifo */
+       mtu->separate_fifo = mtu->u3_capable;
 
        dev_info(mtu->dev, "IP version 0x%x(%s IP)\n", mtu->hw_version,
-               mtu->is_u3_ip ? "U3" : "U2");
+               mtu->u3_capable ? "U3" : "U2");
 
        mtu3_check_params(mtu);
 
index d14494b..42987d0 100644 (file)
@@ -244,6 +244,8 @@ static int get_ssusb_rscs(struct platform_device *pdev, struct ssusb_mtk *ssusb)
        if (ssusb->dr_mode == USB_DR_MODE_UNKNOWN)
                ssusb->dr_mode = USB_DR_MODE_OTG;
 
+       of_property_read_u32(node, "mediatek,u3p-dis-msk", &ssusb->u3p_dis_msk);
+
        if (ssusb->dr_mode == USB_DR_MODE_PERIPHERAL)
                goto out;
 
@@ -255,8 +257,6 @@ static int get_ssusb_rscs(struct platform_device *pdev, struct ssusb_mtk *ssusb)
        }
 
        /* optional property, ignore the error if it does not exist */
-       of_property_read_u32(node, "mediatek,u3p-dis-msk",
-                            &ssusb->u3p_dis_msk);
        of_property_read_u32(node, "mediatek,u2p-dis-msk",
                             &ssusb->u2p_dis_msk);