From 9428ea9afb581ab24af13ef93f2df2b1ed0b270b Mon Sep 17 00:00:00 2001 From: Yue Wang Date: Mon, 12 Mar 2018 10:30:41 +0800 Subject: [PATCH] usb: enable usb suspend. PD#161622: usb: enable usb suspend. Change-Id: I28e2ac7855dbdfe0299592189af179575a264272 Signed-off-by: Yue Wang --- arch/arm64/boot/dts/amlogic/mesong12a.dtsi | 2 +- drivers/amlogic/usb/dwc_otg/310/dwc_otg_driver.h | 2 + drivers/amlogic/usb/dwc_otg/310/dwc_otg_pcd_intr.c | 14 +++++++ .../amlogic/usb/dwc_otg/310/dwc_otg_pcd_linux.c | 11 +++++ drivers/amlogic/usb/phy/phy-aml-new-usb2-v2.c | 48 +++++++++------------- drivers/amlogic/usb/phy/phy-aml-new-usb3-v2.c | 8 +++- drivers/usb/host/xhci-mem.c | 7 ++++ 7 files changed, 61 insertions(+), 31 deletions(-) diff --git a/arch/arm64/boot/dts/amlogic/mesong12a.dtsi b/arch/arm64/boot/dts/amlogic/mesong12a.dtsi index b8b366d..0919f81 100644 --- a/arch/arm64/boot/dts/amlogic/mesong12a.dtsi +++ b/arch/arm64/boot/dts/amlogic/mesong12a.dtsi @@ -356,7 +356,7 @@ compatible = "amlogic, amlogic-new-usb2-v2"; status = "disable"; reg = <0x0 0xffe09000 0x0 0x80 - 0x0 0xffd01008 0x0 0x4 + 0x0 0xffd01008 0x0 0x100 0x0 0xff636000 0x0 0x2000 0x0 0xff63a000 0x0 0x2000>; pll-setting-1 = <0x09400414>; diff --git a/drivers/amlogic/usb/dwc_otg/310/dwc_otg_driver.h b/drivers/amlogic/usb/dwc_otg/310/dwc_otg_driver.h index 707b206..ce90831 100644 --- a/drivers/amlogic/usb/dwc_otg/310/dwc_otg_driver.h +++ b/drivers/amlogic/usb/dwc_otg/310/dwc_otg_driver.h @@ -88,6 +88,8 @@ typedef struct dwc_otg_device { struct notifier_block nb; struct delayed_work work; + + u32 host_plug; } dwc_otg_device_t; /*We must clear S3C24XX_EINTPEND external interrupt register diff --git a/drivers/amlogic/usb/dwc_otg/310/dwc_otg_pcd_intr.c b/drivers/amlogic/usb/dwc_otg/310/dwc_otg_pcd_intr.c index 264749b..e5c8644 100644 --- a/drivers/amlogic/usb/dwc_otg/310/dwc_otg_pcd_intr.c +++ b/drivers/amlogic/usb/dwc_otg/310/dwc_otg_pcd_intr.c @@ -1057,7 +1057,21 @@ int32_t dwc_otg_pcd_handle_enum_done_intr(dwc_otg_pcd_t *pcd) GET_CORE_IF(pcd)->core_global_regs; uint8_t utmi16b, utmi8b; int speed; + dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd); + DWC_DEBUGPL(DBG_PCD, "SPEED ENUM\n"); + if (core_if->controller_type == USB_OTG) { + if (core_if->phy_interface == 0) { + if (pcd->otg_dev->host_plug) { + gintsts.d32 = 0; + gintsts.b.enumdone = 1; + DWC_WRITE_REG32(&GET_CORE_IF(pcd)-> + core_global_regs->gintsts, gintsts.d32); + DWC_DEBUGPL(DBG_PCD, "false speed emun\n"); + return 1; + } + } + } if (GET_CORE_IF(pcd)->snpsid >= OTG_CORE_REV_2_60a) { utmi16b = 6; diff --git a/drivers/amlogic/usb/dwc_otg/310/dwc_otg_pcd_linux.c b/drivers/amlogic/usb/dwc_otg/310/dwc_otg_pcd_linux.c index f4cb084..0565f09 100644 --- a/drivers/amlogic/usb/dwc_otg/310/dwc_otg_pcd_linux.c +++ b/drivers/amlogic/usb/dwc_otg/310/dwc_otg_pcd_linux.c @@ -1258,16 +1258,27 @@ int dwc_usb_change(struct notifier_block *nb, unsigned long value, void *pdata) { dwc_otg_device_t *otg_dev; + dwc_otg_core_global_regs_t *global_regs; otg_dev = container_of(nb, dwc_otg_device_t, nb); + global_regs = otg_dev->core_if->core_global_regs; if (value) { DWC_DEBUGPL(DBG_PCDV, "start usb device\n"); + otg_dev->host_plug = 0; dwc_otg_enable_global_interrupts(otg_dev->core_if); + if (otg_dev->core_if->phy_interface == 0) + dwc_otg_enable_device_interrupts(otg_dev->core_if); otg_dev->pcd->core_if->pcd_cb->start(otg_dev->pcd); } else { + otg_dev->host_plug = 1; DWC_DEBUGPL(DBG_PCDV, "stop usb device\n"); dwc_otg_disable_global_interrupts(otg_dev->core_if); + + /* Disable all interrupts. */ + if (otg_dev->core_if->phy_interface == 0) + DWC_WRITE_REG32(&global_regs->gintmsk, 0); + otg_dev->pcd->core_if->pcd_cb->stop(otg_dev->pcd); } 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 86eaa35..1fdf8f9 100644 --- a/drivers/amlogic/usb/phy/phy-aml-new-usb2-v2.c +++ b/drivers/amlogic/usb/phy/phy-aml-new-usb2-v2.c @@ -47,20 +47,12 @@ static int amlogic_new_usb2_init(struct usb_phy *x) struct u2p_aml_regs_v2 u2p_aml_regs; union u2p_r0_v2 reg0; union u2p_r1_v2 reg1; - //u32 val; + u32 val; - if (phy->suspend_flag) { - phy->suspend_flag = 0; - for (i = 0; i < phy->portnum; i++) { - for (j = 0; j < 2; j++) { - u2p_aml_regs.u2p_r_v2[j] = (void __iomem *) - ((unsigned long)phy->regs + i*PHY_REGISTER_SIZE - + 4 * j); - } - } - /*TO DO: set usb phy to low power mode*/ - return 0; - } + val = readl((void __iomem *) + ((unsigned long)phy->reset_regs + (0x21 * 4 - 0x8))); + writel((val | (0x3 << 16)), (void __iomem *) + ((unsigned long)phy->reset_regs + (0x21 * 4 - 0x8))); amlogic_new_usbphy_reset_v2(phy); @@ -73,9 +65,13 @@ static int amlogic_new_usb2_init(struct usb_phy *x) reg0.d32 = readl(u2p_aml_regs.u2p_r_v2[0]); reg0.b.POR = 1; - reg0.b.host_device = 1; - if (i == 1) - reg0.b.IDPULLUP0 = 1; + if (phy->suspend_flag == 0) { + reg0.b.host_device = 1; + if (i == 1) { + reg0.b.IDPULLUP0 = 1; + reg0.b.DRVVBUS0 = 1; + } + } writel(reg0.d32, u2p_aml_regs.u2p_r_v2[0]); @@ -120,19 +116,15 @@ static int amlogic_new_usb2_suspend(struct usb_phy *x, int suspend) static void amlogic_new_usb2phy_shutdown(struct usb_phy *x) { struct amlogic_usb_v2 *phy = phy_to_amlusb(x); - struct u2p_aml_regs_v2 u2p_aml_regs; - int i, j; + u32 val; - phy->suspend_flag = 1; - for (i = phy->portnum - 1; i >= 0; i--) { - for (j = 0; j < 2; j++) { - u2p_aml_regs.u2p_r_v2[j] = (void __iomem *) - ((unsigned long)phy->regs + i*PHY_REGISTER_SIZE - + 4 * j); - } + /* set usb phy to low power mode */ + val = readl((void __iomem *) + ((unsigned long)phy->reset_regs + (0x21 * 4 - 0x8))); + writel((val & (~(0x3 << 16))), (void __iomem *) + ((unsigned long)phy->reset_regs + (0x21 * 4 - 0x8))); - /*TO DO: set usb phy to low power mode*/ - } + phy->suspend_flag = 1; } static int amlogic_new_usb2_probe(struct platform_device *pdev) @@ -210,7 +202,6 @@ static int amlogic_new_usb2_probe(struct platform_device *pdev) phy->regs = phy_base; phy->reset_regs = reset_base; phy->portnum = portnum; - phy->suspend_flag = 0; phy->phy.dev = phy->dev; phy->phy.label = "amlogic-usbphy2"; phy->phy.init = amlogic_new_usb2_init; @@ -220,6 +211,7 @@ static int amlogic_new_usb2_probe(struct platform_device *pdev) phy->pll_setting[0] = pll_setting[0]; phy->pll_setting[1] = pll_setting[1]; phy->pll_setting[2] = pll_setting[2]; + phy->suspend_flag = 0; for (i = 0; i < portnum; i++) phy->phy_cfg[i] = phy_cfg_base[i]; diff --git a/drivers/amlogic/usb/phy/phy-aml-new-usb3-v2.c b/drivers/amlogic/usb/phy/phy-aml-new-usb3-v2.c index f24bedd..fd06de2 100644 --- a/drivers/amlogic/usb/phy/phy-aml-new-usb3-v2.c +++ b/drivers/amlogic/usb/phy/phy-aml-new-usb3-v2.c @@ -70,7 +70,6 @@ static void aml_new_usb_notifier_call(unsigned long is_device_on) blocking_notifier_call_chain (&aml_new_usb_v2_notifier_list, is_device_on, NULL); } -//EXPORT_SYMBOL(aml_new_usb_notifier_call); static void set_usb_vbus_power (struct gpio_desc *usb_gd, int pin, char is_power_on) @@ -100,6 +99,9 @@ static void amlogic_new_usb3phy_shutdown(struct usb_phy *x) { struct amlogic_usb_v2 *phy = phy_to_amlusb(x); + if (phy->phy.flags == AML_USB3_PHY_ENABLE) + clk_disable_unprepare(phy->clk); + phy->suspend_flag = 1; } @@ -128,6 +130,8 @@ static int amlogic_new_usb3_init(struct usb_phy *x) int i = 0; if (phy->suspend_flag) { + if (phy->phy.flags == AML_USB3_PHY_ENABLE) + clk_prepare_enable(phy->clk); phy->suspend_flag = 0; return 0; } @@ -148,7 +152,7 @@ static int amlogic_new_usb3_init(struct usb_phy *x) writel(r5.d32, usb_new_aml_regs_v2.usb_r_v2[5]); /* config usb3 phy */ - if (phy->portnum > 0) { + if (phy->phy.flags == AML_USB3_PHY_ENABLE) { r3.d32 = readl(usb_new_aml_regs_v2.usb_r_v2[3]); r3.b.p30_ssc_en = 1; r3.b.p30_ref_ssp_en = 1; diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index ac8b4a3..1375915 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -2252,7 +2252,14 @@ static void xhci_add_in_port(struct xhci_hcd *xhci, unsigned int num_ports, } xhci->port_array[i] = major_revision; if (major_revision == 0x03) +#ifdef CONFIG_AMLOGIC_USB + if (xhci->quirks & XHCI_AML_SUPER_SPEED_SUPPORT) + xhci->num_usb3_ports++; + else + xhci->num_usb3_ports = 0; +#else xhci->num_usb3_ports++; +#endif else xhci->num_usb2_ports++; } -- 2.7.4