From: Yue Wang Date: Wed, 20 Mar 2019 07:24:46 +0000 (+0800) Subject: usb: modify usb dts for sm1 [1/1] X-Git-Tag: khadas-vims-v0.9.6-release~835 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f7ceebf77e7089e3eec0156d4f2e040125922c9c;p=platform%2Fkernel%2Flinux-amlogic.git usb: modify usb dts for sm1 [1/1] PD#SWPL-5385 Problem: SM1 bring up Solution: modify usb dts for SM1 bringup Verify: g12a Test: pass Change-Id: Ie6f2925315ce12b3ad2964cf85aa3f4cee4bf2a7 Signed-off-by: Yue Wang --- diff --git a/arch/arm/boot/dts/amlogic/mesonsm1.dtsi b/arch/arm/boot/dts/amlogic/mesonsm1.dtsi index 40345e1..97183ea 100644 --- a/arch/arm/boot/dts/amlogic/mesonsm1.dtsi +++ b/arch/arm/boot/dts/amlogic/mesonsm1.dtsi @@ -374,21 +374,28 @@ reg = <0xffe09000 0x80 0xffd01008 0x100 0xff636000 0x2000 - 0xff63a000 0x2000>; + 0xff63a000 0x2000 + 0xff8000e8 0x10 + 0xff63c100 0x4>; pll-setting-1 = <0x09400414>; pll-setting-2 = <0x927E0000>; - pll-setting-3 = <0xac5f49e5>; + pll-setting-3 = <0xac5f69e5>; pll-setting-4 = <0xfe18>; pll-setting-5 = <0x8000fff>; pll-setting-6 = <0x78000>; pll-setting-7 = <0xe0004>; pll-setting-8 = <0xe000c>; + version = <2>; + pwr-ctl = <1>; }; usb3_phy_v2: usb3phy@ffe09080 { compatible = "amlogic, amlogic-new-usb3-v2"; status = "disable"; - reg = <0xffe09080 0x20>; + reg = <0xffe09080 0x20 + 0xff8000e8 0x10 + 0xff63c100 0x4 + 0xffd01008 0x100>; phy-reg = <0xff646000>; phy-reg-size = <0x2000>; usb2-phy-reg = <0xffe09000>; @@ -396,6 +403,7 @@ interrupts = <0 16 4>; clocks = <&clkc CLKID_PCIE_PLL>; clock-names = "pcie_refpll"; + pwr-ctl = <1>; }; dwc2_a: dwc2_a@ff400000 { @@ -418,7 +426,7 @@ phy-reg = <0xffe09000>; phy-reg-size = <0xa0>; /** phy-interface: 0x0: amlogic phy, 0x1: synopsys phy **/ - phy-interface = <0x0>; + phy-interface = <0x2>; clocks = <&clkc CLKID_USB_GENERAL &clkc CLKID_USB1_TO_DDR>; clock-names = "usb_general", @@ -1015,8 +1023,11 @@ 0xff648000 0x2000 0xfc400000 0x200000 0xff646000 0x2000 - 0xffd01080 0x10>; - reg-names = "elbi", "cfg", "config", "phy", "reset"; + 0xffd01080 0x10 + 0xff8000e8 0x8 + 0xff63c100 0x4>; + reg-names = "elbi", "cfg", "config", "phy", + "reset", "pwr", "hii"; interrupts = <0 221 0>; #interrupt-cells = <1>; bus-range = <0x0 0xff>; @@ -1043,6 +1054,7 @@ pcie-apb-rst-bit = <15>; pcie-phy-rst-bit = <14>; pcie-ctrl-a-rst-bit = <12>; + pwr-ctl = <1>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/amlogic/sm1_s905d3_ac200.dts b/arch/arm/boot/dts/amlogic/sm1_s905d3_ac200.dts index 759471b..3e83a30 100644 --- a/arch/arm/boot/dts/amlogic/sm1_s905d3_ac200.dts +++ b/arch/arm/boot/dts/amlogic/sm1_s905d3_ac200.dts @@ -1392,7 +1392,7 @@ }; &dwc3 { - status = "disabled"; + status = "okay"; }; &usb2_phy_v2 { @@ -1409,7 +1409,7 @@ }; &dwc2_a { - status = "disabled"; + status = "okay"; /** 0: normal, 1: otg+dwc3 host only, 2: otg+dwc3 device only*/ controller-type = <3>; }; diff --git a/arch/arm/boot/dts/amlogic/sm1_s905d3_skt.dts b/arch/arm/boot/dts/amlogic/sm1_s905d3_skt.dts index 1dcc061..03bcbba 100644 --- a/arch/arm/boot/dts/amlogic/sm1_s905d3_skt.dts +++ b/arch/arm/boot/dts/amlogic/sm1_s905d3_skt.dts @@ -1392,7 +1392,7 @@ }; &dwc3 { - status = "disabled"; + status = "okay"; }; &usb2_phy_v2 { @@ -1402,14 +1402,14 @@ &usb3_phy_v2 { status = "okay"; - portnum = <1>; + portnum = <0>; otg = <1>; gpio-vbus-power = "GPIOH_6"; gpios = <&gpio GPIOH_6 GPIO_ACTIVE_HIGH>; }; &dwc2_a { - status = "disabled"; + status = "okay"; /** 0: normal, 1: otg+dwc3 host only, 2: otg+dwc3 device only*/ controller-type = <3>; }; @@ -1596,7 +1596,7 @@ &pcie_A { reset-gpio = <&gpio GPIOX_7 GPIO_ACTIVE_HIGH>; - status = "disable"; + status = "okay"; }; &meson_cooldev { diff --git a/arch/arm64/boot/dts/amlogic/mesonsm1.dtsi b/arch/arm64/boot/dts/amlogic/mesonsm1.dtsi index 45c5633..f2a7761 100644 --- a/arch/arm64/boot/dts/amlogic/mesonsm1.dtsi +++ b/arch/arm64/boot/dts/amlogic/mesonsm1.dtsi @@ -374,21 +374,28 @@ reg = <0x0 0xffe09000 0x0 0x80 0x0 0xffd01008 0x0 0x100 0x0 0xff636000 0x0 0x2000 - 0x0 0xff63a000 0x0 0x2000>; + 0x0 0xff63a000 0x0 0x2000 + 0x0 0xff8000e8 0x0 0x10 + 0x0 0xff63c100 0x0 0x4>; pll-setting-1 = <0x09400414>; pll-setting-2 = <0x927E0000>; - pll-setting-3 = <0xac5f49e5>; + pll-setting-3 = <0xac5f69e5>; pll-setting-4 = <0xfe18>; pll-setting-5 = <0x8000fff>; pll-setting-6 = <0x78000>; pll-setting-7 = <0xe0004>; pll-setting-8 = <0xe000c>; + version = <2>; + pwr-ctl = <1>; }; usb3_phy_v2: usb3phy@ffe09080 { compatible = "amlogic, amlogic-new-usb3-v2"; status = "disable"; - reg = <0x0 0xffe09080 0x0 0x20>; + reg = <0x0 0xffe09080 0x0 0x20 + 0x0 0xff8000e8 0x0 0x10 + 0x0 0xff63c100 0x0 0x4 + 0x0 0xffd01008 0x0 0x100>; phy-reg = <0xff646000>; phy-reg-size = <0x2000>; usb2-phy-reg = <0xffe09000>; @@ -396,6 +403,7 @@ interrupts = <0 16 4>; clocks = <&clkc CLKID_PCIE_PLL>; clock-names = "pcie_refpll"; + pwr-ctl = <1>; }; dwc2_a: dwc2_a@ff400000 { @@ -418,7 +426,7 @@ phy-reg = <0xffe09000>; phy-reg-size = <0xa0>; /** phy-interface: 0x0: amlogic phy, 0x1: synopsys phy **/ - phy-interface = <0x0>; + phy-interface = <0x2>; clocks = <&clkc CLKID_USB_GENERAL &clkc CLKID_USB1_TO_DDR>; clock-names = "usb_general", @@ -1015,8 +1023,11 @@ 0x0 0xff648000 0x0 0x2000 0x0 0xfc400000 0x0 0x200000 0x0 0xff646000 0x0 0x2000 - 0x0 0xffd01080 0x0 0x10>; - reg-names = "elbi", "cfg", "config", "phy", "reset"; + 0x0 0xffd01080 0x0 0x10 + 0x0 0xff8000e8 0x0 0x8 + 0x0 0xff63c100 0x0 0x4>; + reg-names = "elbi", "cfg", "config", "phy", + "reset", "pwr", "hii"; interrupts = <0 221 0>; #interrupt-cells = <1>; bus-range = <0x0 0xff>; @@ -1043,6 +1054,7 @@ pcie-apb-rst-bit = <15>; pcie-phy-rst-bit = <14>; pcie-ctrl-a-rst-bit = <12>; + pwr-ctl = <1>; status = "disabled"; }; diff --git a/arch/arm64/boot/dts/amlogic/sm1_s905d3_ac200.dts b/arch/arm64/boot/dts/amlogic/sm1_s905d3_ac200.dts index b58c7a8..dbf8a83 100644 --- a/arch/arm64/boot/dts/amlogic/sm1_s905d3_ac200.dts +++ b/arch/arm64/boot/dts/amlogic/sm1_s905d3_ac200.dts @@ -1390,7 +1390,7 @@ }; &dwc3 { - status = "disabled"; + status = "okay"; }; &usb2_phy_v2 { @@ -1407,7 +1407,7 @@ }; &dwc2_a { - status = "disabled"; + status = "okay"; /** 0: normal, 1: otg+dwc3 host only, 2: otg+dwc3 device only*/ controller-type = <3>; }; diff --git a/arch/arm64/boot/dts/amlogic/sm1_s905d3_skt.dts b/arch/arm64/boot/dts/amlogic/sm1_s905d3_skt.dts index 3986d59..0ea4e99 100644 --- a/arch/arm64/boot/dts/amlogic/sm1_s905d3_skt.dts +++ b/arch/arm64/boot/dts/amlogic/sm1_s905d3_skt.dts @@ -1390,7 +1390,7 @@ }; &dwc3 { - status = "disalbed"; + status = "okay"; }; &usb2_phy_v2 { @@ -1400,14 +1400,14 @@ &usb3_phy_v2 { status = "okay"; - portnum = <1>; + portnum = <0>; otg = <1>; gpio-vbus-power = "GPIOH_6"; gpios = <&gpio GPIOH_6 GPIO_ACTIVE_HIGH>; }; &dwc2_a { - status = "disalbed"; + status = "okay"; /** 0: normal, 1: otg+dwc3 host only, 2: otg+dwc3 device only*/ controller-type = <3>; }; @@ -1594,7 +1594,7 @@ &pcie_A { reset-gpio = <&gpio GPIOX_7 GPIO_ACTIVE_HIGH>; - status = "disable"; + status = "okay"; }; &meson_cooldev { diff --git a/drivers/amlogic/clk/g12a/g12a_clk-pll.c b/drivers/amlogic/clk/g12a/g12a_clk-pll.c index 505a6aa..318079b 100644 --- a/drivers/amlogic/clk/g12a/g12a_clk-pll.c +++ b/drivers/amlogic/clk/g12a/g12a_clk-pll.c @@ -271,7 +271,8 @@ static int meson_g12a_pll_set_rate(struct clk_hw *hw, unsigned long rate, cntlbase = pll->base + p->reg_off; if (!strcmp(clk_hw_get_name(hw), "pcie_pll")) { - if (get_cpu_type() == MESON_CPU_MAJOR_ID_G12A) { + if ((get_cpu_type() == MESON_CPU_MAJOR_ID_G12A) || + ((get_cpu_type() == MESON_CPU_MAJOR_ID_SM1))) { writel(G12A_PCIE_PLL_CNTL0_0, cntlbase + (unsigned long)(0*4)); writel(G12A_PCIE_PLL_CNTL0_1, diff --git a/drivers/amlogic/pci/pcie-amlogic-v2.c b/drivers/amlogic/pci/pcie-amlogic-v2.c index 527ed28..8b9454f 100644 --- a/drivers/amlogic/pci/pcie-amlogic-v2.c +++ b/drivers/amlogic/pci/pcie-amlogic-v2.c @@ -51,6 +51,7 @@ struct amlogic_pcie { u32 pm_enable; u32 device_attch; u32 rst_mod; + u32 pwr_ctl; }; #define to_amlogic_pcie(x) container_of(x, struct amlogic_pcie, pp) @@ -679,6 +680,31 @@ static int __init amlogic_add_pcie_port(struct amlogic_pcie *amlogic_pcie, return 0; } +static void power_switch_to_pcie(struct pcie_phy *phy) +{ + u32 val; + + writel(readl(phy->power_base) & (~(0x1<<18)), phy->power_base); + + writel(readl(phy->hhi_mem_pd_base) & (~(0xf<<26)), + phy->hhi_mem_pd_base); + udelay(100); + + val = readl((void __iomem *)(unsigned long)phy->reset_base); + writel((val & (~(0x1<<12))), + (void __iomem *)(unsigned long)phy->reset_base); + udelay(100); + + writel(readl(phy->power_base+0x4) & (~(0x1<<18)), + phy->power_base + 0x4); + + val = readl((void __iomem *)(unsigned long)phy->reset_base); + writel((val | (0x1<<12)), + (void __iomem *)(unsigned long)phy->reset_base); + udelay(100); +} + + static int __init amlogic_pcie_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -690,6 +716,8 @@ static int __init amlogic_pcie_probe(struct platform_device *pdev) struct resource *phy_base; struct resource *cfg_base; struct resource *reset_base; + struct resource *power_base = NULL; + struct resource *hhi_mem_pd_base = NULL; int ret; int pcie_num = 0; int num_lanes = 0; @@ -703,6 +731,7 @@ static int __init amlogic_pcie_probe(struct platform_device *pdev) int pcie_apb_rst_bit = 0; int pcie_phy_rst_bit = 0; int pcie_ctrl_a_rst_bit = 0; + u32 pwr_ctl = 0; dev_info(&pdev->dev, "amlogic_pcie_probe!\n"); @@ -757,6 +786,49 @@ static int __init amlogic_pcie_probe(struct platform_device *pdev) pp->lanes = 0; pp->lanes = num_lanes; + ret = of_property_read_u32(np, "pwr-ctl", &pwr_ctl); + if (ret) + amlogic_pcie->pwr_ctl = 0; + else + amlogic_pcie->pwr_ctl = pwr_ctl; + + if (pwr_ctl) { + power_base = platform_get_resource_byname( + pdev, IORESOURCE_MEM, "pwr"); + if (power_base) { + amlogic_pcie->phy->power_base = + ioremap(power_base->start, + resource_size(power_base)); + if (IS_ERR(amlogic_pcie->phy->power_base)) + return PTR_ERR(amlogic_pcie->phy->power_base); + } + + hhi_mem_pd_base = platform_get_resource_byname( + pdev, IORESOURCE_MEM, "hii"); + if (hhi_mem_pd_base) { + amlogic_pcie->phy->hhi_mem_pd_base = + ioremap(hhi_mem_pd_base->start, + resource_size(hhi_mem_pd_base)); + if (IS_ERR(amlogic_pcie->phy->hhi_mem_pd_base)) + return PTR_ERR(amlogic_pcie-> + phy->hhi_mem_pd_base); + } + } + + if (!amlogic_pcie->phy->reset_base) { + reset_base = platform_get_resource_byname( + pdev, IORESOURCE_MEM, "reset"); + amlogic_pcie->phy->reset_base = devm_ioremap_resource( + dev, reset_base); + if (IS_ERR(amlogic_pcie->phy->reset_base)) { + ret = PTR_ERR(amlogic_pcie->phy->reset_base); + return ret; + } + } + + if (pwr_ctl) + power_switch_to_pcie(amlogic_pcie->phy); + if (!amlogic_pcie->phy->phy_base) { phy_base = platform_get_resource_byname( pdev, IORESOURCE_MEM, "phy"); @@ -783,17 +855,6 @@ static int __init amlogic_pcie_probe(struct platform_device *pdev) amlogic_pcie->reset_gpio = of_get_named_gpio(np, "reset-gpio", 0); - if (!amlogic_pcie->phy->reset_base) { - reset_base = platform_get_resource_byname( - pdev, IORESOURCE_MEM, "reset"); - amlogic_pcie->phy->reset_base = devm_ioremap_resource( - dev, reset_base); - if (IS_ERR(amlogic_pcie->phy->reset_base)) { - ret = PTR_ERR(amlogic_pcie->phy->reset_base); - goto fail_pcie; - } - } - /* RESET0[1,2,6,7] = 0*/ if (!amlogic_pcie->phy->reset_state) { if (amlogic_pcie->rst_mod == 0) { diff --git a/drivers/amlogic/pci/pcie-amlogic.h b/drivers/amlogic/pci/pcie-amlogic.h index d3fca81..88a6b87 100644 --- a/drivers/amlogic/pci/pcie-amlogic.h +++ b/drivers/amlogic/pci/pcie-amlogic.h @@ -162,6 +162,8 @@ struct pcie_phy { u32 reset_state; void __iomem *phy_base; /* DT 1st resource */ void __iomem *reset_base;/* DT 3nd resource */ + void __iomem *power_base; + void __iomem *hhi_mem_pd_base; }; 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 e2b55e8d..1dc5072 100644 --- a/drivers/amlogic/usb/phy/phy-aml-new-usb2-v2.c +++ b/drivers/amlogic/usb/phy/phy-aml-new-usb2-v2.c @@ -223,6 +223,26 @@ static void amlogic_new_usb2phy_shutdown(struct usb_phy *x) phy->suspend_flag = 1; } +void power_switch_to_usb(struct amlogic_usb_v2 *phy) +{ + /* Powerup usb_comb */ + writel(readl(phy->power_base) & (~(0x1<<17)), phy->power_base); + writel(readl(phy->hhi_mem_pd_base) & (~(0x3<<30)), + phy->hhi_mem_pd_base); + udelay(100); + + writel((readl(phy->reset_regs + (0x21 * 4 - 0x8)) & ~(0x1 << 2)), + phy->reset_regs + (0x21 * 4 - 0x8)); + + udelay(100); + writel(readl(phy->power_base+0x4) & (~(0x1<<17)), + phy->power_base + 0x4); + + writel((readl(phy->reset_regs + (0x21 * 4 - 0x8)) | (0x1 << 2)), + phy->reset_regs + (0x21 * 4 - 0x8)); + udelay(100); +} + static int amlogic_new_usb2_probe(struct platform_device *pdev) { struct amlogic_usb_v2 *phy; @@ -230,15 +250,20 @@ static int amlogic_new_usb2_probe(struct platform_device *pdev) struct resource *phy_mem; struct resource *reset_mem; struct resource *phy_cfg_mem[4]; + struct resource *power_mem = NULL; + struct resource *hhi_mem_pd_mem = NULL; void __iomem *phy_base; void __iomem *reset_base = NULL; void __iomem *phy_cfg_base[4]; + void __iomem *power_base = NULL; + void __iomem *hhi_mem_pd_base = NULL; int portnum = 0; int phy_version = 0; const void *prop; int i = 0; int retval; u32 pll_setting[8]; + u32 pwr_ctl = 0; prop = of_get_property(dev->of_node, "portnum", NULL); if (prop) @@ -284,6 +309,32 @@ static int amlogic_new_usb2_probe(struct platform_device *pdev) } } + prop = of_get_property(dev->of_node, "pwr-ctl", NULL); + if (prop) + pwr_ctl = of_read_ulong(prop, 1); + else + pwr_ctl = 0; + + if (pwr_ctl) { + power_mem = platform_get_resource + (pdev, IORESOURCE_MEM, 2 + portnum); + if (power_mem) { + power_base = ioremap(power_mem->start, + resource_size(power_mem)); + if (IS_ERR(power_base)) + return PTR_ERR(power_base); + } + + hhi_mem_pd_mem = platform_get_resource + (pdev, IORESOURCE_MEM, 3 + portnum); + if (hhi_mem_pd_mem) { + hhi_mem_pd_base = ioremap(hhi_mem_pd_mem->start, + resource_size(hhi_mem_pd_mem)); + if (IS_ERR(hhi_mem_pd_base)) + return PTR_ERR(hhi_mem_pd_base); + } + } + phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL); if (!phy) return -ENOMEM; @@ -351,12 +402,19 @@ static int amlogic_new_usb2_probe(struct platform_device *pdev) phy->pll_setting[7] = pll_setting[7]; phy->suspend_flag = 0; phy->phy_version = phy_version; + phy->pwr_ctl = pwr_ctl; for (i = 0; i < portnum; i++) { phy->phy_cfg[i] = phy_cfg_base[i]; /* set port default tuning state */ phy->phy_cfg_state[i] = 1; } + if (pwr_ctl) { + phy->power_base = power_base; + phy->hhi_mem_pd_base = hhi_mem_pd_base; + power_switch_to_usb(phy); + } + usb_add_phy_dev(&phy->phy); platform_set_drvdata(pdev, phy); 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 727cdd8..0f1839b 100644 --- a/drivers/amlogic/usb/phy/phy-aml-new-usb3-v2.c +++ b/drivers/amlogic/usb/phy/phy-aml-new-usb3-v2.c @@ -145,7 +145,6 @@ static void cr_bus_addr(unsigned int addr) phy_r4.b.phy_cr_data_in = addr; writel(phy_r4.d32, g_phy_v2->phy3_cfg_r4); - phy_r4.b.phy_cr_cap_addr = 0; writel(phy_r4.d32, g_phy_v2->phy3_cfg_r4); phy_r4.b.phy_cr_cap_addr = 1; @@ -312,6 +311,7 @@ static int amlogic_new_usb3_init(struct usb_phy *x) p3_r2.b.phy_tx_vboost_lvl = 0x4; writel(p3_r2.d32, phy->phy3_cfg_r2); udelay(2); + /* * WORKAROUND: There is SSPHY suspend bug due to * which USB enumerates @@ -482,13 +482,44 @@ static bool device_is_available(const struct device_node *device) return false; } +static void power_switch_to_pcie(struct amlogic_usb_v2 *phy) +{ + u32 val; + + writel(readl(phy->power_base) & (~(0x1<<18)), phy->power_base); + + writel(readl(phy->hhi_mem_pd_base) & (~(0xf<<26)), + phy->hhi_mem_pd_base); + udelay(100); + + val = readl((void __iomem *) + ((unsigned long)phy->reset_regs + (0x20 * 4 - 0x8))); + writel((val & (~(0x1<<12))), (void __iomem *) + ((unsigned long)phy->reset_regs + (0x20 * 4 - 0x8))); + udelay(100); + + writel(readl(phy->power_base+0x4) & (~(0x1<<18)), + phy->power_base + 0x4); + val = readl((void __iomem *) + ((unsigned long)phy->reset_regs + (0x20 * 4 - 0x8))); + writel((val | (0x1<<12)), (void __iomem *) + ((unsigned long)phy->reset_regs + (0x20 * 4 - 0x8))); + udelay(100); +} + static int amlogic_new_usb3_v2_probe(struct platform_device *pdev) { struct amlogic_usb_v2 *phy; struct device *dev = &pdev->dev; struct resource *phy_mem; - void __iomem *phy_base; + struct resource *power_mem = NULL; + struct resource *hhi_mem_pd_mem = NULL; + struct resource *reset_mem; + void __iomem *phy_base; void __iomem *phy3_base; + void __iomem *power_base = NULL; + void __iomem *hhi_mem_pd_base = NULL; + void __iomem *reset_base = NULL; unsigned int phy3_mem; unsigned int phy3_mem_size = 0; void __iomem *usb2_phy_base; @@ -504,6 +535,7 @@ static int amlogic_new_usb3_v2_probe(struct platform_device *pdev) int otg = 0; int ret; struct device_node *tsi_pci; + u32 pwr_ctl = 0; gpio_name = of_get_property(dev->of_node, "gpio-vbus-power", NULL); if (gpio_name) { @@ -554,6 +586,38 @@ static int amlogic_new_usb3_v2_probe(struct platform_device *pdev) if (!phy3_base) return -ENOMEM; + prop = of_get_property(dev->of_node, "pwr-ctl", NULL); + if (prop) + pwr_ctl = of_read_ulong(prop, 1); + else + pwr_ctl = 0; + + if (pwr_ctl) { + power_mem = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (power_mem) { + power_base = ioremap(power_mem->start, + resource_size(power_mem)); + if (IS_ERR(power_base)) + return PTR_ERR(power_base); + } + + hhi_mem_pd_mem = platform_get_resource(pdev, IORESOURCE_MEM, 2); + if (hhi_mem_pd_mem) { + hhi_mem_pd_base = ioremap(hhi_mem_pd_mem->start, + resource_size(hhi_mem_pd_mem)); + if (IS_ERR(hhi_mem_pd_base)) + return PTR_ERR(hhi_mem_pd_base); + } + + reset_mem = platform_get_resource(pdev, IORESOURCE_MEM, 3); + if (reset_mem) { + reset_base = ioremap(reset_mem->start, + resource_size(reset_mem)); + if (IS_ERR(reset_base)) + return PTR_ERR(reset_base); + } + } + retval = of_property_read_u32 (dev->of_node, "usb2-phy-reg", &usb2_phy_mem); if (retval < 0) @@ -615,9 +679,16 @@ static int amlogic_new_usb3_v2_probe(struct platform_device *pdev) phy->phy.flags = AML_USB3_PHY_DISABLE; phy->vbus_power_pin = gpio_vbus_power_pin; phy->usb_gpio_desc = usb_gd; + phy->pwr_ctl = pwr_ctl; /* set the phy from pcie to usb3 */ if (phy->portnum > 0) { + if (phy->pwr_ctl) { + phy->power_base = power_base; + phy->hhi_mem_pd_base = hhi_mem_pd_base; + phy->reset_regs = reset_base; + power_switch_to_pcie(phy); + } writel((readl(phy->phy3_cfg) | (3<<5)), phy->phy3_cfg); udelay(100); @@ -634,6 +705,7 @@ static int amlogic_new_usb3_v2_probe(struct platform_device *pdev) ret = PTR_ERR(phy->clk); return ret; } + phy->phy.flags = AML_USB3_PHY_ENABLE; } diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index a4d1b83..6b14a82 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -760,6 +760,7 @@ static int dwc3_core_init(struct dwc3 *dwc) ret = dwc3_phy_setup(dwc); if (ret) goto err0; + #ifdef CONFIG_AMLOGIC_USB reg = dwc3_readl(dwc->regs, DWC3_GUCTL1); reg |= DWC3_GUCTL_NAKPERENHHS; @@ -1553,7 +1554,9 @@ MODULE_DEVICE_TABLE(acpi, dwc3_acpi_match); #endif static struct platform_driver dwc3_driver = { +#ifndef CONFIG_AMLOGIC_USB .probe = dwc3_probe, +#endif .remove = dwc3_remove, #ifdef CONFIG_AMLOGIC_USB .shutdown = dwc3_shutdown, @@ -1566,7 +1569,16 @@ static struct platform_driver dwc3_driver = { }, }; +#ifdef CONFIG_AMLOGIC_USB +/* AMLOGIC DWC3 driver does not allow module unload */ +static int __init amlogic_dwc3_init(void) +{ + return platform_driver_probe(&dwc3_driver, dwc3_probe); +} +late_initcall(amlogic_dwc3_init); +#else module_platform_driver(dwc3_driver); +#endif MODULE_ALIAS("platform:dwc3"); MODULE_AUTHOR("Felipe Balbi "); diff --git a/include/linux/amlogic/usb-v2.h b/include/linux/amlogic/usb-v2.h index f3e8f08..dc3774e 100644 --- a/include/linux/amlogic/usb-v2.h +++ b/include/linux/amlogic/usb-v2.h @@ -169,6 +169,8 @@ struct amlogic_usb_v2 { void __iomem *phy3_cfg_r4; void __iomem *phy3_cfg_r5; void __iomem *usb2_phy_cfg; + void __iomem *power_base; + void __iomem *hhi_mem_pd_base; u32 pll_setting[8]; int phy_cfg_state[4]; /* Set VBus Power though GPIO */ @@ -180,6 +182,7 @@ struct amlogic_usb_v2 { int portnum; int suspend_flag; int phy_version; + int pwr_ctl; struct clk *clk; };