usb: bringup TM2 usb3 [1/1]
authorYue Wang <yue.wang@amlogic.com>
Thu, 4 Apr 2019 03:18:28 +0000 (11:18 +0800)
committerJianxiong Pan <jianxiong.pan@amlogic.com>
Thu, 11 Apr 2019 05:30:55 +0000 (13:30 +0800)
PD#SWPL-5609

Problem:
bringup TM2 usb3.

Solution:
bringup TM2 usb3.

Verify:
TM2

Change-Id: Iea60a85e7d344f8f1cd44d07a634a6edd351218c
Signed-off-by: Yue Wang <yue.wang@amlogic.com>
25 files changed:
MAINTAINERS
arch/arm/boot/dts/amlogic/mesontm2.dtsi
arch/arm/boot/dts/amlogic/tm2_t962e2_ab301.dts
arch/arm/boot/dts/amlogic/tm2_t962e2_ab311.dts
arch/arm/boot/dts/amlogic/tm2_t962e2_ab319.dts
arch/arm/boot/dts/amlogic/tm2_t962x3_ab309.dts
arch/arm64/boot/dts/amlogic/mesontm2.dtsi
arch/arm64/boot/dts/amlogic/tm2_t962e2_ab301.dts
arch/arm64/boot/dts/amlogic/tm2_t962e2_ab311.dts
arch/arm64/boot/dts/amlogic/tm2_t962e2_ab319.dts
arch/arm64/boot/dts/amlogic/tm2_t962x3_ab309.dts
drivers/amlogic/pci/pcie-amlogic-v2.c
drivers/amlogic/pci/pcie-amlogic.h
drivers/amlogic/usb/dwc_otg/310/dwc_otg_cil.h
drivers/amlogic/usb/dwc_otg/310/dwc_otg_driver.c
drivers/amlogic/usb/dwc_otg/310/dwc_otg_driver.h
drivers/amlogic/usb/dwc_otg/310/dwc_otg_pcd.h
drivers/amlogic/usb/dwc_otg/310/dwc_otg_pcd_intr.c
drivers/amlogic/usb/dwc_otg/310/dwc_otg_pcd_linux.c
drivers/amlogic/usb/phy/Makefile
drivers/amlogic/usb/phy/phy-aml-new-otg.c [new file with mode: 0644]
drivers/amlogic/usb/phy/phy-aml-new-usb3-v2.c
drivers/amlogic/usb/phy/phy-aml-new-usb3-v3.c [new file with mode: 0644]
drivers/usb/dwc3/core.c
include/linux/amlogic/usb-v2.h

index 7cb297b..a5396e7 100644 (file)
@@ -13554,6 +13554,7 @@ F:      drivers/amlogic/esm/*
 AMLOGIC DWC_OTG USB
 M: Yue Wang <yue.wang@amlogic.com>
 F: drivers/amlogic/usb/*
+F: drivers/amlogic/usb/phy/phy-aml-new-otg.c
 F: drivers/usb/phy/phy-aml-new-usb.h
 F: drivers/usb/phy/phy-aml-new-usb.c
 F: drivers/usb/phy/phy-aml-new-usb2.c
@@ -13562,6 +13563,7 @@ F: drivers/usb/phy/phy-aml-new-usb-v2.h
 F: drivers/usb/phy/phy-aml-new-usb-v2.c
 F: drivers/usb/phy/phy-aml-new-usb2-v2.c
 F: drivers/usb/phy/phy-aml-new-usb3-v2.c
+F: drivers/amlogic/usb/phy/phy-aml-new-usb3-v3.c
 F: drivers/usb/phy/phy-aml-usb.h
 F: drivers/usb/phy/phy-aml-usb.c
 F: drivers/usb/phy/phy-aml-usb2.c
index 813422e..d27619d 100644 (file)
@@ -24,6 +24,7 @@
 #include <dt-bindings/pwm/meson.h>
 #include <dt-bindings/clock/amlogic,tl1-clkc.h>
 #include <dt-bindings/clock/amlogic,tl1-audio-clk.h>
+#include <dt-bindings/phy/phy-amlogic-pcie.h>
 #include "mesong12a-bifrost.dtsi"
 #include <dt-bindings/iio/adc/amlogic-saradc.h>
 / {
                clock-src = "usb3.0";
                clocks = <&clkc CLKID_USB_GENERAL>;
                clock-names = "dwc_general";
+               snps,quirk-frame-length-adjustment = <0x20>;
        };
 
        usb2_phy_v2: usb2phy@ffe09000 {
        };
 
        usb3_phy_v2: usb3phy@ffe09080 {
-               compatible = "amlogic, amlogic-new-usb3-v2";
+               compatible = "amlogic, amlogic-new-usb3-v3";
                status = "disable";
-               reg = <0xffe09080 0x20
-                       0xffd01008 0x100>;
-               phy-reg = <0xff646000>;
-               phy-reg-size = <0x2000>;
+               reg = <0xffe09080 0x20>;
+               phy0-reg = <0xff646000>;
+               phy0-reg-size = <0x2000>;
+               phy1-reg = <0xff65c000>;
+               phy1-reg-size = <0x2000>;
+               reset-reg = <0xffd01008>;
+               reset-reg-size = <0x100>;
+               clocks = <&clkc CLKID_PCIE0_GATE
+                               &clkc CLKID_PCIE_PLL
+                               &clkc CLKID_PCIE1_GATE>;
+               clock-names = "pcie0_gate",
+                               "pcie_refpll",
+                               "pcie1_gate";
+               pwr-ctl = <1>;
+               u30-ctrl-sleep-shift = <18>;
+               u30-hhi-mem-pd-shift = <26>;
+               u30-hhi-mem-pd-mask = <0xf>;
+               u30-ctrl-iso-shift = <18>;
+               usb30-ctrl-a-rst-bit = <12>;
+               u31-ctrl-sleep-shift = <20>;
+               u31-hhi-mem-pd-shift = <4>;
+               u31-hhi-mem-pd-mask = <0xf>;
+               u31-ctrl-iso-shift = <20>;
+               usb31-ctrl-a-rst-bit = <28>;
+       };
+
+       usb_otg: usbotg@ffe09080 {
+               compatible = "amlogic, amlogic-new-otg";
+               status = "disabled";
                usb2-phy-reg = <0xffe09000>;
-               usb2-phy-reg-size = <0x80>;
+               usb2-phy-reg-size = <0x100>;
                interrupts = <0 16 4>;
-               pwr-ctl = <1>;
-               u3-ctrl-sleep-shift = <18>;
-               u3-hhi-mem-pd-shift = <26>;
-               u3-hhi-mem-pd-mask = <0xf>;
-               u3-ctrl-iso-shift = <18>;
        };
 
+
        dwc2_a: dwc2_a@ff400000 {
                compatible = "amlogic, dwc2";
                status = "disabled";
                /** phy-interface: 0x0: amlogic-v1 phy, 0x1: synopsys phy **/
                /**                0x2: amlogic-v2 phy                    **/
                phy-interface = <0x2>;
+               phy-otg = <0x1>;
                clocks = <&clkc CLKID_USB_GENERAL
                                        &clkc CLKID_USB1_TO_DDR>;
                clock-names = "usb_general",
                pinctrl-0 = <&c_uart_pins>;
        };
 
+
+       pcie_A: pcieA@fc000000 {
+               compatible = "amlogic, amlogic-pcie-v2", "snps,dw-pcie";
+               reg = <0xfc000000 0x400000
+                       0xff648000 0x2000
+                       0xfc400000 0x200000
+                       0xff646000 0x2000
+                       0xffd01080 0x10>;
+               reg-names = "elbi", "cfg", "config", "phy", "reset";
+               interrupts = <0 221 0>;
+               #interrupt-cells = <1>;
+               bus-range = <0x0 0xff>;
+               #address-cells = <3>;
+               #size-cells = <2>;
+               interrupt-map-mask = <0 0 0 0>;
+               interrupt-map = <0 0 0 0 &gic GIC_SPI 223 IRQ_TYPE_EDGE_RISING>;
+               device_type = "pci";
+               ranges = <0x81000000 0 0 0xfc600000 0x0 0x100000
+                       /* downstream I/O */
+                       0x82000000 0xfc700000 0x0 0xfc700000 0 0x1900000>;
+                       /* non-prefetchable memory */
+               num-lanes = <1>;
+               pcie-num = <1>;
+
+               clocks = <&clkc CLKID_PCIE0_GATE
+                       &clkc CLKID_PCIE1
+                       &clkc CLKID_PCIE0PHY>;
+               clock-names = "pcie_refpll",
+                               "pcie",
+                               "pcie_phy";
+               /*reset-gpio-type 0:Shared pad(no reset)1:OD pad2:Normal pad*/
+               gpio-type = <2>;
+               pcie-apb-rst-bit = <15>;
+               pcie-phy-rst-bit = <14>;
+               pcie-ctrl-a-rst-bit = <12>;
+               pwr-ctl = <1>;
+               pcie-ctrl-sleep-shift = <18>;
+               pcie-hhi-mem-pd-shift = <26>;
+               pcie-hhi-mem-pd-mask = <0xf>;
+               pcie-ctrl-iso-shift = <18>;
+               status = "disabled";
+       };
+
+       pcie_B: pcieB@fc000000 {
+               compatible = "amlogic, amlogic-pcie-v2", "snps,dw-pcie";
+               reg = <0xfA000000 0x400000
+                       0xff65E000 0x2000
+                       0xfA400000 0x200000
+                       0xff65C000 0x2000
+                       0xffd01080 0x10>;
+               reg-names = "elbi", "cfg", "config", "phy",
+                               "reset";
+               interrupts = <0 229 0>;
+               #interrupt-cells = <1>;
+               bus-range = <0x0 0xff>;
+               #address-cells = <3>;
+               #size-cells = <2>;
+               interrupt-map-mask = <0 0 0 0>;
+               interrupt-map = <0 0 0 0 &gic GIC_SPI 231 IRQ_TYPE_EDGE_RISING>;
+               device_type = "pci";
+               ranges = <0x81000000 0 0 0xfA600000 0x0 0x100000
+                       /* downstream I/O */
+                       0x82000000 0xfA700000 0x0 0xfA700000 0 0x1900000>;
+                       /* non-prefetchable memory */
+               num-lanes = <1>;
+               pcie-num = <1>;
+
+               clocks = <&clkc CLKID_PCIE1_GATE
+                       &clkc CLKID_PCIE1
+                       &clkc CLKID_PCIE1PHY>;
+               clock-names = "pcie_refpll",
+                               "pcie",
+                               "pcie_phy";
+               /*reset-gpio-type 0:Shared pad(no reset)1:OD pad2:Normal pad*/
+               gpio-type = <2>;
+               pcie-apb-rst-bit = <30>;
+               pcie-phy-rst-bit = <29>;
+               pcie-ctrl-a-rst-bit = <28>;
+               pwr-ctl = <1>;
+               pcie-ctrl-sleep-shift = <20>;
+               pcie-hhi-mem-pd-shift = <4>;
+               pcie-hhi-mem-pd-mask = <0xf>;
+               pcie-ctrl-iso-shift = <20>;
+               status = "disabled";
+       };
+
        sd_emmc_c: emmc@ffe07000 {
                status = "disabled";
                compatible = "amlogic, meson-mmc-tm2";
index a5b02d1..3b78519 100644 (file)
 
 &usb3_phy_v2 {
        status = "okay";
-       portnum = <0>;
+       portnum = <2>;
+       portconfig-30 = <1>;
+       portconfig-31 = <1>;
+};
+
+&usb_otg {
+       status = "okay";
        otg = <0>;
 };
 
        controller-type = <1>;
 };
 
+&pcie_A {
+       reset-gpio = <&gpio_ao GPIOAO_4 GPIO_ACTIVE_HIGH>;
+       status = "disable";
+};
+
+&pcie_B {
+       /* ab311 only pcie a, no pcie b */
+       status = "disable";
+};
+
 &spicc0 {
        status = "okay";
        pinctrl-names = "default";
index f2ebfbf..ec1fc22 100644 (file)
 
 &usb3_phy_v2 {
        status = "okay";
-       portnum = <0>;
+       portnum = <2>;
+       portconfig-30 = <1>;
+       portconfig-31 = <1>;
+};
+
+&usb_otg {
+       status = "okay";
        otg = <0>;
 };
 
        controller-type = <1>;
 };
 
+&pcie_A {
+       reset-gpio = <&gpio_ao GPIOAO_4 GPIO_ACTIVE_HIGH>;
+       status = "disable";
+};
+
+&pcie_B {
+       /* ab311 only pcie a, no pcie b */
+       status = "disable";
+};
+
 &spicc0 {
        status = "okay";
        pinctrl-names = "default";
index 3e4bb2f..1be6b71 100644 (file)
 
 &usb3_phy_v2 {
        status = "okay";
-       portnum = <0>;
+       portnum = <2>;
+       portconfig-30 = <1>;
+       portconfig-31 = <1>;
+};
+
+&usb_otg {
+       status = "okay";
        otg = <0>;
 };
 
        controller-type = <1>;
 };
 
+&pcie_A {
+       reset-gpio = <&gpio_ao GPIOAO_11 GPIO_ACTIVE_HIGH>;
+       status = "disable";
+};
+
+&pcie_B {
+       /* pcie b reset gpio is the oe pad, must be changed */
+       reset-gpio = <&gpio GPIOH_22 GPIO_ACTIVE_HIGH>;
+       status = "disable";
+};
+
 &spicc0 {
        status = "okay";
        pinctrl-names = "default";
index 519816f..de76c5a 100644 (file)
 
 &usb3_phy_v2 {
        status = "okay";
-       portnum = <0>;
+       portnum = <2>;
+       portconfig-30 = <1>;
+       portconfig-31 = <1>;
+};
+
+&usb_otg {
+       status = "okay";
        otg = <0>;
 };
 
        controller-type = <1>;
 };
 
+&pcie_A {
+       /* pcie a reset gpio must be updated */
+       reset-gpio = <&gpio_ao GPIOAO_11 GPIO_ACTIVE_HIGH>;
+       status = "disable";
+};
+
+&pcie_B {
+       /* pcie b reset gpio must be updated */
+       reset-gpio = <&gpio GPIOH_22 GPIO_ACTIVE_HIGH>;
+       status = "disable";
+};
+
 &spicc0 {
        status = "okay";
        pinctrl-names = "default";
index 51d46b4..1148019 100644 (file)
@@ -24,6 +24,7 @@
 #include <dt-bindings/pwm/meson.h>
 #include <dt-bindings/clock/amlogic,tl1-clkc.h>
 #include <dt-bindings/clock/amlogic,tl1-audio-clk.h>
+#include <dt-bindings/phy/phy-amlogic-pcie.h>
 #include "mesong12a-bifrost.dtsi"
 #include <dt-bindings/iio/adc/amlogic-saradc.h>
 / {
                clock-src = "usb3.0";
                clocks = <&clkc CLKID_USB_GENERAL>;
                clock-names = "dwc_general";
+               snps,quirk-frame-length-adjustment = <0x20>;
        };
 
        usb2_phy_v2: usb2phy@ffe09000 {
        };
 
        usb3_phy_v2: usb3phy@ffe09080 {
-               compatible = "amlogic, amlogic-new-usb3-v2";
+               compatible = "amlogic, amlogic-new-usb3-v3";
                status = "disable";
-               reg = <0x0 0xffe09080 0x0 0x20
-                       0x0 0xffd01008 0x0 0x100>;
-               phy-reg = <0xff646000>;
-               phy-reg-size = <0x2000>;
+               reg = <0x0 0xffe09080 0x0 0x20>;
+               phy0-reg = <0xff646000>;
+               phy0-reg-size = <0x2000>;
+               phy1-reg = <0xff65c000>;
+               phy1-reg-size = <0x2000>;
+               reset-reg = <0xffd01008>;
+               reset-reg-size = <0x100>;
+               clocks = <&clkc CLKID_PCIE0_GATE
+                               &clkc CLKID_PCIE_PLL
+                               &clkc CLKID_PCIE1_GATE>;
+               clock-names = "pcie0_gate",
+                               "pcie_refpll",
+                               "pcie1_gate";
+               pwr-ctl = <1>;
+               u30-ctrl-sleep-shift = <18>;
+               u30-hhi-mem-pd-shift = <26>;
+               u30-hhi-mem-pd-mask = <0xf>;
+               u30-ctrl-iso-shift = <18>;
+               usb30-ctrl-a-rst-bit = <12>;
+               u31-ctrl-sleep-shift = <20>;
+               u31-hhi-mem-pd-shift = <4>;
+               u31-hhi-mem-pd-mask = <0xf>;
+               u31-ctrl-iso-shift = <20>;
+               usb31-ctrl-a-rst-bit = <28>;
+       };
+
+       usb_otg: usbotg@ffe09080 {
+               compatible = "amlogic, amlogic-new-otg";
+               status = "disabled";
                usb2-phy-reg = <0xffe09000>;
-               usb2-phy-reg-size = <0x80>;
+               usb2-phy-reg-size = <0x100>;
                interrupts = <0 16 4>;
-               pwr-ctl = <1>;
-               u3-ctrl-sleep-shift = <18>;
-               u3-hhi-mem-pd-shift = <26>;
-               u3-hhi-mem-pd-mask = <0xf>;
-               u3-ctrl-iso-shift = <18>;
        };
 
+
        dwc2_a: dwc2_a@ff400000 {
                compatible = "amlogic, dwc2";
                status = "disabled";
                /** phy-interface: 0x0: amlogic-v1 phy, 0x1: synopsys phy **/
                /**                0x2: amlogic-v2 phy                    **/
                phy-interface = <0x2>;
+               phy-otg = <0x1>;
                clocks = <&clkc CLKID_USB_GENERAL
                                        &clkc CLKID_USB1_TO_DDR>;
                clock-names = "usb_general",
                pinctrl-0 = <&c_uart_pins>;
        };
 
+
+       pcie_A: pcieA@fc000000 {
+               compatible = "amlogic, amlogic-pcie-v2", "snps,dw-pcie";
+               reg = <0x0 0xfc000000 0x0 0x400000
+                       0x0 0xff648000 0x0 0x2000
+                       0x0 0xfc400000 0x0 0x200000
+                       0x0 0xff646000 0x0 0x2000
+                       0x0 0xffd01080 0x0 0x10>;
+               reg-names = "elbi", "cfg", "config", "phy", "reset";
+               interrupts = <0 221 0>;
+               #interrupt-cells = <1>;
+               bus-range = <0x0 0xff>;
+               #address-cells = <3>;
+               #size-cells = <2>;
+               interrupt-map-mask = <0 0 0 0>;
+               interrupt-map = <0 0 0 0 &gic GIC_SPI 223 IRQ_TYPE_EDGE_RISING>;
+               device_type = "pci";
+               ranges = <0x81000000 0 0 0 0xfc600000 0x0 0x100000
+                       /* downstream I/O */
+                       0x82000000 0 0xfc700000 0x0 0xfc700000 0 0x1900000>;
+                       /* non-prefetchable memory */
+               num-lanes = <1>;
+               pcie-num = <1>;
+
+               clocks = <&clkc CLKID_PCIE0_GATE
+                       &clkc CLKID_PCIE1
+                       &clkc CLKID_PCIE0PHY>;
+               clock-names = "pcie_refpll",
+                               "pcie",
+                               "pcie_phy";
+               /*reset-gpio-type 0:Shared pad(no reset)1:OD pad2:Normal pad*/
+               gpio-type = <2>;
+               pcie-apb-rst-bit = <15>;
+               pcie-phy-rst-bit = <14>;
+               pcie-ctrl-a-rst-bit = <12>;
+               pwr-ctl = <1>;
+               pcie-ctrl-sleep-shift = <18>;
+               pcie-hhi-mem-pd-shift = <26>;
+               pcie-hhi-mem-pd-mask = <0xf>;
+               pcie-ctrl-iso-shift = <18>;
+               status = "disabled";
+       };
+
+       pcie_B: pcieB@fc000000 {
+               compatible = "amlogic, amlogic-pcie-v2", "snps,dw-pcie";
+               reg = <0x0 0xfA000000 0x0 0x400000
+                       0x0 0xff65E000 0x0 0x2000
+                       0x0 0xfA400000 0x0 0x200000
+                       0x0 0xff65C000 0x0 0x2000
+                       0x0 0xffd01080 0x0 0x10>;
+               reg-names = "elbi", "cfg", "config", "phy",
+                               "reset";
+               interrupts = <0 229 0>;
+               #interrupt-cells = <1>;
+               bus-range = <0x0 0xff>;
+               #address-cells = <3>;
+               #size-cells = <2>;
+               interrupt-map-mask = <0 0 0 0>;
+               interrupt-map = <0 0 0 0 &gic GIC_SPI 231 IRQ_TYPE_EDGE_RISING>;
+               device_type = "pci";
+               ranges = <0x81000000 0 0 0 0xfA600000 0x0 0x100000
+                       /* downstream I/O */
+                       0x82000000 0 0xfA700000 0x0 0xfA700000 0 0x1900000>;
+                       /* non-prefetchable memory */
+               num-lanes = <1>;
+               pcie-num = <1>;
+
+               clocks = <&clkc CLKID_PCIE1_GATE
+                       &clkc CLKID_PCIE1
+                       &clkc CLKID_PCIE1PHY>;
+               clock-names = "pcie_refpll",
+                               "pcie",
+                               "pcie_phy";
+               /*reset-gpio-type 0:Shared pad(no reset)1:OD pad2:Normal pad*/
+               gpio-type = <2>;
+               pcie-apb-rst-bit = <30>;
+               pcie-phy-rst-bit = <29>;
+               pcie-ctrl-a-rst-bit = <28>;
+               pwr-ctl = <1>;
+               pcie-ctrl-sleep-shift = <20>;
+               pcie-hhi-mem-pd-shift = <4>;
+               pcie-hhi-mem-pd-mask = <0xf>;
+               pcie-ctrl-iso-shift = <20>;
+               status = "disabled";
+       };
+
        sd_emmc_c: emmc@ffe07000 {
                status = "disabled";
                compatible = "amlogic, meson-mmc-tm2";
index 6b7dd05..47f6b86 100644 (file)
 
 &usb3_phy_v2 {
        status = "okay";
-       portnum = <0>;
+       portnum = <2>;
+       portconfig-30 = <1>;
+       portconfig-31 = <1>;
+};
+
+&usb_otg {
+       status = "okay";
        otg = <0>;
 };
 
        controller-type = <1>;
 };
 
+&pcie_A {
+       reset-gpio = <&gpio_ao GPIOAO_4 GPIO_ACTIVE_HIGH>;
+       status = "disable";
+};
+
+&pcie_B {
+       /* ab311 only pcie a, no pcie b */
+       status = "disable";
+};
+
 &spicc0 {
        status = "okay";
        pinctrl-names = "default";
index 6a8b347..0d498b3 100644 (file)
 
 &usb3_phy_v2 {
        status = "okay";
-       portnum = <0>;
+       portnum = <2>;
+       portconfig-30 = <1>;
+       portconfig-31 = <1>;
+};
+
+&usb_otg {
+       status = "okay";
        otg = <0>;
 };
 
        controller-type = <1>;
 };
 
+&pcie_A {
+       reset-gpio = <&gpio_ao GPIOAO_4 GPIO_ACTIVE_HIGH>;
+       status = "disable";
+};
+
+&pcie_B {
+       /* ab311 only pcie a, no pcie b */
+       status = "disable";
+};
+
 &spicc0 {
        status = "okay";
        pinctrl-names = "default";
index 6308ca8..c95cc9a 100644 (file)
 
 &usb3_phy_v2 {
        status = "okay";
-       portnum = <0>;
+       portnum = <2>;
+       portconfig-30 = <1>;
+       portconfig-31 = <1>;
+};
+
+&usb_otg {
+       status = "okay";
        otg = <0>;
 };
 
        controller-type = <1>;
 };
 
+&pcie_A {
+       reset-gpio = <&gpio_ao GPIOAO_11 GPIO_ACTIVE_HIGH>;
+       status = "disable";
+};
+
+&pcie_B {
+       /* pcie b reset gpio is the oe pad, must be changed */
+       reset-gpio = <&gpio GPIOH_22 GPIO_ACTIVE_HIGH>;
+       status = "disable";
+};
+
 &spicc0 {
        status = "okay";
        pinctrl-names = "default";
index 5ad6c91..674debc 100644 (file)
 
 &usb3_phy_v2 {
        status = "okay";
-       portnum = <0>;
+       portnum = <2>;
+       portconfig-30 = <1>;
+       portconfig-31 = <1>;
+};
+
+&usb_otg {
+       status = "okay";
        otg = <0>;
 };
 
        controller-type = <1>;
 };
 
+&pcie_A {
+       /* pcie a reset gpio must be updated */
+       reset-gpio = <&gpio_ao GPIOAO_11 GPIO_ACTIVE_HIGH>;
+       status = "disable";
+};
+
+&pcie_B {
+       /* pcie b reset gpio must be updated */
+       reset-gpio = <&gpio GPIOH_22 GPIO_ACTIVE_HIGH>;
+       status = "disable";
+};
+
 &spicc0 {
        status = "okay";
        pinctrl-names = "default";
index 479e445..2bb169c 100644 (file)
@@ -57,7 +57,6 @@ struct amlogic_pcie {
 
 #define to_amlogic_pcie(x)     container_of(x, struct amlogic_pcie, pp)
 struct pcie_phy_aml_regs pcie_aml_regs_v2;
-struct pcie_phy                *g_pcie_phy_v2;
 
 static void amlogic_elb_writel(struct amlogic_pcie *amlogic_pcie, u32 val,
                                                                u32 reg)
@@ -673,6 +672,7 @@ static int __init amlogic_add_pcie_port(struct amlogic_pcie *amlogic_pcie,
                dev_err(pp->dev, "link timeout, disable PCIE PLL\n");
                clk_disable_unprepare(amlogic_pcie->bus_clk);
                clk_disable_unprepare(amlogic_pcie->clk);
+               clk_disable_unprepare(amlogic_pcie->phy_clk);
                dev_err(pp->dev, "power down pcie phy\n");
                writel(0x1d, pcie_aml_regs_v2.pcie_phy_r[0]);
                amlogic_pcie->phy->power_state = 0;
@@ -692,14 +692,14 @@ static void power_switch_to_pcie(struct pcie_phy *phy)
        udelay(100);
 
        val = readl((void __iomem *)(unsigned long)phy->reset_base);
-       writel((val & (~(0x1<<12))),
+       writel((val & (~(0x1<<phy->pcie_ctrl_a_rst_bit))),
                (void __iomem *)(unsigned long)phy->reset_base);
        udelay(100);
 
        power_ctrl_iso(1, phy->pcie_ctrl_iso_shift);
 
        val = readl((void __iomem *)(unsigned long)phy->reset_base);
-       writel((val | (0x1<<12)),
+       writel((val | (0x1<<phy->pcie_ctrl_a_rst_bit)),
                        (void __iomem   *)(unsigned long)phy->reset_base);
        udelay(100);
 }
@@ -744,16 +744,6 @@ static int __init amlogic_pcie_probe(struct platform_device *pdev)
        pp->dev = dev;
        port_num++;
        amlogic_pcie->port_num = port_num;
-       if (amlogic_pcie->port_num == 1) {
-               phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
-               if (!phy) {
-                       port_num--;
-                       return -ENOMEM;
-               }
-               g_pcie_phy_v2 = phy;
-       }
-
-       amlogic_pcie->phy = g_pcie_phy_v2;
 
        ret = of_property_read_u32(np, "pcie-apb-rst-bit", &pcie_apb_rst_bit);
        if (ret)
@@ -768,6 +758,15 @@ static int __init amlogic_pcie_probe(struct platform_device *pdev)
        if (ret)
                amlogic_pcie->rst_mod = 0;
 
+       phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
+       if (!phy) {
+               port_num--;
+               return -ENOMEM;
+       }
+       phy->pcie_ctrl_a_rst_bit = pcie_ctrl_a_rst_bit;
+
+       amlogic_pcie->phy = phy;
+
        ret = of_property_read_u32(np, "pcie-num", &pcie_num);
        if (ret)
                amlogic_pcie->pcie_num = 0;
@@ -828,8 +827,8 @@ static int __init amlogic_pcie_probe(struct platform_device *pdev)
        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);
+               amlogic_pcie->phy->reset_base = ioremap(reset_base->start,
+                               resource_size(reset_base));
                if (IS_ERR(amlogic_pcie->phy->reset_base)) {
                        ret = PTR_ERR(amlogic_pcie->phy->reset_base);
                        return ret;
@@ -901,10 +900,8 @@ static int __init amlogic_pcie_probe(struct platform_device *pdev)
 
        if (!amlogic_pcie->phy->reset_state) {
                rate = clk_get_rate(amlogic_pcie->bus_clk);
-               if (rate != PCIE_PLL_RATE) {
-                       ret = -ENODEV;
-                       goto fail_pcie;
-               }
+               if (rate != PCIE_PLL_RATE)
+                       dev_info(dev, "pcie ref pll is 0x%lx\n", rate);
        }
 
        /*RESET0[6,7] = 1*/
index 394a33a..38a7683 100644 (file)
@@ -166,6 +166,7 @@ struct pcie_phy {
        u32 pcie_hhi_mem_pd_mask;
        u32 pcie_ctrl_iso_shift;
        u32 pcie_hhi_mem_pd_shift;
+       u32 pcie_ctrl_a_rst_bit;
 };
 
 
index a58ba8c..3c8ef42 100644 (file)
@@ -1060,6 +1060,8 @@ struct dwc_otg_core_if {
 
        uint32_t phy_interface;
 
+       uint32_t phy_otg;
+
        dwc_timer_t *device_connect_timer;
 
        uint64_t sof_counter;
index 3ce109b..263ed2c 100644 (file)
@@ -958,6 +958,7 @@ static int dwc_otg_driver_probe(struct platform_device *pdev)
        unsigned int p_ctrl_reg_addr = 0;
        unsigned int phy_reg_addr_size = 0;
        unsigned int phy_interface = 1;
+       unsigned int phy_otg = 0;
        const char *s_clock_name = NULL;
        const char *cpu_type = NULL;
        const char *gpio_name = NULL;
@@ -1059,6 +1060,10 @@ static int dwc_otg_driver_probe(struct platform_device *pdev)
                        if (prop)
                                phy_interface = of_read_ulong(prop, 1);
 
+                       prop = of_get_property(of_node, "phy-otg", NULL);
+                       if (prop)
+                               phy_otg = of_read_ulong(prop, 1);
+
                        if (is_meson_g12b_cpu()) {
                                if (!is_meson_rev_a())
                                        phy_interface = 2;
@@ -1162,6 +1167,7 @@ static int dwc_otg_driver_probe(struct platform_device *pdev)
        dwc_otg_device->core_if->usb_peri_reg = (usb_peri_reg_t *)phy_reg_addr;
        dwc_otg_device->core_if->controller_type = controller_type;
        dwc_otg_device->core_if->phy_interface = phy_interface;
+       dwc_otg_device->core_if->phy_otg = phy_otg;
        /*
        * Attempt to ensure this device is really a DWC_otg Controller.
        * Read and verify the SNPSID register contents. The value should be
@@ -1407,10 +1413,14 @@ static int dwc_otg_driver_probe(struct platform_device *pdev)
 
 #ifdef CONFIG_AMLOGIC_USB3PHY
        if (dwc_otg_device->core_if->controller_type == USB_OTG) {
-               if (dwc_otg_device->core_if->phy_interface == 1)
+               if (dwc_otg_device->core_if->phy_interface == 1) {
                        aml_new_usb_init();
-               else
-                       aml_new_usb_v2_init();
+               } else {
+                       if (dwc_otg_device->core_if->phy_otg)
+                               aml_new_otg_init();
+                       else
+                               aml_new_usb_v2_init();
+               }
        }
 #endif
 
index 897f515..6927292 100644 (file)
@@ -47,6 +47,7 @@
 #ifdef CONFIG_AMLOGIC_USB3PHY
 extern void aml_new_usb_init(void);
 extern void aml_new_usb_v2_init(void);
+extern void aml_new_otg_init(void);
 #endif
 
 /* Type declarations */
index 38a153f..8fbe4a4 100644 (file)
@@ -275,6 +275,7 @@ void dwc_otg_iso_buffer_done(dwc_otg_pcd_t *pcd, dwc_otg_pcd_ep_t *ep,
 
 extern void do_test_mode(void *data);
 extern int aml_new_usb_get_mode(void);
+extern int aml_new_otg_get_mode(void);
 #ifdef CONFIG_AMLOGIC_USB3PHY
 extern void set_usb_phy_device_tuning(int port, int default_val);
 #endif
index 3382a6a..cd503c6 100644 (file)
@@ -1067,14 +1067,30 @@ int32_t dwc_otg_pcd_handle_enum_done_intr(dwc_otg_pcd_t *pcd)
        if (GET_CORE_IF(pcd)->phy_interface != 1) {
                if (GET_CORE_IF(pcd)->controller_type == USB_OTG) {
                        speed = get_device_speed(GET_CORE_IF(pcd));
-                       if ((speed != USB_SPEED_HIGH) &&
-                               (aml_new_usb_get_mode() != 1)) {
-                               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)->phy_otg == 1) {
+                               if ((speed != USB_SPEED_HIGH) &&
+                                       (aml_new_otg_get_mode() != 1)) {
+                                       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;
+                               }
+                       } else {
+                               if ((speed != USB_SPEED_HIGH) &&
+                                       (aml_new_usb_get_mode() != 1)) {
+                                       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;
+                               }
                        }
                }
 
index 6ba3f16..2ad6baf 100644 (file)
@@ -1304,10 +1304,14 @@ int pcd_init(struct platform_device *pdev)
        }
 
 #ifdef CONFIG_AMLOGIC_USB3PHY
-       if (otg_dev->core_if->phy_interface == 1)
+       if (otg_dev->core_if->phy_interface == 1) {
                aml_new_usb_register_notifier(&otg_dev->nb);
-       else
-               aml_new_usb_v2_register_notifier(&otg_dev->nb);
+       } else {
+               if (otg_dev->core_if->phy_otg == 1)
+                       aml_new_otg_register_notifier(&otg_dev->nb);
+               else
+                       aml_new_usb_v2_register_notifier(&otg_dev->nb);
+       }
        otg_dev->nb.notifier_call = dwc_usb_change;
 #endif
 
@@ -1375,10 +1379,14 @@ void pcd_remove(struct platform_device *pdev)
        free_wrapper(gadget_wrapper);
        dwc_otg_pcd_remove(otg_dev->pcd);
 #ifdef CONFIG_AMLOGIC_USB3PHY
-       if (otg_dev->core_if->phy_interface == 1)
+       if (otg_dev->core_if->phy_interface == 1) {
                aml_new_usb_unregister_notifier(&otg_dev->nb);
-       else
-               aml_new_usb_v2_unregister_notifier(&otg_dev->nb);
+       } else {
+               if (otg_dev->core_if->phy_otg == 1)
+                       aml_new_otg_unregister_notifier(&otg_dev->nb);
+               else
+                       aml_new_usb_v2_unregister_notifier(&otg_dev->nb);
+       }
 #endif
        otg_dev->pcd = 0;
 }
index 22433e1..47a6d6d 100644 (file)
@@ -8,3 +8,5 @@ obj-$(CONFIG_AMLOGIC_USB3PHY)           += phy-aml-new-usb3.o
 obj-$(CONFIG_AMLOGIC_USBPHY)            += phy-aml-new-usb-v2.o
 obj-$(CONFIG_AMLOGIC_USB2PHY)           += phy-aml-new-usb2-v2.o
 obj-$(CONFIG_AMLOGIC_USB3PHY)           += phy-aml-new-usb3-v2.o
+obj-$(CONFIG_AMLOGIC_USB3PHY)           += phy-aml-new-usb3-v3.o
+obj-$(CONFIG_AMLOGIC_USB3PHY)           += phy-aml-new-otg.o
diff --git a/drivers/amlogic/usb/phy/phy-aml-new-otg.c b/drivers/amlogic/usb/phy/phy-aml-new-otg.c
new file mode 100644 (file)
index 0000000..d4d4f18
--- /dev/null
@@ -0,0 +1,388 @@
+/*
+ * drivers/amlogic/usb/phy/phy-aml-new-otg.c
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/irqreturn.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/pm_runtime.h>
+#include <linux/delay.h>
+#include <linux/usb/phy.h>
+#include <linux/amlogic/usb-v2.h>
+#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
+#define DEVICE_MODE    1
+
+struct usb_aml_regs_v2 usb_otg_aml_regs;
+struct amlogic_otg     *g_otg;
+
+struct amlogic_otg {
+       struct device           *dev;
+       void __iomem    *phy3_cfg;
+       void __iomem    *phy3_cfg_r1;
+       void __iomem    *phy3_cfg_r2;
+       void __iomem    *phy3_cfg_r4;
+       void __iomem    *phy3_cfg_r5;
+       void __iomem    *usb2_phy_cfg;
+       /* Set VBus Power though GPIO */
+       int vbus_power_pin;
+       int vbus_power_pin_work_mask;
+       struct delayed_work     work;
+       struct gpio_desc *usb_gpio_desc;
+};
+
+static void set_mode(unsigned long reg_addr, int mode);
+BLOCKING_NOTIFIER_HEAD(aml_new_otg_notifier_list);
+
+int aml_new_otg_register_notifier(struct notifier_block *nb)
+{
+       int ret;
+
+       ret = blocking_notifier_chain_register
+                       (&aml_new_otg_notifier_list, nb);
+
+       return ret;
+}
+EXPORT_SYMBOL(aml_new_otg_register_notifier);
+
+int aml_new_otg_unregister_notifier(struct notifier_block *nb)
+{
+       int ret;
+
+       ret = blocking_notifier_chain_unregister
+                       (&aml_new_otg_notifier_list, nb);
+
+       return ret;
+}
+EXPORT_SYMBOL(aml_new_otg_unregister_notifier);
+
+static void aml_new_usb_notifier_call(unsigned long is_device_on)
+{
+       blocking_notifier_call_chain
+                       (&aml_new_otg_notifier_list, is_device_on, NULL);
+}
+
+static void set_usb_vbus_power
+       (struct gpio_desc *usb_gd, int pin, char is_power_on)
+{
+       if (is_power_on)
+               /*set vbus on by gpio*/
+               gpiod_direction_output(usb_gd, 1);
+       else
+               /*set vbus off by gpio first*/
+               gpiod_direction_output(usb_gd, 0);
+}
+
+static void amlogic_new_set_vbus_power
+               (struct amlogic_otg *phy, char is_power_on)
+{
+       if (phy->vbus_power_pin != -1)
+               set_usb_vbus_power(phy->usb_gpio_desc,
+                       phy->vbus_power_pin, is_power_on);
+}
+
+
+
+void aml_new_otg_init(void)
+{
+       union usb_r5_v2 r5 = {.d32 = 0};
+       unsigned long reg_addr;
+
+       if (!g_otg)
+               return;
+
+       reg_addr = (unsigned long)g_otg->usb2_phy_cfg;
+
+       r5.d32 = readl(usb_otg_aml_regs.usb_r_v2[5]);
+       if (r5.b.iddig_curr == 0) {
+               amlogic_new_set_vbus_power(g_otg, 1);
+               aml_new_usb_notifier_call(0);
+               set_mode(reg_addr, HOST_MODE);
+       }
+}
+EXPORT_SYMBOL(aml_new_otg_init);
+
+int aml_new_otg_get_mode(void)
+{
+       union usb_r5_v2 r5 = {.d32 = 0};
+
+       r5.d32 = readl(usb_otg_aml_regs.usb_r_v2[5]);
+       if (r5.b.iddig_curr == 0)
+               return 0;
+       else
+               return 1;
+}
+EXPORT_SYMBOL(aml_new_otg_get_mode);
+
+
+static int amlogic_new_otg_init(struct amlogic_otg *phy)
+{
+       union usb_r1_v2 r1 = {.d32 = 0};
+       union usb_r5_v2 r5 = {.d32 = 0};
+       int i = 0;
+
+       for (i = 0; i < 6; i++) {
+               usb_otg_aml_regs.usb_r_v2[i] = (void __iomem *)
+                       ((unsigned long)phy->usb2_phy_cfg + 0x80 + 4*i);
+       }
+
+       r1.d32 = readl(usb_otg_aml_regs.usb_r_v2[1]);
+       r1.b.u3h_fladj_30mhz_reg = 0x20;
+       writel(r1.d32, usb_otg_aml_regs.usb_r_v2[1]);
+
+       r5.d32 = readl(usb_otg_aml_regs.usb_r_v2[5]);
+       r5.b.iddig_en0 = 1;
+       r5.b.iddig_en1 = 1;
+       r5.b.iddig_th = 255;
+       writel(r5.d32, usb_otg_aml_regs.usb_r_v2[5]);
+
+       return 0;
+}
+
+static void set_mode(unsigned long reg_addr, int mode)
+{
+       struct u2p_aml_regs_v2 u2p_aml_regs;
+       struct usb_aml_regs_v2 usb_gxl_aml_regs;
+       union u2p_r0_v2 reg0;
+       union usb_r0_v2 r0 = {.d32 = 0};
+       union usb_r4_v2 r4 = {.d32 = 0};
+
+       u2p_aml_regs.u2p_r_v2[0] = (void __iomem        *)
+                               ((unsigned long)reg_addr + PHY_REGISTER_SIZE);
+
+       usb_gxl_aml_regs.usb_r_v2[0] = (void __iomem *)
+                               ((unsigned long)reg_addr + 4*PHY_REGISTER_SIZE
+                               + 4*0);
+       usb_gxl_aml_regs.usb_r_v2[1] = (void __iomem *)
+                               ((unsigned long)reg_addr + 4*PHY_REGISTER_SIZE
+                               + 4*1);
+       usb_gxl_aml_regs.usb_r_v2[4] = (void __iomem *)
+                               ((unsigned long)reg_addr + 4*PHY_REGISTER_SIZE
+                               + 4*4);
+
+       r0.d32 = readl(usb_gxl_aml_regs.usb_r_v2[0]);
+       if (mode == DEVICE_MODE) {
+               r0.b.u2d_act = 1;
+               r0.b.u2d_ss_scaledown_mode = 0;
+       } else
+               r0.b.u2d_act = 0;
+       writel(r0.d32, usb_gxl_aml_regs.usb_r_v2[0]);
+
+       r4.d32 = readl(usb_gxl_aml_regs.usb_r_v2[4]);
+       if (mode == DEVICE_MODE)
+               r4.b.p21_SLEEPM0 = 0x1;
+       else
+               r4.b.p21_SLEEPM0 = 0x0;
+       writel(r4.d32, usb_gxl_aml_regs.usb_r_v2[4]);
+
+       reg0.d32 = readl(u2p_aml_regs.u2p_r_v2[0]);
+       if (mode == DEVICE_MODE) {
+               reg0.b.host_device = 0;
+               reg0.b.POR = 0;
+       } else {
+               reg0.b.host_device = 1;
+               reg0.b.POR = 0;
+       }
+       writel(reg0.d32, u2p_aml_regs.u2p_r_v2[0]);
+
+       udelay(500);
+}
+
+static void amlogic_gxl_work(struct work_struct *work)
+{
+       struct amlogic_otg *phy =
+               container_of(work, struct amlogic_otg, work.work);
+       union usb_r5_v2 r5 = {.d32 = 0};
+       unsigned long reg_addr = ((unsigned long)phy->usb2_phy_cfg);
+
+       r5.d32 = readl(usb_otg_aml_regs.usb_r_v2[5]);
+       if (r5.b.iddig_curr == 0) {
+               amlogic_new_set_vbus_power(phy, 1);
+               aml_new_usb_notifier_call(0);
+               set_mode(reg_addr, HOST_MODE);
+       } else {
+               set_mode(reg_addr, DEVICE_MODE);
+               aml_new_usb_notifier_call(1);
+               amlogic_new_set_vbus_power(phy, 0);
+       }
+       r5.b.usb_iddig_irq = 0;
+       writel(r5.d32, usb_otg_aml_regs.usb_r_v2[5]);
+}
+
+static irqreturn_t amlogic_botg_detect_irq(int irq, void *dev)
+{
+       struct amlogic_otg *phy = (struct amlogic_otg *)dev;
+       union usb_r5_v2 r5 = {.d32 = 0};
+
+       r5.d32 = readl(usb_otg_aml_regs.usb_r_v2[5]);
+       r5.b.usb_iddig_irq = 0;
+       writel(r5.d32, usb_otg_aml_regs.usb_r_v2[5]);
+
+       schedule_delayed_work(&phy->work, msecs_to_jiffies(10));
+
+       return IRQ_HANDLED;
+}
+
+static int amlogic_new_otg_probe(struct platform_device *pdev)
+{
+       struct amlogic_otg                      *phy;
+       struct device *dev = &pdev->dev;
+       void __iomem *usb2_phy_base;
+       unsigned int usb2_phy_mem;
+       unsigned int usb2_phy_mem_size = 0;
+       const char *gpio_name = NULL;
+       struct gpio_desc *usb_gd = NULL;
+       const void *prop;
+       int irq;
+       int retval;
+       int gpio_vbus_power_pin = -1;
+       int otg = 0;
+
+       gpio_name = of_get_property(dev->of_node, "gpio-vbus-power", NULL);
+       if (gpio_name) {
+               gpio_vbus_power_pin = 1;
+               usb_gd = gpiod_get_index(&pdev->dev,
+                                NULL, 0, GPIOD_OUT_LOW);
+               if (IS_ERR(usb_gd))
+                       return -1;
+       }
+
+       prop = of_get_property(dev->of_node, "otg", NULL);
+       if (prop)
+               otg = of_read_ulong(prop, 1);
+
+       retval = of_property_read_u32
+                               (dev->of_node, "usb2-phy-reg", &usb2_phy_mem);
+       if (retval < 0)
+               return -EINVAL;
+
+       retval = of_property_read_u32
+               (dev->of_node, "usb2-phy-reg-size", &usb2_phy_mem_size);
+       if (retval < 0)
+               return -EINVAL;
+
+       usb2_phy_base = devm_ioremap_nocache
+                               (&(pdev->dev), (resource_size_t)usb2_phy_mem,
+                               (unsigned long)usb2_phy_mem_size);
+       if (!usb2_phy_base)
+               return -ENOMEM;
+
+       phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL);
+       if (!phy)
+               return -ENOMEM;
+
+       if (otg) {
+               irq = platform_get_irq(pdev, 0);
+               if (irq < 0)
+                       return -ENODEV;
+               retval = request_irq(irq, amlogic_botg_detect_irq,
+                               IRQF_SHARED | IRQ_LEVEL,
+                               "amlogic_botg_detect", phy);
+
+               if (retval) {
+                       dev_err(&pdev->dev, "request of irq%d failed\n", irq);
+                       retval = -EBUSY;
+                       return retval;
+               }
+       }
+
+       dev_info(&pdev->dev, "phy_mem:0x%lx, iomap phy_base:0x%lx\n",
+                       (unsigned long)usb2_phy_mem,
+                       (unsigned long)usb2_phy_base);
+
+       phy->dev                = dev;
+       phy->usb2_phy_cfg       = usb2_phy_base;
+       phy->vbus_power_pin = gpio_vbus_power_pin;
+       phy->usb_gpio_desc = usb_gd;
+
+       INIT_DELAYED_WORK(&phy->work, amlogic_gxl_work);
+
+       platform_set_drvdata(pdev, phy);
+
+       pm_runtime_enable(phy->dev);
+       g_otg = phy;
+
+       amlogic_new_otg_init(phy);
+
+       return 0;
+}
+
+static int amlogic_new_otg_remove(struct platform_device *pdev)
+{
+       return 0;
+}
+
+#ifdef CONFIG_PM_RUNTIME
+
+static int amlogic_new_otg_runtime_suspend(struct device *dev)
+{
+       return 0;
+}
+
+static int amlogic_new_otg_runtime_resume(struct device *dev)
+{
+       u32 ret = 0;
+
+       return ret;
+}
+
+static const struct dev_pm_ops amlogic_new_otg_pm_ops = {
+       SET_RUNTIME_PM_OPS(amlogic_new_otg_runtime_suspend,
+               amlogic_new_otg_runtime_resume,
+               NULL)
+};
+
+#define DEV_PM_OPS     (&amlogic_new_otg_pm_ops)
+#else
+#define DEV_PM_OPS     NULL
+#endif
+
+#ifdef CONFIG_OF
+static const struct of_device_id amlogic_new_otg_id_table[] = {
+       { .compatible = "amlogic, amlogic-new-otg" },
+       {}
+};
+MODULE_DEVICE_TABLE(of, amlogic_new_otg_id_table);
+#endif
+
+static struct platform_driver amlogic_new_otg_driver = {
+       .probe          = amlogic_new_otg_probe,
+       .remove         = amlogic_new_otg_remove,
+       .driver         = {
+               .name   = "amlogic-new-otg",
+               .owner  = THIS_MODULE,
+               .pm     = DEV_PM_OPS,
+               .of_match_table = of_match_ptr(amlogic_new_otg_id_table),
+       },
+};
+
+module_platform_driver(amlogic_new_otg_driver);
+
+MODULE_ALIAS("platform: amlogic_usb3_v2");
+MODULE_AUTHOR("Amlogic Inc.");
+MODULE_DESCRIPTION("amlogic USB3 v2 phy driver");
+MODULE_LICENSE("GPL v2");
index 3c97500..ef22d47 100644 (file)
@@ -146,6 +146,7 @@ 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,7 +313,6 @@ 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
@@ -487,8 +487,9 @@ static void power_switch_to_pcie(struct amlogic_usb_v2 *phy)
 {
        u32 val;
 
-       power_ctrl_sleep(1, phy->u3_ctrl_sleep_shift);
-       power_ctrl_mempd0(1, phy->u3_hhi_mem_pd_mask, phy->u3_hhi_mem_pd_shift);
+       power_ctrl_sleep(1, phy->u30_ctrl_sleep_shift);
+       power_ctrl_mempd0(1, phy->u30_hhi_mem_pd_mask,
+                       phy->u30_hhi_mem_pd_shift);
        udelay(100);
 
        val = readl((void __iomem *)
@@ -497,7 +498,7 @@ static void power_switch_to_pcie(struct amlogic_usb_v2 *phy)
                ((unsigned long)phy->reset_regs + (0x20 * 4 - 0x8)));
        udelay(100);
 
-       power_ctrl_iso(1, phy->u3_ctrl_iso_shift);
+       power_ctrl_iso(1, phy->u30_ctrl_iso_shift);
 
        val = readl((void __iomem *)
                ((unsigned long)phy->reset_regs + (0x20 * 4 - 0x8)));
@@ -695,10 +696,10 @@ static int amlogic_new_usb3_v2_probe(struct platform_device *pdev)
        /* set the phy from pcie to usb3 */
        if (phy->portnum > 0) {
                if (phy->pwr_ctl) {
-                       phy->u3_ctrl_sleep_shift = u3_ctrl_sleep_shift;
-                       phy->u3_hhi_mem_pd_shift = u3_hhi_mem_pd_shift;
-                       phy->u3_hhi_mem_pd_mask = u3_hhi_mem_pd_mask;
-                       phy->u3_ctrl_iso_shift = u3_ctrl_iso_shift;
+                       phy->u30_ctrl_sleep_shift = u3_ctrl_sleep_shift;
+                       phy->u30_hhi_mem_pd_shift = u3_hhi_mem_pd_shift;
+                       phy->u30_hhi_mem_pd_mask = u3_hhi_mem_pd_mask;
+                       phy->u30_ctrl_iso_shift = u3_ctrl_iso_shift;
                        phy->reset_regs = reset_base;
                        power_switch_to_pcie(phy);
                }
@@ -718,7 +719,6 @@ 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/amlogic/usb/phy/phy-aml-new-usb3-v3.c b/drivers/amlogic/usb/phy/phy-aml-new-usb3-v3.c
new file mode 100644 (file)
index 0000000..86b4c9f
--- /dev/null
@@ -0,0 +1,918 @@
+/*
+ * drivers/amlogic/usb/phy/phy-aml-new-usb3-v3.c
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/irqreturn.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/pm_runtime.h>
+#include <linux/delay.h>
+#include <linux/usb/phy.h>
+#include <linux/amlogic/usb-v2.h>
+#include <linux/amlogic/aml_gpio_consumer.h>
+#include <linux/workqueue.h>
+#include <linux/notifier.h>
+#include <linux/amlogic/usbtype.h>
+#include <linux/amlogic/power_ctrl.h>
+#include "phy-aml-new-usb-v2.h"
+
+#define HOST_MODE      0
+#define DEVICE_MODE    1
+
+struct usb_aml_regs_v2 usb_new_aml_regs_v3;
+
+static int amlogic_new_usb3_suspend(struct usb_phy *x, int suspend)
+{
+       return 0;
+}
+
+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);
+               clk_disable_unprepare(phy->gate1_clk);
+               clk_disable_unprepare(phy->gate0_clk);
+       }
+
+       phy->suspend_flag = 1;
+}
+
+static void cr_bus_addr(struct amlogic_usb_v2 *phy_v3, unsigned int addr)
+{
+       union phy3_r4 phy_r4 = {.d32 = 0};
+       union phy3_r5 phy_r5 = {.d32 = 0};
+       unsigned long timeout_jiffies;
+
+       phy_r4.b.phy_cr_data_in = addr;
+       writel(phy_r4.d32, phy_v3->phy3_cfg_r4);
+
+       phy_r4.b.phy_cr_cap_addr = 0;
+       writel(phy_r4.d32, phy_v3->phy3_cfg_r4);
+       phy_r4.b.phy_cr_cap_addr = 1;
+       writel(phy_r4.d32, phy_v3->phy3_cfg_r4);
+       timeout_jiffies = jiffies +
+                       msecs_to_jiffies(1000);
+       do {
+               phy_r5.d32 = readl(phy_v3->phy3_cfg_r5);
+       } while (phy_r5.b.phy_cr_ack == 0 &&
+               time_is_after_jiffies(timeout_jiffies));
+
+       phy_r4.b.phy_cr_cap_addr = 0;
+       writel(phy_r4.d32, phy_v3->phy3_cfg_r4);
+       timeout_jiffies = jiffies +
+                       msecs_to_jiffies(1000);
+       do {
+               phy_r5.d32 = readl(phy_v3->phy3_cfg_r5);
+       } while (phy_r5.b.phy_cr_ack == 1 &&
+               time_is_after_jiffies(timeout_jiffies));
+}
+
+static int cr_bus_read(struct amlogic_usb_v2 *phy_v3, unsigned int addr)
+{
+       int data;
+       union phy3_r4 phy_r4 = {.d32 = 0};
+       union phy3_r5 phy_r5 = {.d32 = 0};
+       unsigned long timeout_jiffies;
+
+       cr_bus_addr(phy_v3, addr);
+
+       phy_r4.b.phy_cr_read = 0;
+       writel(phy_r4.d32, phy_v3->phy3_cfg_r4);
+       phy_r4.b.phy_cr_read = 1;
+       writel(phy_r4.d32, phy_v3->phy3_cfg_r4);
+
+       timeout_jiffies = jiffies +
+                       msecs_to_jiffies(1000);
+       do {
+               phy_r5.d32 = readl(phy_v3->phy3_cfg_r5);
+       } while (phy_r5.b.phy_cr_ack == 0 &&
+               time_is_after_jiffies(timeout_jiffies));
+
+       data = phy_r5.b.phy_cr_data_out;
+
+       phy_r4.b.phy_cr_read = 0;
+       writel(phy_r4.d32, phy_v3->phy3_cfg_r4);
+       timeout_jiffies = jiffies +
+                       msecs_to_jiffies(1000);
+       do {
+               phy_r5.d32 = readl(phy_v3->phy3_cfg_r5);
+       } while (phy_r5.b.phy_cr_ack == 1 &&
+               time_is_after_jiffies(timeout_jiffies));
+
+       return data;
+}
+
+static void cr_bus_write(struct amlogic_usb_v2 *phy_v3,
+       unsigned int addr, unsigned int data)
+{
+       union phy3_r4 phy_r4 = {.d32 = 0};
+       union phy3_r5 phy_r5 = {.d32 = 0};
+       unsigned long timeout_jiffies;
+
+       cr_bus_addr(phy_v3, addr);
+
+       phy_r4.b.phy_cr_data_in = data;
+       writel(phy_r4.d32, phy_v3->phy3_cfg_r4);
+
+       phy_r4.b.phy_cr_cap_data = 0;
+       writel(phy_r4.d32, phy_v3->phy3_cfg_r4);
+       phy_r4.b.phy_cr_cap_data = 1;
+       writel(phy_r4.d32, phy_v3->phy3_cfg_r4);
+       timeout_jiffies = jiffies +
+               msecs_to_jiffies(1000);
+       do {
+               phy_r5.d32 = readl(phy_v3->phy3_cfg_r5);
+       } while (phy_r5.b.phy_cr_ack == 0 &&
+               time_is_after_jiffies(timeout_jiffies));
+
+       phy_r4.b.phy_cr_cap_data = 0;
+       writel(phy_r4.d32, phy_v3->phy3_cfg_r4);
+       timeout_jiffies = jiffies +
+               msecs_to_jiffies(1000);
+       do {
+               phy_r5.d32 = readl(phy_v3->phy3_cfg_r5);
+       } while (phy_r5.b.phy_cr_ack == 1 &&
+               time_is_after_jiffies(timeout_jiffies));
+
+       phy_r4.b.phy_cr_write = 0;
+       writel(phy_r4.d32, phy_v3->phy3_cfg_r4);
+       phy_r4.b.phy_cr_write = 1;
+       writel(phy_r4.d32, phy_v3->phy3_cfg_r4);
+       timeout_jiffies = jiffies +
+               msecs_to_jiffies(1000);
+       do {
+               phy_r5.d32 = readl(phy_v3->phy3_cfg_r5);
+       } while (phy_r5.b.phy_cr_ack == 0 &&
+               time_is_after_jiffies(timeout_jiffies));
+
+       phy_r4.b.phy_cr_write = 0;
+       writel(phy_r4.d32, phy_v3->phy3_cfg_r4);
+       timeout_jiffies = jiffies +
+               msecs_to_jiffies(1000);
+       do {
+               phy_r5.d32 = readl(phy_v3->phy3_cfg_r5);
+       } while (phy_r5.b.phy_cr_ack == 1 &&
+               time_is_after_jiffies(timeout_jiffies));
+}
+
+static void cr_bus_addr_31(struct amlogic_usb_v2 *phy_v3, unsigned int addr)
+{
+       union phy3_r4 phy_r4 = {.d32 = 0};
+       union phy3_r5 phy_r5 = {.d32 = 0};
+       unsigned long timeout_jiffies;
+
+       phy_r4.b.phy_cr_data_in = addr;
+       writel(phy_r4.d32, phy_v3->phy31_cfg_r4);
+
+       phy_r4.b.phy_cr_cap_addr = 0;
+       writel(phy_r4.d32, phy_v3->phy31_cfg_r4);
+       phy_r4.b.phy_cr_cap_addr = 1;
+       writel(phy_r4.d32, phy_v3->phy31_cfg_r4);
+       timeout_jiffies = jiffies +
+                       msecs_to_jiffies(1000);
+       do {
+               phy_r5.d32 = readl(phy_v3->phy31_cfg_r5);
+       } while (phy_r5.b.phy_cr_ack == 0 &&
+               time_is_after_jiffies(timeout_jiffies));
+
+       phy_r4.b.phy_cr_cap_addr = 0;
+       writel(phy_r4.d32, phy_v3->phy31_cfg_r4);
+       timeout_jiffies = jiffies +
+                       msecs_to_jiffies(1000);
+       do {
+               phy_r5.d32 = readl(phy_v3->phy31_cfg_r5);
+       } while (phy_r5.b.phy_cr_ack == 1 &&
+               time_is_after_jiffies(timeout_jiffies));
+}
+
+static int cr_bus_read_31(struct amlogic_usb_v2 *phy_v3, unsigned int addr)
+{
+       int data;
+       union phy3_r4 phy_r4 = {.d32 = 0};
+       union phy3_r5 phy_r5 = {.d32 = 0};
+       unsigned long timeout_jiffies;
+
+       cr_bus_addr_31(phy_v3, addr);
+
+       phy_r4.b.phy_cr_read = 0;
+       writel(phy_r4.d32, phy_v3->phy31_cfg_r4);
+       phy_r4.b.phy_cr_read = 1;
+       writel(phy_r4.d32, phy_v3->phy31_cfg_r4);
+
+       timeout_jiffies = jiffies +
+                       msecs_to_jiffies(1000);
+       do {
+               phy_r5.d32 = readl(phy_v3->phy31_cfg_r5);
+       } while (phy_r5.b.phy_cr_ack == 0 &&
+               time_is_after_jiffies(timeout_jiffies));
+
+       data = phy_r5.b.phy_cr_data_out;
+
+       phy_r4.b.phy_cr_read = 0;
+       writel(phy_r4.d32, phy_v3->phy31_cfg_r4);
+       timeout_jiffies = jiffies +
+                       msecs_to_jiffies(1000);
+       do {
+               phy_r5.d32 = readl(phy_v3->phy31_cfg_r5);
+       } while (phy_r5.b.phy_cr_ack == 1 &&
+               time_is_after_jiffies(timeout_jiffies));
+
+       return data;
+}
+
+static void cr_bus_write_31(struct amlogic_usb_v2 *phy_v3,
+       unsigned int addr, unsigned int data)
+{
+       union phy3_r4 phy_r4 = {.d32 = 0};
+       union phy3_r5 phy_r5 = {.d32 = 0};
+       unsigned long timeout_jiffies;
+
+       cr_bus_addr(phy_v3, addr);
+
+       phy_r4.b.phy_cr_data_in = data;
+       writel(phy_r4.d32, phy_v3->phy31_cfg_r4);
+
+       phy_r4.b.phy_cr_cap_data = 0;
+       writel(phy_r4.d32, phy_v3->phy31_cfg_r4);
+       phy_r4.b.phy_cr_cap_data = 1;
+       writel(phy_r4.d32, phy_v3->phy31_cfg_r4);
+       timeout_jiffies = jiffies +
+               msecs_to_jiffies(1000);
+       do {
+               phy_r5.d32 = readl(phy_v3->phy31_cfg_r5);
+       } while (phy_r5.b.phy_cr_ack == 0 &&
+               time_is_after_jiffies(timeout_jiffies));
+
+       phy_r4.b.phy_cr_cap_data = 0;
+       writel(phy_r4.d32, phy_v3->phy31_cfg_r4);
+       timeout_jiffies = jiffies +
+               msecs_to_jiffies(1000);
+       do {
+               phy_r5.d32 = readl(phy_v3->phy31_cfg_r5);
+       } while (phy_r5.b.phy_cr_ack == 1 &&
+               time_is_after_jiffies(timeout_jiffies));
+
+       phy_r4.b.phy_cr_write = 0;
+       writel(phy_r4.d32, phy_v3->phy31_cfg_r4);
+       phy_r4.b.phy_cr_write = 1;
+       writel(phy_r4.d32, phy_v3->phy31_cfg_r4);
+       timeout_jiffies = jiffies +
+               msecs_to_jiffies(1000);
+       do {
+               phy_r5.d32 = readl(phy_v3->phy31_cfg_r5);
+       } while (phy_r5.b.phy_cr_ack == 0 &&
+               time_is_after_jiffies(timeout_jiffies));
+
+       phy_r4.b.phy_cr_write = 0;
+       writel(phy_r4.d32, phy_v3->phy31_cfg_r4);
+       timeout_jiffies = jiffies +
+               msecs_to_jiffies(1000);
+       do {
+               phy_r5.d32 = readl(phy_v3->phy31_cfg_r5);
+       } while (phy_r5.b.phy_cr_ack == 1 &&
+               time_is_after_jiffies(timeout_jiffies));
+}
+
+static void usb3_phy_cr_config_30(struct amlogic_usb_v2 *phy)
+{
+       u32 data = 0;
+
+       /*
+        * WORKAROUND: There is SSPHY suspend bug due to
+        * which USB enumerates
+        * in HS mode instead of SS mode. Workaround it by asserting
+        * LANE0.TX_ALT_BLOCK.EN_ALT_BUS to enable TX to use alt bus
+        * mode
+        */
+       data = cr_bus_read(phy, 0x102d);
+       data |= (1 << 7);
+       cr_bus_write(phy, 0x102D, data);
+
+       data = cr_bus_read(phy, 0x1010);
+       data &= ~0xff0;
+       data |= 0x20;
+       cr_bus_write(phy, 0x1010, data);
+
+       /*
+        * Fix RX Equalization setting as follows
+        * LANE0.RX_OVRD_IN_HI. RX_EQ_EN set to 0
+        * LANE0.RX_OVRD_IN_HI.RX_EQ_EN_OVRD set to 1
+        * LANE0.RX_OVRD_IN_HI.RX_EQ set to 3
+        * LANE0.RX_OVRD_IN_HI.RX_EQ_OVRD set to 1
+        */
+       data = cr_bus_read(phy, 0x1006);
+       data &= ~(1 << 6);
+       data |= (1 << 7);
+       data &= ~(0x7 << 8);
+       data |= (0x3 << 8);
+       data |= (0x1 << 11);
+       cr_bus_write(phy, 0x1006, data);
+
+       /*
+        * S    et EQ and TX launch amplitudes as follows
+        * LANE0.TX_OVRD_DRV_LO.PREEMPH set to 22
+        * LANE0.TX_OVRD_DRV_LO.AMPLITUDE set to 127
+        * LANE0.TX_OVRD_DRV_LO.EN set to 1.
+        */
+       data = cr_bus_read(phy, 0x1002);
+       data &= ~0x3f80;
+       data |= (0x16 << 7);
+       data &= ~0x7f;
+       data |= (0x7f | (1 << 14));
+       cr_bus_write(phy, 0x1002, data);
+
+       /*
+        * MPLL_LOOP_CTL.PROP_CNTRL
+        */
+       data = cr_bus_read(phy, 0x30);
+       data &= ~(0xf << 4);
+       data |= (0x8 << 4);
+       cr_bus_write(phy, 0x30, data);
+       udelay(2);
+}
+
+
+static void usb3_phy_cr_config_31(struct amlogic_usb_v2 *phy)
+{
+       u32 data = 0;
+
+       /*
+        * WORKAROUND: There is SSPHY suspend bug due to
+        * which USB enumerates
+        * in HS mode instead of SS mode. Workaround it by asserting
+        * LANE0.TX_ALT_BLOCK.EN_ALT_BUS to enable TX to use alt bus
+        * mode
+        */
+       data = cr_bus_read_31(phy, 0x102d);
+       data |= (1 << 7);
+       cr_bus_write_31(phy, 0x102D, data);
+
+       data = cr_bus_read_31(phy, 0x1010);
+       data &= ~0xff0;
+       data |= 0x20;
+       cr_bus_write_31(phy, 0x1010, data);
+
+       /*
+        * Fix RX Equalization setting as follows
+        * LANE0.RX_OVRD_IN_HI. RX_EQ_EN set to 0
+        * LANE0.RX_OVRD_IN_HI.RX_EQ_EN_OVRD set to 1
+        * LANE0.RX_OVRD_IN_HI.RX_EQ set to 3
+        * LANE0.RX_OVRD_IN_HI.RX_EQ_OVRD set to 1
+        */
+       data = cr_bus_read_31(phy, 0x1006);
+       data &= ~(1 << 6);
+       data |= (1 << 7);
+       data &= ~(0x7 << 8);
+       data |= (0x3 << 8);
+       data |= (0x1 << 11);
+       cr_bus_write_31(phy, 0x1006, data);
+
+       /*
+        * S    et EQ and TX launch amplitudes as follows
+        * LANE0.TX_OVRD_DRV_LO.PREEMPH set to 22
+        * LANE0.TX_OVRD_DRV_LO.AMPLITUDE set to 127
+        * LANE0.TX_OVRD_DRV_LO.EN set to 1.
+        */
+       data = cr_bus_read_31(phy, 0x1002);
+       data &= ~0x3f80;
+       data |= (0x16 << 7);
+       data &= ~0x7f;
+       data |= (0x7f | (1 << 14));
+       cr_bus_write_31(phy, 0x1002, data);
+
+       /*
+        * MPLL_LOOP_CTL.PROP_CNTRL
+        */
+       data = cr_bus_read_31(phy, 0x30);
+       data &= ~(0xf << 4);
+       data |= (0x8 << 4);
+       cr_bus_write_31(phy, 0x30, data);
+       udelay(2);
+}
+
+
+static int amlogic_new_usb3_init_v3(struct usb_phy *x)
+{
+       struct amlogic_usb_v2 *phy = phy_to_amlusb(x);
+       union usb_r1_v2 r1 = {.d32 = 0};
+       union usb_r2_v2 r2 = {.d32 = 0};
+       union usb_r3_v2 r3 = {.d32 = 0};
+       union usb_r7_v2 r7 = {.d32 = 0};
+       union phy3_r2 p3_r2 = {.d32 = 0};
+       union phy3_r1 p3_r1 = {.d32 = 0};
+       int i = 0;
+
+       if (phy->suspend_flag) {
+               if (phy->phy.flags == AML_USB3_PHY_ENABLE) {
+                       clk_prepare_enable(phy->gate0_clk);
+                       clk_prepare_enable(phy->gate1_clk);
+                       clk_prepare_enable(phy->clk);
+               }
+               phy->suspend_flag = 0;
+               return 0;
+       }
+
+       if (phy->phy.flags != AML_USB3_PHY_ENABLE)
+               return 0;
+
+       for (i = 0; i < 8; i++) {
+               usb_new_aml_regs_v3.usb_r_v2[i] = (void __iomem *)
+                       ((unsigned long)phy->regs + 4*i);
+       }
+
+       /* config usb30 phy */
+       r3.d32 = readl(usb_new_aml_regs_v3.usb_r_v2[3]);
+       r3.b.p30_ssc_en = 1;
+       r3.b.p30_ssc_range = 2;
+       r3.b.p30_ref_ssp_en = 1;
+       writel(r3.d32, usb_new_aml_regs_v3.usb_r_v2[3]);
+       udelay(2);
+       r2.d32 = readl(usb_new_aml_regs_v3.usb_r_v2[2]);
+       r2.b.p30_pcs_tx_deemph_3p5db = 0x15;
+       r2.b.p30_pcs_tx_deemph_6db = 0x20;
+       writel(r2.d32, usb_new_aml_regs_v3.usb_r_v2[2]);
+       udelay(2);
+       r1.d32 = readl(usb_new_aml_regs_v3.usb_r_v2[1]);
+       r1.b.u3h_host_port_power_control_present = 1;
+       r1.b.u3h_fladj_30mhz_reg = 0x20;
+       r1.b.p30_pcs_tx_swing_full = 127;
+       r1.b.u3h_host_u3_port_disable = 0;
+       writel(r1.d32, usb_new_aml_regs_v3.usb_r_v2[1]);
+       udelay(2);
+       p3_r2.d32 = readl(phy->phy3_cfg_r2);
+       p3_r2.b.phy_tx_vboost_lvl = 0x4;
+       writel(p3_r2.d32, phy->phy3_cfg_r2);
+       udelay(2);
+
+       usb3_phy_cr_config_30(phy);
+
+       /*
+        * LOS_BIAS     to 0x5
+        * LOS_LEVEL to 0x9
+        */
+       p3_r1.d32 = readl(phy->phy3_cfg_r1);
+       p3_r1.b.phy_los_bias = 0x4;
+       p3_r1.b.phy_los_level = 0x9;
+       writel(p3_r1.d32, phy->phy3_cfg_r1);
+
+       /* config usb31 phy */
+       r7.d32 = readl(usb_new_aml_regs_v3.usb_r_v2[7]);
+       r7.b.p31_ssc_en = 1;
+       r7.b.p31_ssc_range = 2;
+       r7.b.p31_ref_ssp_en = 1;
+       r7.b.p31_pcs_tx_deemph_6db = 0x20;
+       r7.b.p31_pcs_tx_swing_full = 127;
+       writel(r7.d32, usb_new_aml_regs_v3.usb_r_v2[7]);
+
+       udelay(2);
+       p3_r2.d32 = readl(phy->phy31_cfg_r2);
+       p3_r2.b.phy_tx_vboost_lvl = 0x4;
+       writel(p3_r2.d32, phy->phy31_cfg_r2);
+       udelay(2);
+
+       usb3_phy_cr_config_31(phy);
+
+       /*
+        * LOS_BIAS     to 0x5
+        * LOS_LEVEL to 0x9
+        */
+       p3_r1.d32 = readl(phy->phy31_cfg_r1);
+       p3_r1.b.phy_los_bias = 0x4;
+       p3_r1.b.phy_los_level = 0x9;
+       writel(p3_r1.d32, phy->phy31_cfg_r1);
+
+       return 0;
+}
+
+static void power_switch_to_pcie(struct amlogic_usb_v2 *phy)
+{
+       u32 val;
+
+       power_ctrl_sleep(1, phy->u30_ctrl_sleep_shift);
+       power_ctrl_mempd0(1, phy->u30_hhi_mem_pd_mask,
+                               phy->u30_hhi_mem_pd_shift);
+       udelay(100);
+
+       val = readl((void __iomem *)
+               ((unsigned long)phy->reset_regs + (0x20 * 4 - 0x8)));
+       writel((val & (~(0x1 << phy->usb30_ctrl_rst_bit))), (void __iomem *)
+               ((unsigned long)phy->reset_regs + (0x20 * 4 - 0x8)));
+
+       udelay(100);
+
+       power_ctrl_iso(1, phy->u30_ctrl_iso_shift);
+
+       val = readl((void __iomem *)
+               ((unsigned long)phy->reset_regs + (0x20 * 4 - 0x8)));
+
+       writel((val | (0x1 << phy->usb30_ctrl_rst_bit)), (void __iomem  *)
+               ((unsigned long)phy->reset_regs + (0x20 * 4 - 0x8)));
+
+       udelay(100);
+
+       power_ctrl_sleep(1, phy->u31_ctrl_sleep_shift);
+       power_ctrl_mempd0(1, phy->u31_hhi_mem_pd_mask,
+                               phy->u31_hhi_mem_pd_shift);
+       udelay(100);
+
+       val = readl((void __iomem *)
+               ((unsigned long)phy->reset_regs + (0x20 * 4 - 0x8)));
+       writel((val & (~(0x1 << phy->usb31_ctrl_rst_bit))), (void __iomem *)
+               ((unsigned long)phy->reset_regs + (0x20 * 4 - 0x8)));
+
+       udelay(100);
+
+       power_ctrl_iso(1, phy->u31_ctrl_iso_shift);
+
+       val = readl((void __iomem *)
+               ((unsigned long)phy->reset_regs + (0x20 * 4 - 0x8)));
+
+       writel((val | (0x1 << phy->usb31_ctrl_rst_bit)), (void __iomem  *)
+               ((unsigned long)phy->reset_regs + (0x20 * 4 - 0x8)));
+
+       udelay(100);
+}
+
+static int amlogic_new_usb3_v3_probe(struct platform_device *pdev)
+{
+       struct amlogic_usb_v2                   *phy;
+       struct device *dev = &pdev->dev;
+       struct resource *phy_mem;
+       void __iomem    *phy_base;
+       void __iomem *phy3_base;
+       void __iomem *phy31_base;
+       void __iomem    *reset_base = NULL;
+       unsigned int phy3_mem;
+       unsigned int phy3_mem_size = 0;
+       unsigned int phy31_mem;
+       unsigned int phy31_mem_size = 0;
+       unsigned int reset_mem;
+       unsigned int reset_mem_size = 0;
+
+       const void *prop;
+       int portnum = 0;
+       int retval;
+       int ret;
+       u32 pwr_ctl = 0;
+       u32 u30_ctrl_sleep_shift = 0;
+       u32 u30_hhi_mem_pd_shift = 0;
+       u32 u30_hhi_mem_pd_mask = 0;
+       u32 u30_ctrl_iso_shift = 0;
+       u32 usb30_ctrl_rst_bit = 0;
+       u32 u31_ctrl_sleep_shift = 0;
+       u32 u31_hhi_mem_pd_shift = 0;
+       u32 u31_hhi_mem_pd_mask = 0;
+       u32 u31_ctrl_iso_shift = 0;
+       u32 usb31_ctrl_rst_bit = 0;
+       u32 portconfig_30 = 0;
+       u32 portconfig_31 = 0;
+       unsigned long rate;
+#define PCIE_PLL_RATE 100000000
+
+       prop = of_get_property(dev->of_node, "portnum", NULL);
+       if (prop)
+               portnum = of_read_ulong(prop, 1);
+
+       if (!portnum)
+               dev_err(&pdev->dev, "This phy has no usb port\n");
+
+       phy_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       phy_base = devm_ioremap_resource(dev, phy_mem);
+       if (IS_ERR(phy_base))
+               return PTR_ERR(phy_base);
+
+       retval = of_property_read_u32(dev->of_node, "phy0-reg", &phy3_mem);
+       if (retval < 0)
+               return -EINVAL;
+
+       retval = of_property_read_u32
+                               (dev->of_node, "phy0-reg-size", &phy3_mem_size);
+       if (retval < 0)
+               return -EINVAL;
+
+       phy3_base = devm_ioremap_nocache
+                               (&(pdev->dev), (resource_size_t)phy3_mem,
+                               (unsigned long)phy3_mem_size);
+       if (!phy3_base)
+               return -ENOMEM;
+
+       retval = of_property_read_u32(dev->of_node, "phy1-reg", &phy31_mem);
+       if (retval < 0)
+               return -EINVAL;
+
+       retval = of_property_read_u32
+                               (dev->of_node, "phy1-reg-size",
+                                       &phy31_mem_size);
+       if (retval < 0)
+               return -EINVAL;
+
+       phy31_base = devm_ioremap_nocache
+                               (&(pdev->dev), (resource_size_t)phy31_mem,
+                               (unsigned long)phy31_mem_size);
+       if (!phy31_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) {
+               retval = of_property_read_u32(dev->of_node,
+                               "reset-reg", &reset_mem);
+               if (retval < 0)
+                       return -EINVAL;
+
+               retval = of_property_read_u32
+                               (dev->of_node, "reset-reg-size",
+                                       &reset_mem_size);
+               if (retval < 0)
+                       return -EINVAL;
+
+               reset_base = devm_ioremap_nocache
+                               (&(pdev->dev), (resource_size_t)reset_mem,
+                               (unsigned long)reset_mem_size);
+               if (!reset_base)
+                       return -ENOMEM;
+
+               prop = of_get_property(dev->of_node,
+                       "u30-ctrl-sleep-shift", NULL);
+               if (prop)
+                       u30_ctrl_sleep_shift = of_read_ulong(prop, 1);
+               else
+                       pwr_ctl = 0;
+
+               prop = of_get_property(dev->of_node,
+                       "u30-hhi-mem-pd-shift", NULL);
+               if (prop)
+                       u30_hhi_mem_pd_shift = of_read_ulong(prop, 1);
+               else
+                       pwr_ctl = 0;
+
+               prop = of_get_property(dev->of_node,
+                       "u30-hhi-mem-pd-mask", NULL);
+               if (prop)
+                       u30_hhi_mem_pd_mask = of_read_ulong(prop, 1);
+               else
+                       pwr_ctl = 0;
+
+               prop = of_get_property(dev->of_node,
+                       "u30-ctrl-iso-shift", NULL);
+               if (prop)
+                       u30_ctrl_iso_shift = of_read_ulong(prop, 1);
+               else
+                       pwr_ctl = 0;
+
+               prop = of_get_property(dev->of_node,
+                       "usb30-ctrl-a-rst-bit", NULL);
+               if (prop)
+                       usb30_ctrl_rst_bit = of_read_ulong(prop, 1);
+               else
+                       pwr_ctl = 0;
+
+               prop = of_get_property(dev->of_node,
+                       "u31-ctrl-sleep-shift", NULL);
+               if (prop)
+                       u31_ctrl_sleep_shift = of_read_ulong(prop, 1);
+               else
+                       pwr_ctl = 0;
+
+               prop = of_get_property(dev->of_node,
+                       "u31-hhi-mem-pd-shift", NULL);
+               if (prop)
+                       u31_hhi_mem_pd_shift = of_read_ulong(prop, 1);
+               else
+                       pwr_ctl = 0;
+
+               prop = of_get_property(dev->of_node,
+                       "u31-hhi-mem-pd-mask", NULL);
+               if (prop)
+                       u31_hhi_mem_pd_mask = of_read_ulong(prop, 1);
+               else
+                       pwr_ctl = 0;
+
+               prop = of_get_property(dev->of_node,
+                       "u31-ctrl-iso-shift", NULL);
+               if (prop)
+                       u31_ctrl_iso_shift = of_read_ulong(prop, 1);
+               else
+                       pwr_ctl = 0;
+
+               prop = of_get_property(dev->of_node,
+                       "usb31-ctrl-a-rst-bit", NULL);
+               if (prop)
+                       usb31_ctrl_rst_bit = of_read_ulong(prop, 1);
+               else
+                       pwr_ctl = 0;
+       }
+
+       prop = of_get_property(dev->of_node,
+                       "portconfig-30", NULL);
+       if (prop)
+               portconfig_30 = of_read_ulong(prop, 1);
+
+       prop = of_get_property(dev->of_node,
+                       "portconfig-31", NULL);
+       if (prop)
+               portconfig_31 = of_read_ulong(prop, 1);
+
+       phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL);
+       if (!phy)
+               return -ENOMEM;
+
+       dev_info(&pdev->dev, "USB3 phy probe:phy_mem:0x%lx, iomap phy_base:0x%lx\n",
+                       (unsigned long)phy_mem->start, (unsigned long)phy_base);
+
+       phy->dev                = dev;
+       phy->regs               = phy_base;
+       phy->phy3_cfg   = phy3_base;
+       phy->phy3_cfg_r1 = (void __iomem *)
+                       ((unsigned long)phy->phy3_cfg + 4 * 1);
+       phy->phy3_cfg_r2 = (void __iomem *)
+                       ((unsigned long)phy->phy3_cfg + 4 * 2);
+       phy->phy3_cfg_r4 = (void __iomem *)
+                       ((unsigned long)phy->phy3_cfg + 4 * 4);
+       phy->phy3_cfg_r5 = (void __iomem *)
+                       ((unsigned long)phy->phy3_cfg + 4 * 5);
+       phy->phy31_cfg  = phy31_base;
+       phy->phy31_cfg_r1 = (void __iomem *)
+                       ((unsigned long)phy->phy31_cfg + 4 * 1);
+       phy->phy31_cfg_r2 = (void __iomem *)
+                       ((unsigned long)phy->phy31_cfg + 4 * 2);
+       phy->phy31_cfg_r4 = (void __iomem *)
+                       ((unsigned long)phy->phy31_cfg + 4 * 4);
+       phy->phy31_cfg_r5 = (void __iomem *)
+                       ((unsigned long)phy->phy31_cfg + 4 * 5);
+       phy->portnum      = portnum;
+       phy->suspend_flag = 0;
+       phy->phy.dev            = phy->dev;
+       phy->phy.label          = "amlogic-usbphy3";
+       phy->phy.init           = amlogic_new_usb3_init_v3;
+       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->pwr_ctl = pwr_ctl;
+
+       /* set the phy from pcie to usb3 */
+       if (phy->portnum > 0) {
+               if (phy->pwr_ctl) {
+                       phy->u30_ctrl_sleep_shift = u30_ctrl_sleep_shift;
+                       phy->u30_hhi_mem_pd_shift = u30_hhi_mem_pd_shift;
+                       phy->u30_hhi_mem_pd_mask = u30_hhi_mem_pd_mask;
+                       phy->u30_ctrl_iso_shift = u30_ctrl_iso_shift;
+                       phy->reset_regs = reset_base;
+                       phy->usb30_ctrl_rst_bit = usb30_ctrl_rst_bit;
+                       phy->u31_ctrl_sleep_shift = u31_ctrl_sleep_shift;
+                       phy->u31_hhi_mem_pd_shift = u31_hhi_mem_pd_shift;
+                       phy->u31_hhi_mem_pd_mask = u31_hhi_mem_pd_mask;
+                       phy->u31_ctrl_iso_shift = u31_ctrl_iso_shift;
+                       phy->usb31_ctrl_rst_bit = usb31_ctrl_rst_bit;
+                       power_switch_to_pcie(phy);
+               }
+
+               if (portconfig_30)
+                       writel((readl(phy->phy3_cfg) | (3<<5)), phy->phy3_cfg);
+               udelay(100);
+
+               if (portconfig_31)
+                       writel((readl(phy->phy31_cfg) | (3<<5)),
+                                       phy->phy31_cfg);
+               udelay(100);
+
+               phy->gate0_clk = devm_clk_get(dev, "pcie0_gate");
+               if (IS_ERR(phy->gate0_clk)) {
+                       dev_err(dev, "Failed to get usb3 bus clock\n");
+                       ret = PTR_ERR(phy->gate0_clk);
+                       return ret;
+               }
+
+               ret = clk_prepare_enable(phy->gate0_clk);
+               if (ret) {
+                       dev_err(dev, "Failed to enable usb3 bus clock\n");
+                       ret = PTR_ERR(phy->gate0_clk);
+                       return ret;
+               }
+
+               phy->gate1_clk = devm_clk_get(dev, "pcie1_gate");
+               if (IS_ERR(phy->gate1_clk)) {
+                       dev_err(dev, "Failed to get usb3 bus clock\n");
+                       ret = PTR_ERR(phy->gate1_clk);
+                       return ret;
+               }
+
+               ret = clk_prepare_enable(phy->gate1_clk);
+               if (ret) {
+                       dev_err(dev, "Failed to enable usb3 bus clock\n");
+                       ret = PTR_ERR(phy->gate1_clk);
+                       return ret;
+               }
+
+               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;
+               }
+
+               rate = clk_get_rate(phy->clk);
+               if (rate != PCIE_PLL_RATE)
+                       dev_err(dev, "pcie_refpll is not 100M, it is %ld\n",
+                                       rate);
+
+               phy->phy.flags = AML_USB3_PHY_ENABLE;
+       }
+
+       usb_add_phy_dev(&phy->phy);
+
+       platform_set_drvdata(pdev, phy);
+
+       pm_runtime_enable(phy->dev);
+
+       return 0;
+}
+
+static int amlogic_new_usb3_v3_remove(struct platform_device *pdev)
+{
+       return 0;
+}
+
+#ifdef CONFIG_PM_RUNTIME
+
+static int amlogic_new_usb3_v3_runtime_suspend(struct device *dev)
+{
+       return 0;
+}
+
+static int amlogic_new_usb3_v3_runtime_resume(struct device *dev)
+{
+       u32 ret = 0;
+
+       return ret;
+}
+
+static const struct dev_pm_ops amlogic_new_usb3_pm_ops = {
+       SET_RUNTIME_PM_OPS(amlogic_new_usb3_v3_runtime_suspend,
+               amlogic_new_usb3_v3_runtime_resume,
+               NULL)
+};
+
+#define DEV_PM_OPS     (&amlogic_new_usb3_pm_ops)
+#else
+#define DEV_PM_OPS     NULL
+#endif
+
+#ifdef CONFIG_OF
+static const struct of_device_id amlogic_new_usb3_v3_id_table[] = {
+       { .compatible = "amlogic, amlogic-new-usb3-v3" },
+       {}
+};
+MODULE_DEVICE_TABLE(of, amlogic_new_usb3_v3_id_table);
+#endif
+
+static struct platform_driver amlogic_new_usb3_v3_driver = {
+       .probe          = amlogic_new_usb3_v3_probe,
+       .remove         = amlogic_new_usb3_v3_remove,
+       .driver         = {
+               .name   = "amlogic-new-usb3-v3",
+               .owner  = THIS_MODULE,
+               .pm     = DEV_PM_OPS,
+               .of_match_table = of_match_ptr(amlogic_new_usb3_v3_id_table),
+       },
+};
+
+module_platform_driver(amlogic_new_usb3_v3_driver);
+
+MODULE_ALIAS("platform: amlogic_usb3_v2");
+MODULE_AUTHOR("Amlogic Inc.");
+MODULE_DESCRIPTION("amlogic USB3 v2 phy driver");
+MODULE_LICENSE("GPL v2");
index 6b14a82..d3b934e 100644 (file)
@@ -208,6 +208,11 @@ static int dwc3_core_soft_reset(struct dwc3 *dwc)
        reg |= DWC3_GUSB3PIPECTL_PHYSOFTRST;
        dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
 
+               /* Assert USB3 PHY reset */
+       reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(1));
+       reg |= DWC3_GUSB3PIPECTL_PHYSOFTRST;
+       dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(1), reg);
+
        /* Assert USB2 PHY reset */
        reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
        reg |= DWC3_GUSB2PHYCFG_PHYSOFTRST;
@@ -245,6 +250,11 @@ static int dwc3_core_soft_reset(struct dwc3 *dwc)
        reg &= ~DWC3_GUSB3PIPECTL_PHYSOFTRST;
        dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
 
+               /* Clear USB3 PHY reset */
+       reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(1));
+       reg &= ~DWC3_GUSB3PIPECTL_PHYSOFTRST;
+       dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(1), reg);
+
        /* Clear USB2 PHY reset */
        reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
        reg &= ~DWC3_GUSB2PHYCFG_PHYSOFTRST;
@@ -959,6 +969,7 @@ static int dwc3_core_get_phy(struct dwc3 *dwc)
        if (dwc->usb3_phy)
                if (dwc->usb3_phy->flags == AML_USB3_PHY_ENABLE)
                        dwc->super_speed_support = 1;
+
 #endif
 
        dwc->usb2_generic_phy = devm_phy_get(dev, "usb2-phy");
index 4d5df3a..8b3092c 100644 (file)
@@ -30,6 +30,8 @@
 
 int aml_new_usb_v2_register_notifier(struct notifier_block *nb);
 int aml_new_usb_v2_unregister_notifier(struct notifier_block *nb);
+int aml_new_otg_register_notifier(struct notifier_block *nb);
+int aml_new_otg_unregister_notifier(struct notifier_block *nb);
 
 struct u2p_aml_regs_v2 {
        void __iomem    *u2p_r_v2[2];
@@ -64,7 +66,7 @@ union u2p_r1_v2 {
 };
 
 struct usb_aml_regs_v2 {
-       void __iomem    *usb_r_v2[6];
+       void __iomem    *usb_r_v2[8];
 };
 
 union usb_r0_v2 {
@@ -88,13 +90,10 @@ union usb_r1_v2 {
        struct {
                unsigned u3h_bigendian_gs:1;
                unsigned u3h_pme_en:1;
-               unsigned u3h_hub_port_overcurrent:3;
-               unsigned reserved_1:2;
-               unsigned u3h_hub_port_perm_attach:3;
-               unsigned reserved_2:2;
-               unsigned u3h_host_u2_port_disable:2;
-               unsigned reserved_3:2;
-               unsigned u3h_host_u3_port_disable:1;
+               unsigned u3h_hub_port_overcurrent:5;
+               unsigned u3h_hub_port_perm_attach:5;
+               unsigned u3h_host_u2_port_disable:3;
+               unsigned u3h_host_u3_port_disable:2;
                unsigned u3h_host_port_power_control_present:1;
                unsigned u3h_host_msi_enable:1;
                unsigned u3h_fladj_30mhz_reg:6;
@@ -135,7 +134,11 @@ union usb_r4_v2 {
                unsigned p21_SLEEPM0:1;
                unsigned mem_pd:2;
                unsigned p21_only:1;
-               unsigned reserved:27;
+               unsigned reserved:12;
+               unsigned p31_lane0_tx2rx_loopback:1;
+               unsigned p31_lane0_ext_pclk_req:1;
+               unsigned p31_pcs_rx_los_mask_val:10;
+               unsigned reserve:3;
        } b;
 };
 
@@ -157,6 +160,22 @@ union usb_r5_v2 {
        } b;
 };
 
+union usb_r7_v2 {
+       /** raw register data */
+       uint32_t d32;
+       /** register bits */
+       struct {
+               unsigned p31_ssc_en:1;
+               unsigned p31_ssc_range:3;
+               unsigned p31_ssc_ref_clk_sel:9;
+               unsigned p31_ref_ssp_en:1;
+               unsigned reserved:2;
+               unsigned p31_pcs_tx_deemph_6db:6;
+               unsigned reserve:3;
+               unsigned p31_pcs_tx_swing_full:7;
+       } b;
+};
+
 struct amlogic_usb_v2 {
        struct usb_phy          phy;
        struct device           *dev;
@@ -168,7 +187,14 @@ struct amlogic_usb_v2 {
        void __iomem    *phy3_cfg_r2;
        void __iomem    *phy3_cfg_r4;
        void __iomem    *phy3_cfg_r5;
+       void __iomem    *phy31_cfg;
+       void __iomem    *phy31_cfg_r1;
+       void __iomem    *phy31_cfg_r2;
+       void __iomem    *phy31_cfg_r4;
+       void __iomem    *phy31_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 */
@@ -185,11 +211,19 @@ struct amlogic_usb_v2 {
        u32 u2_hhi_mem_pd_mask;
        u32 u2_ctrl_iso_shift;
        u32 u2_hhi_mem_pd_shift;
-       u32 u3_ctrl_sleep_shift;
-       u32 u3_hhi_mem_pd_mask;
-       u32 u3_ctrl_iso_shift;
-       u32 u3_hhi_mem_pd_shift;
+       u32 u30_ctrl_sleep_shift;
+       u32 u30_hhi_mem_pd_mask;
+       u32 u30_ctrl_iso_shift;
+       u32 u30_hhi_mem_pd_shift;
+       u32 usb30_ctrl_rst_bit;
+       u32 u31_ctrl_sleep_shift;
+       u32 u31_hhi_mem_pd_mask;
+       u32 u31_ctrl_iso_shift;
+       u32 u31_hhi_mem_pd_shift;
+       u32 usb31_ctrl_rst_bit;
        struct clk              *clk;
+       struct clk              *gate0_clk;
+       struct clk              *gate1_clk;
 };
 
 union phy3_r1 {