|
@@ -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 */
|