usb: add usb3.0 driver support for g12a

PD#156734: usb: add usb3.0 driver support for g12a

Change-Id: Iac057b29d041a5c80114407df0ccd965aae11ca1
Signed-off-by: Yue Wang <yue.wang@amlogic.com>
This commit is contained in:
Yue Wang
2018-02-02 19:41:59 +08:00
committed by Yixun Lan
parent 22d18caa56
commit 09e5ee34b5
7 changed files with 83 additions and 19 deletions

View File

@@ -441,7 +441,6 @@
clock-src = "usb3.0";
clocks = <&clkc CLKID_USB_GENERAL>;
clock-names = "dwc_general";
/*snps,super_speed_support;*/
};
usb2_phy_v2: usb2phy@ffe09000 {
@@ -463,6 +462,8 @@
phy-reg-size = <0x4>;
interrupts = <0 16 4>;
otg = <0>;
clocks = <&clkc CLKID_PCIE_PLL>;
clock-names = "pcie_refpll";
};
dwc2_a {

View File

@@ -31,6 +31,7 @@
#include <linux/amlogic/aml_gpio_consumer.h>
#include <linux/workqueue.h>
#include <linux/notifier.h>
#include <linux/amlogic/usbtype.h>
#include "phy-aml-new-usb-v2.h"
#define HOST_MODE 0
@@ -131,17 +132,13 @@ static int amlogic_new_usb3_init(struct usb_phy *x)
return 0;
}
/* set the phy from pcie to usb3 */
if (phy->portnum > 0)
writel((readl(phy->phy3_cfg) | (3<<5)), phy->phy3_cfg);
for (i = 0; i < 6; i++) {
usb_new_aml_regs_v2.usb_r_v2[i] = (void __iomem *)
((unsigned long)phy->regs + 4*i);
}
r1.d32 = readl(usb_new_aml_regs_v2.usb_r_v2[1]);
r1.b.u3h_fladj_30mhz_reg = 0x20;
r1.b.u3h_fladj_30mhz_reg = 0x26;
writel(r1.d32, usb_new_aml_regs_v2.usb_r_v2[1]);
r5.d32 = readl(usb_new_aml_regs_v2.usb_r_v2[5]);
@@ -164,7 +161,7 @@ static int amlogic_new_usb3_init(struct usb_phy *x)
udelay(2);
r1.d32 = readl(usb_new_aml_regs_v2.usb_r_v2[1]);
r1.b.u3h_host_port_power_control_present = 1;
r1.b.u3h_fladj_30mhz_reg = 32;
r1.b.u3h_fladj_30mhz_reg = 0x26;
writel(r1.d32, usb_new_aml_regs_v2.usb_r_v2[1]);
udelay(2);
}
@@ -256,6 +253,26 @@ static irqreturn_t amlogic_botg_detect_irq(int irq, void *dev)
return IRQ_HANDLED;
}
static bool device_is_available(const struct device_node *device)
{
const char *status;
int statlen;
if (!device)
return false;
status = of_get_property(device, "status", &statlen);
if (status == NULL)
return true;
if (statlen > 0) {
if (!strcmp(status, "okay") || !strcmp(status, "ok"))
return true;
}
return false;
}
static int amlogic_new_usb3_v2_probe(struct platform_device *pdev)
{
struct amlogic_usb_v2 *phy;
@@ -273,6 +290,8 @@ static int amlogic_new_usb3_v2_probe(struct platform_device *pdev)
int retval;
int gpio_vbus_power_pin = -1;
int otg = 0;
int ret;
struct device_node *tsi_pci;
gpio_name = of_get_property(dev->of_node, "gpio-vbus-power", NULL);
if (gpio_name) {
@@ -290,6 +309,15 @@ static int amlogic_new_usb3_v2_probe(struct platform_device *pdev)
if (!portnum)
dev_err(&pdev->dev, "This phy has no usb port\n");
tsi_pci = of_find_node_by_type(NULL, "pci");
if (tsi_pci) {
if (device_is_available(tsi_pci)) {
dev_info(&pdev->dev,
"pci-e driver probe, disable USB 3.0 function!!!\n");
portnum = 0;
}
}
prop = of_get_property(dev->of_node, "otg", NULL);
if (prop)
otg = of_read_ulong(prop, 1);
@@ -347,9 +375,31 @@ static int amlogic_new_usb3_v2_probe(struct platform_device *pdev)
phy->phy.set_suspend = amlogic_new_usb3_suspend;
phy->phy.shutdown = amlogic_new_usb3phy_shutdown;
phy->phy.type = USB_PHY_TYPE_USB3;
phy->phy.flags = AML_USB3_PHY_DISABLE;
phy->vbus_power_pin = gpio_vbus_power_pin;
phy->usb_gpio_desc = usb_gd;
/* set the phy from pcie to usb3 */
if (phy->portnum > 0) {
writel((readl(phy->phy3_cfg) | (3<<5)), phy->phy3_cfg);
udelay(100);
phy->clk = devm_clk_get(dev, "pcie_refpll");
if (IS_ERR(phy->clk)) {
dev_err(dev, "Failed to get usb3 bus clock\n");
ret = PTR_ERR(phy->clk);
return ret;
}
ret = clk_prepare_enable(phy->clk);
if (ret) {
dev_err(dev, "Failed to enable usb3 bus clock\n");
ret = PTR_ERR(phy->clk);
return ret;
}
phy->phy.flags = AML_USB3_PHY_ENABLE;
}
INIT_DELAYED_WORK(&phy->work, amlogic_gxl_work);
usb_add_phy_dev(&phy->phy);

View File

@@ -212,6 +212,7 @@ static int dwc3_core_soft_reset(struct dwc3 *dwc)
usb_phy_init(dwc->usb2_phy);
usb_phy_init(dwc->usb3_phy);
ret = phy_init(dwc->usb2_generic_phy);
if (ret < 0)
return ret;
@@ -221,7 +222,8 @@ static int dwc3_core_soft_reset(struct dwc3 *dwc)
phy_exit(dwc->usb2_generic_phy);
return ret;
}
mdelay(100);
udelay(1000);
/* Clear USB3 PHY reset */
reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
@@ -249,7 +251,7 @@ static int dwc3_core_soft_reset(struct dwc3 *dwc)
reg &= ~DWC3_GUSB2PHYCFG_PHYSOFTRST;
dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(3), reg);
mdelay(100);
udelay(1000);
/* After PHYs are stable we can take Core out of reset state */
reg = dwc3_readl(dwc->regs, DWC3_GCTL);
@@ -925,6 +927,13 @@ static int dwc3_core_get_phy(struct dwc3 *dwc)
}
}
#ifdef CONFIG_AMLOGIC_USB
if (dwc->usb3_phy->flags == AML_USB3_PHY_ENABLE)
dwc->super_speed_support = 1;
else
dwc->super_speed_support = 0;
#endif
dwc->usb2_generic_phy = devm_phy_get(dev, "usb2-phy");
if (IS_ERR(dwc->usb2_generic_phy)) {
ret = PTR_ERR(dwc->usb2_generic_phy);
@@ -1141,10 +1150,7 @@ static int dwc3_probe(struct platform_device *pdev)
&dwc->hsphy_interface);
device_property_read_u32(dev, "snps,quirk-frame-length-adjustment",
&dwc->fladj);
#ifdef CONFIG_AMLOGIC_USB
dwc->super_speed_support = device_property_read_bool(dev,
"snps,super_speed_support");
#endif
dwc->lpm_nyet_threshold = lpm_nyet_threshold;
dwc->tx_de_emphasis = tx_de_emphasis;

View File

@@ -105,6 +105,11 @@ int dwc3_host_init(struct dwc3 *dwc)
if (dwc->revision <= DWC3_REVISION_300A)
props[prop_idx++].name = "quirk-broken-port-ped";
#ifdef CONFIG_AMLOGIC_USB
if (dwc->super_speed_support)
props[prop_idx++].name = "super_speed_support";
#endif
if (prop_idx) {
ret = platform_device_add_properties(xhci, props);
if (ret) {
@@ -113,11 +118,6 @@ int dwc3_host_init(struct dwc3 *dwc)
}
}
#ifdef CONFIG_AMLOGIC_USB
if (dwc->super_speed_support)
props[prop_idx++].name = "usb3-support";
#endif
phy_create_lookup(dwc->usb2_generic_phy, "usb2-phy",
dev_name(&xhci->dev));
phy_create_lookup(dwc->usb3_generic_phy, "usb3-phy",

View File

@@ -238,7 +238,7 @@ static int xhci_plat_probe(struct platform_device *pdev)
xhci->quirks |= XHCI_BROKEN_PORT_PED;
#ifdef CONFIG_AMLOGIC_USB
if (device_property_read_bool(&pdev->dev, "usb3-support"))
if (device_property_read_bool(&pdev->dev, "super_speed_support"))
xhci->quirks |= XHCI_AML_SUPER_SPEED_SUPPORT;
#endif

View File

@@ -23,6 +23,7 @@
#include <linux/amlogic/aml_gpio_consumer.h>
#include <linux/workqueue.h>
#include <linux/notifier.h>
#include <linux/clk.h>
#define PHY_REGISTER_SIZE 0x20
/* Register definitions */
@@ -171,6 +172,7 @@ struct amlogic_usb_v2 {
int portnum;
int suspend_flag;
struct clk *clk;
};
#endif

View File

@@ -40,6 +40,11 @@
#define USB_CORE_RESET_TIME 10
#define USB_ID_CHANGE_TIME 100
enum usb3_phy_func_e {
AML_USB3_PHY_DISABLE = 0,
AML_USB3_PHY_ENABLE,
};
enum usb_port_type_e {
USB_PORT_TYPE_OTG = 0,
USB_PORT_TYPE_HOST,