提交 5517525e 编写于 作者: R Ricardo Ribalda Delgado 提交者: Felipe Balbi

usb: gadget: udc: net2280: Improve patching of defect 7374

Once the defect 7374 is patched, there is no reason the keep reading the
idx scratch register.

Cache the content of the scratch idx register on device flag.
Signed-off-by: NRicardo Ribalda Delgado <ricardo.ribalda@gmail.com>
Signed-off-by: NFelipe Balbi <balbi@ti.com>
上级 485f44d0
......@@ -1765,76 +1765,73 @@ static void defect7374_disable_data_eps(struct net2280 *dev)
static void defect7374_enable_data_eps_zero(struct net2280 *dev)
{
u32 tmp = 0, tmp_reg;
u32 fsmvalue, scratch;
u32 scratch;
int i;
unsigned char ep_sel;
scratch = get_idx_reg(dev->regs, SCRATCH);
fsmvalue = scratch & (0xf << DEFECT7374_FSM_FIELD);
WARN_ON((scratch & (0xf << DEFECT7374_FSM_FIELD))
== DEFECT7374_FSM_SS_CONTROL_READ);
scratch &= ~(0xf << DEFECT7374_FSM_FIELD);
/*See if firmware needs to set up for workaround*/
if (fsmvalue != DEFECT7374_FSM_SS_CONTROL_READ) {
ep_warn(dev, "Operate Defect 7374 workaround soft this time");
ep_warn(dev, "It will operate on cold-reboot and SS connect");
/*GPEPs:*/
tmp = ((0 << ENDPOINT_NUMBER) | BIT(ENDPOINT_DIRECTION) |
(2 << OUT_ENDPOINT_TYPE) | (2 << IN_ENDPOINT_TYPE) |
((dev->enhanced_mode) ?
BIT(OUT_ENDPOINT_ENABLE) : BIT(ENDPOINT_ENABLE)) |
BIT(IN_ENDPOINT_ENABLE));
for (i = 1; i < 5; i++)
writel(tmp, &dev->ep[i].cfg->ep_cfg);
/* CSRIN, PCIIN, STATIN, RCIN*/
tmp = ((0 << ENDPOINT_NUMBER) | BIT(ENDPOINT_ENABLE));
writel(tmp, &dev->dep[1].dep_cfg);
writel(tmp, &dev->dep[3].dep_cfg);
writel(tmp, &dev->dep[4].dep_cfg);
writel(tmp, &dev->dep[5].dep_cfg);
/*Implemented for development and debug.
* Can be refined/tuned later.*/
for (ep_sel = 0; ep_sel <= 21; ep_sel++) {
/* Select an endpoint for subsequent operations: */
tmp_reg = readl(&dev->plregs->pl_ep_ctrl);
writel(((tmp_reg & ~0x1f) | ep_sel),
&dev->plregs->pl_ep_ctrl);
if (ep_sel == 1) {
tmp =
(readl(&dev->plregs->pl_ep_ctrl) |
BIT(CLEAR_ACK_ERROR_CODE) | 0);
writel(tmp, &dev->plregs->pl_ep_ctrl);
continue;
}
ep_warn(dev, "Operate Defect 7374 workaround soft this time");
ep_warn(dev, "It will operate on cold-reboot and SS connect");
if (ep_sel == 0 || (ep_sel > 9 && ep_sel < 14) ||
ep_sel == 18 || ep_sel == 20)
continue;
/*GPEPs:*/
tmp = ((0 << ENDPOINT_NUMBER) | BIT(ENDPOINT_DIRECTION) |
(2 << OUT_ENDPOINT_TYPE) | (2 << IN_ENDPOINT_TYPE) |
((dev->enhanced_mode) ?
BIT(OUT_ENDPOINT_ENABLE) : BIT(ENDPOINT_ENABLE)) |
BIT(IN_ENDPOINT_ENABLE));
tmp = (readl(&dev->plregs->pl_ep_cfg_4) |
BIT(NON_CTRL_IN_TOLERATE_BAD_DIR) | 0);
writel(tmp, &dev->plregs->pl_ep_cfg_4);
for (i = 1; i < 5; i++)
writel(tmp, &dev->ep[i].cfg->ep_cfg);
tmp = readl(&dev->plregs->pl_ep_ctrl) &
~BIT(EP_INITIALIZED);
writel(tmp, &dev->plregs->pl_ep_ctrl);
/* CSRIN, PCIIN, STATIN, RCIN*/
tmp = ((0 << ENDPOINT_NUMBER) | BIT(ENDPOINT_ENABLE));
writel(tmp, &dev->dep[1].dep_cfg);
writel(tmp, &dev->dep[3].dep_cfg);
writel(tmp, &dev->dep[4].dep_cfg);
writel(tmp, &dev->dep[5].dep_cfg);
/*Implemented for development and debug.
* Can be refined/tuned later.*/
for (ep_sel = 0; ep_sel <= 21; ep_sel++) {
/* Select an endpoint for subsequent operations: */
tmp_reg = readl(&dev->plregs->pl_ep_ctrl);
writel(((tmp_reg & ~0x1f) | ep_sel),
&dev->plregs->pl_ep_ctrl);
if (ep_sel == 1) {
tmp =
(readl(&dev->plregs->pl_ep_ctrl) |
BIT(CLEAR_ACK_ERROR_CODE) | 0);
writel(tmp, &dev->plregs->pl_ep_ctrl);
continue;
}
/* Set FSM to focus on the first Control Read:
* - Tip: Connection speed is known upon the first
* setup request.*/
scratch |= DEFECT7374_FSM_WAITING_FOR_CONTROL_READ;
set_idx_reg(dev->regs, SCRATCH, scratch);
if (ep_sel == 0 || (ep_sel > 9 && ep_sel < 14) ||
ep_sel == 18 || ep_sel == 20)
continue;
tmp = (readl(&dev->plregs->pl_ep_cfg_4) |
BIT(NON_CTRL_IN_TOLERATE_BAD_DIR) | 0);
writel(tmp, &dev->plregs->pl_ep_cfg_4);
tmp = readl(&dev->plregs->pl_ep_ctrl) &
~BIT(EP_INITIALIZED);
writel(tmp, &dev->plregs->pl_ep_ctrl);
} else{
ep_warn(dev, "Defect 7374 workaround soft will NOT operate");
ep_warn(dev, "It will operate on cold-reboot and SS connect");
}
/* Set FSM to focus on the first Control Read:
* - Tip: Connection speed is known upon the first
* setup request.*/
scratch |= DEFECT7374_FSM_WAITING_FOR_CONTROL_READ;
set_idx_reg(dev->regs, SCRATCH, scratch);
}
/* keeping it simple:
......@@ -1885,21 +1882,13 @@ static void usb_reset_228x(struct net2280 *dev)
static void usb_reset_338x(struct net2280 *dev)
{
u32 tmp;
u32 fsmvalue;
dev->gadget.speed = USB_SPEED_UNKNOWN;
(void)readl(&dev->usb->usbctl);
net2280_led_init(dev);
fsmvalue = get_idx_reg(dev->regs, SCRATCH) &
(0xf << DEFECT7374_FSM_FIELD);
/* See if firmware needs to set up for workaround: */
if (fsmvalue != DEFECT7374_FSM_SS_CONTROL_READ) {
ep_info(dev, "%s: Defect 7374 FsmValue 0x%08x\n", __func__,
fsmvalue);
} else {
if (dev->bug7734_patched) {
/* disable automatic responses, and irqs */
writel(0, &dev->usb->stdrsp);
writel(0, &dev->regs->pciirqenb0);
......@@ -1916,7 +1905,7 @@ static void usb_reset_338x(struct net2280 *dev)
writel(~0, &dev->regs->irqstat0), writel(~0, &dev->regs->irqstat1);
if (fsmvalue == DEFECT7374_FSM_SS_CONTROL_READ) {
if (dev->bug7734_patched) {
/* reset, and enable pci */
tmp = readl(&dev->regs->devinit) |
BIT(PCI_ENABLE) |
......@@ -1982,7 +1971,6 @@ static void usb_reinit_338x(struct net2280 *dev)
{
int i;
u32 tmp, val;
u32 fsmvalue;
static const u32 ne[9] = { 0, 1, 2, 3, 4, 1, 2, 3, 4 };
static const u32 ep_reg_addr[9] = { 0x00, 0xC0, 0x00, 0xC0, 0x00,
0x00, 0xC0, 0x00, 0xC0 };
......@@ -2020,14 +2008,7 @@ static void usb_reinit_338x(struct net2280 *dev)
dev->ep[0].stopped = 0;
/* Link layer set up */
fsmvalue = get_idx_reg(dev->regs, SCRATCH) &
(0xf << DEFECT7374_FSM_FIELD);
/* See if driver needs to set up for workaround: */
if (fsmvalue != DEFECT7374_FSM_SS_CONTROL_READ)
ep_info(dev, "%s: Defect 7374 FsmValue %08x\n",
__func__, fsmvalue);
else {
if (dev->bug7734_patched) {
tmp = readl(&dev->usb_ext->usbctl2) &
~(BIT(U1_ENABLE) | BIT(U2_ENABLE) | BIT(LTM_ENABLE));
writel(tmp, &dev->usb_ext->usbctl2);
......@@ -2134,15 +2115,8 @@ static void ep0_start_228x(struct net2280 *dev)
static void ep0_start_338x(struct net2280 *dev)
{
u32 fsmvalue;
fsmvalue = get_idx_reg(dev->regs, SCRATCH) &
(0xf << DEFECT7374_FSM_FIELD);
if (fsmvalue != DEFECT7374_FSM_SS_CONTROL_READ)
ep_info(dev, "%s: Defect 7374 FsmValue %08x\n", __func__,
fsmvalue);
else
if (dev->bug7734_patched)
writel(BIT(CLEAR_NAK_OUT_PACKETS_MODE) |
BIT(SET_EP_HIDE_STATUS_PHASE),
&dev->epregs[0].ep_rsp);
......@@ -2230,7 +2204,7 @@ static int net2280_start(struct usb_gadget *_gadget,
*/
net2280_led_active(dev, 1);
if (dev->quirks & PLX_SUPERSPEED)
if ((dev->quirks & PLX_SUPERSPEED) && !dev->bug7734_patched)
defect7374_enable_data_eps_zero(dev);
ep0_start(dev);
......@@ -2552,6 +2526,7 @@ static void defect7374_workaround(struct net2280 *dev, struct usb_ctrlrequest r)
* run after the next USB connection.
*/
scratch |= DEFECT7374_FSM_NON_SS_CONTROL_READ;
dev->bug7734_patched = 1;
goto restore_data_eps;
}
......@@ -2565,6 +2540,7 @@ static void defect7374_workaround(struct net2280 *dev, struct usb_ctrlrequest r)
if ((state >= (ACK_GOOD_NORMAL << STATE)) &&
(state <= (ACK_GOOD_MORE_ACKS_TO_COME << STATE))) {
scratch |= DEFECT7374_FSM_SS_CONTROL_READ;
dev->bug7734_patched = 1;
break;
}
......@@ -2904,7 +2880,7 @@ static void handle_stat0_irqs(struct net2280 *dev, u32 stat)
cpu_to_le32s(&u.raw[0]);
cpu_to_le32s(&u.raw[1]);
if (dev->quirks & PLX_SUPERSPEED)
if ((dev->quirks & PLX_SUPERSPEED) && !dev->bug7734_patched)
defect7374_workaround(dev, u.r);
tmp = 0;
......@@ -3418,9 +3394,12 @@ static int net2280_probe(struct pci_dev *pdev, const struct pci_device_id *id)
fsmvalue = get_idx_reg(dev->regs, SCRATCH) &
(0xf << DEFECT7374_FSM_FIELD);
/* See if firmware needs to set up for workaround: */
if (fsmvalue == DEFECT7374_FSM_SS_CONTROL_READ)
if (fsmvalue == DEFECT7374_FSM_SS_CONTROL_READ) {
dev->bug7734_patched = 1;
writel(0, &dev->usb->usbctl);
} else{
} else
dev->bug7734_patched = 0;
} else {
dev->enhanced_mode = 0;
dev->n_ep = 7;
/* put into initial config, link up all endpoints */
......
......@@ -165,7 +165,8 @@ struct net2280 {
ltm_enable:1,
wakeup_enable:1,
selfpowered:1,
addressed_state:1;
addressed_state:1,
bug7734_patched:1;
u16 chiprev;
int enhanced_mode;
int n_ep;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册