usb: USB keyboard not recognized at low probability [1/1]
authorhe.he <he.he@amlogic.com>
Mon, 22 Apr 2019 10:05:47 +0000 (18:05 +0800)
committerTao Zeng <tao.zeng@amlogic.com>
Fri, 26 Apr 2019 06:02:29 +0000 (23:02 -0700)
PD#TV-4365

Problem:
USB keyboard not recognized after reboot repeatedly.

Solution:
Reset the reset_FS_LS_Clock_Divider bit of the usb phy.

Verify:
tl1

Change-Id: I0f4bf35be04d3aff1094bf55641348ccaca072e4
Signed-off-by: he.he <he.he@amlogic.com>
drivers/amlogic/usb/phy/phy-aml-new-usb2-v2.c
drivers/usb/host/xhci-hub.c
drivers/usb/host/xhci.h

index 6aaf4f997bd8379538ecd190b58a350dbee60013..1ad47f90822629e828af2ed2baab94ddee8a7716 100644 (file)
@@ -92,6 +92,44 @@ void set_usb_phy_device_tuning(int port, int default_val)
        g_phy2_v2->phy_cfg_state[port] = default_val;
 }
 
+void set_usb_phy_host_low_reset(int port)
+{
+       void __iomem    *phy_reg_base;
+       u32 val;
+
+       if (!g_phy2_v2)
+               return;
+       if (port > g_phy2_v2->portnum)
+               return;
+
+       if (g_phy2_v2->phy_version) {
+               phy_reg_base = g_phy2_v2->phy_cfg[port];
+               val = readl(phy_reg_base);
+               val &= (~(1 << 14));
+               writel(val, phy_reg_base);
+               val = readl(phy_reg_base + 0x08);
+               val &= 0xfff;
+               writel(val | readl(phy_reg_base + 0x10), phy_reg_base + 0x10);
+               writel(g_phy2_v2->pll_setting[5], phy_reg_base + 0x34);
+
+               val = readl(phy_reg_base);
+               val |= (1 << 14);
+               writel(val, phy_reg_base);
+               writel(g_phy2_v2->pll_setting[5], phy_reg_base + 0x34);
+       } else {
+               phy_reg_base = g_phy2_v2->phy_cfg[port];
+               val = readl(phy_reg_base);
+               val &= (~(1 << 12));
+               writel(val, phy_reg_base);
+               writel(g_phy2_v2->pll_setting[5], phy_reg_base + 0x34);
+               val |= (1 << 12);
+               writel(val, phy_reg_base);
+               writel(g_phy2_v2->pll_setting[5], phy_reg_base + 0x34);
+       }
+
+}
+
+
 void set_usb_pll(struct amlogic_usb_v2 *phy, void __iomem      *reg)
 {
        /* TO DO set usb  PLL */
index 89c9165306af781d1a5feb924c59a63479b80a6c..d7d04dee225add4adf1ba9fc7bd57307ed688b00 100644 (file)
@@ -555,6 +555,9 @@ static void xhci_clear_port_change_bit(struct xhci_hcd *xhci, u16 wValue,
        if (DEV_HIGHSPEED(port_status) &&
                (wValue == USB_PORT_FEAT_C_RESET))
                set_usb_phy_host_tuning(wIndex, 0);
+       if (DEV_LOWSPEED(port_status) &&
+               (wValue == USB_PORT_FEAT_C_RESET))
+               set_usb_phy_host_low_reset(wIndex);
 #endif
 }
 
index 08fe97add339999bd179762123520cf22ac81bef..8c812445464584f54f61543c475bab12b4178bf6 100644 (file)
@@ -2013,6 +2013,7 @@ int xhci_test_single_step(struct xhci_hcd *xhci, gfp_t mem_flags,
                struct urb *urb, int slot_id,
                unsigned int ep_index, int testflag);
 extern void set_usb_phy_host_tuning(int port, int default_val);
+extern void set_usb_phy_host_low_reset(int port);
 #endif
 
 #endif /* __LINUX_XHCI_HCD_H */