diff --git a/projects/Allwinner/devices/H6/patches/linux/07-opi3.patch b/projects/Allwinner/devices/H6/patches/linux/07-opi3.patch new file mode 100644 index 0000000000..eaafd8aefa --- /dev/null +++ b/projects/Allwinner/devices/H6/patches/linux/07-opi3.patch @@ -0,0 +1,1568 @@ +From 9ea7a168e5cab7ad820439f1c595360e8c2415db Mon Sep 17 00:00:00 2001 +From: Ondrej Jirman +Date: Tue, 19 Feb 2019 21:54:24 +0100 +Subject: [PATCH 01/34] rtc: sun6i: Add support for H6 RTC + +It is mostly the same as on H5 and H3, but with slight differences +in features that are not yet supported by this driver, so we need +a different compatible, but we can re-use sun8i_h3_rtc_clk_init. + +Some differences are already stated in the comments in existing code. +One other difference is that H6 has extra bit in LOSC_CTRL_REG, called +EXT_LOSC_EN to enable/disable external low speed crystal oscillator. + +It also has bit EXT_LOSC_STA in LOSC_AUTO_SWT_STA_REG, to check whether +external low speed oscillator is working correctly. + +Signed-off-by: Ondrej Jirman +--- + drivers/rtc/rtc-sun6i.c | 47 +++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 45 insertions(+), 2 deletions(-) + +diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c +index 11f56de521791..b0fbaa1837dd5 100644 +--- a/drivers/rtc/rtc-sun6i.c ++++ b/drivers/rtc/rtc-sun6i.c +@@ -41,11 +41,15 @@ + /* Control register */ + #define SUN6I_LOSC_CTRL 0x0000 + #define SUN6I_LOSC_CTRL_KEY (0x16aa << 16) ++#define SUN6I_LOSC_CTRL_AUTO_SWT_EN BIT(14) ++#define SUN6I_LOSC_CTRL_AUTO_SWT_BYPASS BIT(15) + #define SUN6I_LOSC_CTRL_ALM_DHMS_ACC BIT(9) + #define SUN6I_LOSC_CTRL_RTC_HMS_ACC BIT(8) + #define SUN6I_LOSC_CTRL_RTC_YMD_ACC BIT(7) ++#define SUN6I_LOSC_CTRL_EXT_LOSC_EN BIT(4) + #define SUN6I_LOSC_CTRL_EXT_OSC BIT(0) + #define SUN6I_LOSC_CTRL_ACC_MASK GENMASK(9, 7) ++#define SUN6I_LOSC_CTRL_EXT_OSC_GSM 0x08 + + #define SUN6I_LOSC_CLK_PRESCAL 0x0008 + +@@ -137,6 +141,8 @@ struct sun6i_rtc_clk_data { + unsigned int has_prescaler : 1; + unsigned int has_out_clk : 1; + unsigned int export_iosc : 1; ++ unsigned int has_losc_en : 1; ++ unsigned int has_auto_swt : 1; + }; + + struct sun6i_rtc_dev { +@@ -199,6 +205,10 @@ static int sun6i_rtc_osc_set_parent(struct clk_hw *hw, u8 index) + val &= ~SUN6I_LOSC_CTRL_EXT_OSC; + val |= SUN6I_LOSC_CTRL_KEY; + val |= index ? SUN6I_LOSC_CTRL_EXT_OSC : 0; ++ if (rtc->data->has_losc_en) { ++ val &= ~SUN6I_LOSC_CTRL_EXT_LOSC_EN; ++ val |= index ? SUN6I_LOSC_CTRL_EXT_LOSC_EN : 0; ++ } + writel(val, rtc->base + SUN6I_LOSC_CTRL); + spin_unlock_irqrestore(&rtc->lock, flags); + +@@ -224,6 +234,7 @@ static void __init sun6i_rtc_clk_init(struct device_node *node, + const char *iosc_name = "rtc-int-osc"; + const char *clkout_name = "osc32k-out"; + const char *parents[2]; ++ u32 reg; + + rtc = kzalloc(sizeof(*rtc), GFP_KERNEL); + if (!rtc) +@@ -244,9 +255,23 @@ static void __init sun6i_rtc_clk_init(struct device_node *node, + goto err; + } + ++ reg = SUN6I_LOSC_CTRL_KEY; ++ if (rtc->data->has_auto_swt) { ++ /* Bypass auto-switch to int osc, on ext losc failure */ ++ reg |= SUN6I_LOSC_CTRL_AUTO_SWT_BYPASS; ++ writel(reg, rtc->base + SUN6I_LOSC_CTRL); ++ } ++ + /* Switch to the external, more precise, oscillator */ +- writel(SUN6I_LOSC_CTRL_KEY | SUN6I_LOSC_CTRL_EXT_OSC, +- rtc->base + SUN6I_LOSC_CTRL); ++ reg |= SUN6I_LOSC_CTRL_EXT_OSC; ++ if (rtc->data->has_losc_en) ++ reg |= SUN6I_LOSC_CTRL_EXT_LOSC_EN; ++ writel(reg, rtc->base + SUN6I_LOSC_CTRL); ++ ++ /* Set GSM with some delay, after switching to ext losc. */ ++ udelay(10); ++ reg |= SUN6I_LOSC_CTRL_EXT_OSC_GSM; ++ writel(reg, rtc->base + SUN6I_LOSC_CTRL); + + /* Yes, I know, this is ugly. */ + sun6i_rtc = rtc; +@@ -354,6 +379,23 @@ CLK_OF_DECLARE_DRIVER(sun8i_h3_rtc_clk, "allwinner,sun8i-h3-rtc", + CLK_OF_DECLARE_DRIVER(sun50i_h5_rtc_clk, "allwinner,sun50i-h5-rtc", + sun8i_h3_rtc_clk_init); + ++static const struct sun6i_rtc_clk_data sun50i_h6_rtc_data = { ++ .rc_osc_rate = 16000000, ++ .fixed_prescaler = 32, ++ .has_prescaler = 1, ++ .has_out_clk = 1, ++ .export_iosc = 1, ++ .has_losc_en = 1, ++ .has_auto_swt = 1, ++}; ++ ++static void __init sun50i_h6_rtc_clk_init(struct device_node *node) ++{ ++ sun6i_rtc_clk_init(node, &sun50i_h6_rtc_data); ++} ++CLK_OF_DECLARE_DRIVER(sun50i_h6_rtc_clk, "allwinner,sun50i-h6-rtc", ++ sun50i_h6_rtc_clk_init); ++ + static const struct sun6i_rtc_clk_data sun8i_v3_rtc_data = { + .rc_osc_rate = 32000, + .has_out_clk = 1, +@@ -683,6 +725,7 @@ static const struct of_device_id sun6i_rtc_dt_ids[] = { + { .compatible = "allwinner,sun8i-h3-rtc" }, + { .compatible = "allwinner,sun8i-v3-rtc" }, + { .compatible = "allwinner,sun50i-h5-rtc" }, ++ { .compatible = "allwinner,sun50i-h6-rtc" }, + { /* sentinel */ }, + }; + MODULE_DEVICE_TABLE(of, sun6i_rtc_dt_ids); + +From 80472652eff72ba5198dc5d678612fb91e411ed1 Mon Sep 17 00:00:00 2001 +From: Ondrej Jirman +Date: Fri, 12 Apr 2019 13:32:05 +0200 +Subject: [PATCH 02/34] arm64: dts: sun50i-h6: Add support for RTC and fix the + clock tree + +This patch adds RTC node and fixes the clock properties and nodes +to reflect the real clock tree. + +The device nodes for the internal oscillator and osc32k are removed, +as these clocks are now provided by the RTC device. Clock references +are fixed accordingly, too. + +Signed-off-by: Ondrej Jirman +--- + arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 30 +++++++++++--------- + 1 file changed, 16 insertions(+), 14 deletions(-) + +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi +index c9e861a50a633..ae7977f3f054c 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi +@@ -56,14 +56,6 @@ + status = "disabled"; + }; + +- iosc: internal-osc-clk { +- #clock-cells = <0>; +- compatible = "fixed-clock"; +- clock-frequency = <16000000>; +- clock-accuracy = <300000000>; +- clock-output-names = "iosc"; +- }; +- + osc24M: osc24M_clk { + #clock-cells = <0>; + compatible = "fixed-clock"; +@@ -71,11 +63,11 @@ + clock-output-names = "osc24M"; + }; + +- osc32k: osc32k_clk { ++ ext_osc32k: ext_osc32k_clk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <32768>; +- clock-output-names = "osc32k"; ++ clock-output-names = "ext_osc32k"; + }; + + psci { +@@ -186,7 +178,7 @@ + ccu: clock@3001000 { + compatible = "allwinner,sun50i-h6-ccu"; + reg = <0x03001000 0x1000>; +- clocks = <&osc24M>, <&osc32k>, <&iosc>; ++ clocks = <&osc24M>, <&rtc 0>, <&rtc 2>; + clock-names = "hosc", "losc", "iosc"; + #clock-cells = <1>; + #reset-cells = <1>; +@@ -199,7 +191,7 @@ + , + , + ; +- clocks = <&ccu CLK_APB1>, <&osc24M>, <&osc32k>; ++ clocks = <&ccu CLK_APB1>, <&osc24M>, <&rtc 0>; + clock-names = "apb", "hosc", "losc"; + gpio-controller; + #gpio-cells = <3>; +@@ -583,10 +575,20 @@ + }; + }; + ++ rtc: rtc@7000000 { ++ compatible = "allwinner,sun50i-h6-rtc"; ++ reg = <0x07000000 0x400>; ++ interrupts = , ++ ; ++ clock-output-names = "osc32k", "osc32k-out", "iosc"; ++ clocks = <&ext_osc32k>; ++ #clock-cells = <1>; ++ }; ++ + r_ccu: clock@7010000 { + compatible = "allwinner,sun50i-h6-r-ccu"; + reg = <0x07010000 0x400>; +- clocks = <&osc24M>, <&osc32k>, <&iosc>, ++ clocks = <&osc24M>, <&rtc 0>, <&rtc 2>, + <&ccu CLK_PLL_PERIPH0>; + clock-names = "hosc", "losc", "iosc", "pll-periph"; + #clock-cells = <1>; +@@ -607,7 +609,7 @@ + reg = <0x07022000 0x400>; + interrupts = , + ; +- clocks = <&r_ccu CLK_R_APB1>, <&osc24M>, <&osc32k>; ++ clocks = <&r_ccu CLK_R_APB1>, <&osc24M>, <&rtc 0>; + clock-names = "apb", "hosc", "losc"; + gpio-controller; + #gpio-cells = <3>; + +From de4dc594bb3cb124d21fd7550ca0497c7fa22ff0 Mon Sep 17 00:00:00 2001 +From: Ondrej Jirman +Date: Thu, 11 Apr 2019 11:20:54 +0200 +Subject: [PATCH 07/34] arm64: dts: h6: Make mmc0_pins the default for &mmc0 + +Signed-off-by: Ondrej Jirman +--- + arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi +index ae7977f3f054c..91623a8cd2a08 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi +@@ -254,6 +254,8 @@ + resets = <&ccu RST_BUS_MMC0>; + reset-names = "ahb"; + interrupts = ; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&mmc0_pins>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + +From 45bbbb485eb478df71079fd69f7ee8e48d0b0809 Mon Sep 17 00:00:00 2001 +From: Ondrej Jirman +Date: Thu, 11 Apr 2019 11:11:21 +0200 +Subject: [PATCH 08/34] arm64: dts: allwinner: h6: Add Orange Pi 3 DTS + +Orange Pi 3 is a H6 based SBC made by Xulong, released in January 2019. It +has the following features: + +- Allwinner H6 quad-core 64-bit ARM Cortex-A53 +- GPU Mali-T720 +- 1GB or 2GB LPDDR3 RAM +- AXP805 PMIC +- AP6256 Wifi/BT 5.0 +- USB 2.0 host port (A) +- USB 2.0 micro usb, OTG +- USB 3.0 Host + 4 port USB hub (GL3510) +- Gigabit Ethernet (Realtek RTL8211E phy) +- HDMI 2.0 port +- soldered eMMC (optional) +- 3x LED (one is on the bottom) +- microphone +- audio jack +- PCIe + +Add basic support for the board. + +Signed-off-by: Ondrej Jirman +Signed-off-by: Maxime Ripard +--- + arch/arm64/boot/dts/allwinner/Makefile | 1 + + .../dts/allwinner/sun50i-h6-orangepi-3.dts | 215 ++++++++++++++++++ + 2 files changed, 216 insertions(+) + create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts + +diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile +index 0b09171110994..13a7e87bc35cc 100644 +--- a/arch/arm64/boot/dts/allwinner/Makefile ++++ b/arch/arm64/boot/dts/allwinner/Makefile +@@ -19,6 +19,7 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-orangepi-pc2.dtb + dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-orangepi-prime.dtb + dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-orangepi-zero-plus.dtb + dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-orangepi-zero-plus2.dtb ++dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-orangepi-3.dtb + dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-orangepi-lite2.dtb + dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-orangepi-one-plus.dtb + dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-pine-h64.dtb +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts +new file mode 100644 +index 0000000000000..17d4969901086 +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts +@@ -0,0 +1,219 @@ ++// SPDX-License-Identifier: (GPL-2.0+ or MIT) ++/* ++ * Copyright (C) 2019 Ondřej Jirman ++ */ ++ ++/dts-v1/; ++ ++#include "sun50i-h6.dtsi" ++ ++#include ++ ++/ { ++ model = "OrangePi 3"; ++ compatible = "xunlong,orangepi-3", "allwinner,sun50i-h6"; ++ ++ aliases { ++ serial0 = &uart0; ++ }; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ power { ++ label = "orangepi:red:power"; ++ gpios = <&r_pio 0 4 GPIO_ACTIVE_HIGH>; /* PL4 */ ++ default-state = "on"; ++ }; ++ ++ status { ++ label = "orangepi:green:status"; ++ gpios = <&r_pio 0 7 GPIO_ACTIVE_HIGH>; /* PL7 */ ++ }; ++ }; ++ ++ reg_vcc5v: vcc5v { ++ /* board wide 5V supply directly from the DC jack */ ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc-5v"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ regulator-always-on; ++ }; ++}; ++ ++&cpu0 { ++ cpu-supply = <®_dcdca>; ++}; ++ ++&ehci0 { ++ status = "okay"; ++}; ++ ++&ehci3 { ++ status = "okay"; ++}; ++ ++&gpu { ++ mali-supply = <®_dcdcc>; ++}; ++ ++&mmc0 { ++ vmmc-supply = <®_cldo1>; ++ cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */ ++ bus-width = <4>; ++ status = "okay"; ++}; ++ ++&ohci0 { ++ status = "okay"; ++}; ++ ++&ohci3 { ++ status = "okay"; ++}; ++ ++&pio { ++ vcc-pc-supply = <®_bldo2>; ++ vcc-pd-supply = <®_cldo1>; ++}; ++ ++&r_i2c { ++ status = "okay"; ++ ++ axp805: pmic@36 { ++ compatible = "x-powers,axp805", "x-powers,axp806"; ++ reg = <0x36>; ++ interrupt-parent = <&r_intc>; ++ interrupts = <0 IRQ_TYPE_LEVEL_LOW>; ++ interrupt-controller; ++ #interrupt-cells = <1>; ++ x-powers,self-working-mode; ++ vina-supply = <®_vcc5v>; ++ vinb-supply = <®_vcc5v>; ++ vinc-supply = <®_vcc5v>; ++ vind-supply = <®_vcc5v>; ++ vine-supply = <®_vcc5v>; ++ aldoin-supply = <®_vcc5v>; ++ bldoin-supply = <®_vcc5v>; ++ cldoin-supply = <®_vcc5v>; ++ ++ regulators { ++ reg_aldo1: aldo1 { ++ regulator-always-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-name = "vcc-pl-led-ir"; ++ }; ++ ++ reg_aldo2: aldo2 { ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-name = "vcc33-audio-tv-ephy-mac"; ++ }; ++ ++ /* ALDO3 is shorted to CLDO1 */ ++ reg_aldo3: aldo3 { ++ regulator-always-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-name = "vcc33-io-pd-emmc-sd-usb-uart-1"; ++ }; ++ ++ reg_bldo1: bldo1 { ++ regulator-always-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-name = "vcc18-dram-bias-pll"; ++ }; ++ ++ reg_bldo2: bldo2 { ++ regulator-always-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-name = "vcc-efuse-pcie-hdmi-pc"; ++ }; ++ ++ bldo3 { ++ /* unused */ ++ }; ++ ++ bldo4 { ++ /* unused */ ++ }; ++ ++ reg_cldo1: cldo1 { ++ regulator-always-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-name = "vcc33-io-pd-emmc-sd-usb-uart-2"; ++ }; ++ ++ cldo2 { ++ /* unused */ ++ }; ++ ++ cldo3 { ++ /* unused */ ++ }; ++ ++ reg_dcdca: dcdca { ++ regulator-always-on; ++ regulator-min-microvolt = <800000>; ++ regulator-max-microvolt = <1160000>; ++ regulator-name = "vdd-cpu"; ++ }; ++ ++ reg_dcdcc: dcdcc { ++ regulator-min-microvolt = <810000>; ++ regulator-max-microvolt = <1080000>; ++ regulator-name = "vdd-gpu"; ++ }; ++ ++ reg_dcdcd: dcdcd { ++ regulator-always-on; ++ regulator-min-microvolt = <960000>; ++ regulator-max-microvolt = <960000>; ++ regulator-name = "vdd-sys"; ++ }; ++ ++ reg_dcdce: dcdce { ++ regulator-always-on; ++ regulator-min-microvolt = <1200000>; ++ regulator-max-microvolt = <1200000>; ++ regulator-name = "vcc-dram"; ++ }; ++ ++ sw { ++ /* unused */ ++ }; ++ }; ++ }; ++}; ++ ++&uart0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_ph_pins>; ++ status = "okay"; ++}; ++ ++&usb2otg { ++ /* ++ * This board doesn't have a controllable VBUS even though it ++ * does have an ID pin. Using it as anything but a USB host is ++ * unsafe. ++ */ ++ dr_mode = "host"; ++ status = "okay"; ++}; ++ ++&usb2phy { ++ usb0_id_det-gpios = <&pio 2 15 GPIO_ACTIVE_HIGH>; /* PC15 */ ++ usb0_vbus-supply = <®_vcc5v>; ++ usb3_vbus-supply = <®_vcc5v>; ++ status = "okay"; ++}; + +From 2a87073bd0857fd9707de2ac96cb04d6d9e0e288 Mon Sep 17 00:00:00 2001 +From: Icenowy Zheng +Date: Tue, 9 Jan 2018 23:58:12 +0800 +Subject: [PATCH 10/34] net: stmmac: sun8i: force select external PHY when no + internal one + +From e6d3f7e02d211522c7f1cc09df946292601b55b6 Mon Sep 17 00:00:00 2001 +From: Ondrej Jirman +Date: Wed, 27 Mar 2019 13:21:06 +0100 +Subject: [PATCH 13/34] arm64: dts: allwinner: orange-pi-3: Enable ethernet + +Orange Pi 3 has two regulators that power the Realtek RTL8211E. According +to the phy datasheet, both regulators need to be enabled at the same time, +but we can only specify a single phy-supply in the DT. + +This can be achieved by making one regulator depedning on the other via +vin-supply. While it's not a technically correct description of the +hardware, it achieves the purpose. + +All values of RX/TX delay were tested exhaustively and a middle one of the +working values was chosen. + +Signed-off-by: Ondrej Jirman +--- + .../dts/allwinner/sun50i-h6-orangepi-3.dts | 44 +++++++++++++++++++ + 1 file changed, 44 insertions(+) + +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts +index 17d4969901086..6d6b1f66796d9 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts +@@ -15,6 +15,7 @@ + + aliases { + serial0 = &uart0; ++ ethernet0 = &emac; + }; + + chosen { +@@ -44,6 +45,27 @@ + regulator-max-microvolt = <5000000>; + regulator-always-on; + }; ++ ++ /* ++ * The board uses 2.5V RGMII signalling. Power sequence to enable ++ * the phy is to enable GMAC-2V5 and GMAC-3V3 (aldo2) power rails ++ * at the same time and to wait 100ms. ++ */ ++ reg_gmac_2v5: gmac-2v5 { ++ compatible = "regulator-fixed"; ++ regulator-name = "gmac-2v5"; ++ regulator-min-microvolt = <2500000>; ++ regulator-max-microvolt = <2500000>; ++ startup-delay-us = <100000>; ++ enable-active-high; ++ gpio = <&pio 3 6 GPIO_ACTIVE_HIGH>; /* PD6 */ ++ ++ /* The real parent of gmac-2v5 is reg_vcc5v, but we need to ++ * enable two regulators to power the phy. This is one way ++ * to achieve that. ++ */ ++ vin-supply = <®_aldo2>; /* GMAC-3V3 */ ++ }; + }; + + &cpu0 { +@@ -58,6 +80,28 @@ + status = "okay"; + }; + ++&emac { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&ext_rgmii_pins>; ++ phy-mode = "rgmii"; ++ phy-handle = <&ext_rgmii_phy>; ++ phy-supply = <®_gmac_2v5>; ++ allwinner,rx-delay-ps = <1500>; ++ allwinner,tx-delay-ps = <700>; ++ status = "okay"; ++}; ++ ++&mdio { ++ ext_rgmii_phy: ethernet-phy@1 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <1>; ++ ++ reset-gpios = <&pio 3 14 GPIO_ACTIVE_LOW>; /* PD14 */ ++ reset-assert-us = <15000>; ++ reset-deassert-us = <40000>; ++ }; ++}; ++ + &mmc0 { + vmmc-supply = <®_cldo1>; + cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */ + +From b641bc59468e93ab57fd016ad36b037f3890b994 Mon Sep 17 00:00:00 2001 +From: Ondrej Jirman +Date: Tue, 26 Mar 2019 15:06:37 +0100 +Subject: [PATCH 15/34] drm: sun4i: Add support for enabling DDC I2C bus power + to dw_hdmi glue + +Orange Pi 3 board requires enabling DDC I2C bus via some GPIO connected +transistors, before the bus can be used. + +Model this as a power supply for DDC bus on the HDMI connector connected +to the output port (port 1) of the HDMI controller. + +Signed-off-by: Ondrej Jirman +--- + drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c | 60 ++++++++++++++++++++++++++- + drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h | 2 + + 2 files changed, 60 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c +index 39d8509d96a0d..1b6ffba41177f 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c ++++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c +@@ -98,6 +98,30 @@ static u32 sun8i_dw_hdmi_find_possible_crtcs(struct drm_device *drm, + return crtcs; + } + ++static int sun8i_dw_hdmi_find_connector_pdev(struct device *dev, ++ struct platform_device **pdev_out) ++{ ++ struct platform_device* pdev; ++ struct device_node *remote; ++ ++ remote = of_graph_get_remote_node(dev->of_node, 1, -1); ++ if (!remote) ++ return -ENODEV; ++ ++ if (!of_device_is_compatible(remote, "hdmi-connector")) { ++ of_node_put(remote); ++ return -ENODEV; ++ } ++ ++ pdev = of_find_device_by_node(remote); ++ of_node_put(remote); ++ if (!pdev) ++ return -ENODEV; ++ ++ *pdev_out = pdev; ++ return 0; ++} ++ + static int sun8i_dw_hdmi_bind(struct device *dev, struct device *master, + void *data) + { +@@ -151,16 +175,34 @@ static int sun8i_dw_hdmi_bind(struct device *dev, struct device *master, + return PTR_ERR(hdmi->regulator); + } + ++ ret = sun8i_dw_hdmi_find_connector_pdev(dev, &hdmi->connector_pdev); ++ if (!ret) { ++ hdmi->ddc_regulator = regulator_get(&hdmi->connector_pdev->dev, "ddc"); ++ if (IS_ERR(hdmi->ddc_regulator)) { ++ platform_device_put(hdmi->connector_pdev); ++ dev_err(dev, "Couldn't get ddc regulator\n"); ++ return PTR_ERR(hdmi->ddc_regulator); ++ } ++ } ++ + ret = regulator_enable(hdmi->regulator); + if (ret) { + dev_err(dev, "Failed to enable regulator\n"); +- return ret; ++ goto err_unref_ddc_regulator; ++ } ++ ++ if (hdmi->ddc_regulator) { ++ ret = regulator_enable(hdmi->ddc_regulator); ++ if (ret) { ++ dev_err(dev, "Failed to enable ddc regulator\n"); ++ goto err_disable_regulator; ++ } + } + + ret = reset_control_deassert(hdmi->rst_ctrl); + if (ret) { + dev_err(dev, "Could not deassert ctrl reset control\n"); +- goto err_disable_regulator; ++ goto err_disable_ddc_regulator; + } + + ret = clk_prepare_enable(hdmi->clk_tmds); +@@ -213,8 +255,15 @@ static int sun8i_dw_hdmi_bind(struct device *dev, struct device *master, + clk_disable_unprepare(hdmi->clk_tmds); + err_assert_ctrl_reset: + reset_control_assert(hdmi->rst_ctrl); ++err_disable_ddc_regulator: ++ if (hdmi->ddc_regulator) ++ regulator_disable(hdmi->ddc_regulator); + err_disable_regulator: + regulator_disable(hdmi->regulator); ++err_unref_ddc_regulator: ++ if (hdmi->ddc_regulator) ++ regulator_put(hdmi->ddc_regulator); ++ platform_device_put(hdmi->connector_pdev); + + return ret; + } +@@ -229,6 +278,13 @@ static void sun8i_dw_hdmi_unbind(struct device *dev, struct device *master, + clk_disable_unprepare(hdmi->clk_tmds); + reset_control_assert(hdmi->rst_ctrl); + regulator_disable(hdmi->regulator); ++ ++ if (hdmi->ddc_regulator) { ++ regulator_disable(hdmi->ddc_regulator); ++ regulator_put(hdmi->ddc_regulator); ++ } ++ ++ platform_device_put(hdmi->connector_pdev); + } + + static const struct component_ops sun8i_dw_hdmi_ops = { +diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h +index 720c5aa8adc14..60f5200aee73b 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h ++++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h +@@ -188,8 +188,10 @@ struct sun8i_dw_hdmi { + struct sun8i_hdmi_phy *phy; + struct dw_hdmi_plat_data plat_data; + struct regulator *regulator; ++ struct regulator *ddc_regulator; + const struct sun8i_dw_hdmi_quirks *quirks; + struct reset_control *rst_ctrl; ++ struct platform_device *connector_pdev; + }; + + static inline struct sun8i_dw_hdmi * + +From c1d7c7796ea7e76829c71b993c7531f23c0f5913 Mon Sep 17 00:00:00 2001 +From: Ondrej Jirman +Date: Tue, 9 Apr 2019 01:41:58 +0200 +Subject: [PATCH 16/34] arm64: dts: allwinner: orange-pi-3: Enable HDMI output + +Orange Pi 3 has a DDC_CEC_EN signal connected to PH2, that enables the DDC +I2C bus voltage shifter. Before EDID can be read, we need to pull PH2 high. + +Signed-off-by: Ondrej Jirman +--- + .../dts/allwinner/sun50i-h6-orangepi-3.dts | 35 +++++++++++++++++++ + 1 file changed, 35 insertions(+) + +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts +index 6d6b1f66796d9..58a6635c909e3 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts +@@ -22,6 +22,18 @@ + stdout-path = "serial0:115200n8"; + }; + ++ connector { ++ compatible = "hdmi-connector"; ++ type = "a"; ++ ddc-supply = <®_ddc>; ++ ++ port { ++ hdmi_con_in: endpoint { ++ remote-endpoint = <&hdmi_out_con>; ++ }; ++ }; ++ }; ++ + leds { + compatible = "gpio-leds"; + +@@ -37,6 +49,15 @@ + }; + }; + ++ reg_ddc: ddc-io { ++ compatible = "regulator-fixed"; ++ regulator-name = "ddc-io"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ enable-active-high; ++ gpio = <&pio 7 2 GPIO_ACTIVE_HIGH>; /* PH2 */ ++ }; ++ + reg_vcc5v: vcc5v { + /* board wide 5V supply directly from the DC jack */ + compatible = "regulator-fixed"; +@@ -72,6 +93,10 @@ + cpu-supply = <®_dcdca>; + }; + ++&de { ++ status = "okay"; ++}; ++ + &ehci0 { + status = "okay"; + }; +@@ -91,6 +116,16 @@ + status = "okay"; + }; + ++&hdmi { ++ status = "okay"; ++}; ++ ++&hdmi_out { ++ hdmi_out_con: endpoint { ++ remote-endpoint = <&hdmi_con_in>; ++ }; ++}; ++ + &mdio { + ext_rgmii_phy: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + +From 756b0ba6d79844dbc04c6c4ea0fc25b52209721a Mon Sep 17 00:00:00 2001 +From: Ondrej Jirman +Date: Fri, 5 Apr 2019 22:21:00 +0200 +Subject: [PATCH 17/34] brcmfmac: Loading the correct firmware for brcm43456 + +SDIO based brcm43456 is currently misdetected as brcm43455 and the wrong +firmware name is used. Correct the detection and load the correct firmware +file. Chiprev for brcm43456 is "9". + +Signed-off-by: Ondrej Jirman +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +index 4d104ab80fd8e..50e56fd056baa 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -622,6 +622,7 @@ BRCMF_FW_DEF(43430A0, "brcmfmac43430a0-sdio"); + /* Note the names are not postfixed with a1 for backward compatibility */ + BRCMF_FW_DEF(43430A1, "brcmfmac43430-sdio"); + BRCMF_FW_DEF(43455, "brcmfmac43455-sdio"); ++BRCMF_FW_DEF(43456, "brcmfmac43456-sdio"); + BRCMF_FW_DEF(4354, "brcmfmac4354-sdio"); + BRCMF_FW_DEF(4356, "brcmfmac4356-sdio"); + BRCMF_FW_DEF(4373, "brcmfmac4373-sdio"); +@@ -642,7 +643,8 @@ static const struct brcmf_firmware_mapping brcmf_sdio_fwnames[] = { + BRCMF_FW_ENTRY(BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, 4339), + BRCMF_FW_ENTRY(BRCM_CC_43430_CHIP_ID, 0x00000001, 43430A0), + BRCMF_FW_ENTRY(BRCM_CC_43430_CHIP_ID, 0xFFFFFFFE, 43430A1), +- BRCMF_FW_ENTRY(BRCM_CC_4345_CHIP_ID, 0xFFFFFFC0, 43455), ++ BRCMF_FW_ENTRY(BRCM_CC_4345_CHIP_ID, 0x00000200, 43456), ++ BRCMF_FW_ENTRY(BRCM_CC_4345_CHIP_ID, 0xFFFFFDC0, 43455), + BRCMF_FW_ENTRY(BRCM_CC_4354_CHIP_ID, 0xFFFFFFFF, 4354), + BRCMF_FW_ENTRY(BRCM_CC_4356_CHIP_ID, 0xFFFFFFFF, 4356), + BRCMF_FW_ENTRY(CY_CC_4373_CHIP_ID, 0xFFFFFFFF, 4373), + +From 5bf634f86c57f59f5c4a4fade9ccfe582334464f Mon Sep 17 00:00:00 2001 +From: Ondrej Jirman +Date: Mon, 18 Feb 2019 13:53:18 +0100 +Subject: [PATCH 18/34] arm64: dts: allwinner: h6: Add MMC1 pins + +MMC1 is used on some H6 boards we want to support. Typical use is 4-bit +SDIO interface with a WiFi chip. Add pin definitions for this use case. + +As this is the only possible configration for mmc1, make it the default +one, too. + +Signed-off-by: Ondrej Jirman +--- + arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi +index 91623a8cd2a08..c5c0608e67403 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi +@@ -219,6 +219,15 @@ + bias-pull-up; + }; + ++ /omit-if-no-ref/ ++ mmc1_pins: mmc1-pins { ++ pins = "PG0", "PG1", "PG2", "PG3", ++ "PG4", "PG5"; ++ function = "mmc1"; ++ drive-strength = <30>; ++ bias-pull-up; ++ }; ++ + mmc2_pins: mmc2-pins { + pins = "PC1", "PC4", "PC5", "PC6", + "PC7", "PC8", "PC9", "PC10", +@@ -270,6 +279,8 @@ + resets = <&ccu RST_BUS_MMC1>; + reset-names = "ahb"; + interrupts = ; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&mmc1_pins>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + +From 200cf18794214700f023440021cb7fd40dcc0f01 Mon Sep 17 00:00:00 2001 +From: Ondrej Jirman +Date: Tue, 9 Apr 2019 00:16:35 +0200 +Subject: [PATCH 19/34] arm64: dts: allwinner: orange-pi-3: Enable WiFi + +Orange Pi 3 has AP6256 WiFi/BT module. WiFi part of the module is called +bcm43356 and can be used with the brcmfmac driver. The module is powered by +the two always on regulators (not AXP805). + +WiFi uses a PG port with 1.8V voltage level signals. SoC needs to be +configured so that it sets up an 1.8V input bias on this port. This is done +by the pio driver by reading the vcc-pg-supply voltage. + +You'll need a fw_bcm43456c5_ag.bin firmware file and nvram.txt +configuration that can be found in the Xulongs's repository for H6: + +https://github.com/orangepi-xunlong/OrangePiH6_external/tree/master/ap6256 + +Mainline brcmfmac driver expects the firmware and nvram at the following +paths relative to the firmware directory: + + brcm/brcmfmac43456-sdio.bin + brcm/brcmfmac43456-sdio.txt + +Signed-off-by: Ondrej Jirman +--- + .../dts/allwinner/sun50i-h6-orangepi-3.dts | 48 +++++++++++++++++++ + 1 file changed, 48 insertions(+) + +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts +index 58a6635c909e3..f795362f5b77e 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts +@@ -67,6 +67,26 @@ + regulator-always-on; + }; + ++ reg_vcc33_wifi: vcc33-wifi { ++ /* Always on 3.3V regulator for WiFi and BT */ ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc33-wifi"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ vin-supply = <®_vcc5v>; ++ }; ++ ++ reg_vcc_wifi_io: vcc-wifi-io { ++ /* Always on 1.8V/300mA regulator for WiFi and BT IO */ ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc-wifi-io"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ vin-supply = <®_vcc33_wifi>; ++ }; ++ + /* + * The board uses 2.5V RGMII signalling. Power sequence to enable + * the phy is to enable GMAC-2V5 and GMAC-3V3 (aldo2) power rails +@@ -87,6 +107,14 @@ + */ + vin-supply = <®_aldo2>; /* GMAC-3V3 */ + }; ++ ++ wifi_pwrseq: wifi_pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ clocks = <&rtc 1>; ++ clock-names = "ext_clock"; ++ reset-gpios = <&r_pio 1 3 GPIO_ACTIVE_LOW>; /* PM3 */ ++ post-power-on-delay-ms = <200>; ++ }; + }; + + &cpu0 { +@@ -144,6 +172,25 @@ + status = "okay"; + }; + ++&mmc1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&mmc1_pins>; ++ vmmc-supply = <®_vcc33_wifi>; ++ vqmmc-supply = <®_vcc_wifi_io>; ++ mmc-pwrseq = <&wifi_pwrseq>; ++ bus-width = <4>; ++ non-removable; ++ status = "okay"; ++ ++ brcm: sdio-wifi@1 { ++ reg = <1>; ++ compatible = "brcm,bcm4329-fmac"; ++ interrupt-parent = <&r_pio>; ++ interrupts = <1 0 IRQ_TYPE_LEVEL_LOW>; /* PM0 */ ++ interrupt-names = "host-wake"; ++ }; ++}; ++ + &ohci0 { + status = "okay"; + }; +@@ -155,6 +202,7 @@ + &pio { + vcc-pc-supply = <®_bldo2>; + vcc-pd-supply = <®_cldo1>; ++ vcc-pg-supply = <®_vcc_wifi_io>; + }; + + &r_i2c { + +From d996492e1f700a9f0a104c50b126a022dee77dd6 Mon Sep 17 00:00:00 2001 +From: Icenowy Zheng +Date: Mon, 25 Dec 2017 12:04:02 +0800 +Subject: [PATCH 20/34] phy: allwinner: add phy driver for USB3 PHY on + Allwinner H6 SoC + +Allwinner H6 SoC contains a USB3 PHY (with USB2 DP/DM lines also +controlled). + +Add a driver for it. + +The register operations in this driver is mainly extracted from the BSP +USB3 driver. + +Signed-off-by: Icenowy Zheng +Reviewed-by: Chen-Yu Tsai +--- + drivers/phy/allwinner/Kconfig | 12 ++ + drivers/phy/allwinner/Makefile | 1 + + drivers/phy/allwinner/phy-sun50i-usb3.c | 194 ++++++++++++++++++++++++ + 3 files changed, 207 insertions(+) + create mode 100644 drivers/phy/allwinner/phy-sun50i-usb3.c + +diff --git a/drivers/phy/allwinner/Kconfig b/drivers/phy/allwinner/Kconfig +index fb1204bcc4548..2c363db177f20 100644 +--- a/drivers/phy/allwinner/Kconfig ++++ b/drivers/phy/allwinner/Kconfig +@@ -41,3 +41,15 @@ config PHY_SUN9I_USB + sun9i SoCs. + + This driver controls each individual USB 2 host PHY. ++ ++config PHY_SUN50I_USB3 ++ tristate "Allwinner sun50i SoC USB3 PHY driver" ++ depends on ARCH_SUNXI && HAS_IOMEM && OF ++ depends on RESET_CONTROLLER ++ select USB_COMMON ++ select GENERIC_PHY ++ help ++ Enable this to support the USB3.0-capable transceiver that is ++ part of some Allwinner sun50i SoCs. ++ ++ This driver controls each individual USB 2+3 host PHY combo. +diff --git a/drivers/phy/allwinner/Makefile b/drivers/phy/allwinner/Makefile +index 7d0053efbfaa6..59575a895779b 100644 +--- a/drivers/phy/allwinner/Makefile ++++ b/drivers/phy/allwinner/Makefile +@@ -1,3 +1,4 @@ + obj-$(CONFIG_PHY_SUN4I_USB) += phy-sun4i-usb.o + obj-$(CONFIG_PHY_SUN6I_MIPI_DPHY) += phy-sun6i-mipi-dphy.o + obj-$(CONFIG_PHY_SUN9I_USB) += phy-sun9i-usb.o ++obj-$(CONFIG_PHY_SUN50I_USB3) += phy-sun50i-usb3.o +diff --git a/drivers/phy/allwinner/phy-sun50i-usb3.c b/drivers/phy/allwinner/phy-sun50i-usb3.c +new file mode 100644 +index 0000000000000..226c99c2d664c +--- /dev/null ++++ b/drivers/phy/allwinner/phy-sun50i-usb3.c +@@ -0,0 +1,194 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Allwinner sun50i(H6) USB 3.0 phy driver ++ * ++ * Copyright (C) 2017 Icenowy Zheng ++ * ++ * Based on phy-sun9i-usb.c, which is: ++ * ++ * Copyright (C) 2014-2015 Chen-Yu Tsai ++ * ++ * Based on code from Allwinner BSP, which is: ++ * ++ * Copyright (c) 2010-2015 Allwinner Technology Co., Ltd. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Interface Status and Control Registers */ ++#define SUNXI_ISCR 0x00 ++#define SUNXI_PIPE_CLOCK_CONTROL 0x14 ++#define SUNXI_PHY_TUNE_LOW 0x18 ++#define SUNXI_PHY_TUNE_HIGH 0x1c ++#define SUNXI_PHY_EXTERNAL_CONTROL 0x20 ++ ++/* USB2.0 Interface Status and Control Register */ ++#define SUNXI_ISCR_FORCE_VBUS (3 << 12) ++ ++/* PIPE Clock Control Register */ ++#define SUNXI_PCC_PIPE_CLK_OPEN (1 << 6) ++ ++/* PHY External Control Register */ ++#define SUNXI_PEC_EXTERN_VBUS (3 << 1) ++#define SUNXI_PEC_SSC_EN (1 << 24) ++#define SUNXI_PEC_REF_SSP_EN (1 << 26) ++ ++/* PHY Tune High Register */ ++#define SUNXI_TX_DEEMPH_3P5DB(n) ((n) << 19) ++#define SUNXI_TX_DEEMPH_3P5DB_MASK GENMASK(24, 19) ++#define SUNXI_TX_DEEMPH_6DB(n) ((n) << 13) ++#define SUNXI_TX_DEEMPH_6GB_MASK GENMASK(18, 13) ++#define SUNXI_TX_SWING_FULL(n) ((n) << 6) ++#define SUNXI_TX_SWING_FULL_MASK GENMASK(12, 6) ++#define SUNXI_LOS_BIAS(n) ((n) << 3) ++#define SUNXI_LOS_BIAS_MASK GENMASK(5, 3) ++#define SUNXI_TXVBOOSTLVL(n) ((n) << 0) ++#define SUNXI_TXVBOOSTLVL_MASK GENMASK(0, 2) ++ ++struct sun50i_usb3_phy { ++ struct phy *phy; ++ void __iomem *regs; ++ struct reset_control *reset; ++ struct clk *clk; ++}; ++ ++static void sun50i_usb3_phy_open(struct sun50i_usb3_phy *phy) ++{ ++ u32 val; ++ ++ val = readl(phy->regs + SUNXI_PHY_EXTERNAL_CONTROL); ++ val |= SUNXI_PEC_EXTERN_VBUS; ++ val |= SUNXI_PEC_SSC_EN | SUNXI_PEC_REF_SSP_EN; ++ writel(val, phy->regs + SUNXI_PHY_EXTERNAL_CONTROL); ++ ++ val = readl(phy->regs + SUNXI_PIPE_CLOCK_CONTROL); ++ val |= SUNXI_PCC_PIPE_CLK_OPEN; ++ writel(val, phy->regs + SUNXI_PIPE_CLOCK_CONTROL); ++ ++ val = readl(phy->regs + SUNXI_ISCR); ++ val |= SUNXI_ISCR_FORCE_VBUS; ++ writel(val, phy->regs + SUNXI_ISCR); ++ ++ /* ++ * All the magic numbers written to the PHY_TUNE_{LOW_HIGH} ++ * registers are directly taken from the BSP USB3 driver from ++ * Allwiner. ++ */ ++ writel(0x0047fc87, phy->regs + SUNXI_PHY_TUNE_LOW); ++ ++ val = readl(phy->regs + SUNXI_PHY_TUNE_HIGH); ++ val &= ~(SUNXI_TXVBOOSTLVL_MASK | SUNXI_LOS_BIAS_MASK | ++ SUNXI_TX_SWING_FULL_MASK | SUNXI_TX_DEEMPH_6GB_MASK | ++ SUNXI_TX_DEEMPH_3P5DB_MASK); ++ val |= SUNXI_TXVBOOSTLVL(0x7); ++ val |= SUNXI_LOS_BIAS(0x7); ++ val |= SUNXI_TX_SWING_FULL(0x55); ++ val |= SUNXI_TX_DEEMPH_6DB(0x20); ++ val |= SUNXI_TX_DEEMPH_3P5DB(0x15); ++ writel(val, phy->regs + SUNXI_PHY_TUNE_HIGH); ++} ++ ++static int sun50i_usb3_phy_init(struct phy *_phy) ++{ ++ struct sun50i_usb3_phy *phy = phy_get_drvdata(_phy); ++ int ret; ++ ++ ret = clk_prepare_enable(phy->clk); ++ if (ret) ++ goto err_clk; ++ ++ ret = reset_control_deassert(phy->reset); ++ if (ret) ++ goto err_reset; ++ ++ sun50i_usb3_phy_open(phy); ++ return 0; ++ ++err_reset: ++ clk_disable_unprepare(phy->clk); ++ ++err_clk: ++ return ret; ++} ++ ++static int sun50i_usb3_phy_exit(struct phy *_phy) ++{ ++ struct sun50i_usb3_phy *phy = phy_get_drvdata(_phy); ++ ++ reset_control_assert(phy->reset); ++ clk_disable_unprepare(phy->clk); ++ ++ return 0; ++} ++ ++static const struct phy_ops sun50i_usb3_phy_ops = { ++ .init = sun50i_usb3_phy_init, ++ .exit = sun50i_usb3_phy_exit, ++ .owner = THIS_MODULE, ++}; ++ ++static int sun50i_usb3_phy_probe(struct platform_device *pdev) ++{ ++ struct sun50i_usb3_phy *phy; ++ struct device *dev = &pdev->dev; ++ struct phy_provider *phy_provider; ++ struct resource *res; ++ ++ phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); ++ if (!phy) ++ return -ENOMEM; ++ ++ phy->clk = devm_clk_get(dev, NULL); ++ if (IS_ERR(phy->clk)) { ++ dev_err(dev, "failed to get phy clock\n"); ++ return PTR_ERR(phy->clk); ++ } ++ ++ phy->reset = devm_reset_control_get(dev, NULL); ++ if (IS_ERR(phy->reset)) { ++ dev_err(dev, "failed to get reset control\n"); ++ return PTR_ERR(phy->reset); ++ } ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ phy->regs = devm_ioremap_resource(dev, res); ++ if (IS_ERR(phy->regs)) ++ return PTR_ERR(phy->regs); ++ ++ phy->phy = devm_phy_create(dev, NULL, &sun50i_usb3_phy_ops); ++ if (IS_ERR(phy->phy)) { ++ dev_err(dev, "failed to create PHY\n"); ++ return PTR_ERR(phy->phy); ++ } ++ ++ phy_set_drvdata(phy->phy, phy); ++ phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); ++ ++ return PTR_ERR_OR_ZERO(phy_provider); ++} ++ ++static const struct of_device_id sun50i_usb3_phy_of_match[] = { ++ { .compatible = "allwinner,sun50i-h6-usb3-phy" }, ++ { }, ++}; ++MODULE_DEVICE_TABLE(of, sun50i_usb3_phy_of_match); ++ ++static struct platform_driver sun50i_usb3_phy_driver = { ++ .probe = sun50i_usb3_phy_probe, ++ .driver = { ++ .of_match_table = sun50i_usb3_phy_of_match, ++ .name = "sun50i-usb3-phy", ++ } ++}; ++module_platform_driver(sun50i_usb3_phy_driver); ++ ++MODULE_DESCRIPTION("Allwinner sun50i USB 3.0 phy driver"); ++MODULE_AUTHOR("Icenowy Zheng "); ++MODULE_LICENSE("GPL"); + +From 5fd2d3bd956cc875d07433454f18dcbc14e120d5 Mon Sep 17 00:00:00 2001 +From: Ondrej Jirman +Date: Tue, 26 Mar 2019 15:14:14 +0100 +Subject: [PATCH 24/34] bluetooth: bcm: Add support for loading firmware for + BCM4345C5 + +WIP + +Signed-off-by: Ondrej Jirman +--- + drivers/bluetooth/btbcm.c | 3 +++ + drivers/bluetooth/hci_bcm.c | 1 + + 2 files changed, 4 insertions(+) + +diff --git a/drivers/bluetooth/btbcm.c b/drivers/bluetooth/btbcm.c +index d5d6e6e5da3bf..a58bf860bcbfc 100644 +--- a/drivers/bluetooth/btbcm.c ++++ b/drivers/bluetooth/btbcm.c +@@ -37,6 +37,7 @@ + #define BDADDR_BCM43430A0 (&(bdaddr_t) {{0xac, 0x1f, 0x12, 0xa0, 0x43, 0x43}}) + #define BDADDR_BCM4324B3 (&(bdaddr_t) {{0x00, 0x00, 0x00, 0xb3, 0x24, 0x43}}) + #define BDADDR_BCM4330B1 (&(bdaddr_t) {{0x00, 0x00, 0x00, 0xb1, 0x30, 0x43}}) ++#define BDADDR_BCM4345C5 (&(bdaddr_t) {{0xac, 0x1f, 0x00, 0xc5, 0x45, 0x43}}) + + int btbcm_check_bdaddr(struct hci_dev *hdev) + { +@@ -82,6 +83,7 @@ int btbcm_check_bdaddr(struct hci_dev *hdev) + !bacmp(&bda->bdaddr, BDADDR_BCM20702A1) || + !bacmp(&bda->bdaddr, BDADDR_BCM4324B3) || + !bacmp(&bda->bdaddr, BDADDR_BCM4330B1) || ++ !bacmp(&bda->bdaddr, BDADDR_BCM4345C5) || + !bacmp(&bda->bdaddr, BDADDR_BCM43430A0)) { + bt_dev_info(hdev, "BCM: Using default device address (%pMR)", + &bda->bdaddr); +@@ -339,6 +341,7 @@ static const struct bcm_subver_table bcm_uart_subver_table[] = { + { 0x2122, "BCM4343A0" }, /* 001.001.034 */ + { 0x2209, "BCM43430A1" }, /* 001.002.009 */ + { 0x6119, "BCM4345C0" }, /* 003.001.025 */ ++ { 0x6606, "BCM4345C5" }, /* 003.006.006 */ + { 0x230f, "BCM4356A2" }, /* 001.003.015 */ + { 0x220e, "BCM20702A1" }, /* 001.002.014 */ + { 0x4217, "BCM4329B1" }, /* 002.002.023 */ +diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c +index ddbe518c3e5b8..d5d5ddc3cf1b8 100644 +--- a/drivers/bluetooth/hci_bcm.c ++++ b/drivers/bluetooth/hci_bcm.c +@@ -1419,6 +1419,7 @@ static void bcm_serdev_remove(struct serdev_device *serdev) + #ifdef CONFIG_OF + static const struct of_device_id bcm_bluetooth_of_match[] = { + { .compatible = "brcm,bcm20702a1" }, ++ { .compatible = "brcm,bcm4345c5" }, + { .compatible = "brcm,bcm4330-bt" }, + { .compatible = "brcm,bcm43438-bt" }, + { }, + +From d5626d424fbdc9dde5f8a2e525e88de33fc898cc Mon Sep 17 00:00:00 2001 +From: Ondrej Jirman +Date: Fri, 12 Apr 2019 13:24:26 +0200 +Subject: [PATCH 25/34] bluetooth: hci_bcm: Give more time to come out of reset + +Some devices need more time to come out of reset (eg. BCM4345). +Increase the post-reset delay. I don't have datasheet, so rather +be safe than to get intermittent failures during probe. + +Signed-off-by: Ondrej Jirman +--- + drivers/bluetooth/hci_bcm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c +index d5d5ddc3cf1b8..9eacaf8f72ec3 100644 +--- a/drivers/bluetooth/hci_bcm.c ++++ b/drivers/bluetooth/hci_bcm.c +@@ -263,7 +263,7 @@ static int bcm_gpio_set_power(struct bcm_device *dev, bool powered) + } + + /* wait for device to power on and come out of reset */ +- usleep_range(10000, 20000); ++ usleep_range(50000, 60000); + + dev->res_enabled = powered; + + +From 5141fbafc9bf5f1a7cbb6923bc719f595ce54dae Mon Sep 17 00:00:00 2001 +From: Icenowy Zheng +Date: Mon, 25 Dec 2017 12:10:06 +0800 +Subject: [PATCH 26/34] arm64: dts: allwinner: h6: add USB3 device nodes + +Allwinner H6 SoC features USB3 functionality, with a DWC3 controller and +a custom PHY. + +Add device tree nodes for them. + +Signed-off-by: Icenowy Zheng +Reviewed-by: Chen-Yu Tsai +--- + arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 32 ++++++++++++++++++++ + 1 file changed, 32 insertions(+) + +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi +index c5c0608e67403..38784589558ca 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi +@@ -420,6 +420,38 @@ + status = "disabled"; + }; + ++ dwc3: dwc3@5200000 { ++ compatible = "snps,dwc3"; ++ reg = <0x05200000 0x10000>; ++ interrupts = ; ++ clocks = <&ccu CLK_BUS_XHCI>, ++ <&ccu CLK_BUS_XHCI>, ++ <&rtc 0>; ++ clock-names = "ref", "bus_early", "suspend"; ++ resets = <&ccu RST_BUS_XHCI>; ++ /* ++ * The datasheet of the chip doesn't declare the ++ * peripheral function, and there's no boards known ++ * to have a USB Type-B port routed to the port. ++ * In addition, no one has tested the peripheral ++ * function yet. ++ * So set the dr_mode to "host" in the DTSI file. ++ */ ++ dr_mode = "host"; ++ phys = <&usb3phy>; ++ phy-names = "usb3-phy"; ++ status = "disabled"; ++ }; ++ ++ usb3phy: phy@5210000 { ++ compatible = "allwinner,sun50i-h6-usb3-phy"; ++ reg = <0x5210000 0x10000>; ++ clocks = <&ccu CLK_USB_PHY1>; ++ resets = <&ccu RST_USB_PHY1>; ++ #phy-cells = <0>; ++ status = "disabled"; ++ }; ++ + ehci3: usb@5311000 { + compatible = "allwinner,sun50i-h6-ehci", "generic-ehci"; + reg = <0x05311000 0x100>; + +FFrom 19ed1005f6d1d2955c9e3e88c3fe037b46284ca8 Mon Sep 17 00:00:00 2001 +From: Ondrej Jirman +Date: Tue, 26 Mar 2019 15:13:34 +0100 +Subject: [PATCH 32/34] arm64: dts: allwinner: h6: Add pin configs for uart1 + +Orange Pi 3 uses UART1 for bluetooth. Add pinconfigs so that +we can use them. + +Signed-off-by: Ondrej Jirman +--- + arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi +index 5c5b1240c7790..dc785da9ce0a2 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi +@@ -322,6 +322,16 @@ + pins = "PH0", "PH1"; + function = "uart0"; + }; ++ ++ uart1_pins: uart1-pins { ++ pins = "PG6", "PG7"; ++ function = "uart1"; ++ }; ++ ++ uart1_rts_cts_pins: uart1-rts-cts-pins { ++ pins = "PG8", "PG9"; ++ function = "uart1"; ++ }; + }; + + gic: interrupt-controller@3021000 { + +From 785248f1b1d89bbd8a25435f873bfa91c27fa123 Mon Sep 17 00:00:00 2001 +From: Ondrej Jirman +Date: Wed, 27 Mar 2019 13:48:59 +0100 +Subject: [PATCH 33/34] arm64: dts: allwinner: orange-pi-3: Enable UART1 / + Bluetooth + +The board contains AP6256 WiFi/BT module that has its bluetooth +part connected to SoC's UART1 port. Enable this port, and add +node for the bluetooth device. + +Bluetooth part is named bcm4345c5. + +You'll need a BCM4345C5.hcd firmware file that can be found in +the Xulongs's repository for H6: + +https://github.com/orangepi-xunlong/OrangePiH6_external/tree/master/ap6256 + +Mainline brcmbt driver expects the firmware at the following path +relative to the firmware directory: + + brcm/BCM4345C5.hcd + +Signed-off-by: Ondrej Jirman +--- + .../dts/allwinner/sun50i-h6-orangepi-3.dts | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts +index f795362f5b77e..d9e8610b5f83f 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts +@@ -15,6 +15,7 @@ + + aliases { + serial0 = &uart0; ++ serial1 = &uart1; + ethernet0 = &emac; + }; + +@@ -324,6 +325,24 @@ + status = "okay"; + }; + ++/* There's the BT part of the AP6256 connected to that UART */ ++&uart1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>; ++ uart-has-rtscts; ++ status = "okay"; ++ ++ bluetooth { ++ compatible = "brcm,bcm4345c5"; ++ clocks = <&rtc 1>; ++ clock-names = "lpo"; ++ device-wakeup-gpios = <&r_pio 1 2 GPIO_ACTIVE_HIGH>; /* PM2 */ ++ host-wakeup-gpios = <&r_pio 1 1 GPIO_ACTIVE_HIGH>; /* PM1 */ ++ shutdown-gpios = <&r_pio 1 4 GPIO_ACTIVE_HIGH>; /* PM4 */ ++ max-speed = <1500000>; ++ }; ++}; ++ + &usb2otg { + /* + * This board doesn't have a controllable VBUS even though it + +From c74e4ba1e28d5808cda02b34eee59dc1a5f15a6d Mon Sep 17 00:00:00 2001 +From: Ondrej Jirman +Date: Wed, 27 Mar 2019 13:43:25 +0100 +Subject: [PATCH 34/34] arm64: dts: allwinner: orange-pi-3: Enable USB 3.0 host + support + +Enable Allwinner's USB 3.0 phy and the host controller. Orange Pi 3 +board has GL3510 USB 3.0 4-port hub connected to the SoC's USB 3.0 +port. All four ports are exposed via USB3-A connectors. The hub is +powered directly from DCIN/VCC-5V. + +Signed-off-by: Ondrej Jirman +--- + arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts +index d9e8610b5f83f..afee79fb88f18 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts +@@ -126,6 +126,10 @@ + status = "okay"; + }; + ++&dwc3 { ++ status = "okay"; ++}; ++ + &ehci0 { + status = "okay"; + }; +@@ -359,3 +363,8 @@ + usb3_vbus-supply = <®_vcc5v>; + status = "okay"; + }; ++ ++&usb3phy { ++ phy-supply = <®_vcc5v>; ++ status = "okay"; ++}; diff --git a/projects/Allwinner/devices/H6/patches/u-boot/002-orange-pi-3-support.patch b/projects/Allwinner/devices/H6/patches/u-boot/002-orange-pi-3-support.patch new file mode 100644 index 0000000000..ce8c18bf06 --- /dev/null +++ b/projects/Allwinner/devices/H6/patches/u-boot/002-orange-pi-3-support.patch @@ -0,0 +1,352 @@ +diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile +index 0e2ffdb87f..ad60ae0179 100644 +--- a/arch/arm/dts/Makefile ++++ b/arch/arm/dts/Makefile +@@ -467,6 +467,7 @@ dtb-$(CONFIG_MACH_SUN50I_H5) += \ + sun50i-h5-orangepi-prime.dtb \ + sun50i-h5-orangepi-zero-plus2.dtb + dtb-$(CONFIG_MACH_SUN50I_H6) += \ ++ sun50i-h6-orangepi-3.dtb \ + sun50i-h6-orangepi-lite2.dtb \ + sun50i-h6-orangepi-one-plus.dtb \ + sun50i-h6-pine-h64.dtb +diff --git a/arch/arm/dts/sun50i-h6-orangepi-3.dts b/arch/arm/dts/sun50i-h6-orangepi-3.dts +new file mode 100644 +index 0000000000..8070adc39b +--- /dev/null ++++ b/arch/arm/dts/sun50i-h6-orangepi-3.dts +@@ -0,0 +1,316 @@ ++// SPDX-License-Identifier: (GPL-2.0+ or MIT) ++/* ++ * Copyright (C) 2019 Ondřej Jirman ++ */ ++ ++/dts-v1/; ++ ++#include "sun50i-h6.dtsi" ++ ++#include ++ ++/ { ++ model = "OrangePi 3"; ++ compatible = "xunlong,orangepi-3", "allwinner,sun50i-h6"; ++ ++ aliases { ++ serial0 = &uart0; ++ serial1 = &uart1; ++ ethernet0 = &emac; ++ }; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ connector { ++ compatible = "hdmi-connector"; ++ type = "a"; ++ ddc-supply = <®_ddc>; ++ ++ port { ++ hdmi_con_in: endpoint { ++ remote-endpoint = <&hdmi_out_con>; ++ }; ++ }; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ power { ++ label = "orangepi:red:power"; ++ gpios = <&r_pio 0 4 GPIO_ACTIVE_HIGH>; /* PL4 */ ++ default-state = "on"; ++ }; ++ ++ status { ++ label = "orangepi:green:status"; ++ gpios = <&r_pio 0 7 GPIO_ACTIVE_HIGH>; /* PL7 */ ++ }; ++ }; ++ ++ reg_ddc: ddc-io { ++ compatible = "regulator-fixed"; ++ regulator-name = "ddc-io"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ enable-active-high; ++ gpio = <&pio 7 2 GPIO_ACTIVE_HIGH>; /* PH2 */ ++ }; ++ ++ reg_vcc5v: vcc5v { ++ /* board wide 5V supply directly from the DC jack */ ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc-5v"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ regulator-always-on; ++ }; ++ ++ reg_vcc33_wifi: vcc33-wifi { ++ /* Always on 3.3V regulator for WiFi and BT */ ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc33-wifi"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ vin-supply = <®_vcc5v>; ++ }; ++ ++ reg_vcc_wifi_io: vcc-wifi-io { ++ /* Always on 1.8V/300mA regulator for WiFi and BT IO */ ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc-wifi-io"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ vin-supply = <®_vcc33_wifi>; ++ }; ++ ++ /* ++ * The board uses 2.5V RGMII signalling. Power sequence to enable ++ * the phy is to enable GMAC-2V5 and GMAC-3V3 (aldo2) power rails ++ * at the same time and to wait 100ms. ++ */ ++ reg_gmac_2v5: gmac-2v5 { ++ compatible = "regulator-fixed"; ++ regulator-name = "gmac-2v5"; ++ regulator-min-microvolt = <2500000>; ++ regulator-max-microvolt = <2500000>; ++ startup-delay-us = <100000>; ++ enable-active-high; ++ gpio = <&pio 3 6 GPIO_ACTIVE_HIGH>; /* PD6 */ ++ ++ /* The real parent of gmac-2v5 is reg_vcc5v, but we need to ++ * enable two regulators to power the phy. This is one way ++ * to achieve that. ++ */ ++ vin-supply = <®_aldo2>; /* GMAC-3V3 */ ++ }; ++}; ++ ++&cpu0 { ++ cpu-supply = <®_dcdca>; ++}; ++ ++&de { ++ status = "okay"; ++}; ++ ++&ehci0 { ++ status = "okay"; ++}; ++ ++&ehci3 { ++ status = "okay"; ++}; ++ ++&emac { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&ext_rgmii_pins>; ++ phy-mode = "rgmii"; ++ phy-handle = <&ext_rgmii_phy>; ++ phy-supply = <®_gmac_2v5>; ++ allwinner,rx-delay-ps = <1500>; ++ allwinner,tx-delay-ps = <700>; ++ status = "okay"; ++}; ++ ++&hdmi { ++ status = "okay"; ++}; ++ ++&hdmi_out { ++ hdmi_out_con: endpoint { ++ remote-endpoint = <&hdmi_con_in>; ++ }; ++}; ++ ++&mdio { ++ ext_rgmii_phy: ethernet-phy@1 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <1>; ++ ++ reset-gpios = <&pio 3 14 GPIO_ACTIVE_LOW>; /* PD14 */ ++ reset-assert-us = <15000>; ++ reset-deassert-us = <40000>; ++ }; ++}; ++ ++&mmc0 { ++ vmmc-supply = <®_cldo1>; ++ cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */ ++ bus-width = <4>; ++ status = "okay"; ++}; ++ ++&ohci0 { ++ status = "okay"; ++}; ++ ++&ohci3 { ++ status = "okay"; ++}; ++ ++&pio { ++ vcc-pc-supply = <®_bldo2>; ++ vcc-pd-supply = <®_cldo1>; ++ vcc-pg-supply = <®_vcc_wifi_io>; ++}; ++ ++&r_i2c { ++ status = "okay"; ++ ++ axp805: pmic@36 { ++ compatible = "x-powers,axp805", "x-powers,axp806"; ++ reg = <0x36>; ++ interrupt-parent = <&r_intc>; ++ interrupts = <0 IRQ_TYPE_LEVEL_LOW>; ++ interrupt-controller; ++ #interrupt-cells = <1>; ++ x-powers,self-working-mode; ++ vina-supply = <®_vcc5v>; ++ vinb-supply = <®_vcc5v>; ++ vinc-supply = <®_vcc5v>; ++ vind-supply = <®_vcc5v>; ++ vine-supply = <®_vcc5v>; ++ aldoin-supply = <®_vcc5v>; ++ bldoin-supply = <®_vcc5v>; ++ cldoin-supply = <®_vcc5v>; ++ ++ regulators { ++ reg_aldo1: aldo1 { ++ regulator-always-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-name = "vcc-pl-led-ir"; ++ }; ++ ++ reg_aldo2: aldo2 { ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-name = "vcc33-audio-tv-ephy-mac"; ++ }; ++ ++ /* ALDO3 is shorted to CLDO1 */ ++ reg_aldo3: aldo3 { ++ regulator-always-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-name = "vcc33-io-pd-emmc-sd-usb-uart-1"; ++ }; ++ ++ reg_bldo1: bldo1 { ++ regulator-always-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-name = "vcc18-dram-bias-pll"; ++ }; ++ ++ reg_bldo2: bldo2 { ++ regulator-always-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-name = "vcc-efuse-pcie-hdmi-pc"; ++ }; ++ ++ bldo3 { ++ /* unused */ ++ }; ++ ++ bldo4 { ++ /* unused */ ++ }; ++ ++ reg_cldo1: cldo1 { ++ regulator-always-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-name = "vcc33-io-pd-emmc-sd-usb-uart-2"; ++ }; ++ ++ cldo2 { ++ /* unused */ ++ }; ++ ++ cldo3 { ++ /* unused */ ++ }; ++ ++ reg_dcdca: dcdca { ++ regulator-always-on; ++ regulator-min-microvolt = <800000>; ++ regulator-max-microvolt = <1160000>; ++ regulator-name = "vdd-cpu"; ++ }; ++ ++ reg_dcdcc: dcdcc { ++ regulator-min-microvolt = <810000>; ++ regulator-max-microvolt = <1080000>; ++ regulator-name = "vdd-gpu"; ++ }; ++ ++ reg_dcdcd: dcdcd { ++ regulator-always-on; ++ regulator-min-microvolt = <960000>; ++ regulator-max-microvolt = <960000>; ++ regulator-name = "vdd-sys"; ++ }; ++ ++ reg_dcdce: dcdce { ++ regulator-always-on; ++ regulator-min-microvolt = <1200000>; ++ regulator-max-microvolt = <1200000>; ++ regulator-name = "vcc-dram"; ++ }; ++ ++ sw { ++ /* unused */ ++ }; ++ }; ++ }; ++}; ++ ++&uart0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_ph_pins>; ++ status = "okay"; ++}; ++ ++&usb2otg { ++ /* ++ * This board doesn't have a controllable VBUS even though it ++ * does have an ID pin. Using it as anything but a USB host is ++ * unsafe. ++ */ ++ dr_mode = "host"; ++ status = "okay"; ++}; ++ ++&usb2phy { ++ usb0_id_det-gpios = <&pio 2 15 GPIO_ACTIVE_HIGH>; /* PC15 */ ++ usb0_vbus-supply = <®_vcc5v>; ++ usb3_vbus-supply = <®_vcc5v>; ++ status = "okay"; ++}; +diff --git a/configs/orangepi_3_defconfig b/configs/orangepi_3_defconfig +new file mode 100644 +index 0000000000..9a9cd28142 +--- /dev/null ++++ b/configs/orangepi_3_defconfig +@@ -0,0 +1,12 @@ ++CONFIG_ARM=y ++CONFIG_ARCH_SUNXI=y ++CONFIG_SPL=y ++CONFIG_MACH_SUN50I_H6=y ++CONFIG_MMC0_CD_PIN="PF6" ++# CONFIG_PSCI_RESET is not set ++CONFIG_NR_DRAM_BANKS=1 ++# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set ++# CONFIG_CMD_FLASH is not set ++# CONFIG_SPL_DOS_PARTITION is not set ++# CONFIG_SPL_EFI_PARTITION is not set ++CONFIG_DEFAULT_DEVICE_TREE="sun50i-h6-orangepi-3" diff --git a/projects/Allwinner/linux/linux.aarch64.conf b/projects/Allwinner/linux/linux.aarch64.conf index 6c5aecac90..e35244c61e 100644 --- a/projects/Allwinner/linux/linux.aarch64.conf +++ b/projects/Allwinner/linux/linux.aarch64.conf @@ -4856,6 +4856,7 @@ CONFIG_PHY_XGENE=y CONFIG_PHY_SUN4I_USB=y # CONFIG_PHY_SUN6I_MIPI_DPHY is not set # CONFIG_PHY_SUN9I_USB is not set +CONFIG_PHY_SUN50I_USB3=y # CONFIG_BCM_KONA_USB2_PHY is not set # CONFIG_PHY_CADENCE_DP is not set # CONFIG_PHY_CADENCE_DPHY is not set