[PATCH 3/5] usb: mtu3: add feature to disable device's usb3 port

From: Chunfeng Yun
Date: Fri Jul 08 2022 - 03:19:29 EST


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@xxxxxxxxxxxx>
---
drivers/usb/mtu3/mtu3.h | 4 +++-
drivers/usb/mtu3/mtu3_core.c | 32 +++++++++++++++++++-------------
drivers/usb/mtu3/mtu3_plat.c | 4 ++--
3 files changed, 24 insertions(+), 16 deletions(-)

diff --git a/drivers/usb/mtu3/mtu3.h b/drivers/usb/mtu3/mtu3.h
index 9893dd1bafbb..388839397142 100644
--- a/drivers/usb/mtu3/mtu3.h
+++ b/drivers/usb/mtu3/mtu3.h
@@ -319,6 +319,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;
@@ -355,11 +356,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;
diff --git a/drivers/usb/mtu3/mtu3_core.c b/drivers/usb/mtu3/mtu3_core.c
index 3c6a670efafa..0ca173af87bb 100644
--- a/drivers/usb/mtu3/mtu3_core.c
+++ b/drivers/usb/mtu3/mtu3_core.c
@@ -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);

diff --git a/drivers/usb/mtu3/mtu3_plat.c b/drivers/usb/mtu3/mtu3_plat.c
index d14494b30064..42987d08ce8c 100644
--- a/drivers/usb/mtu3/mtu3_plat.c
+++ b/drivers/usb/mtu3/mtu3_plat.c
@@ -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);

--
2.18.0