From b1a53605ec79f7963746d4f23e2cd97248a075b6 Mon Sep 17 00:00:00 2001 From: "he.he" Date: Mon, 22 Apr 2019 18:05:47 +0800 Subject: [PATCH] usb: USB keyboard not recognized at low probability [1/1] 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 --- drivers/amlogic/usb/phy/phy-aml-new-usb2-v2.c | 38 +++++++++++++++++++++++++++ drivers/usb/host/xhci-hub.c | 3 +++ drivers/usb/host/xhci.h | 1 + 3 files changed, 42 insertions(+) diff --git a/drivers/amlogic/usb/phy/phy-aml-new-usb2-v2.c b/drivers/amlogic/usb/phy/phy-aml-new-usb2-v2.c index 6aaf4f9..1ad47f9 100644 --- a/drivers/amlogic/usb/phy/phy-aml-new-usb2-v2.c +++ b/drivers/amlogic/usb/phy/phy-aml-new-usb2-v2.c @@ -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 */ diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 89c9165..d7d04de 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -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 } diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 08fe97a..8c81244 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -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 */ -- 2.7.4