[U-Boot] [PATCH v2 0/4] Add support for Meson GXBB GPIOs to U-Boot

Hi,
this series adds to U-Boot a GPIO driver for Meson GXBB and enables it on Odroid-C2.
Changes since v1: - updated dts files from Linux 4.12 - added missing asm/arch/gpio.h - added patch 4 to convert driver to livetree
Beniamino Galvani (4): arm: dts: meson: import dts files from Linux 4.12 pinctrl: meson: add GPIO support odroid-c2: enable GPIO pinctrl: meson: convert to livetree
arch/arm/dts/meson-gx.dtsi | 97 +++++++++++-- arch/arm/dts/meson-gxbb-odroidc2.dts | 82 ++++++++++- arch/arm/dts/meson-gxbb.dtsi | 187 +++++++++++++++++++----- arch/arm/include/asm/arch-meson/gpio.h | 11 ++ configs/odroid-c2_defconfig | 2 + drivers/pinctrl/meson/pinctrl-meson-gxbb.c | 21 +++ drivers/pinctrl/meson/pinctrl-meson.c | 221 +++++++++++++++++++++++++---- drivers/pinctrl/meson/pinctrl-meson.h | 63 ++++++++ include/dt-bindings/clock/gxbb-clkc.h | 24 +++- 9 files changed, 636 insertions(+), 72 deletions(-) create mode 100644 arch/arm/include/asm/arch-meson/gpio.h

Import Amlogic Meson DTS files from Linux kernel version 4.12
Signed-off-by: Beniamino Galvani b.galvani@gmail.com --- arch/arm/dts/meson-gx.dtsi | 97 ++++++++++++++++-- arch/arm/dts/meson-gxbb-odroidc2.dts | 82 ++++++++++++++- arch/arm/dts/meson-gxbb.dtsi | 187 ++++++++++++++++++++++++++++------ include/dt-bindings/clock/gxbb-clkc.h | 24 ++++- 4 files changed, 344 insertions(+), 46 deletions(-)
diff --git a/arch/arm/dts/meson-gx.dtsi b/arch/arm/dts/meson-gx.dtsi index c129100..436b875 100644 --- a/arch/arm/dts/meson-gx.dtsi +++ b/arch/arm/dts/meson-gx.dtsi @@ -71,6 +71,14 @@ reg = <0x0 0x10000000 0x0 0x200000>; no-map; }; + + linux,cma { + compatible = "shared-dma-pool"; + reusable; + size = <0x0 0xbc00000>; + alignment = <0x0 0x400000>; + linux,cma-default; + }; };
cpus { @@ -233,7 +241,7 @@ };
i2c_A: i2c@8500 { - compatible = "amlogic,meson-gxbb-i2c"; + compatible = "amlogic,meson-gx-i2c", "amlogic,meson-gxbb-i2c"; reg = <0x0 0x08500 0x0 0x20>; interrupts = <GIC_SPI 21 IRQ_TYPE_EDGE_RISING>; #address-cells = <1>; @@ -255,6 +263,14 @@ status = "disabled"; };
+ saradc: adc@8680 { + compatible = "amlogic,meson-saradc"; + reg = <0x0 0x8680 0x0 0x34>; + #io-channel-cells = <1>; + interrupts = <GIC_SPI 73 IRQ_TYPE_EDGE_RISING>; + status = "disabled"; + }; + pwm_ef: pwm@86c0 { compatible = "amlogic,meson-gx-pwm", "amlogic,meson-gxbb-pwm"; reg = <0x0 0x086c0 0x0 0x10>; @@ -271,7 +287,7 @@ };
i2c_B: i2c@87c0 { - compatible = "amlogic,meson-gxbb-i2c"; + compatible = "amlogic,meson-gx-i2c", "amlogic,meson-gxbb-i2c"; reg = <0x0 0x087c0 0x0 0x20>; interrupts = <GIC_SPI 214 IRQ_TYPE_EDGE_RISING>; #address-cells = <1>; @@ -280,7 +296,7 @@ };
i2c_C: i2c@87e0 { - compatible = "amlogic,meson-gxbb-i2c"; + compatible = "amlogic,meson-gx-i2c", "amlogic,meson-gxbb-i2c"; reg = <0x0 0x087e0 0x0 0x20>; interrupts = <GIC_SPI 215 IRQ_TYPE_EDGE_RISING>; #address-cells = <1>; @@ -288,6 +304,14 @@ status = "disabled"; };
+ spifc: spi@8c80 { + compatible = "amlogic,meson-gx-spifc", "amlogic,meson-gxbb-spifc"; + reg = <0x0 0x08c80 0x0 0x80>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + watchdog@98d0 { compatible = "amlogic,meson-gx-wdt", "amlogic,meson-gxbb-wdt"; reg = <0x0 0x098d0 0x0 0x10>; @@ -309,7 +333,7 @@ };
sram: sram@c8000000 { - compatible = "amlogic,meson-gxbb-sram", "mmio-sram"; + compatible = "amlogic,meson-gx-sram", "amlogic,meson-gxbb-sram", "mmio-sram"; reg = <0x0 0xc8000000 0x0 0x14000>;
#address-cells = <1>; @@ -317,12 +341,12 @@ ranges = <0 0x0 0xc8000000 0x14000>;
cpu_scp_lpri: scp-shmem@0 { - compatible = "amlogic,meson-gxbb-scp-shmem"; + compatible = "amlogic,meson-gx-scp-shmem", "amlogic,meson-gxbb-scp-shmem"; reg = <0x13000 0x400>; };
cpu_scp_hpri: scp-shmem@200 { - compatible = "amlogic,meson-gxbb-scp-shmem"; + compatible = "amlogic,meson-gx-scp-shmem", "amlogic,meson-gxbb-scp-shmem"; reg = <0x13400 0x400>; }; }; @@ -334,6 +358,13 @@ #size-cells = <2>; ranges = <0x0 0x0 0x0 0xc8100000 0x0 0x100000>;
+ clkc_AO: clock-controller@040 { + compatible = "amlogic,gx-aoclkc", "amlogic,gxbb-aoclkc"; + reg = <0x0 0x00040 0x0 0x4>; + #clock-cells = <1>; + #reset-cells = <1>; + }; + uart_AO: serial@4c0 { compatible = "amlogic,meson-uart"; reg = <0x0 0x004c0 0x0 0x14>; @@ -350,8 +381,24 @@ status = "disabled"; };
+ i2c_AO: i2c@500 { + compatible = "amlogic,meson-gx-i2c", "amlogic,meson-gxbb-i2c"; + reg = <0x0 0x500 0x0 0x20>; + interrupts = <GIC_SPI 195 IRQ_TYPE_EDGE_RISING>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + pwm_AO_ab: pwm@550 { + compatible = "amlogic,meson-gx-pwm", "amlogic,meson-gxbb-pwm"; + reg = <0x0 0x00550 0x0 0x10>; + #pwm-cells = <3>; + status = "disabled"; + }; + ir: ir@580 { - compatible = "amlogic,meson-gxbb-ir"; + compatible = "amlogic,meson-gx-ir", "amlogic,meson-gxbb-ir"; reg = <0x0 0x00580 0x0 0x40>; interrupts = <GIC_SPI 196 IRQ_TYPE_EDGE_RISING>; status = "disabled"; @@ -365,13 +412,12 @@ #size-cells = <2>; ranges = <0x0 0x0 0x0 0xc8834000 0x0 0x2000>;
- rng { + hwrng: rng { compatible = "amlogic,meson-rng"; reg = <0x0 0x0 0x0 0x4>; }; };
- hiubus: hiubus@c883c000 { compatible = "simple-bus"; reg = <0x0 0xc883c000 0x0 0x2000>; @@ -395,7 +441,6 @@ 0x0 0xc8834540 0x0 0x4>; interrupts = <0 8 1>; interrupt-names = "macirq"; - phy-mode = "rgmii"; status = "disabled"; };
@@ -442,6 +487,38 @@ cvbs_vdac_port: port@0 { reg = <0>; }; + + /* HDMI-TX output port */ + hdmi_tx_port: port@1 { + reg = <1>; + + hdmi_tx_out: endpoint { + remote-endpoint = <&hdmi_tx_in>; + }; + }; + }; + + hdmi_tx: hdmi-tx@c883a000 { + compatible = "amlogic,meson-gx-dw-hdmi"; + reg = <0x0 0xc883a000 0x0 0x1c>; + interrupts = <GIC_SPI 57 IRQ_TYPE_EDGE_RISING>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + /* VPU VENC Input */ + hdmi_tx_venc_port: port@0 { + reg = <0>; + + hdmi_tx_in: endpoint { + remote-endpoint = <&hdmi_tx_out>; + }; + }; + + /* TMDS Output */ + hdmi_tx_tmds_port: port@1 { + reg = <1>; + }; }; }; }; diff --git a/arch/arm/dts/meson-gxbb-odroidc2.dts b/arch/arm/dts/meson-gxbb-odroidc2.dts index c737183..54a9c6a 100644 --- a/arch/arm/dts/meson-gxbb-odroidc2.dts +++ b/arch/arm/dts/meson-gxbb-odroidc2.dts @@ -50,7 +50,7 @@ / { compatible = "hardkernel,odroid-c2", "amlogic,meson-gxbb"; model = "Hardkernel ODROID-C2"; - + aliases { serial0 = &uart_AO; }; @@ -96,7 +96,7 @@ regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>;
- gpio = <&gpio_ao GPIOAO_12 GPIO_ACTIVE_HIGH>; + gpio = <&gpio GPIOY_12 GPIO_ACTIVE_HIGH>; enable-active-high; };
@@ -152,6 +152,13 @@ pinctrl-0 = <ð_rgmii_pins>; pinctrl-names = "default"; phy-handle = <ð_phy0>; + phy-mode = "rgmii"; + + snps,reset-gpio = <&gpio GPIOZ_14 0>; + snps,reset-delays-us = <0 10000 1000000>; + snps,reset-active-low; + + amlogic,tx-delay-ns = <2>;
mdio { compatible = "snps,dwmac-mdio"; @@ -165,6 +172,57 @@ }; };
+&pinctrl_aobus { + gpio-line-names = "UART TX", "UART RX", "VCCK En", "TF 3V3/1V8 En", + "USB HUB nRESET", "USB OTG Power En", + "J7 Header Pin2", "IR In", "J7 Header Pin4", + "J7 Header Pin6", "J7 Header Pin5", "J7 Header Pin7", + "HDMI CEC", "SYS LED"; +}; + +&pinctrl_periphs { + gpio-line-names = /* Bank GPIOZ */ + "Eth MDIO", "Eth MDC", "Eth RGMII RX Clk", + "Eth RX DV", "Eth RX D0", "Eth RX D1", "Eth RX D2", + "Eth RX D3", "Eth RGMII TX Clk", "Eth TX En", + "Eth TX D0", "Eth TX D1", "Eth TX D2", "Eth TX D3", + "Eth PHY nRESET", "Eth PHY Intc", + /* Bank GPIOH */ + "HDMI HPD", "HDMI DDC SDA", "HDMI DDC SCL", "", + /* Bank BOOT */ + "eMMC D0", "eMMC D1", "eMMC D2", "eMMC D3", "eMMC D4", + "eMMC D5", "eMMC D6", "eMMC D7", "eMMC Clk", + "eMMC Reset", "eMMC CMD", + "", "", "", "", "", "", "", + /* Bank CARD */ + "SDCard D1", "SDCard D0", "SDCard CLK", "SDCard CMD", + "SDCard D3", "SDCard D2", "SDCard Det", + /* Bank GPIODV */ + "", "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", + "I2C A SDA", "I2C A SCK", "I2C B SDA", "I2C B SCK", + "PWM D", "PWM B", + /* Bank GPIOY */ + "Revision Bit0", "Revision Bit1", "", + "J2 Header Pin35", "", "", "", "J2 Header Pin36", + "J2 Header Pin31", "", "", "", "TF VDD En", + "J2 Header Pin32", "J2 Header Pin26", "", "", + /* Bank GPIOX */ + "J2 Header Pin29", "J2 Header Pin24", + "J2 Header Pin23", "J2 Header Pin22", + "J2 Header Pin21", "J2 Header Pin18", + "J2 Header Pin33", "J2 Header Pin19", + "J2 Header Pin16", "J2 Header Pin15", + "J2 Header Pin12", "J2 Header Pin13", + "J2 Header Pin8", "J2 Header Pin10", + "", "", "", "", "", + "J2 Header Pin11", "", "J2 Header Pin7", + /* Bank GPIOCLK */ + "", "", "", "", + /* GPIO_TEST_N */ + ""; +}; + &ir { status = "okay"; pinctrl-0 = <&remote_input_ao_pins>; @@ -177,6 +235,21 @@ pinctrl-names = "default"; };
+&gpio_ao { + /* + * WARNING: The USB Hub on the Odroid-C2 needs a reset signal + * to be turned high in order to be detected by the USB Controller + * This signal should be handled by a USB specific power sequence + * in order to reset the Hub when USB bus is powered down. + */ + usb-hub { + gpio-hog; + gpios = <GPIOAO_4 GPIO_ACTIVE_HIGH>; + output-high; + line-name = "usb-hub-reset"; + }; +}; + &usb0_phy { status = "okay"; phy-supply = <&usb_otg_pwr>; @@ -194,6 +267,11 @@ status = "okay"; };
+&saradc { + status = "okay"; + vref-supply = <&vcc1v8>; +}; + /* SD */ &sd_emmc_b { status = "okay"; diff --git a/arch/arm/dts/meson-gxbb.dtsi b/arch/arm/dts/meson-gxbb.dtsi index 39a774a..86105a6 100644 --- a/arch/arm/dts/meson-gxbb.dtsi +++ b/arch/arm/dts/meson-gxbb.dtsi @@ -97,17 +97,6 @@ }; };
-&cbus { - spifc: spi@8c80 { - compatible = "amlogic,meson-gxbb-spifc"; - reg = <0x0 0x08c80 0x0 0x80>; - #address-cells = <1>; - #size-cells = <0>; - clocks = <&clkc CLKID_SPI>; - status = "disabled"; - }; -}; - ðmac { clocks = <&clkc CLKID_ETH>, <&clkc CLKID_FCLK_DIV2>, @@ -129,6 +118,7 @@ reg-names = "mux", "pull", "gpio"; gpio-controller; #gpio-cells = <2>; + gpio-ranges = <&pinctrl_aobus 0 0 14>; };
uart_ao_a_pins: uart_ao_a { @@ -203,30 +193,62 @@ function = "pwm_ao_b"; }; }; - };
- clkc_AO: clock-controller@040 { - compatible = "amlogic,gxbb-aoclkc"; - reg = <0x0 0x00040 0x0 0x4>; - #clock-cells = <1>; - #reset-cells = <1>; - }; + i2s_am_clk_pins: i2s_am_clk { + mux { + groups = "i2s_am_clk"; + function = "i2s_out_ao"; + }; + };
- pwm_ab_AO: pwm@550 { - compatible = "amlogic,meson-gxbb-pwm"; - reg = <0x0 0x0550 0x0 0x10>; - #pwm-cells = <3>; - status = "disabled"; - }; + i2s_out_ao_clk_pins: i2s_out_ao_clk { + mux { + groups = "i2s_out_ao_clk"; + function = "i2s_out_ao"; + }; + }; + + i2s_out_lr_clk_pins: i2s_out_lr_clk { + mux { + groups = "i2s_out_lr_clk"; + function = "i2s_out_ao"; + }; + }; + + i2s_out_ch01_ao_pins: i2s_out_ch01_ao { + mux { + groups = "i2s_out_ch01_ao"; + function = "i2s_out_ao"; + }; + }; + + i2s_out_ch23_ao_pins: i2s_out_ch23_ao { + mux { + groups = "i2s_out_ch23_ao"; + function = "i2s_out_ao"; + }; + }; + + i2s_out_ch45_ao_pins: i2s_out_ch45_ao { + mux { + groups = "i2s_out_ch45_ao"; + function = "i2s_out_ao"; + }; + }; + + spdif_out_ao_6_pins: spdif_out_ao_6 { + mux { + groups = "spdif_out_ao_6"; + function = "spdif_out_ao"; + }; + };
- i2c_AO: i2c@500 { - compatible = "amlogic,meson-gxbb-i2c"; - reg = <0x0 0x500 0x0 0x20>; - interrupts = <GIC_SPI 195 IRQ_TYPE_EDGE_RISING>; - clocks = <&clkc CLKID_AO_I2C>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; + spdif_out_ao_13_pins: spdif_out_ao_13 { + mux { + groups = "spdif_out_ao_13"; + function = "spdif_out_ao"; + }; + }; }; };
@@ -245,6 +267,7 @@ reg-names = "mux", "pull", "pull-enable", "gpio"; gpio-controller; #gpio-cells = <2>; + gpio-ranges = <&pinctrl_periphs 0 14 120>; };
emmc_pins: emmc { @@ -467,6 +490,34 @@ function = "hdmi_i2c"; }; }; + + i2sout_ch23_y_pins: i2sout_ch23_y { + mux { + groups = "i2sout_ch23_y"; + function = "i2s_out"; + }; + }; + + i2sout_ch45_y_pins: i2sout_ch45_y { + mux { + groups = "i2sout_ch45_y"; + function = "i2s_out"; + }; + }; + + i2sout_ch67_y_pins: i2sout_ch67_y { + mux { + groups = "i2sout_ch67_y"; + function = "i2s_out"; + }; + }; + + spdif_out_y_pins: spdif_out_y { + mux { + groups = "spdif_out_y"; + function = "spdif_out"; + }; + }; }; };
@@ -478,10 +529,51 @@ }; };
+&apb { + mali: gpu@c0000 { + compatible = "amlogic,meson-gxbb-mali", "arm,mali-450"; + reg = <0x0 0xc0000 0x0 0x40000>; + interrupts = <GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "gp", "gpmmu", "pp", "pmu", + "pp0", "ppmmu0", "pp1", "ppmmu1", + "pp2", "ppmmu2"; + clocks = <&clkc CLKID_CLK81>, <&clkc CLKID_MALI>; + clock-names = "bus", "core"; + + /* + * Mali clocking is provided by two identical clock paths + * MALI_0 and MALI_1 muxed to a single clock by a glitch + * free mux to safely change frequency while running. + */ + assigned-clocks = <&clkc CLKID_MALI_0_SEL>, + <&clkc CLKID_MALI_0>, + <&clkc CLKID_MALI>; /* Glitch free mux */ + assigned-clock-parents = <&clkc CLKID_FCLK_DIV3>, + <0>, /* Do Nothing */ + <&clkc CLKID_MALI_0>; + assigned-clock-rates = <0>, /* Do Nothing */ + <666666666>, + <0>; /* Do Nothing */ + }; +}; + &i2c_A { clocks = <&clkc CLKID_I2C>; };
+&i2c_AO { + clocks = <&clkc CLKID_AO_I2C>; +}; + &i2c_B { clocks = <&clkc CLKID_I2C>; }; @@ -490,6 +582,16 @@ clocks = <&clkc CLKID_I2C>; };
+&saradc { + compatible = "amlogic,meson-gxbb-saradc", "amlogic,meson-saradc"; + clocks = <&xtal>, + <&clkc CLKID_SAR_ADC>, + <&clkc CLKID_SANA>, + <&clkc CLKID_SAR_ADC_CLK>, + <&clkc CLKID_SAR_ADC_SEL>; + clock-names = "clkin", "core", "sana", "adc_clk", "adc_sel"; +}; + &sd_emmc_a { clocks = <&clkc CLKID_SD_EMMC_A>, <&xtal>, @@ -511,6 +613,27 @@ clock-names = "core", "clkin0", "clkin1"; };
+&spifc { + clocks = <&clkc CLKID_SPI>; +}; + &vpu { compatible = "amlogic,meson-gxbb-vpu", "amlogic,meson-gx-vpu"; }; + +&hwrng { + clocks = <&clkc CLKID_RNG0>; + clock-names = "core"; +}; + +&hdmi_tx { + compatible = "amlogic,meson-gxbb-dw-hdmi", "amlogic,meson-gx-dw-hdmi"; + resets = <&reset RESET_HDMITX_CAPB3>, + <&reset RESET_HDMI_SYSTEM_RESET>, + <&reset RESET_HDMI_TX>; + reset-names = "hdmitx_apb", "hdmitx", "hdmitx_phy"; + clocks = <&clkc CLKID_HDMI_PCLK>, + <&clkc CLKID_CLK81>, + <&clkc CLKID_GCLK_VENCI_INT0>; + clock-names = "isfr", "iahb", "venci"; +}; diff --git a/include/dt-bindings/clock/gxbb-clkc.h b/include/dt-bindings/clock/gxbb-clkc.h index 692846c..e3e9f79 100644 --- a/include/dt-bindings/clock/gxbb-clkc.h +++ b/include/dt-bindings/clock/gxbb-clkc.h @@ -5,30 +5,50 @@ #ifndef __GXBB_CLKC_H #define __GXBB_CLKC_H
-#define CLKID_CPUCLK 1 #define CLKID_HDMI_PLL 2 #define CLKID_FCLK_DIV2 4 #define CLKID_FCLK_DIV3 5 #define CLKID_FCLK_DIV4 6 +#define CLKID_GP0_PLL 9 #define CLKID_CLK81 12 #define CLKID_MPLL2 15 -#define CLKID_SPI 34 +#define CLKID_SPICC 21 #define CLKID_I2C 22 #define CLKID_SAR_ADC 23 +#define CLKID_RNG0 25 +#define CLKID_UART0 26 +#define CLKID_SPI 34 #define CLKID_ETH 36 +#define CLKID_AIU_GLUE 38 +#define CLKID_IEC958 39 +#define CLKID_I2S_OUT 40 +#define CLKID_MIXER_IFACE 44 +#define CLKID_AIU 47 +#define CLKID_UART1 48 #define CLKID_USB0 50 #define CLKID_USB1 51 #define CLKID_USB 55 #define CLKID_HDMI_PCLK 63 #define CLKID_USB1_DDR_BRIDGE 64 #define CLKID_USB0_DDR_BRIDGE 65 +#define CLKID_UART2 68 #define CLKID_SANA 69 #define CLKID_GCLK_VENCI_INT0 77 +#define CLKID_AOCLK_GATE 80 +#define CLKID_IEC958_GATE 81 #define CLKID_AO_I2C 93 #define CLKID_SD_EMMC_A 94 #define CLKID_SD_EMMC_B 95 #define CLKID_SD_EMMC_C 96 #define CLKID_SAR_ADC_CLK 97 #define CLKID_SAR_ADC_SEL 98 +#define CLKID_MALI_0_SEL 100 +#define CLKID_MALI_0 102 +#define CLKID_MALI_1_SEL 103 +#define CLKID_MALI_1 105 +#define CLKID_MALI 106 +#define CLKID_CTS_AMCLK 107 +#define CLKID_CTS_MCLK_I958 110 +#define CLKID_CTS_I958 113
#endif /* __GXBB_CLKC_H */

On 9 July 2017 at 16:30, Beniamino Galvani b.galvani@gmail.com wrote:
Import Amlogic Meson DTS files from Linux kernel version 4.12
Signed-off-by: Beniamino Galvani b.galvani@gmail.com
arch/arm/dts/meson-gx.dtsi | 97 ++++++++++++++++-- arch/arm/dts/meson-gxbb-odroidc2.dts | 82 ++++++++++++++- arch/arm/dts/meson-gxbb.dtsi | 187 ++++++++++++++++++++++++++++------ include/dt-bindings/clock/gxbb-clkc.h | 24 ++++- 4 files changed, 344 insertions(+), 46 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org

On Mon, Jul 10, 2017 at 12:30:03AM +0200, Beniamino Galvani wrote:
Import Amlogic Meson DTS files from Linux kernel version 4.12
Signed-off-by: Beniamino Galvani b.galvani@gmail.com Reviewed-by: Simon Glass sjg@chromium.org
Applied to u-boot/master, thanks!

This commit adds GPIO support to the Amlogic Meson pin controller driver, based on code from Linux kernel.
Reviewed-by: Simon Glass sjg@chromium.org Signed-off-by: Beniamino Galvani b.galvani@gmail.com --- arch/arm/include/asm/arch-meson/gpio.h | 11 ++ drivers/pinctrl/meson/pinctrl-meson-gxbb.c | 21 ++++ drivers/pinctrl/meson/pinctrl-meson.c | 167 ++++++++++++++++++++++++++++- drivers/pinctrl/meson/pinctrl-meson.h | 63 +++++++++++ 4 files changed, 260 insertions(+), 2 deletions(-) create mode 100644 arch/arm/include/asm/arch-meson/gpio.h
diff --git a/arch/arm/include/asm/arch-meson/gpio.h b/arch/arm/include/asm/arch-meson/gpio.h new file mode 100644 index 0000000..7079ab3 --- /dev/null +++ b/arch/arm/include/asm/arch-meson/gpio.h @@ -0,0 +1,11 @@ +/* + * (C) Copyright 2017 - Beniamino Galvani b.galvani@gmail.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_ARCH_MESON_GPIO_H +#define __ASM_ARCH_MESON_GPIO_H + + +#endif /* __ASM_ARCH_MESON_GPIO_H */ diff --git a/drivers/pinctrl/meson/pinctrl-meson-gxbb.c b/drivers/pinctrl/meson/pinctrl-meson-gxbb.c index 2fa840c..87c9912 100644 --- a/drivers/pinctrl/meson/pinctrl-meson-gxbb.c +++ b/drivers/pinctrl/meson/pinctrl-meson-gxbb.c @@ -391,14 +391,33 @@ static struct meson_pmx_func meson_gxbb_aobus_functions[] = { FUNCTION(i2c_slave_ao), };
+static struct meson_bank meson_gxbb_periphs_banks[] = { + /* name first last pullen pull dir out in */ + BANK("X", PIN(GPIOX_0, EE_OFF), PIN(GPIOX_22, EE_OFF), 4, 0, 4, 0, 12, 0, 13, 0, 14, 0), + BANK("Y", PIN(GPIOY_0, EE_OFF), PIN(GPIOY_16, EE_OFF), 1, 0, 1, 0, 3, 0, 4, 0, 5, 0), + BANK("DV", PIN(GPIODV_0, EE_OFF), PIN(GPIODV_29, EE_OFF), 0, 0, 0, 0, 0, 0, 1, 0, 2, 0), + BANK("H", PIN(GPIOH_0, EE_OFF), PIN(GPIOH_3, EE_OFF), 1, 20, 1, 20, 3, 20, 4, 20, 5, 20), + BANK("Z", PIN(GPIOZ_0, EE_OFF), PIN(GPIOZ_15, EE_OFF), 3, 0, 3, 0, 9, 0, 10, 0, 11, 0), + BANK("CARD", PIN(CARD_0, EE_OFF), PIN(CARD_6, EE_OFF), 2, 20, 2, 20, 6, 20, 7, 20, 8, 20), + BANK("BOOT", PIN(BOOT_0, EE_OFF), PIN(BOOT_17, EE_OFF), 2, 0, 2, 0, 6, 0, 7, 0, 8, 0), + BANK("CLK", PIN(GPIOCLK_0, EE_OFF), PIN(GPIOCLK_3, EE_OFF), 3, 28, 3, 28, 9, 28, 10, 28, 11, 28), +}; + +static struct meson_bank meson_gxbb_aobus_banks[] = { + /* name first last pullen pull dir out in */ + BANK("AO", PIN(GPIOAO_0, 0), PIN(GPIOAO_13, 0), 0, 0, 0, 16, 0, 0, 0, 16, 1, 0), +}; + struct meson_pinctrl_data meson_gxbb_periphs_pinctrl_data = { .name = "periphs-banks", .pin_base = 14, .groups = meson_gxbb_periphs_groups, .funcs = meson_gxbb_periphs_functions, + .banks = meson_gxbb_periphs_banks, .num_pins = 120, .num_groups = ARRAY_SIZE(meson_gxbb_periphs_groups), .num_funcs = ARRAY_SIZE(meson_gxbb_periphs_functions), + .num_banks = ARRAY_SIZE(meson_gxbb_periphs_banks), };
struct meson_pinctrl_data meson_gxbb_aobus_pinctrl_data = { @@ -406,9 +425,11 @@ struct meson_pinctrl_data meson_gxbb_aobus_pinctrl_data = { .pin_base = 0, .groups = meson_gxbb_aobus_groups, .funcs = meson_gxbb_aobus_functions, + .banks = meson_gxbb_aobus_banks, .num_pins = 14, .num_groups = ARRAY_SIZE(meson_gxbb_aobus_groups), .num_funcs = ARRAY_SIZE(meson_gxbb_aobus_functions), + .num_banks = ARRAY_SIZE(meson_gxbb_aobus_banks), };
static const struct udevice_id meson_gxbb_pinctrl_match[] = { diff --git a/drivers/pinctrl/meson/pinctrl-meson.c b/drivers/pinctrl/meson/pinctrl-meson.c index 6281f52..a860200 100644 --- a/drivers/pinctrl/meson/pinctrl-meson.c +++ b/drivers/pinctrl/meson/pinctrl-meson.c @@ -6,11 +6,14 @@
#include <common.h> #include <dm.h> +#include <dm/device-internal.h> +#include <dm/lists.h> #include <dm/pinctrl.h> #include <fdt_support.h> #include <linux/err.h> #include <linux/io.h> #include <linux/sizes.h> +#include <asm/gpio.h>
#include "pinctrl-meson.h"
@@ -117,6 +120,143 @@ const struct pinctrl_ops meson_pinctrl_ops = { .set_state = pinctrl_generic_set_state, };
+static int meson_gpio_calc_reg_and_bit(struct udevice *dev, unsigned int offset, + enum meson_reg_type reg_type, + unsigned int *reg, unsigned int *bit) +{ + struct meson_pinctrl *priv = dev_get_priv(dev->parent); + struct meson_bank *bank = NULL; + struct meson_reg_desc *desc; + unsigned int pin; + int i; + + pin = priv->data->pin_base + offset; + + for (i = 0; i < priv->data->num_banks; i++) { + if (pin >= priv->data->banks[i].first && + pin <= priv->data->banks[i].last) { + bank = &priv->data->banks[i]; + break; + } + } + + if (!bank) + return -EINVAL; + + desc = &bank->regs[reg_type]; + *reg = desc->reg * 4; + *bit = desc->bit + pin - bank->first; + + return 0; +} + +static int meson_gpio_get(struct udevice *dev, unsigned int offset) +{ + struct meson_pinctrl *priv = dev_get_priv(dev->parent); + unsigned int reg, bit; + int ret; + + ret = meson_gpio_calc_reg_and_bit(dev, offset, REG_IN, ®, &bit); + if (ret) + return ret; + + return !!(readl(priv->reg_gpio + reg) & BIT(bit)); +} + +static int meson_gpio_set(struct udevice *dev, unsigned int offset, int value) +{ + struct meson_pinctrl *priv = dev_get_priv(dev->parent); + unsigned int reg, bit; + int ret; + + ret = meson_gpio_calc_reg_and_bit(dev, offset, REG_OUT, ®, &bit); + if (ret) + return ret; + + clrsetbits_le32(priv->reg_gpio + reg, BIT(bit), value ? BIT(bit) : 0); + + return 0; +} + +static int meson_gpio_get_direction(struct udevice *dev, unsigned int offset) +{ + struct meson_pinctrl *priv = dev_get_priv(dev->parent); + unsigned int reg, bit, val; + int ret; + + ret = meson_gpio_calc_reg_and_bit(dev, offset, REG_DIR, ®, &bit); + if (ret) + return ret; + + val = readl(priv->reg_gpio + reg); + + return (val & BIT(bit)) ? GPIOF_INPUT : GPIOF_OUTPUT; +} + +static int meson_gpio_direction_input(struct udevice *dev, unsigned int offset) +{ + struct meson_pinctrl *priv = dev_get_priv(dev->parent); + unsigned int reg, bit; + int ret; + + ret = meson_gpio_calc_reg_and_bit(dev, offset, REG_DIR, ®, &bit); + if (ret) + return ret; + + clrsetbits_le32(priv->reg_gpio + reg, BIT(bit), 1); + + return 0; +} + +static int meson_gpio_direction_output(struct udevice *dev, + unsigned int offset, int value) +{ + struct meson_pinctrl *priv = dev_get_priv(dev->parent); + unsigned int reg, bit; + int ret; + + ret = meson_gpio_calc_reg_and_bit(dev, offset, REG_DIR, ®, &bit); + if (ret) + return ret; + + clrsetbits_le32(priv->reg_gpio + reg, BIT(bit), 0); + + ret = meson_gpio_calc_reg_and_bit(dev, offset, REG_OUT, ®, &bit); + if (ret) + return ret; + + clrsetbits_le32(priv->reg_gpio + reg, BIT(bit), value ? BIT(bit) : 0); + + return 0; +} + +static int meson_gpio_probe(struct udevice *dev) +{ + struct meson_pinctrl *priv = dev_get_priv(dev->parent); + struct gpio_dev_priv *uc_priv; + + uc_priv = dev_get_uclass_priv(dev); + uc_priv->bank_name = priv->data->name; + uc_priv->gpio_count = priv->data->num_pins; + + return 0; +} + +static const struct dm_gpio_ops meson_gpio_ops = { + .set_value = meson_gpio_set, + .get_value = meson_gpio_get, + .get_function = meson_gpio_get_direction, + .direction_input = meson_gpio_direction_input, + .direction_output = meson_gpio_direction_output, +}; + +static struct driver meson_gpio_driver = { + .name = "meson-gpio", + .id = UCLASS_GPIO, + .probe = meson_gpio_probe, + .ops = &meson_gpio_ops, +}; + static fdt_addr_t parse_address(int offset, const char *name, int na, int ns) { int index, len = 0; @@ -138,9 +278,12 @@ static fdt_addr_t parse_address(int offset, const char *name, int na, int ns) int meson_pinctrl_probe(struct udevice *dev) { struct meson_pinctrl *priv = dev_get_priv(dev); + struct uclass_driver *drv; + struct udevice *gpio_dev; fdt_addr_t addr; int node, gpio = -1, len; int na, ns; + char *name;
na = fdt_address_cells(gd->fdt_blob, dev_of_offset(dev->parent)); if (na < 1) { @@ -168,12 +311,32 @@ int meson_pinctrl_probe(struct udevice *dev)
addr = parse_address(gpio, "mux", na, ns); if (addr == FDT_ADDR_T_NONE) { - debug("mux not found\n"); + debug("mux address not found\n"); return -EINVAL; } - priv->reg_mux = (void __iomem *)addr; + + addr = parse_address(gpio, "gpio", na, ns); + if (addr == FDT_ADDR_T_NONE) { + debug("gpio address not found\n"); + return -EINVAL; + } + priv->reg_gpio = (void __iomem *)addr; priv->data = (struct meson_pinctrl_data *)dev_get_driver_data(dev);
+ /* Lookup GPIO driver */ + drv = lists_uclass_lookup(UCLASS_GPIO); + if (!drv) { + puts("Cannot find GPIO driver\n"); + return -ENOENT; + } + + name = calloc(1, 32); + sprintf(name, "meson-gpio"); + + /* Create child device UCLASS_GPIO and bind it */ + device_bind(dev, &meson_gpio_driver, name, NULL, gpio, &gpio_dev); + dev_set_of_offset(gpio_dev, gpio); + return 0; } diff --git a/drivers/pinctrl/meson/pinctrl-meson.h b/drivers/pinctrl/meson/pinctrl-meson.h index 4127a60..90d2369 100644 --- a/drivers/pinctrl/meson/pinctrl-meson.h +++ b/drivers/pinctrl/meson/pinctrl-meson.h @@ -28,15 +28,64 @@ struct meson_pinctrl_data { const char *name; struct meson_pmx_group *groups; struct meson_pmx_func *funcs; + struct meson_bank *banks; unsigned int pin_base; unsigned int num_pins; unsigned int num_groups; unsigned int num_funcs; + unsigned int num_banks; };
struct meson_pinctrl { struct meson_pinctrl_data *data; void __iomem *reg_mux; + void __iomem *reg_gpio; +}; + +/** + * struct meson_reg_desc - a register descriptor + * + * @reg: register offset in the regmap + * @bit: bit index in register + * + * The structure describes the information needed to control pull, + * pull-enable, direction, etc. for a single pin + */ +struct meson_reg_desc { + unsigned int reg; + unsigned int bit; +}; + +/** + * enum meson_reg_type - type of registers encoded in @meson_reg_desc + */ +enum meson_reg_type { + REG_PULLEN, + REG_PULL, + REG_DIR, + REG_OUT, + REG_IN, + NUM_REG, +}; + +/** + * struct meson bank + * + * @name: bank name + * @first: first pin of the bank + * @last: last pin of the bank + * @regs: array of register descriptors + * + * A bank represents a set of pins controlled by a contiguous set of + * bits in the domain registers. The structure specifies which bits in + * the regmap control the different functionalities. Each member of + * the @regs array refers to the first pin of the bank. + */ +struct meson_bank { + const char *name; + unsigned int first; + unsigned int last; + struct meson_reg_desc regs[NUM_REG]; };
#define PIN(x, b) (b + x) @@ -65,6 +114,20 @@ struct meson_pinctrl { .num_groups = ARRAY_SIZE(fn ## _groups), \ }
+#define BANK(n, f, l, per, peb, pr, pb, dr, db, or, ob, ir, ib) \ + { \ + .name = n, \ + .first = f, \ + .last = l, \ + .regs = { \ + [REG_PULLEN] = { per, peb }, \ + [REG_PULL] = { pr, pb }, \ + [REG_DIR] = { dr, db }, \ + [REG_OUT] = { or, ob }, \ + [REG_IN] = { ir, ib }, \ + }, \ + } + #define MESON_PIN(x, b) PINCTRL_PIN(PIN(x, b), #x)
extern const struct pinctrl_ops meson_pinctrl_ops;

On Mon, Jul 10, 2017 at 12:30:04AM +0200, Beniamino Galvani wrote:
This commit adds GPIO support to the Amlogic Meson pin controller driver, based on code from Linux kernel.
Reviewed-by: Simon Glass sjg@chromium.org Signed-off-by: Beniamino Galvani b.galvani@gmail.com
Applied to u-boot/master, thanks!

GPIOs are now supported on Meson GXBB, enable driver and command in the config.
Signed-off-by: Beniamino Galvani b.galvani@gmail.com --- configs/odroid-c2_defconfig | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/configs/odroid-c2_defconfig b/configs/odroid-c2_defconfig index 3531414..3ad2219 100644 --- a/configs/odroid-c2_defconfig +++ b/configs/odroid-c2_defconfig @@ -13,9 +13,11 @@ CONFIG_DEBUG_UART=y # CONFIG_CMD_LOADS is not set CONFIG_CMD_MMC=y # CONFIG_CMD_FPGA is not set +CONFIG_CMD_GPIO=y # CONFIG_CMD_SETEXPR is not set CONFIG_OF_CONTROL=y CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_DM_GPIO=y CONFIG_DM_MMC=y CONFIG_MMC_MESON_GX=y CONFIG_DM_ETH=y

On 9 July 2017 at 16:30, Beniamino Galvani b.galvani@gmail.com wrote:
GPIOs are now supported on Meson GXBB, enable driver and command in the config.
Signed-off-by: Beniamino Galvani b.galvani@gmail.com
configs/odroid-c2_defconfig | 2 ++ 1 file changed, 2 insertions(+)
Reviewed-by: Simon Glass sjg@chromium.org

On Mon, Jul 10, 2017 at 12:30:05AM +0200, Beniamino Galvani wrote:
GPIOs are now supported on Meson GXBB, enable driver and command in the config.
Signed-off-by: Beniamino Galvani b.galvani@gmail.com Reviewed-by: Simon Glass sjg@chromium.org
Applied to u-boot/master, thanks!

Update the Meson pinctrl/gpio driver to support a live device tree.
Signed-off-by: Beniamino Galvani b.galvani@gmail.com --- drivers/pinctrl/meson/pinctrl-meson.c | 66 +++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 30 deletions(-)
diff --git a/drivers/pinctrl/meson/pinctrl-meson.c b/drivers/pinctrl/meson/pinctrl-meson.c index a860200..c8cae51 100644 --- a/drivers/pinctrl/meson/pinctrl-meson.c +++ b/drivers/pinctrl/meson/pinctrl-meson.c @@ -8,6 +8,8 @@ #include <dm.h> #include <dm/device-internal.h> #include <dm/lists.h> +#include <dm/of_addr.h> +#include <linux/ioport.h> #include <dm/pinctrl.h> #include <fdt_support.h> #include <linux/err.h> @@ -257,66 +259,70 @@ static struct driver meson_gpio_driver = { .ops = &meson_gpio_ops, };
-static fdt_addr_t parse_address(int offset, const char *name, int na, int ns) +static phys_addr_t parse_address(struct udevice *dev, ofnode node, + const char *name) { - int index, len = 0; - const fdt32_t *reg; + struct resource r; + fdt_size_t sz; + int na, ns, index;
- index = fdt_stringlist_search(gd->fdt_blob, offset, "reg-names", name); + index = ofnode_stringlist_search(node, "reg-names", name); if (index < 0) return FDT_ADDR_T_NONE;
- reg = fdt_getprop(gd->fdt_blob, offset, "reg", &len); - if (!reg || (len <= (index * sizeof(fdt32_t) * (na + ns)))) + if (of_live_active()) { + if (of_address_to_resource(ofnode_to_np(node), index, &r)) + return FDT_ADDR_T_NONE; + else + return r.start; + } + + na = dev_read_addr_cells(dev->parent); + if (na < 1) { + debug("bad #address-cells\n"); return FDT_ADDR_T_NONE; + }
- reg += index * (na + ns); + ns = dev_read_size_cells(dev->parent); + if (ns < 1) { + debug("bad #size-cells\n"); + return FDT_ADDR_T_NONE; + }
- return fdt_translate_address((void *)gd->fdt_blob, offset, reg); + return fdtdec_get_addr_size_fixed(gd->fdt_blob, ofnode_to_offset(node), + "reg", index, na, ns, &sz, true); }
int meson_pinctrl_probe(struct udevice *dev) { struct meson_pinctrl *priv = dev_get_priv(dev); + ofnode node, gpio = ofnode_null(); struct uclass_driver *drv; struct udevice *gpio_dev; - fdt_addr_t addr; - int node, gpio = -1, len; - int na, ns; + phys_addr_t addr; char *name; + int len;
- na = fdt_address_cells(gd->fdt_blob, dev_of_offset(dev->parent)); - if (na < 1) { - debug("bad #address-cells\n"); - return -EINVAL; - } - - ns = fdt_size_cells(gd->fdt_blob, dev_of_offset(dev->parent)); - if (ns < 1) { - debug("bad #size-cells\n"); - return -EINVAL; - } - - fdt_for_each_subnode(node, gd->fdt_blob, dev_of_offset(dev)) { - if (fdt_getprop(gd->fdt_blob, node, "gpio-controller", &len)) { + dev_for_each_subnode(node, dev) { + if (ofnode_read_prop(node, "gpio-controller", &len)) { gpio = node; break; } }
- if (!gpio) { + if (!ofnode_valid(gpio)) { debug("gpio node not found\n"); return -EINVAL; }
- addr = parse_address(gpio, "mux", na, ns); + addr = parse_address(dev, gpio, "mux"); if (addr == FDT_ADDR_T_NONE) { debug("mux address not found\n"); return -EINVAL; } priv->reg_mux = (void __iomem *)addr;
- addr = parse_address(gpio, "gpio", na, ns); + addr = parse_address(dev, gpio, "gpio"); if (addr == FDT_ADDR_T_NONE) { debug("gpio address not found\n"); return -EINVAL; @@ -335,8 +341,8 @@ int meson_pinctrl_probe(struct udevice *dev) sprintf(name, "meson-gpio");
/* Create child device UCLASS_GPIO and bind it */ - device_bind(dev, &meson_gpio_driver, name, NULL, gpio, &gpio_dev); - dev_set_of_offset(gpio_dev, gpio); + device_bind_with_driver_data(dev, &meson_gpio_driver, name, 0, + gpio, &gpio_dev);
return 0; }

On Mon, Jul 10, 2017 at 12:30:06AM +0200, Beniamino Galvani wrote:
Update the Meson pinctrl/gpio driver to support a live device tree.
Signed-off-by: Beniamino Galvani b.galvani@gmail.com
This does not apply on top of master currently. Should I wait until some other changes land to apply the whole series? Or just 1-3 for now? Thanks!

On Mon, Jul 24, 2017 at 08:45:10PM -0400, Tom Rini wrote:
On Mon, Jul 10, 2017 at 12:30:06AM +0200, Beniamino Galvani wrote:
Update the Meson pinctrl/gpio driver to support a live device tree.
Signed-off-by: Beniamino Galvani b.galvani@gmail.com
This does not apply on top of master currently. Should I wait until some other changes land to apply the whole series? Or just 1-3 for now?
Please apply patches 1, 2, 3 for now. I'll update and resend patch 4 separately.
Thanks, Beniamino
participants (3)
-
Beniamino Galvani
-
Simon Glass
-
Tom Rini