mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 11:26:02 +09:00
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:
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user