Commit 4c5964b4 authored by Chunfeng Yun's avatar Chunfeng Yun Committed by Greg Kroah-Hartman

usb: mtu3: fix transfer error of USB3 Gen2 isoc

To support USB3 Gen2 ISOC, the registers of TXCSR1 and RXCSR1
are adjusted to support greater maxpkt and mult value, this
patch fix this issue
Signed-off-by: default avatarChunfeng Yun <chunfeng.yun@mediatek.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 918f0f23
......@@ -62,6 +62,15 @@ struct mtu3_request;
#define MTU3_U3_IP_SLOT_DEFAULT 2
#define MTU3_U2_IP_SLOT_DEFAULT 1
/**
* IP TRUNK version
* from 0x1003 version, USB3 Gen2 is supported, two changes affect driver:
* 1. MAXPKT and MULTI bits layout of TXCSR1 and RXCSR1 are adjusted,
* but not backward compatible
* 2. QMU extend buffer length supported
*/
#define MTU3_TRUNK_VERS_1003 0x1003
/**
* Normally the device works on HS or SS, to simplify fifo management,
* devide fifo into some 512B parts, use bitmap to manage it; And
......@@ -316,6 +325,7 @@ static inline struct ssusb_mtk *dev_to_ssusb(struct device *dev)
* @may_wakeup: means device's remote wakeup is enabled
* @is_self_powered: is reported in device status and the config descriptor
* @delayed_status: true when function drivers ask for delayed status
* @gen2cp: compatible with USB3 Gen2 IP
* @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
......@@ -356,6 +366,7 @@ struct mtu3 {
unsigned u2_enable:1;
unsigned is_u3_ip:1;
unsigned delayed_status:1;
unsigned gen2cp:1;
u8 address;
u8 test_mode_nr;
......
......@@ -299,6 +299,7 @@ int mtu3_config_ep(struct mtu3 *mtu, struct mtu3_ep *mep,
int interval, int burst, int mult)
{
void __iomem *mbase = mtu->mac_base;
bool gen2cp = mtu->gen2cp;
int epnum = mep->epnum;
u32 csr0, csr1, csr2;
int fifo_sgsz, fifo_addr;
......@@ -319,7 +320,7 @@ int mtu3_config_ep(struct mtu3 *mtu, struct mtu3_ep *mep,
num_pkts = (burst + 1) * (mult + 1) - 1;
csr1 = TX_SS_BURST(burst) | TX_SLOT(mep->slot);
csr1 |= TX_MAX_PKT(num_pkts) | TX_MULT(mult);
csr1 |= TX_MAX_PKT(gen2cp, num_pkts) | TX_MULT(gen2cp, mult);
csr2 = TX_FIFOADDR(fifo_addr >> 4);
csr2 |= TX_FIFOSEGSIZE(fifo_sgsz);
......@@ -355,7 +356,7 @@ int mtu3_config_ep(struct mtu3 *mtu, struct mtu3_ep *mep,
num_pkts = (burst + 1) * (mult + 1) - 1;
csr1 = RX_SS_BURST(burst) | RX_SLOT(mep->slot);
csr1 |= RX_MAX_PKT(num_pkts) | RX_MULT(mult);
csr1 |= RX_MAX_PKT(gen2cp, num_pkts) | RX_MULT(gen2cp, mult);
csr2 = RX_FIFOADDR(fifo_addr >> 4);
csr2 |= RX_FIFOSEGSIZE(fifo_sgsz);
......@@ -749,13 +750,14 @@ static irqreturn_t mtu3_irq(int irq, void *data)
static int mtu3_hw_init(struct mtu3 *mtu)
{
u32 cap_dev;
u32 value;
int ret;
mtu->hw_version = mtu3_readl(mtu->ippc_base, U3D_SSUSB_HW_ID);
value = mtu3_readl(mtu->ippc_base, U3D_SSUSB_IP_TRUNK_VERS);
mtu->hw_version = IP_TRUNK_VERS(value);
cap_dev = mtu3_readl(mtu->ippc_base, U3D_SSUSB_IP_DEV_CAP);
mtu->is_u3_ip = !!SSUSB_IP_DEV_U3_PORT_NUM(cap_dev);
value = mtu3_readl(mtu->ippc_base, U3D_SSUSB_IP_DEV_CAP);
mtu->is_u3_ip = !!SSUSB_IP_DEV_U3_PORT_NUM(value);
dev_info(mtu->dev, "IP version 0x%x(%s IP)\n", mtu->hw_version,
mtu->is_u3_ip ? "U3" : "U2");
......
......@@ -133,11 +133,23 @@
#define TX_W1C_BITS (~(TX_SENTSTALL))
/* U3D_TX1CSR1 */
#define TX_MULT(x) (((x) & 0x3) << 22)
#define TX_MAX_PKT(x) (((x) & 0x3f) << 16)
#define TX_MAX_PKT_G2(x) (((x) & 0x7f) << 24)
#define TX_MULT_G2(x) (((x) & 0x7) << 21)
#define TX_MULT_OG(x) (((x) & 0x3) << 22)
#define TX_MAX_PKT_OG(x) (((x) & 0x3f) << 16)
#define TX_SLOT(x) (((x) & 0x3f) << 8)
#define TX_TYPE(x) (((x) & 0x3) << 4)
#define TX_SS_BURST(x) (((x) & 0xf) << 0)
#define TX_MULT(g2c, x) \
({ \
typeof(x) x_ = (x); \
(g2c) ? TX_MULT_G2(x_) : TX_MULT_OG(x_); \
})
#define TX_MAX_PKT(g2c, x) \
({ \
typeof(x) x_ = (x); \
(g2c) ? TX_MAX_PKT_G2(x_) : TX_MAX_PKT_OG(x_); \
})
/* for TX_TYPE & RX_TYPE */
#define TYPE_BULK (0x0)
......@@ -160,11 +172,23 @@
#define RX_W1C_BITS (~(RX_SENTSTALL | RX_RXPKTRDY))
/* U3D_RX1CSR1 */
#define RX_MULT(x) (((x) & 0x3) << 22)
#define RX_MAX_PKT(x) (((x) & 0x3f) << 16)
#define RX_MAX_PKT_G2(x) (((x) & 0x7f) << 24)
#define RX_MULT_G2(x) (((x) & 0x7) << 21)
#define RX_MULT_OG(x) (((x) & 0x3) << 22)
#define RX_MAX_PKT_OG(x) (((x) & 0x3f) << 16)
#define RX_SLOT(x) (((x) & 0x3f) << 8)
#define RX_TYPE(x) (((x) & 0x3) << 4)
#define RX_SS_BURST(x) (((x) & 0xf) << 0)
#define RX_MULT(g2c, x) \
({ \
typeof(x) x_ = (x); \
(g2c) ? RX_MULT_G2(x_) : RX_MULT_OG(x_); \
})
#define RX_MAX_PKT(g2c, x) \
({ \
typeof(x) x_ = (x); \
(g2c) ? RX_MAX_PKT_G2(x_) : RX_MAX_PKT_OG(x_); \
})
/* U3D_RX1CSR2 */
#define RX_BINTERVAL(x) (((x) & 0xff) << 24)
......@@ -419,6 +443,7 @@
#define U3D_SSUSB_DEV_RST_CTRL (SSUSB_SIFSLV_IPPC_BASE + 0x0098)
#define U3D_SSUSB_HW_ID (SSUSB_SIFSLV_IPPC_BASE + 0x00A0)
#define U3D_SSUSB_HW_SUB_ID (SSUSB_SIFSLV_IPPC_BASE + 0x00A4)
#define U3D_SSUSB_IP_TRUNK_VERS (U3D_SSUSB_HW_SUB_ID)
#define U3D_SSUSB_IP_SPARE0 (SSUSB_SIFSLV_IPPC_BASE + 0x00C8)
/*---------------- SSUSB_SIFSLV_IPPC FIELD DEFINITION ----------------*/
......@@ -483,4 +508,7 @@
/* U3D_SSUSB_DEV_RST_CTRL */
#define SSUSB_DEV_SW_RST BIT(0)
/* U3D_SSUSB_IP_TRUNK_VERS */
#define IP_TRUNK_VERS(x) (((x) >> 16) & 0xffff)
#endif /* _SSUSB_HW_REGS_H_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment