]> git.sur5r.net Git - u-boot/commitdiff
Merge git://git.denx.de/u-boot-mmc
authorTom Rini <trini@konsulko.com>
Tue, 8 May 2018 17:47:39 +0000 (13:47 -0400)
committerTom Rini <trini@konsulko.com>
Tue, 8 May 2018 17:47:39 +0000 (13:47 -0400)
92 files changed:
arch/arm/dts/armada-38x-controlcenterdc.dts
arch/arm/dts/meson-gx.dtsi
arch/arm/dts/meson-gxbb-odroidc2.dts
arch/arm/dts/meson-gxbb.dtsi
arch/arm/dts/meson-gxl-s905x-khadas-vim.dts
arch/arm/dts/meson-gxl-s905x-libretech-cc.dts
arch/arm/dts/meson-gxl-s905x-p212.dts
arch/arm/dts/meson-gxl-s905x-p212.dtsi
arch/arm/dts/meson-gxl.dtsi
arch/arm/dts/stm32mp157.dtsi
arch/arm/dts/stm32mp157c-ed1.dts
arch/arm/include/asm/arch-meson/gx.h [new file with mode: 0644]
arch/arm/include/asm/arch-meson/gxbb.h [deleted file]
arch/arm/mach-at91/include/mach/atmel_pio4.h
arch/arm/mach-meson/board.c
arch/arm/mach-meson/eth.c
arch/arm/mach-meson/sm.c
arch/arm/mach-omap2/utils.c
arch/arm/mach-stm32mp/Makefile
arch/arm/mach-stm32mp/include/mach/stm32.h
arch/arm/mach-stm32mp/pwr_regulator.c [new file with mode: 0644]
arch/arm/mach-stm32mp/syscon.c
arch/sandbox/dts/test.dts
board/amlogic/khadas-vim/khadas-vim.c
board/amlogic/libretech-cc/libretech-cc.c
board/amlogic/odroid-c2/odroid-c2.c
board/amlogic/p212/p212.c
board/atmel/sama5d27_som1_ek/sama5d27_som1_ek.c
board/atmel/sama5d2_ptc_ek/sama5d2_ptc_ek.c
board/atmel/sama5d2_xplained/sama5d2_xplained.c
cmd/Kconfig
cmd/Makefile
cmd/mmc.c
cmd/smccc.c [new file with mode: 0644]
common/fb_mmc.c
common/fb_nand.c
common/image-sparse.c
configs/sama5d2_ptc_ek_mmc_defconfig
configs/sama5d2_ptc_ek_nandflash_defconfig
configs/sama5d36ek_cmp_nandflash_defconfig
configs/sama5d36ek_cmp_spiflash_defconfig
configs/sama5d3_xplained_nandflash_defconfig
configs/sama5d3xek_nandflash_defconfig
configs/sama5d3xek_spiflash_defconfig
configs/sama5d4_xplained_nandflash_defconfig
configs/sama5d4_xplained_spiflash_defconfig
configs/sama5d4ek_nandflash_defconfig
configs/sama5d4ek_spiflash_defconfig
configs/stm32mp15_basic_defconfig
configs/uniphier_v8_defconfig
doc/device-tree-bindings/regulator/st,stm32-vrefbuf.txt [new file with mode: 0644]
drivers/adc/Kconfig
drivers/adc/Makefile
drivers/adc/meson-saradc.c [new file with mode: 0644]
drivers/clk/clk_stm32f.c
drivers/clk/clk_stm32mp1.c
drivers/core/regmap.c
drivers/gpio/atmel_pio4.c
drivers/led/led_gpio.c
drivers/misc/stm32_rcc.c
drivers/pci/Kconfig
drivers/pci/Makefile
drivers/pci/pcie_intel_fpga.c [new file with mode: 0644]
drivers/pinctrl/meson/pinctrl-meson-gxbb.c
drivers/pinctrl/meson/pinctrl-meson-gxl.c
drivers/pinctrl/uniphier/pinctrl-uniphier-core.c
drivers/pinctrl/uniphier/pinctrl-uniphier-ld20.c
drivers/pinctrl/uniphier/pinctrl-uniphier-ld6b.c
drivers/pinctrl/uniphier/pinctrl-uniphier.h
drivers/power/pmic/stpmu1.c
drivers/power/regulator/Kconfig
drivers/power/regulator/Makefile
drivers/power/regulator/stm32-vrefbuf.c [new file with mode: 0644]
drivers/power/regulator/stpmu1.c [new file with mode: 0644]
include/configs/khadas-vim.h
include/configs/libretech-cc.h
include/configs/meson-gx-common.h [new file with mode: 0644]
include/configs/meson-gxbb-common.h [deleted file]
include/configs/odroid-c2.h
include/configs/p212.h
include/dt-bindings/clock/gxbb-aoclkc.h
include/dt-bindings/clock/gxbb-clkc.h
include/dt-bindings/gpio/meson-gxbb-gpio.h
include/dt-bindings/gpio/meson-gxl-gpio.h
include/dt-bindings/mfd/st,stpmu1.h [new file with mode: 0644]
include/environment/ti/boot.h
include/image-sparse.h
include/regmap.h
include/stm32_rcc.h
lib/Kconfig
test/dm/led.c
test/dm/regmap.c

index 896f8ae66dc2f346ab8c59cd4522f4f76101e6a5..2cc996876a77e3bd96bc197373394f47a4185370 100644 (file)
                                spi-flash@0 {
                                        #address-cells = <1>;
                                        #size-cells = <1>;
-                                       compatible = "n25q016a";
+                                       compatible = "n25q016a", "spi-flash";
                                        reg = <0>; /* Chip select 0 */
                                        spi-max-frequency = <108000000>;
                                };
                                spi-flash@1 {
                                        #address-cells = <1>;
                                        #size-cells = <1>;
-                                       compatible = "n25q128a11";
+                                       compatible = "n25q128a11", "spi-flash";
                                        reg = <1>; /* Chip select 1 */
                                        spi-max-frequency = <108000000>;
                                        u-boot,dm-pre-reloc;
index 738ed689ff692b0f16b9add648f9f32dd514d010..4ee2e7951482f43122620d2668b244de1744e6b9 100644 (file)
                #size-cells = <2>;
                ranges;
 
-               cbus: cbus@c1100000 {
+               cbus: bus@c1100000 {
                        compatible = "simple-bus";
                        reg = <0x0 0xc1100000 0x0 0x100000>;
                        #address-cells = <2>;
                        #size-cells = <2>;
                        ranges = <0x0 0x0 0x0 0xc1100000 0x0 0x100000>;
 
+                       gpio_intc: interrupt-controller@9880 {
+                               compatible = "amlogic,meson-gpio-intc";
+                               reg = <0x0 0x9880 0x0 0x10>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                               amlogic,channel-interrupts = <64 65 66 67 68 69 70 71>;
+                               status = "disabled";
+                       };
+
                        reset: reset-controller@4404 {
                                compatible = "amlogic,meson-gx-reset", "amlogic,meson-gxbb-reset";
-                               reg = <0x0 0x04404 0x0 0x20>;
+                               reg = <0x0 0x04404 0x0 0x9c>;
                                #reset-cells = <1>;
                        };
 
                        uart_A: serial@84c0 {
-                               compatible = "amlogic,meson-uart";
-                               reg = <0x0 0x84c0 0x0 0x14>;
+                               compatible = "amlogic,meson-gx-uart";
+                               reg = <0x0 0x84c0 0x0 0x18>;
                                interrupts = <GIC_SPI 26 IRQ_TYPE_EDGE_RISING>;
-                               clocks = <&xtal>;
                                status = "disabled";
                        };
 
                        uart_B: serial@84dc {
-                               compatible = "amlogic,meson-uart";
-                               reg = <0x0 0x84dc 0x0 0x14>;
+                               compatible = "amlogic,meson-gx-uart";
+                               reg = <0x0 0x84dc 0x0 0x18>;
                                interrupts = <GIC_SPI 75 IRQ_TYPE_EDGE_RISING>;
-                               clocks = <&xtal>;
                                status = "disabled";
                        };
 
                        };
 
                        uart_C: serial@8700 {
-                               compatible = "amlogic,meson-uart";
-                               reg = <0x0 0x8700 0x0 0x14>;
+                               compatible = "amlogic,meson-gx-uart";
+                               reg = <0x0 0x8700 0x0 0x18>;
                                interrupts = <GIC_SPI 93 IRQ_TYPE_EDGE_RISING>;
-                               clocks = <&xtal>;
                                status = "disabled";
                        };
 
                        };
                };
 
-               aobus: aobus@c8100000 {
+               aobus: bus@c8100000 {
                        compatible = "simple-bus";
                        reg = <0x0 0xc8100000 0x0 0x100000>;
                        #address-cells = <2>;
                        #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>;
+                       sysctrl_AO: sys-ctrl@0 {
+                               compatible = "amlogic,meson-gx-ao-sysctrl", "syscon", "simple-mfd";
+                               reg =  <0x0 0x0 0x0 0x100>;
+
+                               pwrc_vpu: power-controller-vpu {
+                                       compatible = "amlogic,meson-gx-pwrc-vpu";
+                                       #power-domain-cells = <0>;
+                                       amlogic,hhi-sysctrl = <&sysctrl>;
+                               };
+
+                               clkc_AO: clock-controller {
+                                       compatible = "amlogic,meson-gx-aoclkc";
+                                       #clock-cells = <1>;
+                                       #reset-cells = <1>;
+                               };
+                       };
+
+                       cec_AO: cec@100 {
+                               compatible = "amlogic,meson-gx-ao-cec";
+                               reg = <0x0 0x00100 0x0 0x14>;
+                               interrupts = <GIC_SPI 199 IRQ_TYPE_EDGE_RISING>;
+                       };
+
+                       sec_AO: ao-secure@140 {
+                               compatible = "amlogic,meson-gx-ao-secure", "syscon";
+                               reg = <0x0 0x140 0x0 0x140>;
+                               amlogic,has-chip-id;
                        };
 
                        uart_AO: serial@4c0 {
-                               compatible = "amlogic,meson-uart";
-                               reg = <0x0 0x004c0 0x0 0x14>;
+                               compatible = "amlogic,meson-gx-uart", "amlogic,meson-ao-uart";
+                               reg = <0x0 0x004c0 0x0 0x18>;
                                interrupts = <GIC_SPI 193 IRQ_TYPE_EDGE_RISING>;
-                               clocks = <&xtal>;
                                status = "disabled";
                        };
 
                        uart_AO_B: serial@4e0 {
-                               compatible = "amlogic,meson-uart";
-                               reg = <0x0 0x004e0 0x0 0x14>;
+                               compatible = "amlogic,meson-gx-uart", "amlogic,meson-ao-uart";
+                               reg = <0x0 0x004e0 0x0 0x18>;
                                interrupts = <GIC_SPI 197 IRQ_TYPE_EDGE_RISING>;
-                               clocks = <&xtal>;
                                status = "disabled";
                        };
 
                        };
                };
 
-               hiubus: hiubus@c883c000 {
+               hiubus: bus@c883c000 {
                        compatible = "simple-bus";
                        reg = <0x0 0xc883c000 0x0 0x2000>;
                        #address-cells = <2>;
                        #size-cells = <2>;
                        ranges = <0x0 0x0 0x0 0xc883c000 0x0 0x2000>;
 
+                       sysctrl: system-controller@0 {
+                               compatible = "amlogic,meson-gx-hhi-sysctrl", "syscon", "simple-mfd";
+                               reg = <0 0 0 0x400>;
+                       };
+
                        mailbox: mailbox@404 {
                                compatible = "amlogic,meson-gx-mhu", "amlogic,meson-gxbb-mhu";
                                reg = <0 0x404 0 0x4c>;
-                               interrupts = <0 208 IRQ_TYPE_EDGE_RISING>,
-                                            <0 209 IRQ_TYPE_EDGE_RISING>,
-                                            <0 210 IRQ_TYPE_EDGE_RISING>;
+                               interrupts = <GIC_SPI 208 IRQ_TYPE_EDGE_RISING>,
+                                            <GIC_SPI 209 IRQ_TYPE_EDGE_RISING>,
+                                            <GIC_SPI 210 IRQ_TYPE_EDGE_RISING>;
                                #mbox-cells = <1>;
                        };
                };
                        compatible = "amlogic,meson-gx-dwmac", "amlogic,meson-gxbb-dwmac", "snps,dwmac";
                        reg = <0x0 0xc9410000 0x0 0x10000
                               0x0 0xc8834540 0x0 0x4>;
-                       interrupts = <0 8 1>;
+                       interrupts = <GIC_SPI 8 IRQ_TYPE_EDGE_RISING>;
                        interrupt-names = "macirq";
                        status = "disabled";
                };
index d147c853ab054d86affa734311ae2c9df713ea58..ee4ada61c59cf583ae87b0ff85ba9a87788ad002 100644 (file)
@@ -50,7 +50,7 @@
 / {
        compatible = "hardkernel,odroid-c2", "amlogic,meson-gxbb";
        model = "Hardkernel ODROID-C2";
-       
+
        aliases {
                serial0 = &uart_AO;
        };
                compatible = "mmc-pwrseq-emmc";
                reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>;
        };
+
+       hdmi-connector {
+               compatible = "hdmi-connector";
+               type = "a";
+
+               port {
+                       hdmi_connector_in: endpoint {
+                               remote-endpoint = <&hdmi_tx_tmds_out>;
+                       };
+               };
+       };
+};
+
+&cec_AO {
+       status = "okay";
+       pinctrl-0 = <&ao_cec_pins>;
+       pinctrl-names = "default";
+       hdmi-phandle = <&hdmi_tx>;
 };
 
 &ethmac {
                #size-cells = <0>;
 
                eth_phy0: ethernet-phy@0 {
+                       /* Realtek RTL8211F (0x001cc916) */
                        reg = <0>;
+                       interrupt-parent = <&gpio_intc>;
+                       /* MAC_INTR on GPIOZ_15 */
+                       interrupts = <29 IRQ_TYPE_LEVEL_LOW>;
                        eee-broken-1000t;
                };
        };
        };
 };
 
+&hdmi_tx {
+       status = "okay";
+       pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>;
+       pinctrl-names = "default";
+};
+
+&hdmi_tx_tmds_port {
+       hdmi_tx_tmds_out: endpoint {
+               remote-endpoint = <&hdmi_connector_in>;
+       };
+};
+
 &i2c_A {
        status = "okay";
        pinctrl-0 = <&i2c_a_pins>;
                          "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";
+                         "HDMI CEC", "SYS LED",
+                         /* GPIO_TEST_N */
+                         "";
 };
 
 &pinctrl_periphs {
                          "J2 Header Pin12", "J2 Header Pin13",
                          "J2 Header Pin8", "J2 Header Pin10",
                          "", "", "", "", "",
-                         "J2 Header Pin11", "", "J2 Header Pin7",
+                         "J2 Header Pin11", "", "J2 Header Pin7", "",
                          /* Bank GPIOCLK */
-                         "", "", "", "",
-                         /* GPIO_TEST_N */
-                         "";
+                         "", "", "", "";
 };
 
 &saradc {
 &sd_emmc_b {
        status = "okay";
        pinctrl-0 = <&sdcard_pins>;
-       pinctrl-names = "default";
+       pinctrl-1 = <&sdcard_clk_gate_pins>;
+       pinctrl-names = "default", "clk-gate";
 
        bus-width = <4>;
        cap-sd-highspeed;
 /* eMMC */
 &sd_emmc_c {
        status = "okay";
-       pinctrl-0 = <&emmc_pins>;
-       pinctrl-names = "default";
+       pinctrl-0 = <&emmc_pins>, <&emmc_ds_pins>;
+       pinctrl-1 = <&emmc_clk_gate_pins>;
+       pinctrl-names = "default", "clk-gate";
 
        bus-width = <8>;
-       cap-sd-highspeed;
        max-frequency = <200000000>;
        non-removable;
        disable-wp;
 
 &usb1_phy {
        status = "okay";
+       phy-supply = <&usb_otg_pwr>;
 };
 
 &usb0 {
index 17d3efdf146968b9ea60a47ec10045e49be6a4d8..3290a4dc3522a09d376173251e85f3321abaf5f1 100644 (file)
        };
 };
 
+&cec_AO {
+       clocks = <&clkc_AO CLKID_AO_CEC_32K>;
+       clock-names = "core";
+};
+
+&clkc_AO {
+       compatible = "amlogic,meson-gxbb-aoclkc", "amlogic,meson-gx-aoclkc";
+};
+
 &ethmac {
        clocks = <&clkc CLKID_ETH>,
                 <&clkc CLKID_FCLK_DIV2>,
        clock-names = "stmmaceth", "clkin0", "clkin1";
 };
 
+&gpio_intc {
+       compatible = "amlogic,meson-gpio-intc",
+                    "amlogic,meson-gxbb-gpio-intc";
+       status = "okay";
+};
+
 &hdmi_tx {
        compatible = "amlogic,meson-gxbb-dw-hdmi", "amlogic,meson-gx-dw-hdmi";
        resets = <&reset RESET_HDMITX_CAPB3>,
                        reg-names = "mux", "pull", "pull-enable", "gpio";
                        gpio-controller;
                        #gpio-cells = <2>;
-                       gpio-ranges = <&pinctrl_periphs 0 14 120>;
+                       gpio-ranges = <&pinctrl_periphs 0 0 119>;
                };
 
                emmc_pins: emmc {
                        mux {
                                groups = "emmc_nand_d07",
                                       "emmc_cmd",
-                                      "emmc_clk",
-                                      "emmc_ds";
+                                      "emmc_clk";
+                               function = "emmc";
+                       };
+               };
+
+               emmc_ds_pins: emmc-ds {
+                       mux {
+                               groups = "emmc_ds";
                                function = "emmc";
                        };
                };
 
+               emmc_clk_gate_pins: emmc_clk_gate {
+                       mux {
+                               groups = "BOOT_8";
+                               function = "gpio_periphs";
+                       };
+                       cfg-pull-down {
+                               pins = "BOOT_8";
+                               bias-pull-down;
+                       };
+               };
+
                nor_pins: nor {
                        mux {
                                groups = "nor_d",
                        };
                };
 
+               sdcard_clk_gate_pins: sdcard_clk_gate {
+                       mux {
+                               groups = "CARD_2";
+                               function = "gpio_periphs";
+                       };
+                       cfg-pull-down {
+                               pins = "CARD_2";
+                               bias-pull-down;
+                       };
+               };
+
                sdio_pins: sdio {
                        mux {
                                groups = "sdio_d0",
                        };
                };
 
+               sdio_clk_gate_pins: sdio_clk_gate {
+                       mux {
+                               groups = "GPIOX_4";
+                               function = "gpio_periphs";
+                       };
+                       cfg-pull-down {
+                               pins = "GPIOX_4";
+                               bias-pull-down;
+                       };
+               };
+
                sdio_irq_pins: sdio_irq {
                        mux {
                                groups = "sdio_irq";
        };
 };
 
+&pwrc_vpu {
+       resets = <&reset RESET_VIU>,
+                <&reset RESET_VENC>,
+                <&reset RESET_VCBUS>,
+                <&reset RESET_BT656>,
+                <&reset RESET_DVIN_RESET>,
+                <&reset RESET_RDMA>,
+                <&reset RESET_VENCI>,
+                <&reset RESET_VENCP>,
+                <&reset RESET_VDAC>,
+                <&reset RESET_VDI6>,
+                <&reset RESET_VENCL>,
+                <&reset RESET_VID_LOCK>;
+       clocks = <&clkc CLKID_VPU>,
+                <&clkc CLKID_VAPB>;
+       clock-names = "vpu", "vapb";
+       /*
+        * VPU clocking is provided by two identical clock paths
+        * VPU_0 and VPU_1 muxed to a single clock by a glitch
+        * free mux to safely change frequency while running.
+        * Same for VAPB but with a final gate after the glitch free mux.
+        */
+       assigned-clocks = <&clkc CLKID_VPU_0_SEL>,
+                         <&clkc CLKID_VPU_0>,
+                         <&clkc CLKID_VPU>, /* Glitch free mux */
+                         <&clkc CLKID_VAPB_0_SEL>,
+                         <&clkc CLKID_VAPB_0>,
+                         <&clkc CLKID_VAPB_SEL>; /* Glitch free mux */
+       assigned-clock-parents = <&clkc CLKID_FCLK_DIV3>,
+                                <0>, /* Do Nothing */
+                                <&clkc CLKID_VPU_0>,
+                                <&clkc CLKID_FCLK_DIV4>,
+                                <0>, /* Do Nothing */
+                                <&clkc CLKID_VAPB_0>;
+       assigned-clock-rates = <0>, /* Do Nothing */
+                              <666666666>,
+                              <0>, /* Do Nothing */
+                              <0>, /* Do Nothing */
+                              <250000000>,
+                              <0>; /* Do Nothing */
+};
+
 &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";
+       clock-names = "clkin", "core", "adc_clk", "adc_sel";
 };
 
 &sd_emmc_a {
        clocks = <&clkc CLKID_SD_EMMC_A>,
-                <&xtal>,
+                <&clkc CLKID_SD_EMMC_A_CLK0>,
                 <&clkc CLKID_FCLK_DIV2>;
        clock-names = "core", "clkin0", "clkin1";
 };
 
 &sd_emmc_b {
        clocks = <&clkc CLKID_SD_EMMC_B>,
-                <&xtal>,
+                <&clkc CLKID_SD_EMMC_B_CLK0>,
                 <&clkc CLKID_FCLK_DIV2>;
        clock-names = "core", "clkin0", "clkin1";
 };
 
 &sd_emmc_c {
        clocks = <&clkc CLKID_SD_EMMC_C>,
-                <&xtal>,
+                <&clkc CLKID_SD_EMMC_C_CLK0>,
                 <&clkc CLKID_FCLK_DIV2>;
        clock-names = "core", "clkin0", "clkin1";
 };
        clocks = <&clkc CLKID_SPI>;
 };
 
+&uart_A {
+       clocks = <&xtal>, <&clkc CLKID_UART0>, <&xtal>;
+       clock-names = "xtal", "pclk", "baud";
+};
+
+&uart_AO {
+       clocks = <&xtal>, <&clkc CLKID_CLK81>, <&xtal>;
+       clock-names = "xtal", "pclk", "baud";
+};
+
+&uart_AO_B {
+       clocks = <&xtal>, <&clkc CLKID_CLK81>, <&xtal>;
+       clock-names = "xtal", "pclk", "baud";
+};
+
+&uart_B {
+       clocks = <&xtal>, <&clkc CLKID_UART1>, <&xtal>;
+       clock-names = "xtal", "pclk", "baud";
+};
+
+&uart_C {
+       clocks = <&xtal>, <&clkc CLKID_UART2>, <&xtal>;
+       clock-names = "xtal", "pclk", "baud";
+};
+
 &vpu {
        compatible = "amlogic,meson-gxbb-vpu", "amlogic,meson-gx-vpu";
+       power-domains = <&pwrc_vpu>;
 };
index 84cbebb534079fbcfae7f67aa489b1a21b8b89c3..c3515599ed3c41b200831bfb0f6481cb9b0b6799 100644 (file)
        };
 };
 
+&cec_AO {
+       status = "okay";
+       pinctrl-0 = <&ao_cec_pins>;
+       pinctrl-names = "default";
+       hdmi-phandle = <&hdmi_tx>;
+};
+
 &hdmi_tx {
        status = "okay";
        pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>;
        linux,rc-map-name = "rc-geekbox";
 };
 
+&pinctrl_aobus {
+       gpio-line-names = "UART TX",
+                         "UART RX",
+                         "Power Key In",
+                         "J9 Header Pin35",
+                         "J9 Header Pin16",
+                         "J9 Header Pin15",
+                         "J9 Header Pin33",
+                         "IR In",
+                         "HDMI CEC",
+                         "SYS LED",
+                         /* GPIO_TEST_N */
+                         "";
+};
+
+&pinctrl_periphs {
+       gpio-line-names = /* Bank GPIOZ */
+                         "", "", "", "", "", "", "",
+                         "", "", "", "", "", "", "",
+                         "Power OFF",
+                         "VCCK Enable",
+                         /* Bank GPIOH */
+                         "HDMI HPD", "HDMI SDA", "HDMI SCL",
+                         "HDMI_5V_EN", "SPDIF",
+                         "J9 Header Pin37",
+                         "J9 Header Pin30",
+                         "J9 Header Pin29",
+                         "J9 Header Pin32",
+                         "J9 Header Pin31",
+                         /* Bank BOOT */
+                         "eMMC D0", "eMMC D1", "eMMC D2", "eMMC D3",
+                         "eMMC D4", "eMMC D5", "eMMC D6", "eMMC D7",
+                         "eMMC Clk", "eMMC Reset", "eMMC CMD",
+                         "", "BOOT_MODE", "", "", "eMMC Data Strobe",
+                         /* 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",
+                         "VCCK Regulator", "VDDEE Regulator",
+                         /* Bank GPIOX */
+                         "WIFI SDIO D0", "WIFI SDIO D1", "WIFI SDIO D2",
+                         "WIFI SDIO D3", "WIFI SDIO CLK", "WIFI SDIO CMD",
+                         "WIFI Power Enable", "WIFI WAKE HOST",
+                         "Bluetooth PCM DOUT", "Bluetooth PCM DIN",
+                         "Bluetooth PCM SYNC", "Bluetooth PCM CLK",
+                         "Bluetooth UART TX", "Bluetooth UART RX",
+                         "Bluetooth UART CTS", "Bluetooth UART RTS",
+                         "WIFI 32K", "Bluetooth Enable",
+                         "Bluetooth WAKE HOST",
+                         /* Bank GPIOCLK */
+                         "", "J9 Header Pin39";
+};
+
 &pwm_AO_ab {
        status = "okay";
        pinctrl-0 = <&pwm_ao_a_3_pins>, <&pwm_ao_b_pins>;
index dc2acf4d16f4eaa02410b5f34c92e1c25fcb4424..9139761c799132d388f7b28aa035184c65cb668a 100644 (file)
                reg = <0x0 0x0 0x0 0x80000000>;
        };
 
+       hdmi_5v: regulator-hdmi-5v {
+               compatible = "regulator-fixed";
+
+               regulator-name = "HDMI_5V";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+
+               gpio = <&gpio GPIOH_3 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+               regulator-always-on;
+       };
+
        vcc_3v3: regulator-vcc_3v3 {
                compatible = "regulator-fixed";
                regulator-name = "VCC_3V3";
 
                states = <3300000 0>,
                         <1800000 1>;
+
+               regulator-settling-time-up-us = <200>;
+               regulator-settling-time-down-us = <50000>;
+       };
+
+       vddio_ao18: regulator-vddio_ao18 {
+               compatible = "regulator-fixed";
+               regulator-name = "VDDIO_AO18";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
        };
 
        vddio_boot: regulator-vddio_boot {
        };
 };
 
+&cec_AO {
+       status = "okay";
+       pinctrl-0 = <&ao_cec_pins>;
+       pinctrl-names = "default";
+       hdmi-phandle = <&hdmi_tx>;
+};
+
 &cvbs_vdac_port {
        cvbs_vdac_out: endpoint {
                remote-endpoint = <&cvbs_connector_in>;
        status = "okay";
 };
 
+&internal_phy {
+       pinctrl-0 = <&eth_link_led_pins>, <&eth_act_led_pins>;
+       pinctrl-names = "default";
+};
+
 &ir {
        status = "okay";
        pinctrl-0 = <&remote_input_ao_pins>;
        };
 };
 
+&pinctrl_aobus {
+       gpio-line-names = "UART TX",
+                         "UART RX",
+                         "Blue LED",
+                         "SDCard Voltage Switch",
+                         "7J1 Header Pin5",
+                         "7J1 Header Pin3",
+                         "7J1 Header Pin12",
+                         "IR In",
+                         "9J3 Switch HDMI CEC/7J1 Header Pin11",
+                         "7J1 Header Pin13",
+                         /* GPIO_TEST_N */
+                         "7J1 Header Pin15";
+};
+
+&pinctrl_periphs {
+       gpio-line-names = /* Bank GPIOZ */
+                         "", "", "", "", "", "", "",
+                         "", "", "", "", "", "", "",
+                         "Eth Link LED", "Eth Activity LED",
+                         /* Bank GPIOH */
+                         "HDMI HPD", "HDMI SDA", "HDMI SCL",
+                         "HDMI_5V_EN", "9J1 Header Pin2",
+                         "Analog Audio Mute",
+                         "2J3 Header Pin6",
+                         "2J3 Header Pin5",
+                         "2J3 Header Pin4",
+                         "2J3 Header Pin3",
+                         /* Bank BOOT */
+                         "eMMC D0", "eMMC D1", "eMMC D2", "eMMC D3",
+                         "eMMC D4", "eMMC D5", "eMMC D6", "eMMC D7",
+                         "eMMC Clk", "eMMC Reset", "eMMC CMD",
+                         "ALT BOOT MODE", "", "", "", "eMMC Data Strobe",
+                         /* Bank CARD */
+                         "SDCard D1", "SDCard D0", "SDCard CLK", "SDCard CMD",
+                         "SDCard D3", "SDCard D2", "SDCard Det",
+                         /* Bank GPIODV */
+                         "", "", "", "", "", "", "", "", "", "", "", "",
+                         "", "", "", "", "", "", "", "", "", "", "", "",
+                         "Green LED", "VCCK Enable",
+                         "7J1 Header Pin27", "7J1 Header Pin28",
+                         "VCCK Regulator", "VDDEE Regulator",
+                         /* Bank GPIOX */
+                         "7J1 Header Pin22", "7J1 Header Pin26",
+                         "7J1 Header Pin36", "7J1 Header Pin38",
+                         "7J1 Header Pin40", "7J1 Header Pin37",
+                         "7J1 Header Pin33", "7J1 Header Pin35",
+                         "7J1 Header Pin19", "7J1 Header Pin21",
+                         "7J1 Header Pin24", "7J1 Header Pin23",
+                         "7J1 Header Pin8", "7J1 Header Pin10",
+                         "7J1 Header Pin16", "7J1 Header Pin18",
+                         "7J1 Header Pin32", "7J1 Header Pin29",
+                         "7J1 Header Pin31",
+                         /* Bank GPIOCLK */
+                         "7J1 Header Pin7", "";
+};
+
+&saradc {
+       status = "okay";
+       vref-supply = <&vddio_ao18>;
+};
+
 /* SD card */
 &sd_emmc_b {
        status = "okay";
        pinctrl-0 = <&sdcard_pins>;
-       pinctrl-names = "default";
+       pinctrl-1 = <&sdcard_clk_gate_pins>;
+       pinctrl-names = "default", "clk-gate";
 
        bus-width = <4>;
        cap-sd-highspeed;
+       sd-uhs-sdr12;
+       sd-uhs-sdr25;
+       sd-uhs-sdr50;
        max-frequency = <100000000>;
        disable-wp;
 
 /* eMMC */
 &sd_emmc_c {
        status = "okay";
-       pinctrl-0 = <&emmc_pins>;
-       pinctrl-names = "default";
+       pinctrl-0 = <&emmc_pins>, <&emmc_ds_pins>;
+       pinctrl-1 = <&emmc_clk_gate_pins>;
+       pinctrl-names = "default", "clk-gate";
 
        bus-width = <8>;
        cap-mmc-highspeed;
+       mmc-ddr-3_3v;
        max-frequency = <50000000>;
        non-removable;
        disable-wp;
index 6ab17c1eeefdc198f7e4417baa780935b885c6c5..6e2bf858291c5f58b0268200c1a014554d24a59d 100644 (file)
        };
 };
 
+&cec_AO {
+       status = "okay";
+       pinctrl-0 = <&ao_cec_pins>;
+       pinctrl-names = "default";
+       hdmi-phandle = <&hdmi_tx>;
+};
+
 &cvbs_vdac_port {
        cvbs_vdac_out: endpoint {
                remote-endpoint = <&cvbs_connector_in>;
index 0385fb986148efc37b03d2362152e2009decadf9..2db1377819d56680cfa24c0ac26cdcdcbbd96b03 100644 (file)
                reg = <0x0 0x0 0x0 0x80000000>;
        };
 
+       hdmi_5v: regulator-hdmi-5v {
+               compatible = "regulator-fixed";
+
+               regulator-name = "HDMI_5V";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+
+               gpio = <&gpio GPIOH_3 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+               regulator-always-on;
+       };
+
        vddio_boot: regulator-vddio_boot {
                compatible = "regulator-fixed";
                regulator-name = "VDDIO_BOOT";
 &sd_emmc_a {
        status = "okay";
        pinctrl-0 = <&sdio_pins>;
-       pinctrl-names = "default";
+       pinctrl-1 = <&sdio_clk_gate_pins>;
+       pinctrl-names = "default", "clk-gate";
        #address-cells = <1>;
        #size-cells = <0>;
 
 &sd_emmc_b {
        status = "okay";
        pinctrl-0 = <&sdcard_pins>;
-       pinctrl-names = "default";
+       pinctrl-1 = <&sdcard_clk_gate_pins>;
+       pinctrl-names = "default", "clk-gate";
 
        bus-width = <4>;
        cap-sd-highspeed;
 /* eMMC */
 &sd_emmc_c {
        status = "okay";
-       pinctrl-0 = <&emmc_pins>;
-       pinctrl-names = "default";
+       pinctrl-0 = <&emmc_pins>, <&emmc_ds_pins>;
+       pinctrl-1 = <&emmc_clk_gate_pins>;
+       pinctrl-names = "default", "clk-gate";
 
        bus-width = <8>;
-       cap-sd-highspeed;
        cap-mmc-highspeed;
        max-frequency = <200000000>;
        non-removable;
index 8d4f3160a0eefa1220e48541eb8e117441ed6c42..c8514110b9da2dc2f40988ad0ae733437e33420a 100644 (file)
 
 #include "meson-gx.dtsi"
 #include <dt-bindings/clock/gxbb-clkc.h>
+#include <dt-bindings/clock/gxbb-aoclkc.h>
 #include <dt-bindings/gpio/meson-gxl-gpio.h>
 #include <dt-bindings/reset/amlogic,meson-gxbb-reset.h>
 
 / {
        compatible = "amlogic,meson-gxl";
+
+       reserved-memory {
+               /* Alternate 3 MiB reserved for ARM Trusted Firmware (BL31) */
+               secmon_reserved_alt: secmon@5000000 {
+                       reg = <0x0 0x05000000 0x0 0x300000>;
+                       no-map;
+               };
+       };
 };
 
 &ethmac {
        };
 };
 
+&cec_AO {
+       clocks = <&clkc_AO CLKID_AO_CEC_32K>;
+       clock-names = "core";
+};
+
+&clkc_AO {
+       compatible = "amlogic,meson-gxl-aoclkc", "amlogic,meson-gx-aoclkc";
+};
+
+&gpio_intc {
+       compatible = "amlogic,meson-gpio-intc",
+                    "amlogic,meson-gxl-gpio-intc";
+       status = "okay";
+};
+
 &hdmi_tx {
        compatible = "amlogic,meson-gxl-dw-hdmi", "amlogic,meson-gx-dw-hdmi";
        resets = <&reset RESET_HDMITX_CAPB3>,
                        reg-names = "mux", "pull", "pull-enable", "gpio";
                        gpio-controller;
                        #gpio-cells = <2>;
-                       gpio-ranges = <&pinctrl_periphs 0 10 101>;
+                       gpio-ranges = <&pinctrl_periphs 0 0 100>;
                };
 
                emmc_pins: emmc {
                        mux {
                                groups = "emmc_nand_d07",
                                       "emmc_cmd",
-                                      "emmc_clk",
-                                      "emmc_ds";
+                                      "emmc_clk";
                                function = "emmc";
                        };
                };
 
+               emmc_ds_pins: emmc-ds {
+                       mux {
+                               groups = "emmc_ds";
+                               function = "emmc";
+                       };
+               };
+
+               emmc_clk_gate_pins: emmc_clk_gate {
+                       mux {
+                               groups = "BOOT_8";
+                               function = "gpio_periphs";
+                       };
+                       cfg-pull-down {
+                               pins = "BOOT_8";
+                               bias-pull-down;
+                       };
+               };
+
                nor_pins: nor {
                        mux {
                                groups = "nor_d",
                        };
                };
 
+               sdcard_clk_gate_pins: sdcard_clk_gate {
+                       mux {
+                               groups = "CARD_2";
+                               function = "gpio_periphs";
+                       };
+                       cfg-pull-down {
+                               pins = "CARD_2";
+                               bias-pull-down;
+                       };
+               };
+
                sdio_pins: sdio {
                        mux {
                                groups = "sdio_d0",
                        };
                };
 
+               sdio_clk_gate_pins: sdio_clk_gate {
+                       mux {
+                               groups = "GPIOX_4";
+                               function = "gpio_periphs";
+                       };
+                       cfg-pull-down {
+                               pins = "GPIOX_4";
+                               bias-pull-down;
+                       };
+               };
+
                sdio_irq_pins: sdio_irq {
                        mux {
                                groups = "sdio_irq";
 
                        internal_phy: ethernet-phy@8 {
                                compatible = "ethernet-phy-id0181.4400", "ethernet-phy-ieee802.3-c22";
+                               interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
                                reg = <8>;
                                max-speed = <100>;
                        };
        };
 };
 
+&pwrc_vpu {
+       resets = <&reset RESET_VIU>,
+                <&reset RESET_VENC>,
+                <&reset RESET_VCBUS>,
+                <&reset RESET_BT656>,
+                <&reset RESET_DVIN_RESET>,
+                <&reset RESET_RDMA>,
+                <&reset RESET_VENCI>,
+                <&reset RESET_VENCP>,
+                <&reset RESET_VDAC>,
+                <&reset RESET_VDI6>,
+                <&reset RESET_VENCL>,
+                <&reset RESET_VID_LOCK>;
+       clocks = <&clkc CLKID_VPU>,
+                <&clkc CLKID_VAPB>;
+       clock-names = "vpu", "vapb";
+       /*
+        * VPU clocking is provided by two identical clock paths
+        * VPU_0 and VPU_1 muxed to a single clock by a glitch
+        * free mux to safely change frequency while running.
+        * Same for VAPB but with a final gate after the glitch free mux.
+        */
+       assigned-clocks = <&clkc CLKID_VPU_0_SEL>,
+                         <&clkc CLKID_VPU_0>,
+                         <&clkc CLKID_VPU>, /* Glitch free mux */
+                         <&clkc CLKID_VAPB_0_SEL>,
+                         <&clkc CLKID_VAPB_0>,
+                         <&clkc CLKID_VAPB_SEL>; /* Glitch free mux */
+       assigned-clock-parents = <&clkc CLKID_FCLK_DIV3>,
+                                <0>, /* Do Nothing */
+                                <&clkc CLKID_VPU_0>,
+                                <&clkc CLKID_FCLK_DIV4>,
+                                <0>, /* Do Nothing */
+                                <&clkc CLKID_VAPB_0>;
+       assigned-clock-rates = <0>, /* Do Nothing */
+                              <666666666>,
+                              <0>, /* Do Nothing */
+                              <0>, /* Do Nothing */
+                              <250000000>,
+                              <0>; /* Do Nothing */
+};
+
 &saradc {
        compatible = "amlogic,meson-gxl-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";
+       clock-names = "clkin", "core", "adc_clk", "adc_sel";
 };
 
 &sd_emmc_a {
        clocks = <&clkc CLKID_SD_EMMC_A>,
-                <&xtal>,
+                <&clkc CLKID_SD_EMMC_A_CLK0>,
                 <&clkc CLKID_FCLK_DIV2>;
        clock-names = "core", "clkin0", "clkin1";
 };
 
 &sd_emmc_b {
        clocks = <&clkc CLKID_SD_EMMC_B>,
-                <&xtal>,
+                <&clkc CLKID_SD_EMMC_B_CLK0>,
                 <&clkc CLKID_FCLK_DIV2>;
        clock-names = "core", "clkin0", "clkin1";
 };
 
 &sd_emmc_c {
        clocks = <&clkc CLKID_SD_EMMC_C>,
-                <&xtal>,
+                <&clkc CLKID_SD_EMMC_C_CLK0>,
                 <&clkc CLKID_FCLK_DIV2>;
        clock-names = "core", "clkin0", "clkin1";
 };
        clocks = <&clkc CLKID_SPI>;
 };
 
+&uart_A {
+       clocks = <&xtal>, <&clkc CLKID_UART0>, <&xtal>;
+       clock-names = "xtal", "pclk", "baud";
+};
+
+&uart_AO {
+       clocks = <&xtal>, <&clkc CLKID_CLK81>, <&xtal>;
+       clock-names = "xtal", "pclk", "baud";
+};
+
+&uart_AO_B {
+       clocks = <&xtal>, <&clkc CLKID_CLK81>, <&xtal>;
+       clock-names = "xtal", "pclk", "baud";
+};
+
+&uart_B {
+       clocks = <&xtal>, <&clkc CLKID_UART1>, <&xtal>;
+       clock-names = "xtal", "pclk", "baud";
+};
+
+&uart_C {
+       clocks = <&xtal>, <&clkc CLKID_UART2>, <&xtal>;
+       clock-names = "xtal", "pclk", "baud";
+};
+
 &vpu {
        compatible = "amlogic,meson-gxl-vpu", "amlogic,meson-gx-vpu";
+       power-domains = <&pwrc_vpu>;
 };
index b84899a1ea94c1990dd00e19a38b28fb65530b17..2b894162e9e963ea7cde4ed7aea3845a416bf0ad 100644 (file)
                        };
                };
 
+               pwr: pwr@50001000 {
+                       compatible = "st,stm32mp1-pwr", "st,stm32-pwr", "syscon", "simple-mfd";
+                       reg = <0x50001000 0x400>;
+                       system-power-controller;
+                       interrupts = <GIC_SPI 149 IRQ_TYPE_NONE>;
+                       st,sysrcc = <&rcc>;
+                       clocks = <&rcc_clk PLL2_R>;
+                       clock-names = "phyclk";
+
+                       pwr-regulators@c {
+                               compatible = "st,stm32mp1,pwr-reg";
+                               st,tzcr = <&rcc 0x0 0x1>;
+
+                               reg11: reg11 {
+                                       regulator-name = "reg11";
+                                       regulator-min-microvolt = <1100000>;
+                                       regulator-max-microvolt = <1100000>;
+                               };
+
+                               reg18: reg18 {
+                                       regulator-name = "reg18";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                               };
+
+                               usb33: usb33 {
+                                       regulator-name = "usb33";
+                                       regulator-min-microvolt = <3300000>;
+                                       regulator-max-microvolt = <3300000>;
+                               };
+                       };
+               };
+
+               vrefbuf: vrefbuf@50025000 {
+                       compatible = "st,stm32-vrefbuf";
+                       reg = <0x50025000 0x8>;
+                       regulator-min-microvolt = <1500000>;
+                       regulator-max-microvolt = <2500000>;
+                       clocks = <&rcc_clk VREF>;
+                       status = "disabled";
+               };
+
                pinctrl: pin-controller {
                        compatible = "st,stm32mp157-pinctrl";
                        #address-cells = <1>;
index 129cd02418aa0efdb5c28b8bcbd062fe8b59d3e8..233470742257b1765c20489b6e7247cfb96199bf 100644 (file)
@@ -10,6 +10,7 @@
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/input/input.h>
 #include <dt-bindings/pinctrl/stm32-pinfunc.h>
+#include <dt-bindings/mfd/st,stpmu1.h>
 
 / {
        model = "STMicroelectronics STM32MP157C pmic eval daughter";
        memory {
                reg = <0xC0000000 0x40000000>;
        };
+
+       sd_switch: regulator-sd_switch {
+               compatible = "regulator-gpio";
+               regulator-name = "sd_switch";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <2900000>;
+               regulator-type = "voltage";
+               regulator-always-on;
+
+               gpios = <&gpiof 14 GPIO_ACTIVE_HIGH>;
+               gpios-states = <0>;
+               states = <1800000 0x1 2900000 0x0>;
+       };
 };
 
 &gpioa {
                interrupt-controller;
                #interrupt-cells = <2>;
                status = "okay";
+
+               st,main_control_register = <0x04>;
+               st,vin_control_register = <0xc0>;
+               st,usb_control_register = <0x30>;
+
+               regulators {
+                       compatible = "st,stpmu1-regulators";
+
+                       ldo1-supply = <&v3v3>;
+                       ldo2-supply = <&v3v3>;
+                       ldo3-supply = <&vdd_ddr>;
+                       ldo5-supply = <&v3v3>;
+                       ldo6-supply = <&v3v3>;
+                       pwr_sw1-supply = <&bst_out>;
+                       pwr_sw2-supply = <&bst_out>;
+
+                       vddcore: buck1 {
+                               regulator-name = "vddcore";
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <1350000>;
+                               regulator-always-on;
+                               regulator-initial-mode = <2>;
+                               regulator-over-current-protection;
+
+                               regulator-state-standby {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1200000>;
+                                       regulator-mode = <8>;
+                               };
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                               regulator-state-disk {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vdd_ddr: buck2 {
+                               regulator-name = "vdd_ddr";
+                               regulator-min-microvolt = <1350000>;
+                               regulator-max-microvolt = <1350000>;
+                               regulator-always-on;
+                               regulator-initial-mode = <2>;
+                               regulator-over-current-protection;
+
+                               regulator-state-standby {
+                                       regulator-suspend-microvolt = <1350000>;
+                                       regulator-on-in-suspend;
+                                       regulator-mode = <8>;
+                               };
+                               regulator-state-mem {
+                                       regulator-suspend-microvolt = <1350000>;
+                                       regulator-on-in-suspend;
+                                       regulator-mode = <8>;
+                               };
+                               regulator-state-disk {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vdd: buck3 {
+                               regulator-name = "vdd";
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                               st,mask_reset;
+                               regulator-initial-mode = <8>;
+                               regulator-over-current-protection;
+
+                               regulator-state-standby {
+                                       regulator-suspend-microvolt = <3300000>;
+                                       regulator-on-in-suspend;
+                                       regulator-mode = <8>;
+                               };
+                               regulator-state-mem {
+                                       regulator-suspend-microvolt = <3300000>;
+                                       regulator-on-in-suspend;
+                                       regulator-mode = <8>;
+                               };
+                               regulator-state-disk {
+                                       regulator-suspend-microvolt = <3300000>;
+                                       regulator-on-in-suspend;
+                                       regulator-mode = <8>;
+                               };
+                       };
+
+                       v3v3: buck4 {
+                               regulator-name = "v3v3";
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-boot-on;
+                               regulator-over-current-protection;
+                               regulator-initial-mode = <8>;
+
+                               regulator-state-standby {
+                                       regulator-suspend-microvolt = <3300000>;
+                                       regulator-unchanged-in-suspend;
+                                       regulator-mode = <8>;
+                               };
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                               regulator-state-disk {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vdda: ldo1 {
+                               regulator-name = "vdda";
+                               regulator-min-microvolt = <2900000>;
+                               regulator-max-microvolt = <2900000>;
+                               interrupts = <IT_CURLIM_LDO1 0>;
+                               interrupt-parent = <&pmic>;
+
+                               regulator-state-standby {
+                                       regulator-suspend-microvolt = <2900000>;
+                                       regulator-unchanged-in-suspend;
+                               };
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                               regulator-state-disk {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       v2v8: ldo2 {
+                               regulator-name = "v2v8";
+                               regulator-min-microvolt = <2800000>;
+                               regulator-max-microvolt = <2800000>;
+                               interrupts = <IT_CURLIM_LDO2 0>;
+                               interrupt-parent = <&pmic>;
+
+                               regulator-state-standby {
+                                       regulator-suspend-microvolt = <2800000>;
+                                       regulator-unchanged-in-suspend;
+                               };
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                               regulator-state-disk {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vtt_ddr: ldo3 {
+                               regulator-name = "vtt_ddr";
+                               regulator-min-microvolt = <0000000>;
+                               regulator-max-microvolt = <1000000>;
+                               regulator-always-on;
+                               regulator-over-current-protection;
+
+                               regulator-state-standby {
+                                       regulator-off-in-suspend;
+                               };
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                               regulator-state-disk {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vdd_usb: ldo4 {
+                               regulator-name = "vdd_usb";
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               interrupts = <IT_CURLIM_LDO4 0>;
+                               interrupt-parent = <&pmic>;
+
+                               regulator-state-standby {
+                                       regulator-unchanged-in-suspend;
+                               };
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                               regulator-state-disk {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vdd_sd: ldo5 {
+                               regulator-name = "vdd_sd";
+                               regulator-min-microvolt = <2900000>;
+                               regulator-max-microvolt = <2900000>;
+                               interrupts = <IT_CURLIM_LDO5 0>;
+                               interrupt-parent = <&pmic>;
+                               regulator-boot-on;
+
+                               regulator-state-standby {
+                                       regulator-suspend-microvolt = <2900000>;
+                                       regulator-unchanged-in-suspend;
+                               };
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                               regulator-state-disk {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       v1v8: ldo6 {
+                               regulator-name = "v1v8";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               interrupts = <IT_CURLIM_LDO6 0>;
+                               interrupt-parent = <&pmic>;
+
+                               regulator-state-standby {
+                                       regulator-suspend-microvolt = <1800000>;
+                                       regulator-unchanged-in-suspend;
+                               };
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                               regulator-state-disk {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vref_ddr: vref_ddr {
+                               regulator-name = "vref_ddr";
+                               regulator-always-on;
+                               regulator-over-current-protection;
+
+                               regulator-state-standby {
+                                       regulator-on-in-suspend;
+                               };
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                               };
+                               regulator-state-disk {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                        bst_out: boost {
+                               regulator-name = "bst_out";
+                               interrupts = <IT_OCP_BOOST 0>;
+                               interrupt-parent = <&pmic>;
+                        };
+
+                       vbus_otg: pwr_sw1 {
+                               regulator-name = "vbus_otg";
+                               interrupts = <IT_OCP_OTG 0>;
+                               interrupt-parent = <&pmic>;
+                               regulator-active-discharge;
+                        };
+
+                        vbus_sw: pwr_sw2 {
+                               regulator-name = "vbus_sw";
+                               interrupts = <IT_OCP_SWOUT 0>;
+                               interrupt-parent = <&pmic>;
+                               regulator-active-discharge;
+                        };
+               };
        };
 };
 
        st,negedge;
        st,pin-ckin;
        bus-width = <4>;
+       vmmc-supply = <&vdd_sd>;
+       vqmmc-supply = <&sd_switch>;
        sd-uhs-sdr12;
        sd-uhs-sdr25;
        sd-uhs-sdr50;
diff --git a/arch/arm/include/asm/arch-meson/gx.h b/arch/arm/include/asm/arch-meson/gx.h
new file mode 100644 (file)
index 0000000..03fb6b0
--- /dev/null
@@ -0,0 +1,69 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2016 - Beniamino Galvani <b.galvani@gmail.com>
+ */
+
+#ifndef __GX_H__
+#define __GX_H__
+
+#define GX_FIRMWARE_MEM_SIZE   0x1000000
+
+#define GX_AOBUS_BASE          0xc8100000
+#define GX_PERIPHS_BASE        0xc8834400
+#define GX_HIU_BASE            0xc883c000
+#define GX_ETH_BASE            0xc9410000
+
+/* Always-On Peripherals registers */
+#define GX_AO_ADDR(off)        (GX_AOBUS_BASE + ((off) << 2))
+
+#define GX_AO_SEC_GP_CFG0      GX_AO_ADDR(0x90)
+#define GX_AO_SEC_GP_CFG3      GX_AO_ADDR(0x93)
+#define GX_AO_SEC_GP_CFG4      GX_AO_ADDR(0x94)
+#define GX_AO_SEC_GP_CFG5      GX_AO_ADDR(0x95)
+
+#define GX_AO_MEM_SIZE_MASK    0xFFFF0000
+#define GX_AO_MEM_SIZE_SHIFT   16
+#define GX_AO_BL31_RSVMEM_SIZE_MASK    0xFFFF0000
+#define GX_AO_BL31_RSVMEM_SIZE_SHIFT   16
+#define GX_AO_BL32_RSVMEM_SIZE_MASK    0xFFFF
+
+/* Peripherals registers */
+#define GX_PERIPHS_ADDR(off)   (GX_PERIPHS_BASE + ((off) << 2))
+
+/* GPIO registers 0 to 6 */
+#define _GX_GPIO_OFF(n)        ((n) == 6 ? 0x08 : 0x0c + 3 * (n))
+#define GX_GPIO_EN(n)          GX_PERIPHS_ADDR(_GX_GPIO_OFF(n) + 0)
+#define GX_GPIO_IN(n)          GX_PERIPHS_ADDR(_GX_GPIO_OFF(n) + 1)
+#define GX_GPIO_OUT(n) GX_PERIPHS_ADDR(_GX_GPIO_OFF(n) + 2)
+
+#define GX_ETH_REG_0           GX_PERIPHS_ADDR(0x50)
+#define GX_ETH_REG_1           GX_PERIPHS_ADDR(0x51)
+#define GX_ETH_REG_2           GX_PERIPHS_ADDR(0x56)
+#define GX_ETH_REG_3           GX_PERIPHS_ADDR(0x57)
+
+#define GX_ETH_REG_0_PHY_INTF          BIT(0)
+#define GX_ETH_REG_0_TX_PHASE(x)       (((x) & 3) << 5)
+#define GX_ETH_REG_0_TX_RATIO(x)       (((x) & 7) << 7)
+#define GX_ETH_REG_0_PHY_CLK_EN        BIT(10)
+#define GX_ETH_REG_0_INVERT_RMII_CLK   BIT(11)
+#define GX_ETH_REG_0_CLK_EN            BIT(12)
+
+/* HIU registers */
+#define GX_HIU_ADDR(off)       (GX_HIU_BASE + ((off) << 2))
+
+#define GX_MEM_PD_REG_0        GX_HIU_ADDR(0x40)
+
+/* Ethernet memory power domain */
+#define GX_MEM_PD_REG_0_ETH_MASK       (BIT(2) | BIT(3))
+
+/* Clock gates */
+#define GX_GCLK_MPEG_0 GX_HIU_ADDR(0x50)
+#define GX_GCLK_MPEG_1 GX_HIU_ADDR(0x51)
+#define GX_GCLK_MPEG_2 GX_HIU_ADDR(0x52)
+#define GX_GCLK_MPEG_OTHER     GX_HIU_ADDR(0x53)
+#define GX_GCLK_MPEG_AO        GX_HIU_ADDR(0x54)
+
+#define GX_GCLK_MPEG_0_I2C   BIT(9)
+#define GX_GCLK_MPEG_1_ETH     BIT(3)
+
+#endif /* __GX_H__ */
diff --git a/arch/arm/include/asm/arch-meson/gxbb.h b/arch/arm/include/asm/arch-meson/gxbb.h
deleted file mode 100644 (file)
index c7713b2..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * (C) Copyright 2016 - Beniamino Galvani <b.galvani@gmail.com>
- */
-
-#ifndef __GXBB_H__
-#define __GXBB_H__
-
-#define GXBB_FIRMWARE_MEM_SIZE 0x1000000
-
-#define GXBB_AOBUS_BASE                0xc8100000
-#define GXBB_PERIPHS_BASE      0xc8834400
-#define GXBB_HIU_BASE          0xc883c000
-#define GXBB_ETH_BASE          0xc9410000
-
-/* Always-On Peripherals registers */
-#define GXBB_AO_ADDR(off)      (GXBB_AOBUS_BASE + ((off) << 2))
-
-#define GXBB_AO_SEC_GP_CFG0    GXBB_AO_ADDR(0x90)
-#define GXBB_AO_SEC_GP_CFG3    GXBB_AO_ADDR(0x93)
-#define GXBB_AO_SEC_GP_CFG4    GXBB_AO_ADDR(0x94)
-#define GXBB_AO_SEC_GP_CFG5    GXBB_AO_ADDR(0x95)
-
-#define GXBB_AO_MEM_SIZE_MASK  0xFFFF0000
-#define GXBB_AO_MEM_SIZE_SHIFT 16
-#define GXBB_AO_BL31_RSVMEM_SIZE_MASK  0xFFFF0000
-#define GXBB_AO_BL31_RSVMEM_SIZE_SHIFT 16
-#define GXBB_AO_BL32_RSVMEM_SIZE_MASK  0xFFFF
-
-/* Peripherals registers */
-#define GXBB_PERIPHS_ADDR(off) (GXBB_PERIPHS_BASE + ((off) << 2))
-
-/* GPIO registers 0 to 6 */
-#define _GXBB_GPIO_OFF(n)      ((n) == 6 ? 0x08 : 0x0c + 3 * (n))
-#define GXBB_GPIO_EN(n)                GXBB_PERIPHS_ADDR(_GXBB_GPIO_OFF(n) + 0)
-#define GXBB_GPIO_IN(n)                GXBB_PERIPHS_ADDR(_GXBB_GPIO_OFF(n) + 1)
-#define GXBB_GPIO_OUT(n)       GXBB_PERIPHS_ADDR(_GXBB_GPIO_OFF(n) + 2)
-
-#define GXBB_ETH_REG_0         GXBB_PERIPHS_ADDR(0x50)
-#define GXBB_ETH_REG_1         GXBB_PERIPHS_ADDR(0x51)
-#define GXBB_ETH_REG_2         GXBB_PERIPHS_ADDR(0x56)
-#define GXBB_ETH_REG_3         GXBB_PERIPHS_ADDR(0x57)
-
-#define GXBB_ETH_REG_0_PHY_INTF                BIT(0)
-#define GXBB_ETH_REG_0_TX_PHASE(x)     (((x) & 3) << 5)
-#define GXBB_ETH_REG_0_TX_RATIO(x)     (((x) & 7) << 7)
-#define GXBB_ETH_REG_0_PHY_CLK_EN      BIT(10)
-#define GXBB_ETH_REG_0_INVERT_RMII_CLK BIT(11)
-#define GXBB_ETH_REG_0_CLK_EN          BIT(12)
-
-/* HIU registers */
-#define GXBB_HIU_ADDR(off)     (GXBB_HIU_BASE + ((off) << 2))
-
-#define GXBB_MEM_PD_REG_0      GXBB_HIU_ADDR(0x40)
-
-/* Ethernet memory power domain */
-#define GXBB_MEM_PD_REG_0_ETH_MASK     (BIT(2) | BIT(3))
-
-/* Clock gates */
-#define GXBB_GCLK_MPEG_0       GXBB_HIU_ADDR(0x50)
-#define GXBB_GCLK_MPEG_1       GXBB_HIU_ADDR(0x51)
-#define GXBB_GCLK_MPEG_2       GXBB_HIU_ADDR(0x52)
-#define GXBB_GCLK_MPEG_OTHER   GXBB_HIU_ADDR(0x53)
-#define GXBB_GCLK_MPEG_AO      GXBB_HIU_ADDR(0x54)
-
-#define GXBB_GCLK_MPEG_0_I2C   BIT(9)
-#define GXBB_GCLK_MPEG_1_ETH   BIT(3)
-
-#endif /* __GXBB_H__ */
index 81e0e9f3322a8376efbb9b4b940ecd3f546c0789..7a03d6d3c73e85370e820f923a3936f93555fbdf 100644 (file)
@@ -47,6 +47,10 @@ struct atmel_pio4_port {
 #define ATMEL_PIO_IFSCEN_MASK          BIT(13)
 #define ATMEL_PIO_OPD_MASK             BIT(14)
 #define ATMEL_PIO_SCHMITT_MASK         BIT(15)
+#define ATMEL_PIO_DRVSTR_MASK          GENMASK(17, 16)
+#define ATMEL_PIO_DRVSTR_LO            (1 << 16)
+#define ATMEL_PIO_DRVSTR_ME            (2 << 16)
+#define ATMEL_PIO_DRVSTR_HI            (3 << 16)
 #define ATMEL_PIO_CFGR_EVTSEL_MASK     GENMASK(26, 24)
 #define ATMEL_PIO_CFGR_EVTSEL_FALLING  (0 << 24)
 #define ATMEL_PIO_CFGR_EVTSEL_RISING   (1 << 24)
@@ -68,14 +72,14 @@ struct atmel_pio4_port {
 #define AT91_PIO_PORTC         0x2
 #define AT91_PIO_PORTD         0x3
 
-int atmel_pio4_set_gpio(u32 port, u32 pin, u32 use_pullup);
-int atmel_pio4_set_a_periph(u32 port, u32 pin, u32 use_pullup);
-int atmel_pio4_set_b_periph(u32 port, u32 pin, u32 use_pullup);
-int atmel_pio4_set_c_periph(u32 port, u32 pin, u32 use_pullup);
-int atmel_pio4_set_d_periph(u32 port, u32 pin, u32 use_pullup);
-int atmel_pio4_set_e_periph(u32 port, u32 pin, u32 use_pullup);
-int atmel_pio4_set_f_periph(u32 port, u32 pin, u32 use_pullup);
-int atmel_pio4_set_g_periph(u32 port, u32 pin, u32 use_pullup);
+int atmel_pio4_set_gpio(u32 port, u32 pin, u32 config);
+int atmel_pio4_set_a_periph(u32 port, u32 pin, u32 config);
+int atmel_pio4_set_b_periph(u32 port, u32 pin, u32 config);
+int atmel_pio4_set_c_periph(u32 port, u32 pin, u32 config);
+int atmel_pio4_set_d_periph(u32 port, u32 pin, u32 config);
+int atmel_pio4_set_e_periph(u32 port, u32 pin, u32 config);
+int atmel_pio4_set_f_periph(u32 port, u32 pin, u32 config);
+int atmel_pio4_set_g_periph(u32 port, u32 pin, u32 config);
 int atmel_pio4_set_pio_output(u32 port, u32 pin, u32 value);
 int atmel_pio4_get_pio_input(u32 port, u32 pin);
 
index 89e75fb65b646ce3d2689f90e22778d8789bfdcf..1ef7e5a6d1aa90e32c94195361abf7f42428f387 100644 (file)
@@ -6,7 +6,7 @@
 #include <common.h>
 #include <linux/libfdt.h>
 #include <linux/err.h>
-#include <asm/arch/gxbb.h>
+#include <asm/arch/gx.h>
 #include <asm/arch/sm.h>
 #include <asm/armv8/mmu.h>
 #include <asm/unaligned.h>
@@ -39,8 +39,8 @@ int dram_init(void)
 phys_size_t get_effective_memsize(void)
 {
        /* Size is reported in MiB, convert it in bytes */
-       return ((readl(GXBB_AO_SEC_GP_CFG0) & GXBB_AO_MEM_SIZE_MASK)
-                       >> GXBB_AO_MEM_SIZE_SHIFT) * SZ_1M;
+       return ((readl(GX_AO_SEC_GP_CFG0) & GX_AO_MEM_SIZE_MASK)
+                       >> GX_AO_MEM_SIZE_SHIFT) * SZ_1M;
 }
 
 static void meson_board_add_reserved_memory(void *fdt, u64 start, u64 size)
@@ -71,27 +71,27 @@ void meson_gx_init_reserved_memory(void *fdt)
         * - AO_SEC_GP_CFG4: bl32 physical start address, can be NULL
         */
 
-       reg = readl(GXBB_AO_SEC_GP_CFG3);
+       reg = readl(GX_AO_SEC_GP_CFG3);
 
-       bl31_size = ((reg & GXBB_AO_BL31_RSVMEM_SIZE_MASK)
-                       >> GXBB_AO_BL31_RSVMEM_SIZE_SHIFT) * SZ_1K;
-       bl32_size = (reg & GXBB_AO_BL32_RSVMEM_SIZE_MASK) * SZ_1K;
+       bl31_size = ((reg & GX_AO_BL31_RSVMEM_SIZE_MASK)
+                       >> GX_AO_BL31_RSVMEM_SIZE_SHIFT) * SZ_1K;
+       bl32_size = (reg & GX_AO_BL32_RSVMEM_SIZE_MASK) * SZ_1K;
 
-       bl31_start = readl(GXBB_AO_SEC_GP_CFG5);
-       bl32_start = readl(GXBB_AO_SEC_GP_CFG4);
+       bl31_start = readl(GX_AO_SEC_GP_CFG5);
+       bl32_start = readl(GX_AO_SEC_GP_CFG4);
 
        /*
-        * Early Meson GXBB Firmware revisions did not provide the reserved
+        * Early Meson GX Firmware revisions did not provide the reserved
         * memory zones in the registers, keep fixed memory zone handling.
         */
-       if (IS_ENABLED(CONFIG_MESON_GXBB) &&
+       if (IS_ENABLED(CONFIG_MESON_GX) &&
            !reg && !bl31_start && !bl32_start) {
                bl31_start = 0x10000000;
                bl31_size = 0x200000;
        }
 
        /* Add first 16MiB reserved zone */
-       meson_board_add_reserved_memory(fdt, 0, GXBB_FIRMWARE_MEM_SIZE);
+       meson_board_add_reserved_memory(fdt, 0, GX_FIRMWARE_MEM_SIZE);
 
        /* Add BL31 reserved zone */
        if (bl31_start && bl31_size)
@@ -107,7 +107,7 @@ void reset_cpu(ulong addr)
        psci_system_reset();
 }
 
-static struct mm_region gxbb_mem_map[] = {
+static struct mm_region gx_mem_map[] = {
        {
                .virt = 0x0UL,
                .phys = 0x0UL,
@@ -127,4 +127,4 @@ static struct mm_region gxbb_mem_map[] = {
        }
 };
 
-struct mm_region *mem_map = gxbb_mem_map;
+struct mm_region *mem_map = gx_mem_map;
index e340212c2a279b18cd532136561972850acae893..061f19a0e31c4407ed99e666226b67759b12cec2 100644 (file)
@@ -7,7 +7,7 @@
 #include <common.h>
 #include <dm.h>
 #include <asm/io.h>
-#include <asm/arch/gxbb.h>
+#include <asm/arch/gx.h>
 #include <asm/arch/eth.h>
 #include <phy.h>
 
@@ -22,23 +22,23 @@ void meson_gx_eth_init(phy_interface_t mode, unsigned int flags)
        case PHY_INTERFACE_MODE_RGMII_RXID:
        case PHY_INTERFACE_MODE_RGMII_TXID:
                /* Set RGMII mode */
-               setbits_le32(GXBB_ETH_REG_0, GXBB_ETH_REG_0_PHY_INTF |
-                            GXBB_ETH_REG_0_TX_PHASE(1) |
-                            GXBB_ETH_REG_0_TX_RATIO(4) |
-                            GXBB_ETH_REG_0_PHY_CLK_EN |
-                            GXBB_ETH_REG_0_CLK_EN);
+               setbits_le32(GX_ETH_REG_0, GX_ETH_REG_0_PHY_INTF |
+                            GX_ETH_REG_0_TX_PHASE(1) |
+                            GX_ETH_REG_0_TX_RATIO(4) |
+                            GX_ETH_REG_0_PHY_CLK_EN |
+                            GX_ETH_REG_0_CLK_EN);
                break;
 
        case PHY_INTERFACE_MODE_RMII:
                /* Set RMII mode */
-               out_le32(GXBB_ETH_REG_0, GXBB_ETH_REG_0_INVERT_RMII_CLK |
-                                        GXBB_ETH_REG_0_CLK_EN);
+               out_le32(GX_ETH_REG_0, GX_ETH_REG_0_INVERT_RMII_CLK |
+                                        GX_ETH_REG_0_CLK_EN);
 
                /* Use GXL RMII Internal PHY */
                if (IS_ENABLED(CONFIG_MESON_GXL) &&
                    (flags & MESON_GXL_USE_INTERNAL_RMII_PHY)) {
-                       writel(0x10110181, GXBB_ETH_REG_2);
-                       writel(0xe40908ff, GXBB_ETH_REG_3);
+                       writel(0x10110181, GX_ETH_REG_2);
+                       writel(0xe40908ff, GX_ETH_REG_3);
                }
 
                break;
@@ -49,6 +49,6 @@ void meson_gx_eth_init(phy_interface_t mode, unsigned int flags)
        }
 
        /* Enable power and clock gate */
-       setbits_le32(GXBB_GCLK_MPEG_1, GXBB_GCLK_MPEG_1_ETH);
-       clrbits_le32(GXBB_MEM_PD_REG_0, GXBB_MEM_PD_REG_0_ETH_MASK);
+       setbits_le32(GX_GCLK_MPEG_1, GX_GCLK_MPEG_1_ETH);
+       clrbits_le32(GX_MEM_PD_REG_0, GX_MEM_PD_REG_0_ETH_MASK);
 }
index 9829bae657db493608c937852496da6bf11a6f48..0bba5e4a0733145bb2ae17451e03eb2323e6c581 100644 (file)
@@ -6,7 +6,7 @@
  */
 
 #include <common.h>
-#include <asm/arch/gxbb.h>
+#include <asm/arch/gx.h>
 #include <linux/kernel.h>
 
 #define FN_GET_SHARE_MEM_INPUT_BASE    0x82000020
index 92a6f799d45c4f32fc41cab43fe71c24d29a260f..dc7b37f1643500d864e3defcfd59d3735fde0220 100644 (file)
@@ -29,6 +29,8 @@ static void omap_set_fastboot_cpu(void)
 
        switch (cpu_rev) {
        case DRA762_ES1_0:
+       case DRA762_ABZ_ES1_0:
+       case DRA762_ACD_ES1_0:
                cpu = "DRA762";
                break;
        case DRA752_ES1_0:
index a9b523d96fd711854b9956f628f685f1614ca3c7..08ee642d908670888a68b8b74b3e95850ac4871b 100644 (file)
@@ -9,3 +9,4 @@ obj-y += syscon.o
 
 obj-$(CONFIG_SPL_BUILD) += spl.o
 obj-$(CONFIG_ARMV7_PSCI) += psci.o
+obj-$(CONFIG_$(SPL_)DM_REGULATOR) += pwr_regulator.o
index afcab299cfa3e71ad94f6b2540a708d60df06013..a8142013b086e5f1b4e7ff926794b774321247c4 100644 (file)
@@ -28,6 +28,7 @@
 enum {
        STM32MP_SYSCON_UNKNOWN,
        STM32MP_SYSCON_STGEN,
+       STM32MP_SYSCON_PWR,
 };
 
 /*
diff --git a/arch/arm/mach-stm32mp/pwr_regulator.c b/arch/arm/mach-stm32mp/pwr_regulator.c
new file mode 100644 (file)
index 0000000..9484645
--- /dev/null
@@ -0,0 +1,274 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <regmap.h>
+#include <syscon.h>
+#include <power/pmic.h>
+#include <power/regulator.h>
+
+#define STM32MP_PWR_CR3 0xc
+#define STM32MP_PWR_CR3_USB33DEN BIT(24)
+#define STM32MP_PWR_CR3_USB33RDY BIT(26)
+#define STM32MP_PWR_CR3_REG18DEN BIT(28)
+#define STM32MP_PWR_CR3_REG18RDY BIT(29)
+#define STM32MP_PWR_CR3_REG11DEN BIT(30)
+#define STM32MP_PWR_CR3_REG11RDY BIT(31)
+
+struct stm32mp_pwr_reg_info {
+       u32 enable;
+       u32 ready;
+       char *name;
+};
+
+struct stm32mp_pwr_priv {
+       struct regmap *regmap;
+};
+
+static int stm32mp_pwr_write(struct udevice *dev, uint reg,
+                            const uint8_t *buff, int len)
+{
+       struct stm32mp_pwr_priv *priv = dev_get_priv(dev);
+       u32 val = *(u32 *)buff;
+
+       if (len != 4)
+               return -EINVAL;
+
+       return regmap_write(priv->regmap, STM32MP_PWR_CR3, val);
+}
+
+static int stm32mp_pwr_read(struct udevice *dev, uint reg, uint8_t *buff,
+                           int len)
+{
+       struct stm32mp_pwr_priv *priv = dev_get_priv(dev);
+
+       if (len != 4)
+               return -EINVAL;
+
+       return regmap_read(priv->regmap, STM32MP_PWR_CR3, (u32 *)buff);
+}
+
+static int stm32mp_pwr_ofdata_to_platdata(struct udevice *dev)
+{
+       struct stm32mp_pwr_priv *priv = dev_get_priv(dev);
+       struct regmap *regmap;
+
+       regmap = syscon_get_regmap_by_driver_data(STM32MP_SYSCON_PWR);
+       if (IS_ERR(regmap)) {
+               pr_err("%s: unable to find regmap (%ld)\n", __func__,
+                      PTR_ERR(regmap));
+               return PTR_ERR(regmap);
+       }
+       priv->regmap = regmap;
+
+       return 0;
+}
+
+static const struct pmic_child_info pwr_children_info[] = {
+       { .prefix = "reg", .driver = "stm32mp_pwr_regulator"},
+       { .prefix = "usb", .driver = "stm32mp_pwr_regulator"},
+       { },
+};
+
+static int stm32mp_pwr_bind(struct udevice *dev)
+{
+       int children;
+
+       children = pmic_bind_children(dev, dev->node, pwr_children_info);
+       if (!children)
+               dev_dbg(dev, "no child found\n");
+
+       return 0;
+}
+
+static struct dm_pmic_ops stm32mp_pwr_ops = {
+       .read = stm32mp_pwr_read,
+       .write = stm32mp_pwr_write,
+};
+
+static const struct udevice_id stm32mp_pwr_ids[] = {
+       { .compatible = "st,stm32mp1,pwr-reg" },
+       { }
+};
+
+U_BOOT_DRIVER(stm32mp_pwr_pmic) = {
+       .name = "stm32mp_pwr_pmic",
+       .id = UCLASS_PMIC,
+       .of_match = stm32mp_pwr_ids,
+       .bind = stm32mp_pwr_bind,
+       .ops = &stm32mp_pwr_ops,
+       .ofdata_to_platdata = stm32mp_pwr_ofdata_to_platdata,
+       .priv_auto_alloc_size = sizeof(struct stm32mp_pwr_priv),
+};
+
+static const struct stm32mp_pwr_reg_info stm32mp_pwr_reg11 = {
+       .enable = STM32MP_PWR_CR3_REG11DEN,
+       .ready = STM32MP_PWR_CR3_REG11RDY,
+       .name = "reg11"
+};
+
+static const struct stm32mp_pwr_reg_info stm32mp_pwr_reg18 = {
+       .enable = STM32MP_PWR_CR3_REG18DEN,
+       .ready = STM32MP_PWR_CR3_REG18RDY,
+       .name = "reg18"
+};
+
+static const struct stm32mp_pwr_reg_info stm32mp_pwr_usb33 = {
+       .enable = STM32MP_PWR_CR3_USB33DEN,
+       .ready = STM32MP_PWR_CR3_USB33RDY,
+       .name = "usb33"
+};
+
+static const struct stm32mp_pwr_reg_info *stm32mp_pwr_reg_infos[] = {
+       &stm32mp_pwr_reg11,
+       &stm32mp_pwr_reg18,
+       &stm32mp_pwr_usb33,
+       NULL
+};
+
+static int stm32mp_pwr_regulator_probe(struct udevice *dev)
+{
+       const struct stm32mp_pwr_reg_info **p = stm32mp_pwr_reg_infos;
+       struct dm_regulator_uclass_platdata *uc_pdata;
+
+       uc_pdata = dev_get_uclass_platdata(dev);
+
+       while (*p) {
+               int rc;
+
+               rc = dev_read_stringlist_search(dev, "regulator-name",
+                                               (*p)->name);
+               if (rc >= 0) {
+                       dev_dbg(dev, "found regulator %s\n", (*p)->name);
+                       break;
+               } else if (rc != -ENODATA) {
+                       return rc;
+               }
+               p++;
+       }
+       if (!*p) {
+               int i = 0;
+               const char *s;
+
+               dev_dbg(dev, "regulator ");
+               while (dev_read_string_index(dev, "regulator-name",
+                                            i++, &s) >= 0)
+                       dev_dbg(dev, "%s'%s' ", (i > 1) ? ", " : "", s);
+               dev_dbg(dev, "%s not supported\n", (i > 2) ? "are" : "is");
+               return -EINVAL;
+       }
+
+       uc_pdata->type = REGULATOR_TYPE_FIXED;
+       dev->priv = (void *)*p;
+
+       return 0;
+}
+
+static int stm32mp_pwr_regulator_set_value(struct udevice *dev, int uV)
+{
+       struct dm_regulator_uclass_platdata *uc_pdata;
+
+       uc_pdata = dev_get_uclass_platdata(dev);
+       if (!uc_pdata)
+               return -ENXIO;
+
+       if (uc_pdata->min_uV != uV) {
+               dev_dbg(dev, "Invalid uV=%d for: %s\n", uV, uc_pdata->name);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int stm32mp_pwr_regulator_get_value(struct udevice *dev)
+{
+       struct dm_regulator_uclass_platdata *uc_pdata;
+
+       uc_pdata = dev_get_uclass_platdata(dev);
+       if (!uc_pdata)
+               return -ENXIO;
+
+       if (uc_pdata->min_uV != uc_pdata->max_uV) {
+               dev_dbg(dev, "Invalid constraints for: %s\n", uc_pdata->name);
+               return -EINVAL;
+       }
+
+       return uc_pdata->min_uV;
+}
+
+static int stm32mp_pwr_regulator_get_enable(struct udevice *dev)
+{
+       const struct stm32mp_pwr_reg_info *p = dev_get_priv(dev);
+       int rc;
+       u32 reg;
+
+       rc = pmic_read(dev->parent, 0, (uint8_t *)&reg, sizeof(reg));
+       if (rc)
+               return rc;
+
+       dev_dbg(dev, "%s id %s\n", p->name, (reg & p->enable) ? "on" : "off");
+
+       return (reg & p->enable) != 0;
+}
+
+static int stm32mp_pwr_regulator_set_enable(struct udevice *dev, bool enable)
+{
+       const struct stm32mp_pwr_reg_info *p = dev_get_priv(dev);
+       int rc;
+       u32 reg;
+       u32 time_start;
+
+       dev_dbg(dev, "Turning %s %s\n", enable ? "on" : "off", p->name);
+
+       rc = pmic_read(dev->parent, 0, (uint8_t *)&reg, sizeof(reg));
+       if (rc)
+               return rc;
+
+       /* if regulator is already in the wanted state, nothing to do */
+       if (!!(reg & p->enable) == enable)
+               return 0;
+
+       reg &= ~p->enable;
+       if (enable)
+               reg |= p->enable;
+
+       rc = pmic_write(dev->parent, 0, (uint8_t *)&reg, sizeof(reg));
+       if (rc)
+               return rc;
+
+       if (!enable)
+               return 0;
+
+       /* waiting ready for enable */
+       time_start = get_timer(0);
+       while (1) {
+               rc = pmic_read(dev->parent, 0, (uint8_t *)&reg, sizeof(reg));
+               if (rc)
+                       return rc;
+               if (reg & p->ready)
+                       break;
+               if (get_timer(time_start) > CONFIG_SYS_HZ) {
+                       dev_dbg(dev, "%s: timeout\n", p->name);
+                       return -ETIMEDOUT;
+               }
+       }
+       return 0;
+}
+
+static const struct dm_regulator_ops stm32mp_pwr_regulator_ops = {
+       .set_value  = stm32mp_pwr_regulator_set_value,
+       .get_value  = stm32mp_pwr_regulator_get_value,
+       .get_enable = stm32mp_pwr_regulator_get_enable,
+       .set_enable = stm32mp_pwr_regulator_set_enable,
+};
+
+U_BOOT_DRIVER(stm32mp_pwr_regulator) = {
+       .name = "stm32mp_pwr_regulator",
+       .id = UCLASS_REGULATOR,
+       .ops = &stm32mp_pwr_regulator_ops,
+       .probe = stm32mp_pwr_regulator_probe,
+};
index 66b94f592f7943a380516bdc8abd303812fbd00b..eb7f435f10caefbdc9b7ee14952a9504c3da2ea8 100644 (file)
@@ -11,6 +11,8 @@
 static const struct udevice_id stm32mp_syscon_ids[] = {
        { .compatible = "st,stm32-stgen",
          .data = STM32MP_SYSCON_STGEN },
+       { .compatible = "st,stm32mp1-pwr",
+         .data = STM32MP_SYSCON_PWR },
        { }
 };
 
index 3c25cb79ef194055c7ac70381bb802a4f0b65838..683b1970e0afb80d01e98d2bebf79406a31a390c 100644 (file)
                        gpios = <&gpio_a 2 0>;
                        label = "sandbox:green";
                };
+
+               default_on {
+                       gpios = <&gpio_a 5 0>;
+                       label = "sandbox:default_on";
+                       default-state = "on";
+               };
+
+               default_off {
+                       gpios = <&gpio_a 6 0>;
+                       label = "sandbox:default_off";
+                       default-state = "off";
+               };
        };
 
        mbox: mbox {
index d3ae7aa655a8746e3bdd0456d89c0d3aca5df0cf..692bf2add3d39fce7904c0bb0f14eae8ebd8255c 100644 (file)
@@ -8,7 +8,7 @@
 #include <dm.h>
 #include <environment.h>
 #include <asm/io.h>
-#include <asm/arch/gxbb.h>
+#include <asm/arch/gx.h>
 #include <asm/arch/mem.h>
 #include <asm/arch/sm.h>
 #include <asm/arch/eth.h>
index 80c04fb9cd8ad14f1c0674e0c4e712dd075fdcc9..e89bf773cc7ee5f278d57bcdb3f2652e09c1ea32 100644 (file)
@@ -8,7 +8,7 @@
 #include <dm.h>
 #include <environment.h>
 #include <asm/io.h>
-#include <asm/arch/gxbb.h>
+#include <asm/arch/gx.h>
 #include <asm/arch/sm.h>
 #include <asm/arch/eth.h>
 #include <asm/arch/mem.h>
@@ -33,8 +33,8 @@ int misc_init_r(void)
                          MESON_GXL_USE_INTERNAL_RMII_PHY);
 
        /* Enable power and clock gate */
-       setbits_le32(GXBB_GCLK_MPEG_1, GXBB_GCLK_MPEG_1_ETH);
-       clrbits_le32(GXBB_MEM_PD_REG_0, GXBB_MEM_PD_REG_0_ETH_MASK);
+       setbits_le32(GX_GCLK_MPEG_1, GX_GCLK_MPEG_1_ETH);
+       clrbits_le32(GX_MEM_PD_REG_0, GX_MEM_PD_REG_0_ETH_MASK);
 
        if (!eth_env_get_enetaddr("ethaddr", mac_addr)) {
                len = meson_sm_read_efuse(EFUSE_MAC_OFFSET,
index 339a1bf9ca3df6d9cd1654cf17831b2e9bc6bda7..1b7fd8199bb8e32068a16fbbbfbaff7b1ff4b98d 100644 (file)
@@ -7,7 +7,7 @@
 #include <dm.h>
 #include <environment.h>
 #include <asm/io.h>
-#include <asm/arch/gxbb.h>
+#include <asm/arch/gx.h>
 #include <asm/arch/sm.h>
 #include <asm/arch/eth.h>
 #include <asm/arch/mem.h>
@@ -31,13 +31,13 @@ int misc_init_r(void)
        meson_gx_eth_init(PHY_INTERFACE_MODE_RGMII, 0);
 
        /* Enable power and clock gate */
-       setbits_le32(GXBB_GCLK_MPEG_0, GXBB_GCLK_MPEG_0_I2C);
+       setbits_le32(GX_GCLK_MPEG_0, GX_GCLK_MPEG_0_I2C);
 
        /* Reset PHY on GPIOZ_14 */
-       clrbits_le32(GXBB_GPIO_EN(3), BIT(14));
-       clrbits_le32(GXBB_GPIO_OUT(3), BIT(14));
+       clrbits_le32(GX_GPIO_EN(3), BIT(14));
+       clrbits_le32(GX_GPIO_OUT(3), BIT(14));
        mdelay(10);
-       setbits_le32(GXBB_GPIO_OUT(3), BIT(14));
+       setbits_le32(GX_GPIO_OUT(3), BIT(14));
 
        if (!eth_env_get_enetaddr("ethaddr", mac_addr)) {
                len = meson_sm_read_efuse(EFUSE_MAC_OFFSET,
index c1f2aca56709fbc7c7bfcb91957f8aca056b7e30..06c2eaee47fb3b24e1c74e39cb84c471c48a20f9 100644 (file)
@@ -8,7 +8,7 @@
 #include <dm.h>
 #include <environment.h>
 #include <asm/io.h>
-#include <asm/arch/gxbb.h>
+#include <asm/arch/gx.h>
 #include <asm/arch/sm.h>
 #include <asm/arch/eth.h>
 #include <asm/arch/mem.h>
index d805068ac97c1e0ddae3c16f25d674fc505343c5..d5ddf8d2eba1f9c722dfbb8162287ca19ecd4cd1 100644 (file)
@@ -19,7 +19,7 @@ DECLARE_GLOBAL_DATA_PTR;
 
 static void board_usb_hw_init(void)
 {
-       atmel_pio4_set_pio_output(AT91_PIO_PORTB, 10, 1);
+       atmel_pio4_set_pio_output(AT91_PIO_PORTA, 27, 1);
 }
 
 #ifdef CONFIG_BOARD_LATE_INIT
@@ -35,7 +35,7 @@ int board_late_init(void)
 #ifdef CONFIG_DEBUG_UART_BOARD_INIT
 static void board_uart1_hw_init(void)
 {
-       atmel_pio4_set_a_periph(AT91_PIO_PORTD, 2, 1);  /* URXD1 */
+       atmel_pio4_set_a_periph(AT91_PIO_PORTD, 2, ATMEL_PIO_PUEN_MASK);        /* URXD1 */
        atmel_pio4_set_a_periph(AT91_PIO_PORTD, 3, 0);  /* UTXD1 */
 
        at91_periph_clk_enable(ATMEL_ID_UART1);
index ff6efbf3831f69ae523423c53d750b08d13a9771..789841e45a94cb06ba0fd4b8e7c4b7fb70d6d5ea 100644 (file)
@@ -33,10 +33,10 @@ static void board_nand_hw_init(void)
        writel(AT91_SMC_SETUP_NWE(1) | AT91_SMC_SETUP_NCS_WR(1) |
               AT91_SMC_SETUP_NRD(1) | AT91_SMC_SETUP_NCS_RD(1),
               &smc->cs[3].setup);
-       writel(AT91_SMC_PULSE_NWE(2) | AT91_SMC_PULSE_NCS_WR(3) |
+       writel(AT91_SMC_PULSE_NWE(2) | AT91_SMC_PULSE_NCS_WR(4) |
               AT91_SMC_PULSE_NRD(2) | AT91_SMC_PULSE_NCS_RD(3),
               &smc->cs[3].pulse);
-       writel(AT91_SMC_CYCLE_NWE(5) | AT91_SMC_CYCLE_NRD(5),
+       writel(AT91_SMC_CYCLE_NWE(6) | AT91_SMC_CYCLE_NRD(5),
               &smc->cs[3].cycle);
        writel(AT91_SMC_TIMINGS_TCLR(2) | AT91_SMC_TIMINGS_TADL(7) |
               AT91_SMC_TIMINGS_TAR(2)  | AT91_SMC_TIMINGS_TRR(3)   |
@@ -48,32 +48,32 @@ static void board_nand_hw_init(void)
               AT91_SMC_MODE_TDF_CYCLE(3),
               &smc->cs[3].mode);
 
-       atmel_pio4_set_b_periph(AT91_PIO_PORTA, 22, 0); /* D0 */
-       atmel_pio4_set_b_periph(AT91_PIO_PORTA, 23, 0); /* D1 */
-       atmel_pio4_set_b_periph(AT91_PIO_PORTA, 24, 0); /* D2 */
-       atmel_pio4_set_b_periph(AT91_PIO_PORTA, 25, 0); /* D3 */
-       atmel_pio4_set_b_periph(AT91_PIO_PORTA, 26, 0); /* D4 */
-       atmel_pio4_set_b_periph(AT91_PIO_PORTA, 27, 0); /* D5 */
-       atmel_pio4_set_b_periph(AT91_PIO_PORTA, 28, 0); /* D6 */
-       atmel_pio4_set_b_periph(AT91_PIO_PORTA, 29, 0); /* D7 */
+       atmel_pio4_set_b_periph(AT91_PIO_PORTA, 22, ATMEL_PIO_DRVSTR_ME);       /* D0 */
+       atmel_pio4_set_b_periph(AT91_PIO_PORTA, 23, ATMEL_PIO_DRVSTR_ME);       /* D1 */
+       atmel_pio4_set_b_periph(AT91_PIO_PORTA, 24, ATMEL_PIO_DRVSTR_ME);       /* D2 */
+       atmel_pio4_set_b_periph(AT91_PIO_PORTA, 25, ATMEL_PIO_DRVSTR_ME);       /* D3 */
+       atmel_pio4_set_b_periph(AT91_PIO_PORTA, 26, ATMEL_PIO_DRVSTR_ME);       /* D4 */
+       atmel_pio4_set_b_periph(AT91_PIO_PORTA, 27, ATMEL_PIO_DRVSTR_ME);       /* D5 */
+       atmel_pio4_set_b_periph(AT91_PIO_PORTA, 28, ATMEL_PIO_DRVSTR_ME);       /* D6 */
+       atmel_pio4_set_b_periph(AT91_PIO_PORTA, 29, ATMEL_PIO_DRVSTR_ME);       /* D7 */
        atmel_pio4_set_b_periph(AT91_PIO_PORTB, 2, 0);  /* RE */
        atmel_pio4_set_b_periph(AT91_PIO_PORTA, 30, 0); /* WE */
-       atmel_pio4_set_b_periph(AT91_PIO_PORTA, 31, 1); /* NCS */
-       atmel_pio4_set_b_periph(AT91_PIO_PORTC, 8, 1);  /* RDY */
-       atmel_pio4_set_b_periph(AT91_PIO_PORTB, 0, 1);  /* ALE */
-       atmel_pio4_set_b_periph(AT91_PIO_PORTB, 1, 1);  /* CLE */
+       atmel_pio4_set_b_periph(AT91_PIO_PORTA, 31, ATMEL_PIO_PUEN_MASK);       /* NCS */
+       atmel_pio4_set_b_periph(AT91_PIO_PORTC, 8, ATMEL_PIO_PUEN_MASK);        /* RDY */
+       atmel_pio4_set_b_periph(AT91_PIO_PORTB, 0, ATMEL_PIO_PUEN_MASK);        /* ALE */
+       atmel_pio4_set_b_periph(AT91_PIO_PORTB, 1, ATMEL_PIO_PUEN_MASK);        /* CLE */
 }
 #endif
 
 static void board_usb_hw_init(void)
 {
-       atmel_pio4_set_pio_output(AT91_PIO_PORTB, 12, 1);
+       atmel_pio4_set_pio_output(AT91_PIO_PORTB, 12, ATMEL_PIO_PUEN_MASK);
 }
 
 #ifdef CONFIG_DEBUG_UART_BOARD_INIT
 static void board_uart0_hw_init(void)
 {
-       atmel_pio4_set_c_periph(AT91_PIO_PORTB, 26, 1); /* URXD0 */
+       atmel_pio4_set_c_periph(AT91_PIO_PORTB, 26, ATMEL_PIO_PUEN_MASK);       /* URXD0 */
        atmel_pio4_set_c_periph(AT91_PIO_PORTB, 27, 0); /* UTXD0 */
 
        at91_periph_clk_enable(ATMEL_ID_UART0);
index 0ae2e2fec66efe67e468b01f6a707d8e62f5774c..592b4d82dd6b2e4a10d66be0e0d96b4b0d30649d 100644 (file)
@@ -35,7 +35,7 @@ int board_late_init(void)
 #ifdef CONFIG_DEBUG_UART_BOARD_INIT
 static void board_uart1_hw_init(void)
 {
-       atmel_pio4_set_a_periph(AT91_PIO_PORTD, 2, 1);  /* URXD1 */
+       atmel_pio4_set_a_periph(AT91_PIO_PORTD, 2, ATMEL_PIO_PUEN_MASK);        /* URXD1 */
        atmel_pio4_set_a_periph(AT91_PIO_PORTD, 3, 0);  /* UTXD1 */
 
        at91_periph_clk_enable(ATMEL_ID_UART1);
index 43240317caded2c537c27322370b6f4ec687d4e3..ae49b8247156cdcfe5a5d6e19e1748515696ec88 100644 (file)
@@ -1445,6 +1445,20 @@ config CMD_HASH
          saved to memory or to an environment variable. It is also possible
          to verify a hash against data in memory.
 
+config CMD_HVC
+       bool "Support the 'hvc' command"
+       depends on ARM_SMCCC
+       help
+         Allows issuing Hypervisor Calls (HVCs). Mostly useful for
+         development and testing.
+
+config CMD_SMC
+       bool "Support the 'smc' command"
+       depends on ARM_SMCCC
+       help
+         Allows issuing Secure Monitor Calls (SMCs). Mostly useful for
+         development and testing.
+
 config HASH_VERIFY
        bool "hash -v"
        depends on CMD_HASH
index 9695309cc2b7369bd3333a55d152ae697437945f..d7349023a4408665e1c557098714d6a42023f0d2 100644 (file)
@@ -60,6 +60,7 @@ obj-$(CONFIG_CMD_FS_GENERIC) += fs.o
 obj-$(CONFIG_CMD_FUSE) += fuse.o
 obj-$(CONFIG_CMD_GETTIME) += gettime.o
 obj-$(CONFIG_CMD_GPIO) += gpio.o
+obj-$(CONFIG_CMD_HVC) += smccc.o
 obj-$(CONFIG_CMD_I2C) += i2c.o
 obj-$(CONFIG_CMD_IOTRACE) += iotrace.o
 obj-$(CONFIG_CMD_HASH) += hash.o
@@ -112,6 +113,7 @@ obj-$(CONFIG_CMD_SHA1SUM) += sha1sum.o
 obj-$(CONFIG_CMD_SETEXPR) += setexpr.o
 obj-$(CONFIG_CMD_SPI) += spi.o
 obj-$(CONFIG_CMD_STRINGS) += strings.o
+obj-$(CONFIG_CMD_SMC) += smccc.o
 obj-$(CONFIG_CMD_TERMINAL) += terminal.o
 obj-$(CONFIG_CMD_TIME) += time.o
 obj-$(CONFIG_CMD_TRACE) += trace.o
index 5a0b0f660754c4b4ef72223967b9181cb971791c..68bbf1f51353e6ffa496e75e8ff2d96aea031252 100644 (file)
--- a/cmd/mmc.c
+++ b/cmd/mmc.c
@@ -8,6 +8,8 @@
 #include <command.h>
 #include <console.h>
 #include <mmc.h>
+#include <sparse_format.h>
+#include <image-sparse.h>
 
 static int curr_device = -1;
 
@@ -307,6 +309,71 @@ static int do_mmc_read(cmd_tbl_t *cmdtp, int flag,
 }
 
 #if CONFIG_IS_ENABLED(MMC_WRITE)
+#if defined(CONFIG_FASTBOOT_FLASH)
+static lbaint_t mmc_sparse_write(struct sparse_storage *info, lbaint_t blk,
+                                lbaint_t blkcnt, const void *buffer)
+{
+       struct blk_desc *dev_desc = info->priv;
+
+       return blk_dwrite(dev_desc, blk, blkcnt, buffer);
+}
+
+static lbaint_t mmc_sparse_reserve(struct sparse_storage *info,
+                                  lbaint_t blk, lbaint_t blkcnt)
+{
+       return blkcnt;
+}
+
+static int do_mmc_sparse_write(cmd_tbl_t *cmdtp, int flag,
+                              int argc, char * const argv[])
+{
+       struct sparse_storage sparse;
+       struct blk_desc *dev_desc;
+       struct mmc *mmc;
+       char dest[11];
+       void *addr;
+       u32 blk;
+
+       if (argc != 3)
+               return CMD_RET_USAGE;
+
+       addr = (void *)simple_strtoul(argv[1], NULL, 16);
+       blk = simple_strtoul(argv[2], NULL, 16);
+
+       if (!is_sparse_image(addr)) {
+               printf("Not a sparse image\n");
+               return CMD_RET_FAILURE;
+       }
+
+       mmc = init_mmc_device(curr_device, false);
+       if (!mmc)
+               return CMD_RET_FAILURE;
+
+       printf("\nMMC Sparse write: dev # %d, block # %d ... ",
+              curr_device, blk);
+
+       if (mmc_getwp(mmc) == 1) {
+               printf("Error: card is write protected!\n");
+               return CMD_RET_FAILURE;
+       }
+
+       dev_desc = mmc_get_blk_desc(mmc);
+       sparse.priv = dev_desc;
+       sparse.blksz = 512;
+       sparse.start = blk;
+       sparse.size = dev_desc->lba - blk;
+       sparse.write = mmc_sparse_write;
+       sparse.reserve = mmc_sparse_reserve;
+       sparse.mssg = NULL;
+       sprintf(dest, "0x" LBAF, sparse.start * sparse.blksz);
+
+       if (write_sparse_image(&sparse, dest, addr))
+               return CMD_RET_FAILURE;
+       else
+               return CMD_RET_SUCCESS;
+}
+#endif
+
 static int do_mmc_write(cmd_tbl_t *cmdtp, int flag,
                        int argc, char * const argv[])
 {
@@ -801,6 +868,9 @@ static cmd_tbl_t cmd_mmc[] = {
        U_BOOT_CMD_MKENT(read, 4, 1, do_mmc_read, "", ""),
 #if CONFIG_IS_ENABLED(MMC_WRITE)
        U_BOOT_CMD_MKENT(write, 4, 0, do_mmc_write, "", ""),
+#if defined(CONFIG_FASTBOOT_FLASH)
+       U_BOOT_CMD_MKENT(swrite, 3, 0, do_mmc_sparse_write, "", ""),
+#endif
        U_BOOT_CMD_MKENT(erase, 3, 0, do_mmc_erase, "", ""),
 #endif
        U_BOOT_CMD_MKENT(rescan, 1, 1, do_mmc_rescan, "", ""),
@@ -857,6 +927,9 @@ U_BOOT_CMD(
        "info - display info of the current MMC device\n"
        "mmc read addr blk# cnt\n"
        "mmc write addr blk# cnt\n"
+#if defined(CONFIG_FASTBOOT_FLASH)
+       "mmc swrite addr blk#\n"
+#endif
        "mmc erase blk# cnt\n"
        "mmc rescan\n"
        "mmc part - lists available partition on current mmc device\n"
diff --git a/cmd/smccc.c b/cmd/smccc.c
new file mode 100644 (file)
index 0000000..8b1475c
--- /dev/null
@@ -0,0 +1,71 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2018
+ * Michalis Pappas <mpappas@fastmail.fm>
+ */
+#include <asm/psci.h>
+#include <common.h>
+#include <command.h>
+#include <linux/arm-smccc.h>
+#include <linux/compiler.h>
+#include <linux/psci.h>
+
+static int do_call(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+       struct arm_smccc_res res;
+
+       unsigned long fid;
+
+       unsigned long a1;
+       unsigned long a2;
+       unsigned long a3;
+       unsigned long a4;
+       unsigned long a5;
+       unsigned long a6;
+       unsigned long a7;
+
+       if (argc < 2)
+               return CMD_RET_USAGE;
+
+       fid = simple_strtoul(argv[1], NULL, 16);
+
+       a1 = argc > 2 ? simple_strtoul(argv[2], NULL, 16) : 0;
+       a2 = argc > 3 ? simple_strtoul(argv[3], NULL, 16) : 0;
+       a3 = argc > 4 ? simple_strtoul(argv[4], NULL, 16) : 0;
+       a4 = argc > 5 ? simple_strtoul(argv[5], NULL, 16) : 0;
+       a5 = argc > 6 ? simple_strtoul(argv[6], NULL, 16) : 0;
+       a6 = argc > 7 ? simple_strtoul(argv[7], NULL, 16) : 0;
+       a7 = argc > 8 ? simple_strtoul(argv[8], NULL, 16) : 0;
+
+       if (!strcmp(argv[0], "smc"))
+               arm_smccc_smc(fid, a1, a2, a3, a4, a5, a6, a7, &res);
+       else
+               arm_smccc_hvc(fid, a1, a2, a3, a4, a5, a6, a7, &res);
+
+       printf("Res:  %ld %ld %ld %ld\n", res.a0, res.a1, res.a2, res.a3);
+
+       return 0;
+}
+
+#ifdef CONFIG_CMD_SMC
+U_BOOT_CMD(
+       smc,    8,              2,      do_call,
+       "Issue a Secure Monitor Call",
+       "<fid> [arg1 ... arg6] [id]\n"
+       "  - fid Function ID\n"
+       "  - arg SMC arguments, passed to X1-X6 (default to zero)\n"
+       "  - id  Secure OS ID / Session ID, passed to W7 (defaults to zero)\n"
+);
+#endif
+
+#ifdef CONFIG_CMD_HVC
+U_BOOT_CMD(
+       hvc,    8,              2,      do_call,
+       "Issue a Hypervisor Call",
+       "<fid> [arg1...arg7] [id]\n"
+       "  - fid Function ID\n"
+       "  - arg HVC arguments, passed to X1-X6 (default to zero)\n"
+       "  - id  Session ID, passed to W7 (defaults to zero)\n"
+);
+#endif
+
index b748b15f63819d077d7485dd6004b5769c8a7f9c..46f0073dbc239d8c9e3294e914a354ffadbfe719 100644 (file)
@@ -329,6 +329,7 @@ void fb_mmc_flash_write(const char *cmd, void *download_buffer,
        if (is_sparse_image(download_buffer)) {
                struct fb_mmc_sparse sparse_priv;
                struct sparse_storage sparse;
+               int err;
 
                sparse_priv.dev_desc = dev_desc;
 
@@ -337,13 +338,15 @@ void fb_mmc_flash_write(const char *cmd, void *download_buffer,
                sparse.size = info.size;
                sparse.write = fb_mmc_sparse_write;
                sparse.reserve = fb_mmc_sparse_reserve;
+               sparse.mssg = fastboot_fail;
 
                printf("Flashing sparse image at offset " LBAFU "\n",
                       sparse.start);
 
                sparse.priv = &sparse_priv;
-               write_sparse_image(&sparse, cmd, download_buffer,
-                                  download_bytes);
+               err = write_sparse_image(&sparse, cmd, download_buffer);
+               if (!err)
+                       fastboot_okay("");
        } else {
                write_raw_image(dev_desc, &info, cmd, download_buffer,
                                download_bytes);
index 3df0f7287e1609e38b33905dae07c2effd1bb1b8..c07655e49ed8ec10d6143b165855f70b55494d55 100644 (file)
@@ -174,13 +174,15 @@ void fb_nand_flash_write(const char *cmd, void *download_buffer,
                sparse.size = part->size / sparse.blksz;
                sparse.write = fb_nand_sparse_write;
                sparse.reserve = fb_nand_sparse_reserve;
+               sparse.mssg = fastboot_fail;
 
                printf("Flashing sparse image at offset " LBAFU "\n",
                       sparse.start);
 
                sparse.priv = &sparse_priv;
-               write_sparse_image(&sparse, cmd, download_buffer,
-                                  download_bytes);
+               ret = write_sparse_image(&sparse, cmd, download_buffer);
+               if (!ret)
+                       fastboot_okay("");
        } else {
                printf("Flashing raw image at offset 0x%llx\n",
                       part->offset);
index ddf5772cf825ca6ae2f74542491b5e0ae9e76235..9223b9a1b86ce222068e27fe2cc8a90abd83c7ce 100644 (file)
@@ -41,7 +41,6 @@
 #include <malloc.h>
 #include <part.h>
 #include <sparse_format.h>
-#include <fastboot.h>
 
 #include <linux/math64.h>
 
 #define CONFIG_FASTBOOT_FLASH_FILLBUF_SIZE (1024 * 512)
 #endif
 
-void write_sparse_image(
-               struct sparse_storage *info, const char *part_name,
-               void *data, unsigned sz)
+static void default_log(const char *ignored) {}
+
+int write_sparse_image(struct sparse_storage *info,
+                      const char *part_name, void *data)
 {
        lbaint_t blk;
        lbaint_t blkcnt;
@@ -83,6 +83,9 @@ void write_sparse_image(
                data += (sparse_header->file_hdr_sz - sizeof(sparse_header_t));
        }
 
+       if (!info->mssg)
+               info->mssg = default_log;
+
        debug("=== Sparse Image Header ===\n");
        debug("magic: 0x%x\n", sparse_header->magic);
        debug("major_version: 0x%x\n", sparse_header->major_version);
@@ -101,8 +104,8 @@ void write_sparse_image(
        if (offset) {
                printf("%s: Sparse image block size issue [%u]\n",
                       __func__, sparse_header->blk_sz);
-               fastboot_fail("sparse image block size issue");
-               return;
+               info->mssg("sparse image block size issue");
+               return -1;
        }
 
        puts("Flashing Sparse Image\n");
@@ -136,18 +139,16 @@ void write_sparse_image(
                case CHUNK_TYPE_RAW:
                        if (chunk_header->total_sz !=
                            (sparse_header->chunk_hdr_sz + chunk_data_sz)) {
-                               fastboot_fail(
-                                       "Bogus chunk size for chunk type Raw");
-                               return;
+                               info->mssg("Bogus chunk size for chunk type Raw");
+                               return -1;
                        }
 
                        if (blk + blkcnt > info->start + info->size) {
                                printf(
                                    "%s: Request would exceed partition size!\n",
                                    __func__);
-                               fastboot_fail(
-                                   "Request would exceed partition size!");
-                               return;
+                               info->mssg("Request would exceed partition size!");
+                               return -1;
                        }
 
                        blks = info->write(info, blk, blkcnt, data);
@@ -156,9 +157,8 @@ void write_sparse_image(
                                printf("%s: %s" LBAFU " [" LBAFU "]\n",
                                       __func__, "Write failed, block #",
                                       blk, blks);
-                               fastboot_fail(
-                                             "flash write failure");
-                               return;
+                               info->mssg("flash write failure");
+                               return -1;
                        }
                        blk += blks;
                        bytes_written += blkcnt * info->blksz;
@@ -169,9 +169,8 @@ void write_sparse_image(
                case CHUNK_TYPE_FILL:
                        if (chunk_header->total_sz !=
                            (sparse_header->chunk_hdr_sz + sizeof(uint32_t))) {
-                               fastboot_fail(
-                                       "Bogus chunk size for chunk type FILL");
-                               return;
+                               info->mssg("Bogus chunk size for chunk type FILL");
+                               return -1;
                        }
 
                        fill_buf = (uint32_t *)
@@ -180,9 +179,8 @@ void write_sparse_image(
                                                info->blksz * fill_buf_num_blks,
                                                ARCH_DMA_MINALIGN));
                        if (!fill_buf) {
-                               fastboot_fail(
-                                       "Malloc failed for: CHUNK_TYPE_FILL");
-                               return;
+                               info->mssg("Malloc failed for: CHUNK_TYPE_FILL");
+                               return -1;
                        }
 
                        fill_val = *(uint32_t *)data;
@@ -198,9 +196,8 @@ void write_sparse_image(
                                printf(
                                    "%s: Request would exceed partition size!\n",
                                    __func__);
-                               fastboot_fail(
-                                   "Request would exceed partition size!");
-                               return;
+                               info->mssg("Request would exceed partition size!");
+                               return -1;
                        }
 
                        for (i = 0; i < blkcnt;) {
@@ -214,10 +211,9 @@ void write_sparse_image(
                                               __func__,
                                               "Write failed, block #",
                                               blk, j);
-                                       fastboot_fail(
-                                                     "flash write failure");
+                                       info->mssg("flash write failure");
                                        free(fill_buf);
-                                       return;
+                                       return -1;
                                }
                                blk += blks;
                                i += j;
@@ -235,9 +231,8 @@ void write_sparse_image(
                case CHUNK_TYPE_CRC32:
                        if (chunk_header->total_sz !=
                            sparse_header->chunk_hdr_sz) {
-                               fastboot_fail(
-                                       "Bogus chunk size for chunk type Dont Care");
-                               return;
+                               info->mssg("Bogus chunk size for chunk type Dont Care");
+                               return -1;
                        }
                        total_blocks += chunk_header->chunk_sz;
                        data += chunk_data_sz;
@@ -246,8 +241,8 @@ void write_sparse_image(
                default:
                        printf("%s: Unknown chunk type: %x\n", __func__,
                               chunk_header->chunk_type);
-                       fastboot_fail("Unknown chunk type");
-                       return;
+                       info->mssg("Unknown chunk type");
+                       return -1;
                }
        }
 
@@ -255,10 +250,10 @@ void write_sparse_image(
              total_blocks, sparse_header->total_blks);
        printf("........ wrote %u bytes to '%s'\n", bytes_written, part_name);
 
-       if (total_blocks != sparse_header->total_blks)
-               fastboot_fail("sparse image write failure");
-       else
-               fastboot_okay("");
+       if (total_blocks != sparse_header->total_blks) {
+               info->mssg("sparse image write failure");
+               return -1;
+       }
 
-       return;
+       return 0;
 }
index 7a52c10181fb1f58ada2c917f93a7f7f60ae349e..9c3c57806d25ae342abbaadbbab2b1aa7a682d1b 100644 (file)
@@ -7,7 +7,7 @@ CONFIG_DEFAULT_DEVICE_TREE="at91-sama5d2_ptc_ek"
 CONFIG_DEBUG_UART=y
 CONFIG_ENV_VARS_UBOOT_CONFIG=y
 CONFIG_FIT=y
-CONFIG_SYS_EXTRA_OPTIONS="SAMA5D2,SYS_USE_MMC"
+CONFIG_SYS_EXTRA_OPTIONS="SAMA5D2"
 CONFIG_SD_BOOT=y
 CONFIG_BOOTDELAY=3
 CONFIG_CONSOLE_MUX=y
index 2739001cf11e7896e29df6467d185c59c3e7d98b..94d5492f99002bd5e4c6aded574f381b42fe10a3 100644 (file)
@@ -7,7 +7,7 @@ CONFIG_DEFAULT_DEVICE_TREE="at91-sama5d2_ptc_ek"
 CONFIG_DEBUG_UART=y
 CONFIG_ENV_VARS_UBOOT_CONFIG=y
 CONFIG_FIT=y
-CONFIG_SYS_EXTRA_OPTIONS="SAMA5D2,SYS_USE_NANDFLASH"
+CONFIG_SYS_EXTRA_OPTIONS="SAMA5D2"
 CONFIG_NAND_BOOT=y
 CONFIG_BOOTDELAY=3
 CONFIG_CONSOLE_MUX=y
index de777658eb04cd068eae0288bc9a320e846e2880..afe29c6fbcedb004a5d9fae99609aacd3042e3c8 100644 (file)
@@ -10,7 +10,7 @@ CONFIG_FIT=y
 CONFIG_NAND_BOOT=y
 CONFIG_BOOTDELAY=3
 CONFIG_USE_BOOTARGS=y
-CONFIG_BOOTARGS="console=ttyS0,115200 earlyprintk mtdparts=atmel_nand:256k(bootstrap)ro,512k(uboot)ro,256K(env),256k(env_redundant),256k(spare),512k(dtb),6M(kernel)ro,-(rootfs) rootfstype=ubifs ubi.mtd=7 root=ubi0:rootfs"
+CONFIG_BOOTARGS="console=ttyS0,115200 earlyprintk mtdparts=atmel_nand:256k(bootstrap)ro,768k(uboot)ro,256K(env_redundant),256k(env),512k(dtb),6M(kernel)ro,-(rootfs) rootfstype=ubifs ubi.mtd=6 root=ubi0:rootfs"
 # CONFIG_CONSOLE_MUX is not set
 CONFIG_SYS_CONSOLE_IS_IN_ENV=y
 # CONFIG_DISPLAY_BOARDINFO is not set
index 272c370a453fd7447fd4b6ed1e2a63298bc12ced..7c8668ec6928d41187054c0f6cedbe952417a7d7 100644 (file)
@@ -10,7 +10,7 @@ CONFIG_FIT=y
 CONFIG_SPI_BOOT=y
 CONFIG_BOOTDELAY=3
 CONFIG_USE_BOOTARGS=y
-CONFIG_BOOTARGS="console=ttyS0,115200 earlyprintk mtdparts=atmel_nand:256k(bootstrap)ro,512k(uboot)ro,256K(env),256k(env_redundant),256k(spare),512k(dtb),6M(kernel)ro,-(rootfs) rootfstype=ubifs ubi.mtd=7 root=ubi0:rootfs"
+CONFIG_BOOTARGS="console=ttyS0,115200 earlyprintk mtdparts=atmel_nand:256k(bootstrap)ro,768k(uboot)ro,256K(env_redundant),256k(env),512k(dtb),6M(kernel)ro,-(rootfs) rootfstype=ubifs ubi.mtd=6 root=ubi0:rootfs"
 # CONFIG_CONSOLE_MUX is not set
 CONFIG_SYS_CONSOLE_IS_IN_ENV=y
 # CONFIG_DISPLAY_BOARDINFO is not set
index 2468df914bc88ec4a340f6008a82bcf96e3be25e..62716b6c4de9967c5c67a8a6c658382e52146b09 100644 (file)
@@ -17,7 +17,7 @@ CONFIG_FIT=y
 CONFIG_NAND_BOOT=y
 CONFIG_BOOTDELAY=3
 CONFIG_USE_BOOTARGS=y
-CONFIG_BOOTARGS="console=ttyS0,115200 earlyprintk mtdparts=atmel_nand:256k(bootstrap)ro,512k(uboot)ro,256K(env),256k(env_redundant),256k(spare),512k(dtb),6M(kernel)ro,-(rootfs) rootfstype=ubifs ubi.mtd=7 root=ubi0:rootfs"
+CONFIG_BOOTARGS="console=ttyS0,115200 earlyprintk mtdparts=atmel_nand:256k(bootstrap)ro,768k(uboot)ro,256K(env_redundant),256k(env),512k(dtb),6M(kernel)ro,-(rootfs) rootfstype=ubifs ubi.mtd=6 root=ubi0:rootfs"
 # CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_HUSH_PARSER=y
 CONFIG_CMD_BOOTZ=y
index 122668cb79b0e890db9eddd05273bd7b192c503a..d71ccd42e56273ef0d6c319e31543f6f2547607b 100644 (file)
@@ -17,7 +17,7 @@ CONFIG_FIT=y
 CONFIG_NAND_BOOT=y
 CONFIG_BOOTDELAY=3
 CONFIG_USE_BOOTARGS=y
-CONFIG_BOOTARGS="console=ttyS0,115200 earlyprintk mtdparts=atmel_nand:256k(bootstrap)ro,512k(uboot)ro,256K(env),256k(env_redundant),256k(spare),512k(dtb),6M(kernel)ro,-(rootfs) rootfstype=ubifs ubi.mtd=7 root=ubi0:rootfs"
+CONFIG_BOOTARGS="console=ttyS0,115200 earlyprintk mtdparts=atmel_nand:256k(bootstrap)ro,768k(uboot)ro,256K(env_redundant),256k(env),512k(dtb),6M(kernel)ro,-(rootfs) rootfstype=ubifs ubi.mtd=6 root=ubi0:rootfs"
 # CONFIG_CONSOLE_MUX is not set
 CONFIG_SYS_CONSOLE_IS_IN_ENV=y
 # CONFIG_DISPLAY_BOARDINFO is not set
index b1c2f57e81599480997c46ba190e617b5b526cb3..9c36262976384ecd00c5cceb0c50fa5bcf0a166d 100644 (file)
@@ -18,7 +18,7 @@ CONFIG_FIT=y
 CONFIG_SPI_BOOT=y
 CONFIG_BOOTDELAY=3
 CONFIG_USE_BOOTARGS=y
-CONFIG_BOOTARGS="console=ttyS0,115200 earlyprintk mtdparts=atmel_nand:256k(bootstrap)ro,512k(uboot)ro,256K(env),256k(env_redundant),256k(spare),512k(dtb),6M(kernel)ro,-(rootfs) rootfstype=ubifs ubi.mtd=7 root=ubi0:rootfs"
+CONFIG_BOOTARGS="console=ttyS0,115200 earlyprintk mtdparts=atmel_nand:256k(bootstrap)ro,768k(uboot)ro,256K(env_redundant),256k(env),512k(dtb),6M(kernel)ro,-(rootfs) rootfstype=ubifs ubi.mtd=6 root=ubi0:rootfs"
 # CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_SPL_SPI_LOAD=y
 CONFIG_HUSH_PARSER=y
index 478be7d72066db29d7077cbd8dfa507c19c6f9b0..d4f8702e56c8cff99b769a8c2260973150cc1c67 100644 (file)
@@ -17,7 +17,7 @@ CONFIG_FIT=y
 CONFIG_NAND_BOOT=y
 CONFIG_BOOTDELAY=3
 CONFIG_USE_BOOTARGS=y
-CONFIG_BOOTARGS="console=ttyS0,115200 earlyprintk mtdparts=atmel_nand:256k(bootstrap)ro,512k(uboot)ro,256K(env),256k(env_redundant),256k(spare),512k(dtb),6M(kernel)ro,-(rootfs) rootfstype=ubifs ubi.mtd=7 root=ubi0:rootfs"
+CONFIG_BOOTARGS="console=ttyS0,115200 earlyprintk mtdparts=atmel_nand:256k(bootstrap)ro,768k(uboot)ro,256K(env_redundant),256k(env),512k(dtb),6M(kernel)ro,-(rootfs) rootfstype=ubifs ubi.mtd=6 root=ubi0:rootfs"
 # CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_HUSH_PARSER=y
 CONFIG_CMD_BOOTZ=y
index 96c0a3171e10b9a2e7e952afd2cbe33acf6e81f7..2dd4c685d6f083396754d287062a0bd8a930781f 100644 (file)
@@ -18,7 +18,7 @@ CONFIG_FIT=y
 CONFIG_SPI_BOOT=y
 CONFIG_BOOTDELAY=3
 CONFIG_USE_BOOTARGS=y
-CONFIG_BOOTARGS="console=ttyS0,115200 earlyprintk mtdparts=atmel_nand:256k(bootstrap)ro,512k(uboot)ro,256K(env),256k(env_redundant),256k(spare),512k(dtb),6M(kernel)ro,-(rootfs) rootfstype=ubifs ubi.mtd=7 root=ubi0:rootfs"
+CONFIG_BOOTARGS="console=ttyS0,115200 earlyprintk mtdparts=atmel_nand:256k(bootstrap)ro,768k(uboot)ro,256K(env_redundant),256k(env),512k(dtb),6M(kernel)ro,-(rootfs) rootfstype=ubifs ubi.mtd=6 root=ubi0:rootfs"
 # CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_SPL_SPI_LOAD=y
 CONFIG_HUSH_PARSER=y
index e1e7466b21258ae1e84d0c38a5bf29bafc740ef1..df4a0dbb93b989952f30bc9b4b58d7657ce096ca 100644 (file)
@@ -17,7 +17,7 @@ CONFIG_FIT=y
 CONFIG_NAND_BOOT=y
 CONFIG_BOOTDELAY=3
 CONFIG_USE_BOOTARGS=y
-CONFIG_BOOTARGS="console=ttyS0,115200 earlyprintk mtdparts=atmel_nand:256k(bootstrap)ro,512k(uboot)ro,256K(env),256k(env_redundant),256k(spare),512k(dtb),6M(kernel)ro,-(rootfs) rootfstype=ubifs ubi.mtd=7 root=ubi0:rootfs"
+CONFIG_BOOTARGS="console=ttyS0,115200 earlyprintk mtdparts=atmel_nand:256k(bootstrap)ro,768k(uboot)ro,256K(env_redundant),256k(env),512k(dtb),6M(kernel)ro,-(rootfs) rootfstype=ubifs ubi.mtd=6 root=ubi0:rootfs"
 # CONFIG_CONSOLE_MUX is not set
 CONFIG_SYS_CONSOLE_IS_IN_ENV=y
 # CONFIG_DISPLAY_BOARDINFO is not set
index 84ed7bc47f668c490a655b9038e4c21d4da38fed..0fc9c4e8f663e792301f95a26682304d8a09d293 100644 (file)
@@ -18,7 +18,7 @@ CONFIG_FIT=y
 CONFIG_SPI_BOOT=y
 CONFIG_BOOTDELAY=3
 CONFIG_USE_BOOTARGS=y
-CONFIG_BOOTARGS="console=ttyS0,115200 earlyprintk mtdparts=atmel_nand:256k(bootstrap)ro,512k(uboot)ro,256K(env),256k(env_redundant),256k(spare),512k(dtb),6M(kernel)ro,-(rootfs) rootfstype=ubifs ubi.mtd=7 root=ubi0:rootfs"
+CONFIG_BOOTARGS="console=ttyS0,115200 earlyprintk mtdparts=atmel_nand:256k(bootstrap)ro,768k(uboot)ro,256K(env_redundant),256k(env),512k(dtb),6M(kernel)ro,-(rootfs) rootfstype=ubifs ubi.mtd=6 root=ubi0:rootfs"
 # CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_SPL_SPI_LOAD=y
 CONFIG_HUSH_PARSER=y
index 46790bbe0eead93f1f879dea8d6a50b4398cd61b..b1c3690c009437770c92b3bf335e9a6069a14ee2 100644 (file)
@@ -23,6 +23,7 @@ CONFIG_CMD_GPT=y
 CONFIG_CMD_I2C=y
 CONFIG_CMD_MMC=y
 CONFIG_CMD_PMIC=y
+CONFIG_CMD_REGULATOR=y
 CONFIG_CMD_EXT4_WRITE=y
 # CONFIG_SPL_DOS_PARTITION is not set
 CONFIG_DM_I2C=y
@@ -31,6 +32,11 @@ CONFIG_DM_MMC=y
 CONFIG_STM32_SDMMC2=y
 # CONFIG_SPL_PINCTRL_FULL is not set
 CONFIG_DM_PMIC=y
+# CONFIG_SPL_PMIC_CHILDREN is not set
 CONFIG_PMIC_STPMU1=y
+CONFIG_DM_REGULATOR=y
+CONFIG_DM_REGULATOR_GPIO=y
+CONFIG_DM_REGULATOR_STM32_VREFBUF=y
+CONFIG_DM_REGULATOR_STPMU1=y
 CONFIG_STM32_SERIAL=y
 # CONFIG_EFI_LOADER is not set
index b7294a368bc9da8e2c8de2b03e9a4a5590cb8676..cb7680a0c62d305aeb331c57671515c275db72f1 100644 (file)
@@ -43,6 +43,7 @@ CONFIG_NETDEVICES=y
 CONFIG_SMC911X=y
 CONFIG_SMC911X_BASE=0x0
 CONFIG_SMC911X_32_BIT=y
+CONFIG_PINCONF=y
 CONFIG_SYSRESET=y
 CONFIG_SYSRESET_PSCI=y
 CONFIG_USB=y
diff --git a/doc/device-tree-bindings/regulator/st,stm32-vrefbuf.txt b/doc/device-tree-bindings/regulator/st,stm32-vrefbuf.txt
new file mode 100644 (file)
index 0000000..0f6b6fe
--- /dev/null
@@ -0,0 +1,23 @@
+STM32 VREFBUF - Voltage reference buffer
+
+Some STM32 devices embed a voltage reference buffer which can be used as
+voltage reference for ADCs, DACs and also as voltage reference for external
+components through the dedicated VREF+ pin.
+
+Required properties:
+- compatible:          Must be "st,stm32-vrefbuf".
+- reg:                 Offset and length of VREFBUF register set.
+- clocks:              Must contain an entry for peripheral clock.
+
+Optional properties:
+- vdda-supply:         Phandle to the parent vdda supply regulator node.
+
+Example:
+       vrefbuf: regulator@58003c00 {
+               compatible = "st,stm32-vrefbuf";
+               reg = <0x58003C00 0x8>;
+               clocks = <&rcc VREF_CK>;
+               regulator-min-microvolt = <1500000>;
+               regulator-max-microvolt = <2500000>;
+               vdda-supply = <&vdda>;
+       };
index 80944205481eda28702f3b586b19c42f7f9e7eab..93e27f131cab01e1678e6988975b2f15f19956aa 100644 (file)
@@ -29,6 +29,16 @@ config ADC_SANDBOX
          - 16-bit resolution
          - single and multi-channel conversion mode
 
+config SARADC_MESON
+       bool "Enable Amlogic Meson SARADC driver"
+       imply REGMAP
+       help
+         This enables driver for Amlogic Meson SARADC.
+         It provides:
+         - 8 analog input channels
+         - 1O or 12 bits resolution
+         - Up to 1MSPS of sample rate
+
 config SARADC_ROCKCHIP
        bool "Enable Rockchip SARADC driver"
        help
index 4b5aa693ec1d12618339fc75432cf8f79d1d465d..95c93d4c57a1218769495f453e7bcd623c66a994 100644 (file)
@@ -9,3 +9,4 @@ obj-$(CONFIG_ADC) += adc-uclass.o
 obj-$(CONFIG_ADC_EXYNOS) += exynos-adc.o
 obj-$(CONFIG_ADC_SANDBOX) += sandbox.o
 obj-$(CONFIG_SARADC_ROCKCHIP) += rockchip-saradc.o
+obj-$(CONFIG_SARADC_MESON) += meson-saradc.o
diff --git a/drivers/adc/meson-saradc.c b/drivers/adc/meson-saradc.c
new file mode 100644 (file)
index 0000000..bcab76d
--- /dev/null
@@ -0,0 +1,723 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2017 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+ * Copyright (C) 2018 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * Amlogic Meson Successive Approximation Register (SAR) A/D Converter
+ */
+
+#include <common.h>
+#include <adc.h>
+#include <clk.h>
+#include <dm.h>
+#include <regmap.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <linux/math64.h>
+#include <linux/bitfield.h>
+
+#define MESON_SAR_ADC_REG0                                     0x00
+       #define MESON_SAR_ADC_REG0_PANEL_DETECT                 BIT(31)
+       #define MESON_SAR_ADC_REG0_BUSY_MASK                    GENMASK(30, 28)
+       #define MESON_SAR_ADC_REG0_DELTA_BUSY                   BIT(30)
+       #define MESON_SAR_ADC_REG0_AVG_BUSY                     BIT(29)
+       #define MESON_SAR_ADC_REG0_SAMPLE_BUSY                  BIT(28)
+       #define MESON_SAR_ADC_REG0_FIFO_FULL                    BIT(27)
+       #define MESON_SAR_ADC_REG0_FIFO_EMPTY                   BIT(26)
+       #define MESON_SAR_ADC_REG0_FIFO_COUNT_MASK              GENMASK(25, 21)
+       #define MESON_SAR_ADC_REG0_ADC_BIAS_CTRL_MASK           GENMASK(20, 19)
+       #define MESON_SAR_ADC_REG0_CURR_CHAN_ID_MASK            GENMASK(18, 16)
+       #define MESON_SAR_ADC_REG0_ADC_TEMP_SEN_SEL             BIT(15)
+       #define MESON_SAR_ADC_REG0_SAMPLING_STOP                BIT(14)
+       #define MESON_SAR_ADC_REG0_CHAN_DELTA_EN_MASK           GENMASK(13, 12)
+       #define MESON_SAR_ADC_REG0_DETECT_IRQ_POL               BIT(10)
+       #define MESON_SAR_ADC_REG0_DETECT_IRQ_EN                BIT(9)
+       #define MESON_SAR_ADC_REG0_FIFO_CNT_IRQ_MASK            GENMASK(8, 4)
+       #define MESON_SAR_ADC_REG0_FIFO_IRQ_EN                  BIT(3)
+       #define MESON_SAR_ADC_REG0_SAMPLING_START               BIT(2)
+       #define MESON_SAR_ADC_REG0_CONTINUOUS_EN                BIT(1)
+       #define MESON_SAR_ADC_REG0_SAMPLE_ENGINE_ENABLE         BIT(0)
+
+#define MESON_SAR_ADC_CHAN_LIST                                        0x04
+       #define MESON_SAR_ADC_CHAN_LIST_MAX_INDEX_MASK          GENMASK(26, 24)
+       #define MESON_SAR_ADC_CHAN_LIST_ENTRY_MASK(_chan)       \
+                                       (GENMASK(2, 0) << ((_chan) * 3))
+
+#define MESON_SAR_ADC_AVG_CNTL                                 0x08
+       #define MESON_SAR_ADC_AVG_CNTL_AVG_MODE_SHIFT(_chan)    \
+                                       (16 + ((_chan) * 2))
+       #define MESON_SAR_ADC_AVG_CNTL_AVG_MODE_MASK(_chan)     \
+                                       (GENMASK(17, 16) << ((_chan) * 2))
+       #define MESON_SAR_ADC_AVG_CNTL_NUM_SAMPLES_SHIFT(_chan) \
+                                       (0 + ((_chan) * 2))
+       #define MESON_SAR_ADC_AVG_CNTL_NUM_SAMPLES_MASK(_chan)  \
+                                       (GENMASK(1, 0) << ((_chan) * 2))
+
+#define MESON_SAR_ADC_REG3                                     0x0c
+       #define MESON_SAR_ADC_REG3_CNTL_USE_SC_DLY              BIT(31)
+       #define MESON_SAR_ADC_REG3_CLK_EN                       BIT(30)
+       #define MESON_SAR_ADC_REG3_BL30_INITIALIZED             BIT(28)
+       #define MESON_SAR_ADC_REG3_CTRL_CONT_RING_COUNTER_EN    BIT(27)
+       #define MESON_SAR_ADC_REG3_CTRL_SAMPLING_CLOCK_PHASE    BIT(26)
+       #define MESON_SAR_ADC_REG3_CTRL_CHAN7_MUX_SEL_MASK      GENMASK(25, 23)
+       #define MESON_SAR_ADC_REG3_DETECT_EN                    BIT(22)
+       #define MESON_SAR_ADC_REG3_ADC_EN                       BIT(21)
+       #define MESON_SAR_ADC_REG3_PANEL_DETECT_COUNT_MASK      GENMASK(20, 18)
+       #define MESON_SAR_ADC_REG3_PANEL_DETECT_FILTER_TB_MASK  GENMASK(17, 16)
+       #define MESON_SAR_ADC_REG3_ADC_CLK_DIV_SHIFT            10
+       #define MESON_SAR_ADC_REG3_ADC_CLK_DIV_WIDTH            5
+       #define MESON_SAR_ADC_REG3_BLOCK_DLY_SEL_MASK           GENMASK(9, 8)
+       #define MESON_SAR_ADC_REG3_BLOCK_DLY_MASK               GENMASK(7, 0)
+
+#define MESON_SAR_ADC_DELAY                                    0x10
+       #define MESON_SAR_ADC_DELAY_INPUT_DLY_SEL_MASK          GENMASK(25, 24)
+       #define MESON_SAR_ADC_DELAY_BL30_BUSY                   BIT(15)
+       #define MESON_SAR_ADC_DELAY_KERNEL_BUSY                 BIT(14)
+       #define MESON_SAR_ADC_DELAY_INPUT_DLY_CNT_MASK          GENMASK(23, 16)
+       #define MESON_SAR_ADC_DELAY_SAMPLE_DLY_SEL_MASK         GENMASK(9, 8)
+       #define MESON_SAR_ADC_DELAY_SAMPLE_DLY_CNT_MASK         GENMASK(7, 0)
+
+#define MESON_SAR_ADC_LAST_RD                                  0x14
+       #define MESON_SAR_ADC_LAST_RD_LAST_CHANNEL1_MASK        GENMASK(23, 16)
+       #define MESON_SAR_ADC_LAST_RD_LAST_CHANNEL0_MASK        GENMASK(9, 0)
+
+#define MESON_SAR_ADC_FIFO_RD                                  0x18
+       #define MESON_SAR_ADC_FIFO_RD_CHAN_ID_MASK              GENMASK(14, 12)
+       #define MESON_SAR_ADC_FIFO_RD_SAMPLE_VALUE_MASK         GENMASK(11, 0)
+
+#define MESON_SAR_ADC_AUX_SW                                   0x1c
+       #define MESON_SAR_ADC_AUX_SW_MUX_SEL_CHAN_SHIFT(_chan)  \
+                                       (8 + (((_chan) - 2) * 3))
+       #define MESON_SAR_ADC_AUX_SW_VREF_P_MUX                 BIT(6)
+       #define MESON_SAR_ADC_AUX_SW_VREF_N_MUX                 BIT(5)
+       #define MESON_SAR_ADC_AUX_SW_MODE_SEL                   BIT(4)
+       #define MESON_SAR_ADC_AUX_SW_YP_DRIVE_SW                BIT(3)
+       #define MESON_SAR_ADC_AUX_SW_XP_DRIVE_SW                BIT(2)
+       #define MESON_SAR_ADC_AUX_SW_YM_DRIVE_SW                BIT(1)
+       #define MESON_SAR_ADC_AUX_SW_XM_DRIVE_SW                BIT(0)
+
+#define MESON_SAR_ADC_CHAN_10_SW                               0x20
+       #define MESON_SAR_ADC_CHAN_10_SW_CHAN1_MUX_SEL_MASK     GENMASK(25, 23)
+       #define MESON_SAR_ADC_CHAN_10_SW_CHAN1_VREF_P_MUX       BIT(22)
+       #define MESON_SAR_ADC_CHAN_10_SW_CHAN1_VREF_N_MUX       BIT(21)
+       #define MESON_SAR_ADC_CHAN_10_SW_CHAN1_MODE_SEL         BIT(20)
+       #define MESON_SAR_ADC_CHAN_10_SW_CHAN1_YP_DRIVE_SW      BIT(19)
+       #define MESON_SAR_ADC_CHAN_10_SW_CHAN1_XP_DRIVE_SW      BIT(18)
+       #define MESON_SAR_ADC_CHAN_10_SW_CHAN1_YM_DRIVE_SW      BIT(17)
+       #define MESON_SAR_ADC_CHAN_10_SW_CHAN1_XM_DRIVE_SW      BIT(16)
+       #define MESON_SAR_ADC_CHAN_10_SW_CHAN0_MUX_SEL_MASK     GENMASK(9, 7)
+       #define MESON_SAR_ADC_CHAN_10_SW_CHAN0_VREF_P_MUX       BIT(6)
+       #define MESON_SAR_ADC_CHAN_10_SW_CHAN0_VREF_N_MUX       BIT(5)
+       #define MESON_SAR_ADC_CHAN_10_SW_CHAN0_MODE_SEL         BIT(4)
+       #define MESON_SAR_ADC_CHAN_10_SW_CHAN0_YP_DRIVE_SW      BIT(3)
+       #define MESON_SAR_ADC_CHAN_10_SW_CHAN0_XP_DRIVE_SW      BIT(2)
+       #define MESON_SAR_ADC_CHAN_10_SW_CHAN0_YM_DRIVE_SW      BIT(1)
+       #define MESON_SAR_ADC_CHAN_10_SW_CHAN0_XM_DRIVE_SW      BIT(0)
+
+#define MESON_SAR_ADC_DETECT_IDLE_SW                           0x24
+       #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_SW_EN       BIT(26)
+       #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_MUX_MASK    GENMASK(25, 23)
+       #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_VREF_P_MUX  BIT(22)
+       #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_VREF_N_MUX  BIT(21)
+       #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_MODE_SEL    BIT(20)
+       #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_YP_DRIVE_SW BIT(19)
+       #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_XP_DRIVE_SW BIT(18)
+       #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_YM_DRIVE_SW BIT(17)
+       #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_XM_DRIVE_SW BIT(16)
+       #define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_MUX_SEL_MASK  GENMASK(9, 7)
+       #define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_VREF_P_MUX    BIT(6)
+       #define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_VREF_N_MUX    BIT(5)
+       #define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_MODE_SEL      BIT(4)
+       #define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_YP_DRIVE_SW   BIT(3)
+       #define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_XP_DRIVE_SW   BIT(2)
+       #define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_YM_DRIVE_SW   BIT(1)
+       #define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_XM_DRIVE_SW   BIT(0)
+
+#define MESON_SAR_ADC_DELTA_10                                 0x28
+       #define MESON_SAR_ADC_DELTA_10_TEMP_SEL                 BIT(27)
+       #define MESON_SAR_ADC_DELTA_10_TS_REVE1                 BIT(26)
+       #define MESON_SAR_ADC_DELTA_10_CHAN1_DELTA_VALUE_MASK   GENMASK(25, 16)
+       #define MESON_SAR_ADC_DELTA_10_TS_REVE0                 BIT(15)
+       #define MESON_SAR_ADC_DELTA_10_TS_C_SHIFT               11
+       #define MESON_SAR_ADC_DELTA_10_TS_C_MASK                GENMASK(14, 11)
+       #define MESON_SAR_ADC_DELTA_10_TS_VBG_EN                BIT(10)
+       #define MESON_SAR_ADC_DELTA_10_CHAN0_DELTA_VALUE_MASK   GENMASK(9, 0)
+
+/*
+ * NOTE: registers from here are undocumented (the vendor Linux kernel driver
+ * and u-boot source served as reference). These only seem to be relevant on
+ * GXBB and newer.
+ */
+#define MESON_SAR_ADC_REG11                                    0x2c
+       #define MESON_SAR_ADC_REG11_BANDGAP_EN                  BIT(13)
+
+#define MESON_SAR_ADC_REG13                                    0x34
+       #define MESON_SAR_ADC_REG13_12BIT_CALIBRATION_MASK      GENMASK(13, 8)
+
+#define MESON_SAR_ADC_MAX_FIFO_SIZE                            32
+#define MESON_SAR_ADC_TIMEOUT                                  100 /* ms */
+
+#define NUM_CHANNELS                                           8
+
+#define MILLION                                                        1000000
+
+struct meson_saradc_data {
+       int                             num_bits;
+};
+
+struct meson_saradc_priv {
+       const struct meson_saradc_data  *data;
+       struct regmap                   *regmap;
+       struct clk                      core_clk;
+       struct clk                      adc_clk;
+       bool                            initialized;
+       int                             active_channel;
+       int                             calibbias;
+       int                             calibscale;
+};
+
+static unsigned int
+meson_saradc_get_fifo_count(struct meson_saradc_priv *priv)
+{
+       u32 regval;
+
+       regmap_read(priv->regmap, MESON_SAR_ADC_REG0, &regval);
+
+       return FIELD_GET(MESON_SAR_ADC_REG0_FIFO_COUNT_MASK, regval);
+}
+
+static int meson_saradc_lock(struct meson_saradc_priv *priv)
+{
+       uint val, timeout = 10000;
+
+       /* prevent BL30 from using the SAR ADC while we are using it */
+       regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY,
+                          MESON_SAR_ADC_DELAY_KERNEL_BUSY,
+                          MESON_SAR_ADC_DELAY_KERNEL_BUSY);
+
+       /*
+        * wait until BL30 releases it's lock (so we can use the SAR ADC)
+        */
+       do {
+               udelay(1);
+               regmap_read(priv->regmap, MESON_SAR_ADC_DELAY, &val);
+       } while (val & MESON_SAR_ADC_DELAY_BL30_BUSY && timeout--);
+
+       if (timeout < 0) {
+               printf("Timeout while waiting for BL30 unlock\n");
+               return -ETIMEDOUT;
+       }
+
+       return 0;
+}
+
+static void meson_saradc_unlock(struct meson_saradc_priv *priv)
+{
+       /* allow BL30 to use the SAR ADC again */
+       regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY,
+                          MESON_SAR_ADC_DELAY_KERNEL_BUSY, 0);
+}
+
+static void meson_saradc_clear_fifo(struct meson_saradc_priv *priv)
+{
+       unsigned int count, tmp;
+
+       for (count = 0; count < MESON_SAR_ADC_MAX_FIFO_SIZE; count++) {
+               if (!meson_saradc_get_fifo_count(priv))
+                       break;
+
+               regmap_read(priv->regmap, MESON_SAR_ADC_FIFO_RD, &tmp);
+       }
+}
+
+static int meson_saradc_calib_val(struct meson_saradc_priv *priv, int val)
+{
+       int tmp;
+
+       /* use val_calib = scale * val_raw + offset calibration function */
+       tmp = div_s64((s64)val * priv->calibscale, MILLION) + priv->calibbias;
+
+       return clamp(tmp, 0, (1 << priv->data->num_bits) - 1);
+}
+
+static int meson_saradc_wait_busy_clear(struct meson_saradc_priv *priv)
+{
+       uint regval, timeout = 10000;
+
+       /*
+        * NOTE: we need a small delay before reading the status, otherwise
+        * the sample engine may not have started internally (which would
+        * seem to us that sampling is already finished).
+        */
+       do {
+               udelay(1);
+               regmap_read(priv->regmap, MESON_SAR_ADC_REG0, &regval);
+       } while (FIELD_GET(MESON_SAR_ADC_REG0_BUSY_MASK, regval) && timeout--);
+
+       if (timeout < 0)
+               return -ETIMEDOUT;
+
+       return 0;
+}
+
+static int meson_saradc_read_raw_sample(struct meson_saradc_priv *priv,
+                                       unsigned int channel, uint *val)
+{
+       uint regval, fifo_chan, fifo_val, count;
+       int ret;
+
+       ret = meson_saradc_wait_busy_clear(priv);
+       if (ret)
+               return ret;
+
+       count = meson_saradc_get_fifo_count(priv);
+       if (count != 1) {
+               printf("ADC FIFO has %d element(s) instead of one\n", count);
+               return -EINVAL;
+       }
+
+       regmap_read(priv->regmap, MESON_SAR_ADC_FIFO_RD, &regval);
+       fifo_chan = FIELD_GET(MESON_SAR_ADC_FIFO_RD_CHAN_ID_MASK, regval);
+       if (fifo_chan != channel) {
+               printf("ADC FIFO entry belongs to channel %d instead of %d\n",
+                      fifo_chan, channel);
+               return -EINVAL;
+       }
+
+       fifo_val = FIELD_GET(MESON_SAR_ADC_FIFO_RD_SAMPLE_VALUE_MASK, regval);
+       fifo_val &= GENMASK(priv->data->num_bits - 1, 0);
+       *val = meson_saradc_calib_val(priv, fifo_val);
+
+       return 0;
+}
+
+static void meson_saradc_start_sample_engine(struct meson_saradc_priv *priv)
+{
+       regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0,
+                          MESON_SAR_ADC_REG0_FIFO_IRQ_EN,
+                          MESON_SAR_ADC_REG0_FIFO_IRQ_EN);
+
+       regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0,
+                          MESON_SAR_ADC_REG0_SAMPLE_ENGINE_ENABLE,
+                          MESON_SAR_ADC_REG0_SAMPLE_ENGINE_ENABLE);
+
+       regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0,
+                          MESON_SAR_ADC_REG0_SAMPLING_START,
+                          MESON_SAR_ADC_REG0_SAMPLING_START);
+}
+
+static void meson_saradc_stop_sample_engine(struct meson_saradc_priv *priv)
+{
+       regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0,
+                          MESON_SAR_ADC_REG0_FIFO_IRQ_EN, 0);
+
+       regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0,
+                          MESON_SAR_ADC_REG0_SAMPLING_STOP,
+                          MESON_SAR_ADC_REG0_SAMPLING_STOP);
+
+       /* wait until all modules are stopped */
+       meson_saradc_wait_busy_clear(priv);
+
+       regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0,
+                          MESON_SAR_ADC_REG0_SAMPLE_ENGINE_ENABLE, 0);
+}
+
+enum meson_saradc_avg_mode {
+       NO_AVERAGING = 0x0,
+       MEAN_AVERAGING = 0x1,
+       MEDIAN_AVERAGING = 0x2,
+};
+
+enum meson_saradc_num_samples {
+       ONE_SAMPLE = 0x0,
+       TWO_SAMPLES = 0x1,
+       FOUR_SAMPLES = 0x2,
+       EIGHT_SAMPLES = 0x3,
+};
+
+static void meson_saradc_set_averaging(struct meson_saradc_priv *priv,
+                                      unsigned int channel,
+                                      enum meson_saradc_avg_mode mode,
+                                      enum meson_saradc_num_samples samples)
+{
+       int val;
+
+       val = samples << MESON_SAR_ADC_AVG_CNTL_NUM_SAMPLES_SHIFT(channel);
+       regmap_update_bits(priv->regmap, MESON_SAR_ADC_AVG_CNTL,
+                          MESON_SAR_ADC_AVG_CNTL_NUM_SAMPLES_MASK(channel),
+                          val);
+
+       val = mode << MESON_SAR_ADC_AVG_CNTL_AVG_MODE_SHIFT(channel);
+       regmap_update_bits(priv->regmap, MESON_SAR_ADC_AVG_CNTL,
+                          MESON_SAR_ADC_AVG_CNTL_AVG_MODE_MASK(channel), val);
+}
+
+static void meson_saradc_enable_channel(struct meson_saradc_priv *priv,
+                                       unsigned int channel)
+{
+       uint regval;
+
+       /*
+        * the SAR ADC engine allows sampling multiple channels at the same
+        * time. to keep it simple we're only working with one *internal*
+        * channel, which starts counting at index 0 (which means: count = 1).
+        */
+       regval = FIELD_PREP(MESON_SAR_ADC_CHAN_LIST_MAX_INDEX_MASK, 0);
+       regmap_update_bits(priv->regmap, MESON_SAR_ADC_CHAN_LIST,
+                          MESON_SAR_ADC_CHAN_LIST_MAX_INDEX_MASK, regval);
+
+       /* map channel index 0 to the channel which we want to read */
+       regval = FIELD_PREP(MESON_SAR_ADC_CHAN_LIST_ENTRY_MASK(0), channel);
+       regmap_update_bits(priv->regmap, MESON_SAR_ADC_CHAN_LIST,
+                          MESON_SAR_ADC_CHAN_LIST_ENTRY_MASK(0), regval);
+
+       regval = FIELD_PREP(MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_MUX_MASK,
+                           channel);
+       regmap_update_bits(priv->regmap, MESON_SAR_ADC_DETECT_IDLE_SW,
+                          MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_MUX_MASK,
+                          regval);
+
+       regval = FIELD_PREP(MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_MUX_SEL_MASK,
+                           channel);
+       regmap_update_bits(priv->regmap, MESON_SAR_ADC_DETECT_IDLE_SW,
+                          MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_MUX_SEL_MASK,
+                          regval);
+
+       if (channel == 6)
+               regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELTA_10,
+                                  MESON_SAR_ADC_DELTA_10_TEMP_SEL, 0);
+}
+
+static int meson_saradc_get_sample(struct meson_saradc_priv *priv,
+                                  int chan, uint *val)
+{
+       int ret;
+
+       ret = meson_saradc_lock(priv);
+       if (ret)
+               return ret;
+
+       /* clear the FIFO to make sure we're not reading old values */
+       meson_saradc_clear_fifo(priv);
+
+       meson_saradc_set_averaging(priv, chan, MEAN_AVERAGING, EIGHT_SAMPLES);
+
+       meson_saradc_enable_channel(priv, chan);
+
+       meson_saradc_start_sample_engine(priv);
+       ret = meson_saradc_read_raw_sample(priv, chan, val);
+       meson_saradc_stop_sample_engine(priv);
+
+       meson_saradc_unlock(priv);
+
+       if (ret) {
+               printf("failed to read sample for channel %d: %d\n",
+                      chan, ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+static int meson_saradc_channel_data(struct udevice *dev, int channel,
+                                    unsigned int *data)
+{
+       struct meson_saradc_priv *priv = dev_get_priv(dev);
+
+       if (channel != priv->active_channel) {
+               pr_err("Requested channel is not active!");
+               return -EINVAL;
+       }
+
+       return meson_saradc_get_sample(priv, channel, data);
+}
+
+enum meson_saradc_chan7_mux_sel {
+       CHAN7_MUX_VSS = 0x0,
+       CHAN7_MUX_VDD_DIV4 = 0x1,
+       CHAN7_MUX_VDD_DIV2 = 0x2,
+       CHAN7_MUX_VDD_MUL3_DIV4 = 0x3,
+       CHAN7_MUX_VDD = 0x4,
+       CHAN7_MUX_CH7_INPUT = 0x7,
+};
+
+static void meson_saradc_set_chan7_mux(struct meson_saradc_priv *priv,
+                                      enum meson_saradc_chan7_mux_sel sel)
+{
+       u32 regval;
+
+       regval = FIELD_PREP(MESON_SAR_ADC_REG3_CTRL_CHAN7_MUX_SEL_MASK, sel);
+       regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3,
+                          MESON_SAR_ADC_REG3_CTRL_CHAN7_MUX_SEL_MASK, regval);
+
+       udelay(20);
+}
+
+static int meson_saradc_calib(struct meson_saradc_priv *priv)
+{
+       uint nominal0, nominal1, value0, value1;
+       int ret;
+
+       /* use points 25% and 75% for calibration */
+       nominal0 = (1 << priv->data->num_bits) / 4;
+       nominal1 = (1 << priv->data->num_bits) * 3 / 4;
+
+       meson_saradc_set_chan7_mux(priv, CHAN7_MUX_VDD_DIV4);
+       udelay(20);
+       ret = meson_saradc_get_sample(priv, 7, &value0);
+       if (ret < 0)
+               goto out;
+
+       meson_saradc_set_chan7_mux(priv, CHAN7_MUX_VDD_MUL3_DIV4);
+       udelay(20);
+       ret = meson_saradc_get_sample(priv, 7, &value1);
+       if (ret < 0)
+               goto out;
+
+       if (value1 <= value0) {
+               ret = -EINVAL;
+               goto out;
+       }
+
+       priv->calibscale = div_s64((nominal1 - nominal0) * (s64)MILLION,
+                                  value1 - value0);
+       priv->calibbias = nominal0 - div_s64((s64)value0 * priv->calibscale,
+                                            MILLION);
+       ret = 0;
+out:
+       meson_saradc_set_chan7_mux(priv, CHAN7_MUX_CH7_INPUT);
+
+       return ret;
+}
+
+static int meson_saradc_init(struct meson_saradc_priv *priv)
+{
+       uint regval;
+       int ret, i;
+
+       priv->calibscale = MILLION;
+
+       /*
+        * make sure we start at CH7 input since the other muxes are only used
+        * for internal calibration.
+        */
+       meson_saradc_set_chan7_mux(priv, CHAN7_MUX_CH7_INPUT);
+
+       /*
+        * leave sampling delay and the input clocks as configured by
+        * BL30 to make sure BL30 gets the values it expects when
+        * reading the temperature sensor.
+        */
+       regmap_read(priv->regmap, MESON_SAR_ADC_REG3, &regval);
+       if (regval & MESON_SAR_ADC_REG3_BL30_INITIALIZED)
+               return 0;
+
+       meson_saradc_stop_sample_engine(priv);
+
+       /* update the channel 6 MUX to select the temperature sensor */
+       regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0,
+                          MESON_SAR_ADC_REG0_ADC_TEMP_SEN_SEL,
+                          MESON_SAR_ADC_REG0_ADC_TEMP_SEN_SEL);
+
+       /* disable all channels by default */
+       regmap_write(priv->regmap, MESON_SAR_ADC_CHAN_LIST, 0x0);
+
+       regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3,
+                          MESON_SAR_ADC_REG3_CTRL_SAMPLING_CLOCK_PHASE, 0);
+       regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3,
+                          MESON_SAR_ADC_REG3_CNTL_USE_SC_DLY,
+                          MESON_SAR_ADC_REG3_CNTL_USE_SC_DLY);
+
+       /* delay between two samples = (10+1) * 1uS */
+       regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY,
+                          MESON_SAR_ADC_DELAY_INPUT_DLY_CNT_MASK,
+                          FIELD_PREP(MESON_SAR_ADC_DELAY_SAMPLE_DLY_CNT_MASK,
+                                     10));
+       regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY,
+                          MESON_SAR_ADC_DELAY_SAMPLE_DLY_SEL_MASK,
+                          FIELD_PREP(MESON_SAR_ADC_DELAY_SAMPLE_DLY_SEL_MASK,
+                                     0));
+
+       /* delay between two samples = (10+1) * 1uS */
+       regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY,
+                          MESON_SAR_ADC_DELAY_INPUT_DLY_CNT_MASK,
+                          FIELD_PREP(MESON_SAR_ADC_DELAY_INPUT_DLY_CNT_MASK,
+                                     10));
+       regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY,
+                          MESON_SAR_ADC_DELAY_INPUT_DLY_SEL_MASK,
+                          FIELD_PREP(MESON_SAR_ADC_DELAY_INPUT_DLY_SEL_MASK,
+                                     1));
+
+       /*
+        * set up the input channel muxes in MESON_SAR_ADC_CHAN_10_SW
+        * (0 = SAR_ADC_CH0, 1 = SAR_ADC_CH1)
+        */
+       regval = FIELD_PREP(MESON_SAR_ADC_CHAN_10_SW_CHAN0_MUX_SEL_MASK, 0);
+       regmap_update_bits(priv->regmap, MESON_SAR_ADC_CHAN_10_SW,
+                          MESON_SAR_ADC_CHAN_10_SW_CHAN0_MUX_SEL_MASK,
+                          regval);
+       regval = FIELD_PREP(MESON_SAR_ADC_CHAN_10_SW_CHAN1_MUX_SEL_MASK, 1);
+       regmap_update_bits(priv->regmap, MESON_SAR_ADC_CHAN_10_SW,
+                          MESON_SAR_ADC_CHAN_10_SW_CHAN1_MUX_SEL_MASK,
+                          regval);
+
+       /*
+        * set up the input channel muxes in MESON_SAR_ADC_AUX_SW
+        * (2 = SAR_ADC_CH2, 3 = SAR_ADC_CH3, ...) and enable
+        * MESON_SAR_ADC_AUX_SW_YP_DRIVE_SW and
+        * MESON_SAR_ADC_AUX_SW_XP_DRIVE_SW like the vendor driver.
+        */
+       regval = 0;
+       for (i = 2; i <= 7; i++)
+               regval |= i << MESON_SAR_ADC_AUX_SW_MUX_SEL_CHAN_SHIFT(i);
+       regval |= MESON_SAR_ADC_AUX_SW_YP_DRIVE_SW;
+       regval |= MESON_SAR_ADC_AUX_SW_XP_DRIVE_SW;
+       regmap_write(priv->regmap, MESON_SAR_ADC_AUX_SW, regval);
+
+       ret = meson_saradc_lock(priv);
+       if (ret)
+               return ret;
+
+#if CONFIG_IS_ENABLED(CLK)
+       ret = clk_enable(&priv->core_clk);
+       if (ret)
+               return ret;
+#endif
+
+       regval = FIELD_PREP(MESON_SAR_ADC_REG0_FIFO_CNT_IRQ_MASK, 1);
+       regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0,
+                          MESON_SAR_ADC_REG0_FIFO_CNT_IRQ_MASK, regval);
+
+       regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG11,
+                          MESON_SAR_ADC_REG11_BANDGAP_EN,
+                          MESON_SAR_ADC_REG11_BANDGAP_EN);
+
+       regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3,
+                          MESON_SAR_ADC_REG3_ADC_EN,
+                          MESON_SAR_ADC_REG3_ADC_EN);
+
+       udelay(5);
+
+#if CONFIG_IS_ENABLED(CLK)
+       ret = clk_enable(&priv->adc_clk);
+       if (ret)
+               return ret;
+#endif
+
+       meson_saradc_unlock(priv);
+
+       ret = meson_saradc_calib(priv);
+       if (ret) {
+               printf("calibration failed\n");
+               return -EIO;
+       }
+
+       return 0;
+}
+
+static int meson_saradc_start_channel(struct udevice *dev, int channel)
+{
+       struct meson_saradc_priv *priv = dev_get_priv(dev);
+
+       if (channel < 0 || channel >= NUM_CHANNELS) {
+               printf("Requested channel is invalid!");
+               return -EINVAL;
+       }
+
+       if (!priv->initialized) {
+               int ret;
+
+               ret = meson_saradc_init(priv);
+               if (ret)
+                       return ret;
+
+               priv->initialized = true;
+       }
+
+       priv->active_channel = channel;
+
+       return 0;
+}
+
+static int meson_saradc_stop(struct udevice *dev)
+{
+       struct meson_saradc_priv *priv = dev_get_priv(dev);
+
+       priv->active_channel = -1;
+
+       return 0;
+}
+
+static int meson_saradc_probe(struct udevice *dev)
+{
+       struct meson_saradc_priv *priv = dev_get_priv(dev);
+       int ret;
+
+       ret = regmap_init_mem(dev, &priv->regmap);
+       if (ret)
+               return ret;
+
+#if CONFIG_IS_ENABLED(CLK)
+       ret = clk_get_by_name(dev, "core", &priv->core_clk);
+       if (ret)
+               return ret;
+
+       ret = clk_get_by_name(dev, "adc_clk", &priv->adc_clk);
+       if (ret)
+               return ret;
+#endif
+
+       priv->active_channel = -1;
+
+       return 0;
+}
+
+int meson_saradc_ofdata_to_platdata(struct udevice *dev)
+{
+       struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
+       struct meson_saradc_priv *priv = dev_get_priv(dev);
+
+       priv->data = (struct meson_saradc_data *)dev_get_driver_data(dev);
+
+       uc_pdata->data_mask = GENMASK(priv->data->num_bits - 1, 0);
+       uc_pdata->data_format = ADC_DATA_FORMAT_BIN;
+       uc_pdata->data_timeout_us = MESON_SAR_ADC_TIMEOUT * 1000;
+       uc_pdata->channel_mask = GENMASK(NUM_CHANNELS - 1, 0);
+
+       return 0;
+}
+
+static const struct adc_ops meson_saradc_ops = {
+       .start_channel = meson_saradc_start_channel,
+       .channel_data = meson_saradc_channel_data,
+       .stop = meson_saradc_stop,
+};
+
+static const struct meson_saradc_data gxbb_saradc_data = {
+       .num_bits = 10,
+};
+
+static const struct meson_saradc_data gxl_saradc_data = {
+       .num_bits = 12,
+};
+
+static const struct udevice_id meson_saradc_ids[] = {
+       { .compatible = "amlogic,meson-gxbb-saradc",
+         .data = (ulong)&gxbb_saradc_data },
+       { .compatible = "amlogic,meson-gxl-saradc",
+         .data = (ulong)&gxl_saradc_data },
+       { .compatible = "amlogic,meson-gxm-saradc",
+         .data = (ulong)&gxl_saradc_data },
+       { }
+};
+
+U_BOOT_DRIVER(meson_saradc) = {
+       .name           = "meson_saradc",
+       .id             = UCLASS_ADC,
+       .of_match       = meson_saradc_ids,
+       .ops            = &meson_saradc_ops,
+       .probe          = meson_saradc_probe,
+       .ofdata_to_platdata = meson_saradc_ofdata_to_platdata,
+       .priv_auto_alloc_size = sizeof(struct meson_saradc_priv),
+};
index 6c1e2575ff84686321cb21601e41b2346eeee109..cbcfe3a89dd780ae4bff1defde0af0d2de9f9aa4 100644 (file)
@@ -133,6 +133,7 @@ struct stm32_clk {
        struct stm32_pwr_regs *pwr_regs;
        struct stm32_clk_info info;
        unsigned long hse_rate;
+       bool pllsaip;
 };
 
 #ifdef CONFIG_VIDEO_STM32
@@ -179,8 +180,12 @@ static int configure_clocks(struct udevice *dev)
 
        /* configure SDMMC clock */
        if (priv->info.v2) { /*stm32f7 case */
-               /* select PLLQ as 48MHz clock source */
-               clrbits_le32(&regs->dckcfgr2, RCC_DCKCFGRX_CK48MSEL);
+               if (priv->pllsaip)
+                       /* select PLLSAIP as 48MHz clock source */
+                       setbits_le32(&regs->dckcfgr2, RCC_DCKCFGRX_CK48MSEL);
+               else
+                       /* select PLLQ as 48MHz clock source */
+                       clrbits_le32(&regs->dckcfgr2, RCC_DCKCFGRX_CK48MSEL);
 
                /* select 48MHz as SDMMC1 clock source */
                clrbits_le32(&regs->dckcfgr2, RCC_DCKCFGRX_SDMMC1SEL);
@@ -188,17 +193,23 @@ static int configure_clocks(struct udevice *dev)
                /* select 48MHz as SDMMC2 clock source */
                clrbits_le32(&regs->dckcfgr2, RCC_DCKCFGR2_SDMMC2SEL);
        } else  { /* stm32f4 case */
-               /* select PLLQ as 48MHz clock source */
-               clrbits_le32(&regs->dckcfgr, RCC_DCKCFGRX_CK48MSEL);
+               if (priv->pllsaip)
+                       /* select PLLSAIP as 48MHz clock source */
+                       setbits_le32(&regs->dckcfgr, RCC_DCKCFGRX_CK48MSEL);
+               else
+                       /* select PLLQ as 48MHz clock source */
+                       clrbits_le32(&regs->dckcfgr, RCC_DCKCFGRX_CK48MSEL);
 
                /* select 48MHz as SDMMC1 clock source */
                clrbits_le32(&regs->dckcfgr, RCC_DCKCFGRX_SDMMC1SEL);
        }
 
-#ifdef CONFIG_VIDEO_STM32
        /*
-        * Configure the SAI PLL to generate LTDC pixel clock
+        * Configure the SAI PLL to generate LTDC pixel clock and
+        * 48 Mhz for SDMMC and USB
         */
+       clrsetbits_le32(&regs->pllsaicfgr, RCC_PLLSAICFGR_PLLSAIP_MASK,
+                       RCC_PLLSAICFGR_PLLSAIP_4);
        clrsetbits_le32(&regs->pllsaicfgr, RCC_PLLSAICFGR_PLLSAIR_MASK,
                        RCC_PLLSAICFGR_PLLSAIR_3);
        clrsetbits_le32(&regs->pllsaicfgr, RCC_PLLSAICFGR_PLLSAIN_MASK,
@@ -206,18 +217,16 @@ static int configure_clocks(struct udevice *dev)
 
        clrsetbits_le32(&regs->dckcfgr, RCC_DCKCFGR_PLLSAIDIVR_MASK,
                        RCC_DCKCFGR_PLLSAIDIVR_2 << RCC_DCKCFGR_PLLSAIDIVR_SHIFT);
-#endif
+
        /* Enable the main PLL */
        setbits_le32(&regs->cr, RCC_CR_PLLON);
        while (!(readl(&regs->cr) & RCC_CR_PLLRDY))
                ;
 
-#ifdef CONFIG_VIDEO_STM32
-/* Enable the SAI PLL */
+       /* Enable the SAI PLL */
        setbits_le32(&regs->cr, RCC_CR_PLLSAION);
        while (!(readl(&regs->cr) & RCC_CR_PLLSAIRDY))
                ;
-#endif
        setbits_le32(&regs->apb1enr, RCC_APB1ENR_PWREN);
 
        if (priv->info.has_overdrive) {
@@ -617,12 +626,17 @@ static int stm32_clk_probe(struct udevice *dev)
                return -EINVAL;
 
        priv->base = (struct stm32_rcc_regs *)addr;
+       priv->pllsaip = true;
 
        switch (dev_get_driver_data(dev)) {
-       case STM32F4:
+       case STM32F42X:
+               priv->pllsaip = false;
+               /* fallback into STM32F469 case */
+       case STM32F469:
                memcpy(&priv->info, &stm32f4_clk_info,
                       sizeof(struct stm32_clk_info));
                break;
+
        case STM32F7:
                memcpy(&priv->info, &stm32f7_clk_info,
                       sizeof(struct stm32_clk_info));
index ed32585eb02109c24637c52963ef864981fbc65d..1a77eba39cbb430a99fcad34b6768dcccfe4bf96 100644 (file)
 #define RCC_USBCKSELR          0x91C
 #define RCC_MP_APB1ENSETR      0xA00
 #define RCC_MP_APB2ENSETR      0XA08
+#define RCC_MP_APB3ENSETR      0xA10
 #define RCC_MP_AHB2ENSETR      0xA18
 #define RCC_MP_AHB4ENSETR      0xA28
 
@@ -508,6 +509,8 @@ static const struct stm32mp1_clk_gate stm32mp1_clk_gate[] = {
 
        STM32MP1_CLK_SET_CLR(RCC_MP_APB2ENSETR, 13, USART6_K, _UART6_SEL),
 
+       STM32MP1_CLK_SET_CLR_F(RCC_MP_APB3ENSETR, 13, VREF, _PCLK3),
+
        STM32MP1_CLK_SET_CLR(RCC_MP_APB4ENSETR, 8, DDRPERFM, _UNKNOWN_SEL),
        STM32MP1_CLK_SET_CLR(RCC_MP_APB4ENSETR, 15, IWDG2, _UNKNOWN_SEL),
        STM32MP1_CLK_SET_CLR(RCC_MP_APB4ENSETR, 16, USBPHY_K, _USBPHY_SEL),
index fabcc5f53a838fb7bf1bc2a86f7cadfb0763e6e9..8e5c3bcf61bbc4927b2ccf577df927bafba1efb6 100644 (file)
@@ -132,3 +132,17 @@ int regmap_write(struct regmap *map, uint offset, uint val)
 
        return 0;
 }
+
+int regmap_update_bits(struct regmap *map, uint offset, uint mask, uint val)
+{
+       uint reg;
+       int ret;
+
+       ret = regmap_read(map, offset, &reg);
+       if (ret)
+               return ret;
+
+       reg &= ~mask;
+
+       return regmap_write(map, offset, reg | val);
+}
index 2385dec961cefb02dba72a3e178c70f0bf8b0cec..95a189a50f64063857718c1d144ed3c5e14df1f4 100644 (file)
@@ -43,7 +43,7 @@ static struct atmel_pio4_port *atmel_pio4_port_base(u32 port)
 }
 
 static int atmel_pio4_config_io_func(u32 port, u32 pin,
-                                    u32 func, u32 use_pullup)
+                                    u32 func, u32 config)
 {
        struct atmel_pio4_port *port_base;
        u32 reg, mask;
@@ -57,7 +57,7 @@ static int atmel_pio4_config_io_func(u32 port, u32 pin,
 
        mask = 1 << pin;
        reg = func;
-       reg |= use_pullup ? ATMEL_PIO_PUEN_MASK : 0;
+       reg |= config;
 
        writel(mask, &port_base->mskr);
        writel(reg, &port_base->cfgr);
@@ -65,60 +65,60 @@ static int atmel_pio4_config_io_func(u32 port, u32 pin,
        return 0;
 }
 
-int atmel_pio4_set_gpio(u32 port, u32 pin, u32 use_pullup)
+int atmel_pio4_set_gpio(u32 port, u32 pin, u32 config)
 {
        return atmel_pio4_config_io_func(port, pin,
                                         ATMEL_PIO_CFGR_FUNC_GPIO,
-                                        use_pullup);
+                                        config);
 }
 
-int atmel_pio4_set_a_periph(u32 port, u32 pin, u32 use_pullup)
+int atmel_pio4_set_a_periph(u32 port, u32 pin, u32 config)
 {
        return atmel_pio4_config_io_func(port, pin,
                                         ATMEL_PIO_CFGR_FUNC_PERIPH_A,
-                                        use_pullup);
+                                        config);
 }
 
-int atmel_pio4_set_b_periph(u32 port, u32 pin, u32 use_pullup)
+int atmel_pio4_set_b_periph(u32 port, u32 pin, u32 config)
 {
        return atmel_pio4_config_io_func(port, pin,
                                         ATMEL_PIO_CFGR_FUNC_PERIPH_B,
-                                        use_pullup);
+                                        config);
 }
 
-int atmel_pio4_set_c_periph(u32 port, u32 pin, u32 use_pullup)
+int atmel_pio4_set_c_periph(u32 port, u32 pin, u32 config)
 {
        return atmel_pio4_config_io_func(port, pin,
                                         ATMEL_PIO_CFGR_FUNC_PERIPH_C,
-                                        use_pullup);
+                                        config);
 }
 
-int atmel_pio4_set_d_periph(u32 port, u32 pin, u32 use_pullup)
+int atmel_pio4_set_d_periph(u32 port, u32 pin, u32 config)
 {
        return atmel_pio4_config_io_func(port, pin,
                                         ATMEL_PIO_CFGR_FUNC_PERIPH_D,
-                                        use_pullup);
+                                        config);
 }
 
-int atmel_pio4_set_e_periph(u32 port, u32 pin, u32 use_pullup)
+int atmel_pio4_set_e_periph(u32 port, u32 pin, u32 config)
 {
        return atmel_pio4_config_io_func(port, pin,
                                         ATMEL_PIO_CFGR_FUNC_PERIPH_E,
-                                        use_pullup);
+                                        config);
 }
 
-int atmel_pio4_set_f_periph(u32 port, u32 pin, u32 use_pullup)
+int atmel_pio4_set_f_periph(u32 port, u32 pin, u32 config)
 {
        return atmel_pio4_config_io_func(port, pin,
                                         ATMEL_PIO_CFGR_FUNC_PERIPH_F,
-                                        use_pullup);
+                                        config);
 }
 
-int atmel_pio4_set_g_periph(u32 port, u32 pin, u32 use_pullup)
+int atmel_pio4_set_g_periph(u32 port, u32 pin, u32 config)
 {
        return atmel_pio4_config_io_func(port, pin,
                                         ATMEL_PIO_CFGR_FUNC_PERIPH_G,
-                                        use_pullup);
+                                        config);
 }
 
 int atmel_pio4_set_pio_output(u32 port, u32 pin, u32 value)
index b26f7a730cf4955c4f2228d3b1a5b4e57cc85794..a36942b9348bdad938f8478cd91be17931dab499 100644 (file)
@@ -10,6 +10,7 @@
 #include <led.h>
 #include <asm/gpio.h>
 #include <dm/lists.h>
+#include <dm/uclass-internal.h>
 
 struct led_gpio_priv {
        struct gpio_desc gpio;
@@ -57,11 +58,25 @@ static int led_gpio_probe(struct udevice *dev)
 {
        struct led_uc_plat *uc_plat = dev_get_uclass_platdata(dev);
        struct led_gpio_priv *priv = dev_get_priv(dev);
+       const char *default_state;
+       int ret;
 
        /* Ignore the top-level LED node */
        if (!uc_plat->label)
                return 0;
-       return gpio_request_by_name(dev, "gpios", 0, &priv->gpio, GPIOD_IS_OUT);
+
+       ret = gpio_request_by_name(dev, "gpios", 0, &priv->gpio, GPIOD_IS_OUT);
+       if (ret)
+               return ret;
+
+       default_state = dev_read_string(dev, "default-state");
+       if (default_state) {
+               if (!strncmp(default_state, "on", 2))
+                       gpio_led_set_state(dev, LEDST_ON);
+               else if (!strncmp(default_state, "off", 3))
+                       gpio_led_set_state(dev, LEDST_OFF);
+       }
+       return 0;
 }
 
 static int led_gpio_remove(struct udevice *dev)
@@ -103,6 +118,14 @@ static int led_gpio_bind(struct udevice *parent)
                        return ret;
                uc_plat = dev_get_uclass_platdata(dev);
                uc_plat->label = label;
+
+               if (ofnode_read_bool(node, "default-state")) {
+                       struct udevice *devp;
+
+                       ret = uclass_get_device_tail(dev, 0, &devp);
+                       if (ret)
+                               return ret;
+               }
        }
 
        return 0;
index b436900d7cba6adab3d8c8a305213f6e01f1946b..dee82c0b7b1e1edf17f238a102dd52934ede49f6 100644 (file)
 #include <dm/device-internal.h>
 #include <dm/lists.h>
 
-struct stm32_rcc_clk stm32_rcc_clk_f4 = {
+struct stm32_rcc_clk stm32_rcc_clk_f42x = {
        .drv_name = "stm32fx_rcc_clock",
-       .soc = STM32F4,
+       .soc = STM32F42X,
+};
+
+struct stm32_rcc_clk stm32_rcc_clk_f469 = {
+       .drv_name = "stm32fx_rcc_clock",
+       .soc = STM32F469,
 };
 
 struct stm32_rcc_clk stm32_rcc_clk_f7 = {
@@ -61,7 +66,8 @@ static const struct misc_ops stm32_rcc_ops = {
 };
 
 static const struct udevice_id stm32_rcc_ids[] = {
-       {.compatible = "st,stm32f42xx-rcc", .data = (ulong)&stm32_rcc_clk_f4 },
+       {.compatible = "st,stm32f42xx-rcc", .data = (ulong)&stm32_rcc_clk_f42x },
+       {.compatible = "st,stm32f469-rcc", .data = (ulong)&stm32_rcc_clk_f469 },
        {.compatible = "st,stm32f746-rcc", .data = (ulong)&stm32_rcc_clk_f7 },
        {.compatible = "st,stm32h743-rcc", .data = (ulong)&stm32_rcc_clk_h7 },
        { }
index c20a0cc06077833a1db854f473ae32c206df9fe6..f59803dbd650589ab8dd8a422e530cea98a4b88b 100644 (file)
@@ -105,4 +105,11 @@ config PCIE_LAYERSCAPE
          PCIe controllers. The PCIe may works in RC or EP mode according to
          RCW[HOST_AGT_PEX] setting.
 
+config PCIE_INTEL_FPGA
+       bool "Intel FPGA PCIe support"
+       depends on DM_PCI
+       help
+         Say Y here if you want to enable PCIe controller support on Intel
+         FPGA, example Stratix 10.
+
 endif
index 72c09f4af802747615985a478fe1110ded77a232..4923641895948e16cd9901981c9dcf910a31e97b 100644 (file)
@@ -33,3 +33,4 @@ obj-$(CONFIG_PCIE_DW_MVEBU) += pcie_dw_mvebu.o
 obj-$(CONFIG_PCIE_LAYERSCAPE) += pcie_layerscape.o
 obj-$(CONFIG_PCIE_LAYERSCAPE) += pcie_layerscape_fixup.o
 obj-$(CONFIG_PCI_XILINX) += pcie_xilinx.o
+obj-$(CONFIG_PCIE_INTEL_FPGA) += pcie_intel_fpga.o
diff --git a/drivers/pci/pcie_intel_fpga.c b/drivers/pci/pcie_intel_fpga.c
new file mode 100644 (file)
index 0000000..3cdf05b
--- /dev/null
@@ -0,0 +1,430 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Intel FPGA PCIe host controller driver
+ *
+ * Copyright (C) 2013-2018 Intel Corporation. All rights reserved
+ *
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <pci.h>
+#include <asm/io.h>
+
+#define RP_TX_REG0                     0x2000
+#define RP_TX_CNTRL                    0x2004
+#define RP_TX_SOP                      BIT(0)
+#define RP_TX_EOP                      BIT(1)
+#define RP_RXCPL_STATUS                        0x200C
+#define RP_RXCPL_SOP                   BIT(0)
+#define RP_RXCPL_EOP                   BIT(1)
+#define RP_RXCPL_REG                   0x2008
+#define P2A_INT_STATUS                 0x3060
+#define P2A_INT_STS_ALL                        0xf
+#define P2A_INT_ENABLE                 0x3070
+#define RP_CAP_OFFSET                  0x70
+
+/* TLP configuration type 0 and 1 */
+#define TLP_FMTTYPE_CFGRD0             0x04    /* Configuration Read Type 0 */
+#define TLP_FMTTYPE_CFGWR0             0x44    /* Configuration Write Type 0 */
+#define TLP_FMTTYPE_CFGRD1             0x05    /* Configuration Read Type 1 */
+#define TLP_FMTTYPE_CFGWR1             0x45    /* Configuration Write Type 1 */
+#define TLP_PAYLOAD_SIZE               0x01
+#define TLP_READ_TAG                   0x1d
+#define TLP_WRITE_TAG                  0x10
+#define RP_DEVFN                       0
+
+#define RP_CFG_ADDR(pcie, reg)                                         \
+               ((pcie->hip_base) + (reg) + (1 << 20))
+#define TLP_REQ_ID(bus, devfn)         (((bus) << 8) | (devfn))
+
+#define TLP_CFGRD_DW0(pcie, bus)                                       \
+       ((((bus != pcie->first_busno) ? TLP_FMTTYPE_CFGRD0              \
+                                     : TLP_FMTTYPE_CFGRD1) << 24) |    \
+                                       TLP_PAYLOAD_SIZE)
+
+#define TLP_CFGWR_DW0(pcie, bus)                                       \
+       ((((bus != pcie->first_busno) ? TLP_FMTTYPE_CFGWR0              \
+                                     : TLP_FMTTYPE_CFGWR1) << 24) |    \
+                                       TLP_PAYLOAD_SIZE)
+
+#define TLP_CFG_DW1(pcie, tag, be)                                     \
+       (((TLP_REQ_ID(pcie->first_busno,  RP_DEVFN)) << 16) | (tag << 8) | (be))
+#define TLP_CFG_DW2(bus, dev, fn, offset)                              \
+       (((bus) << 24) | ((dev) << 19) | ((fn) << 16) | (offset))
+
+#define TLP_COMP_STATUS(s)             (((s) >> 13) & 7)
+#define TLP_BYTE_COUNT(s)              (((s) >> 0) & 0xfff)
+#define TLP_HDR_SIZE                   3
+#define TLP_LOOP                       500
+#define DWORD_MASK                     3
+
+#define IS_ROOT_PORT(pcie, bdf)                                \
+               ((PCI_BUS(bdf) == pcie->first_busno) ? true : false)
+
+#define PCI_EXP_LNKSTA         18      /* Link Status */
+#define PCI_EXP_LNKSTA_DLLLA   0x2000  /* Data Link Layer Link Active */
+
+/**
+ * struct intel_fpga_pcie - Intel FPGA PCIe controller state
+ * @bus: Pointer to the PCI bus
+ * @cra_base: The base address of CRA register space
+ * @hip_base: The base address of Rootport configuration space
+ * @first_busno: This driver supports multiple PCIe controllers.
+ *               first_busno stores the bus number of the PCIe root-port
+ *               number which may vary depending on the PCIe setup.
+ */
+struct intel_fpga_pcie {
+       struct udevice *bus;
+       void __iomem *cra_base;
+       void __iomem *hip_base;
+       int first_busno;
+};
+
+/**
+ * Intel FPGA PCIe port uses BAR0 of RC's configuration space as the
+ * translation from PCI bus to native BUS. Entire DDR region is mapped
+ * into PCIe space using these registers, so it can be reached by DMA from
+ * EP devices.
+ * The BAR0 of bridge should be hidden during enumeration to avoid the
+ * sizing and resource allocation by PCIe core.
+ */
+static bool intel_fpga_pcie_hide_rc_bar(struct intel_fpga_pcie *pcie,
+                                       pci_dev_t bdf, int offset)
+{
+       if (IS_ROOT_PORT(pcie, bdf) && PCI_DEV(bdf) == 0 &&
+           PCI_FUNC(bdf) == 0 && offset == PCI_BASE_ADDRESS_0)
+               return true;
+
+       return false;
+}
+
+static inline void cra_writel(struct intel_fpga_pcie *pcie, const u32 value,
+                             const u32 reg)
+{
+       writel(value, pcie->cra_base + reg);
+}
+
+static inline u32 cra_readl(struct intel_fpga_pcie *pcie, const u32 reg)
+{
+       return readl(pcie->cra_base + reg);
+}
+
+static bool intel_fpga_pcie_link_up(struct intel_fpga_pcie *pcie)
+{
+       return !!(readw(RP_CFG_ADDR(pcie, RP_CAP_OFFSET + PCI_EXP_LNKSTA))
+                       & PCI_EXP_LNKSTA_DLLLA);
+}
+
+static bool intel_fpga_pcie_addr_valid(struct intel_fpga_pcie *pcie,
+                                      pci_dev_t bdf)
+{
+       /* If there is no link, then there is no device */
+       if (!IS_ROOT_PORT(pcie, bdf) && !intel_fpga_pcie_link_up(pcie))
+               return false;
+
+       /* access only one slot on each root port */
+       if (IS_ROOT_PORT(pcie, bdf) && PCI_DEV(bdf) > 0)
+               return false;
+
+       if ((PCI_BUS(bdf) == pcie->first_busno + 1) && PCI_DEV(bdf) > 0)
+               return false;
+
+       return true;
+}
+
+static void tlp_write_tx(struct intel_fpga_pcie *pcie, u32 reg0, u32 ctrl)
+{
+       cra_writel(pcie, reg0, RP_TX_REG0);
+       cra_writel(pcie, ctrl, RP_TX_CNTRL);
+}
+
+static int tlp_read_packet(struct intel_fpga_pcie *pcie, u32 *value)
+{
+       int i;
+       u32 ctrl;
+       u32 comp_status;
+       u32 dw[4];
+       u32 count = 0;
+
+       for (i = 0; i < TLP_LOOP; i++) {
+               ctrl = cra_readl(pcie, RP_RXCPL_STATUS);
+               if (!(ctrl & RP_RXCPL_SOP))
+                       continue;
+
+               /* read first DW */
+               dw[count++] = cra_readl(pcie, RP_RXCPL_REG);
+
+               /* Poll for EOP */
+               for (i = 0; i < TLP_LOOP; i++) {
+                       ctrl = cra_readl(pcie, RP_RXCPL_STATUS);
+                       dw[count++] = cra_readl(pcie, RP_RXCPL_REG);
+                       if (ctrl & RP_RXCPL_EOP) {
+                               comp_status = TLP_COMP_STATUS(dw[1]);
+                               if (comp_status)
+                                       return -EFAULT;
+
+                               if (value &&
+                                   TLP_BYTE_COUNT(dw[1]) == sizeof(u32) &&
+                                   count >= 3)
+                                       *value = dw[3];
+
+                               return 0;
+                       }
+               }
+
+               udelay(5);
+       }
+
+       dev_err(pcie->dev, "read TLP packet timed out\n");
+       return -ENODEV;
+}
+
+static void tlp_write_packet(struct intel_fpga_pcie *pcie, u32 *headers,
+                            u32 data)
+{
+       tlp_write_tx(pcie, headers[0], RP_TX_SOP);
+
+       tlp_write_tx(pcie, headers[1], 0);
+
+       tlp_write_tx(pcie, headers[2], 0);
+
+       tlp_write_tx(pcie, data, RP_TX_EOP);
+}
+
+static int tlp_cfg_dword_read(struct intel_fpga_pcie *pcie, pci_dev_t bdf,
+                             int offset, u8 byte_en, u32 *value)
+{
+       u32 headers[TLP_HDR_SIZE];
+       u8 busno = PCI_BUS(bdf);
+
+       headers[0] = TLP_CFGRD_DW0(pcie, busno);
+       headers[1] = TLP_CFG_DW1(pcie, TLP_READ_TAG, byte_en);
+       headers[2] = TLP_CFG_DW2(busno, PCI_DEV(bdf), PCI_FUNC(bdf), offset);
+
+       tlp_write_packet(pcie, headers, 0);
+
+       return tlp_read_packet(pcie, value);
+}
+
+static int tlp_cfg_dword_write(struct intel_fpga_pcie *pcie, pci_dev_t bdf,
+                              int offset, u8 byte_en, u32 value)
+{
+       u32 headers[TLP_HDR_SIZE];
+       u8 busno = PCI_BUS(bdf);
+
+       headers[0] = TLP_CFGWR_DW0(pcie, busno);
+       headers[1] = TLP_CFG_DW1(pcie, TLP_WRITE_TAG, byte_en);
+       headers[2] = TLP_CFG_DW2(busno, PCI_DEV(bdf), PCI_FUNC(bdf), offset);
+
+       tlp_write_packet(pcie, headers, value);
+
+       return tlp_read_packet(pcie, NULL);
+}
+
+int intel_fpga_rp_conf_addr(struct udevice *bus, pci_dev_t bdf,
+                           uint offset, void **paddress)
+{
+       struct intel_fpga_pcie *pcie = dev_get_priv(bus);
+
+       *paddress = RP_CFG_ADDR(pcie, offset);
+
+       return 0;
+}
+
+static int intel_fpga_pcie_rp_rd_conf(struct udevice *bus, pci_dev_t bdf,
+                                     uint offset, ulong *valuep,
+                                     enum pci_size_t size)
+{
+       return pci_generic_mmap_read_config(bus, intel_fpga_rp_conf_addr,
+                                           bdf, offset, valuep, size);
+}
+
+static int intel_fpga_pcie_rp_wr_conf(struct udevice *bus, pci_dev_t bdf,
+                                     uint offset, ulong value,
+                                     enum pci_size_t size)
+{
+       int ret;
+       struct intel_fpga_pcie *pcie = dev_get_priv(bus);
+
+       ret = pci_generic_mmap_write_config(bus, intel_fpga_rp_conf_addr,
+                                           bdf, offset, value, size);
+       if (!ret) {
+               /* Monitor changes to PCI_PRIMARY_BUS register on root port
+                * and update local copy of root bus number accordingly.
+                */
+               if (offset == PCI_PRIMARY_BUS)
+                       pcie->first_busno = (u8)(value);
+       }
+
+       return ret;
+}
+
+static u8 pcie_get_byte_en(uint offset, enum pci_size_t size)
+{
+       switch (size) {
+       case PCI_SIZE_8:
+               return 1 << (offset & 3);
+       case PCI_SIZE_16:
+               return 3 << (offset & 3);
+       default:
+               return 0xf;
+       }
+}
+
+static int _pcie_intel_fpga_read_config(struct intel_fpga_pcie *pcie,
+                                       pci_dev_t bdf, uint offset,
+                                       ulong *valuep, enum pci_size_t size)
+{
+       int ret;
+       u32 data;
+       u8 byte_en;
+
+       /* Uses memory mapped method to read rootport config registers */
+       if (IS_ROOT_PORT(pcie, bdf))
+               return intel_fpga_pcie_rp_rd_conf(pcie->bus, bdf,
+                                      offset, valuep, size);
+
+       byte_en = pcie_get_byte_en(offset, size);
+       ret = tlp_cfg_dword_read(pcie, bdf, offset & ~DWORD_MASK,
+                                byte_en, &data);
+       if (ret)
+               return ret;
+
+       dev_dbg(pcie->dev, "(addr,size,val)=(0x%04x, %d, 0x%08x)\n",
+               offset, size, data);
+       *valuep = pci_conv_32_to_size(data, offset, size);
+
+       return 0;
+}
+
+static int _pcie_intel_fpga_write_config(struct intel_fpga_pcie *pcie,
+                                        pci_dev_t bdf, uint offset,
+                                        ulong value, enum pci_size_t size)
+{
+       u32 data;
+       u8 byte_en;
+
+       dev_dbg(pcie->dev, "PCIE CFG write: (b.d.f)=(%02d.%02d.%02d)\n",
+               PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf));
+       dev_dbg(pcie->dev, "(addr,size,val)=(0x%04x, %d, 0x%08lx)\n",
+               offset, size, value);
+
+       /* Uses memory mapped method to read rootport config registers */
+       if (IS_ROOT_PORT(pcie, bdf))
+               return intel_fpga_pcie_rp_wr_conf(pcie->bus, bdf, offset,
+                                                 value, size);
+
+       byte_en = pcie_get_byte_en(offset, size);
+       data = pci_conv_size_to_32(0, value, offset, size);
+
+       return tlp_cfg_dword_write(pcie, bdf, offset & ~DWORD_MASK,
+                                  byte_en, data);
+}
+
+static int pcie_intel_fpga_read_config(struct udevice *bus, pci_dev_t bdf,
+                                      uint offset, ulong *valuep,
+                                      enum pci_size_t size)
+{
+       struct intel_fpga_pcie *pcie = dev_get_priv(bus);
+
+       dev_dbg(pcie->dev, "PCIE CFG read:  (b.d.f)=(%02d.%02d.%02d)\n",
+               PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf));
+
+       if (intel_fpga_pcie_hide_rc_bar(pcie, bdf, offset)) {
+               *valuep = (u32)pci_get_ff(size);
+               return 0;
+       }
+
+       if (!intel_fpga_pcie_addr_valid(pcie, bdf)) {
+               *valuep = (u32)pci_get_ff(size);
+               return 0;
+       }
+
+       return _pcie_intel_fpga_read_config(pcie, bdf, offset, valuep, size);
+}
+
+static int pcie_intel_fpga_write_config(struct udevice *bus, pci_dev_t bdf,
+                                       uint offset, ulong value,
+                                       enum pci_size_t size)
+{
+       struct intel_fpga_pcie *pcie = dev_get_priv(bus);
+
+       if (intel_fpga_pcie_hide_rc_bar(pcie, bdf, offset))
+               return 0;
+
+       if (!intel_fpga_pcie_addr_valid(pcie, bdf))
+               return 0;
+
+       return _pcie_intel_fpga_write_config(pcie, bdf, offset, value,
+                                         size);
+}
+
+static int pcie_intel_fpga_probe(struct udevice *dev)
+{
+       struct intel_fpga_pcie *pcie = dev_get_priv(dev);
+
+       pcie->bus = pci_get_controller(dev);
+       pcie->first_busno = dev->seq;
+
+       /* clear all interrupts */
+       cra_writel(pcie, P2A_INT_STS_ALL, P2A_INT_STATUS);
+       /* disable all interrupts */
+       cra_writel(pcie, 0, P2A_INT_ENABLE);
+
+       return 0;
+}
+
+static int pcie_intel_fpga_ofdata_to_platdata(struct udevice *dev)
+{
+       struct intel_fpga_pcie *pcie = dev_get_priv(dev);
+       struct fdt_resource reg_res;
+       int node = dev_of_offset(dev);
+       int ret;
+
+       DECLARE_GLOBAL_DATA_PTR;
+
+       ret = fdt_get_named_resource(gd->fdt_blob, node, "reg", "reg-names",
+                                    "Cra", &reg_res);
+       if (ret) {
+               dev_err(dev, "resource \"Cra\" not found\n");
+               return ret;
+       }
+
+       pcie->cra_base = map_physmem(reg_res.start,
+                                    fdt_resource_size(&reg_res),
+                                    MAP_NOCACHE);
+
+       ret = fdt_get_named_resource(gd->fdt_blob, node, "reg", "reg-names",
+                                    "Hip", &reg_res);
+       if (ret) {
+               dev_err(dev, "resource \"Hip\" not found\n");
+               return ret;
+       }
+
+       pcie->hip_base = map_physmem(reg_res.start,
+                                    fdt_resource_size(&reg_res),
+                                    MAP_NOCACHE);
+
+       return 0;
+}
+
+static const struct dm_pci_ops pcie_intel_fpga_ops = {
+       .read_config    = pcie_intel_fpga_read_config,
+       .write_config   = pcie_intel_fpga_write_config,
+};
+
+static const struct udevice_id pcie_intel_fpga_ids[] = {
+       { .compatible = "altr,pcie-root-port-2.0" },
+       {},
+};
+
+U_BOOT_DRIVER(pcie_intel_fpga) = {
+       .name                   = "pcie_intel_fpga",
+       .id                     = UCLASS_PCI,
+       .of_match               = pcie_intel_fpga_ids,
+       .ops                    = &pcie_intel_fpga_ops,
+       .ofdata_to_platdata     = pcie_intel_fpga_ofdata_to_platdata,
+       .probe                  = pcie_intel_fpga_probe,
+       .priv_auto_alloc_size   = sizeof(struct intel_fpga_pcie),
+};
index 6e94d3bc287745ce05314db3f8cd2351fb575561..a8e47e3c4e824a71248021ae32fe0c8b5c5ac3e8 100644 (file)
@@ -13,7 +13,7 @@
 
 #include "pinctrl-meson.h"
 
-#define EE_OFF 14
+#define EE_OFF 15
 
 static const unsigned int emmc_nand_d07_pins[] = {
        PIN(BOOT_0, EE_OFF), PIN(BOOT_1, EE_OFF), PIN(BOOT_2, EE_OFF),
@@ -318,8 +318,6 @@ static const char * const gpio_periphs_groups[] = {
        "GPIOX_10", "GPIOX_11", "GPIOX_12", "GPIOX_13", "GPIOX_14",
        "GPIOX_15", "GPIOX_16", "GPIOX_17", "GPIOX_18", "GPIOX_19",
        "GPIOX_20", "GPIOX_21", "GPIOX_22",
-
-       "GPIO_TEST_N",
 };
 
 static const char * const emmc_groups[] = {
@@ -354,6 +352,8 @@ static const char * const gpio_aobus_groups[] = {
        "GPIOAO_0", "GPIOAO_1", "GPIOAO_2", "GPIOAO_3", "GPIOAO_4",
        "GPIOAO_5", "GPIOAO_6", "GPIOAO_7", "GPIOAO_8", "GPIOAO_9",
        "GPIOAO_10", "GPIOAO_11", "GPIOAO_12", "GPIOAO_13",
+
+       "GPIO_TEST_N",
 };
 
 static const char * const uart_ao_groups[] = {
@@ -409,11 +409,11 @@ static struct meson_bank meson_gxbb_aobus_banks[] = {
 
 struct meson_pinctrl_data meson_gxbb_periphs_pinctrl_data = {
        .name           = "periphs-banks",
-       .pin_base       = 14,
+       .pin_base       = 15,
        .groups         = meson_gxbb_periphs_groups,
        .funcs          = meson_gxbb_periphs_functions,
        .banks          = meson_gxbb_periphs_banks,
-       .num_pins       = 120,
+       .num_pins       = 119,
        .num_groups     = ARRAY_SIZE(meson_gxbb_periphs_groups),
        .num_funcs      = ARRAY_SIZE(meson_gxbb_periphs_functions),
        .num_banks      = ARRAY_SIZE(meson_gxbb_periphs_banks),
@@ -425,7 +425,7 @@ struct meson_pinctrl_data meson_gxbb_aobus_pinctrl_data = {
        .groups         = meson_gxbb_aobus_groups,
        .funcs          = meson_gxbb_aobus_functions,
        .banks          = meson_gxbb_aobus_banks,
-       .num_pins       = 14,
+       .num_pins       = 15,
        .num_groups     = ARRAY_SIZE(meson_gxbb_aobus_groups),
        .num_funcs      = ARRAY_SIZE(meson_gxbb_aobus_functions),
        .num_banks      = ARRAY_SIZE(meson_gxbb_aobus_banks),
index fd60bc611d22a7407c35234092dc42cc315c1a8b..ba6e3531d93e9c4e35ae8acde851a5af892aae18 100644 (file)
@@ -13,7 +13,7 @@
 
 #include "pinctrl-meson.h"
 
-#define EE_OFF 10
+#define EE_OFF 11
 
 static const unsigned int emmc_nand_d07_pins[] = {
        PIN(BOOT_0, EE_OFF), PIN(BOOT_1, EE_OFF), PIN(BOOT_2, EE_OFF),
@@ -289,7 +289,7 @@ static struct meson_pmx_group meson_gxl_periphs_groups[] = {
        GPIO_GROUP(GPIOCLK_0, EE_OFF),
        GPIO_GROUP(GPIOCLK_1, EE_OFF),
 
-       GPIO_GROUP(GPIO_TEST_N, EE_OFF),
+       GPIO_GROUP(GPIO_TEST_N, 0),
 
        /* Bank X */
        GROUP(sdio_d0,          5,      31),
@@ -471,8 +471,6 @@ static const char * const gpio_periphs_groups[] = {
        "GPIOX_5", "GPIOX_6", "GPIOX_7", "GPIOX_8", "GPIOX_9",
        "GPIOX_10", "GPIOX_11", "GPIOX_12", "GPIOX_13", "GPIOX_14",
        "GPIOX_15", "GPIOX_16", "GPIOX_17", "GPIOX_18",
-
-       "GPIO_TEST_N",
 };
 
 static const char * const emmc_groups[] = {
@@ -587,6 +585,8 @@ static const char * const tsin_a_groups[] = {
 static const char * const gpio_aobus_groups[] = {
        "GPIOAO_0", "GPIOAO_1", "GPIOAO_2", "GPIOAO_3", "GPIOAO_4",
        "GPIOAO_5", "GPIOAO_6", "GPIOAO_7", "GPIOAO_8", "GPIOAO_9",
+
+       "GPIO_TEST_N",
 };
 
 static const char * const uart_ao_groups[] = {
@@ -691,11 +691,11 @@ static struct meson_bank meson_gxl_aobus_banks[] = {
 
 struct meson_pinctrl_data meson_gxl_periphs_pinctrl_data = {
        .name           = "periphs-banks",
-       .pin_base       = 10,
+       .pin_base       = 11,
        .groups         = meson_gxl_periphs_groups,
        .funcs          = meson_gxl_periphs_functions,
        .banks          = meson_gxl_periphs_banks,
-       .num_pins       = 101,
+       .num_pins       = 100,
        .num_groups     = ARRAY_SIZE(meson_gxl_periphs_groups),
        .num_funcs      = ARRAY_SIZE(meson_gxl_periphs_functions),
        .num_banks      = ARRAY_SIZE(meson_gxl_periphs_banks),
@@ -707,7 +707,7 @@ struct meson_pinctrl_data meson_gxl_aobus_pinctrl_data = {
        .groups         = meson_gxl_aobus_groups,
        .funcs          = meson_gxl_aobus_functions,
        .banks          = meson_gxl_aobus_banks,
-       .num_pins       = 10,
+       .num_pins       = 11,
        .num_groups     = ARRAY_SIZE(meson_gxl_aobus_groups),
        .num_funcs      = ARRAY_SIZE(meson_gxl_aobus_functions),
        .num_banks      = ARRAY_SIZE(meson_gxl_aobus_banks),
index 7b427d06ece5dc2eae3c3eb7939e7cdb5b501e37..a5935e84de3e15fa22bccd81a568da9d16e90468 100644 (file)
 
 #define UNIPHIER_PINCTRL_PINMUX_BASE   0x1000
 #define UNIPHIER_PINCTRL_LOAD_PINMUX   0x1700
+#define UNIPHIER_PINCTRL_DRVCTRL_BASE  0x1800
+#define UNIPHIER_PINCTRL_DRV2CTRL_BASE 0x1900
+#define UNIPHIER_PINCTRL_DRV3CTRL_BASE 0x1980
 #define UNIPHIER_PINCTRL_PUPDCTRL_BASE 0x1a00
 #define UNIPHIER_PINCTRL_IECTRL                0x1d00
 
 static const char *uniphier_pinctrl_dummy_name = "_dummy";
 
+static int uniphier_pinctrl_get_pins_count(struct udevice *dev)
+{
+       struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
+       const struct uniphier_pinctrl_pin *pins = priv->socdata->pins;
+       int pins_count = priv->socdata->pins_count;
+
+       /*
+        * We do not list all pins in the pin table to save memory footprint.
+        * Report the max pin number + 1 to fake the framework.
+        */
+       return pins[pins_count - 1].number + 1;
+}
+
+static const char *uniphier_pinctrl_get_pin_name(struct udevice *dev,
+                                                unsigned int selector)
+{
+       struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
+       const struct uniphier_pinctrl_pin *pins = priv->socdata->pins;
+       int pins_count = priv->socdata->pins_count;
+       int i;
+
+       for (i = 0; i < pins_count; i++)
+               if (pins[i].number == selector)
+                       return pins[i].name;
+
+       return uniphier_pinctrl_dummy_name;
+}
+
 static int uniphier_pinctrl_get_groups_count(struct udevice *dev)
 {
        struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
@@ -113,10 +144,25 @@ static const struct pinconf_param uniphier_pinconf_params[] = {
        { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 },
        { "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 },
        { "bias-pull-pin-default", PIN_CONFIG_BIAS_PULL_PIN_DEFAULT, 1 },
+       { "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 0 },
        { "input-enable", PIN_CONFIG_INPUT_ENABLE, 1 },
        { "input-disable", PIN_CONFIG_INPUT_ENABLE, 0 },
 };
 
+static const struct uniphier_pinctrl_pin *
+uniphier_pinctrl_pin_get(struct uniphier_pinctrl_priv *priv, unsigned int pin)
+{
+       const struct uniphier_pinctrl_pin *pins = priv->socdata->pins;
+       int pins_count = priv->socdata->pins_count;
+       int i;
+
+       for (i = 0; i < pins_count; i++)
+               if (pins[i].number == pin)
+                       return &pins[i];
+
+       return NULL;
+}
+
 static int uniphier_pinconf_bias_set(struct udevice *dev, unsigned int pin,
                                     unsigned int param, unsigned int arg)
 {
@@ -157,8 +203,88 @@ static int uniphier_pinconf_bias_set(struct udevice *dev, unsigned int pin,
        return 0;
 }
 
-static int uniphier_pinconf_set_one(struct udevice *dev, unsigned int pin,
-                                   unsigned int param, unsigned int arg)
+static const unsigned int uniphier_pinconf_drv_strengths_1bit[] = {
+       4, 8,
+};
+
+static const unsigned int uniphier_pinconf_drv_strengths_2bit[] = {
+       8, 12, 16, 20,
+};
+
+static const unsigned int uniphier_pinconf_drv_strengths_3bit[] = {
+       4, 5, 7, 9, 11, 12, 14, 16,
+};
+
+static int uniphier_pinconf_drive_set(struct udevice *dev, unsigned int pin,
+                                     unsigned int strength)
+{
+       struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
+       const struct uniphier_pinctrl_pin *desc;
+       const unsigned int *strengths;
+       unsigned int base, stride, width, drvctrl, reg, shift;
+       u32 val, mask, tmp;
+
+       desc = uniphier_pinctrl_pin_get(priv, pin);
+       if (WARN_ON(!desc))
+               return -EINVAL;
+
+       switch (uniphier_pin_get_drv_type(desc->data)) {
+       case UNIPHIER_PIN_DRV_1BIT:
+               strengths = uniphier_pinconf_drv_strengths_1bit;
+               base = UNIPHIER_PINCTRL_DRVCTRL_BASE;
+               stride = 1;
+               width = 1;
+               break;
+       case UNIPHIER_PIN_DRV_2BIT:
+               strengths = uniphier_pinconf_drv_strengths_2bit;
+               base = UNIPHIER_PINCTRL_DRV2CTRL_BASE;
+               stride = 2;
+               width = 2;
+               break;
+       case UNIPHIER_PIN_DRV_3BIT:
+               strengths = uniphier_pinconf_drv_strengths_3bit;
+               base = UNIPHIER_PINCTRL_DRV3CTRL_BASE;
+               stride = 4;
+               width = 3;
+               break;
+       default:
+               /* drive strength control is not supported for this pin */
+               return -EINVAL;
+       }
+
+       drvctrl = uniphier_pin_get_drvctrl(desc->data);
+       drvctrl *= stride;
+
+       reg = base + drvctrl / 32 * 4;
+       shift = drvctrl % 32;
+       mask = (1U << width) - 1;
+
+       for (val = 0; val <= mask; val++) {
+               if (strengths[val] > strength)
+                       break;
+       }
+
+       if (val == 0) {
+               dev_err(dev, "unsupported drive strength %u mA for pin %s\n",
+                       strength, desc->name);
+               return -EINVAL;
+       }
+
+       if (!mask)
+               return 0;
+
+       val--;
+
+       tmp = readl(priv->base + reg);
+       tmp &= ~(mask << shift);
+       tmp |= (mask & val) << shift;
+       writel(tmp, priv->base + reg);
+
+       return 0;
+}
+
+static int uniphier_pinconf_set(struct udevice *dev, unsigned int pin,
+                               unsigned int param, unsigned int arg)
 {
        int ret;
 
@@ -169,11 +295,14 @@ static int uniphier_pinconf_set_one(struct udevice *dev, unsigned int pin,
        case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
                ret = uniphier_pinconf_bias_set(dev, pin, param, arg);
                break;
+       case PIN_CONFIG_DRIVE_STRENGTH:
+               ret = uniphier_pinconf_drive_set(dev, pin, arg);
+               break;
        case PIN_CONFIG_INPUT_ENABLE:
                ret = uniphier_pinconf_input_enable(dev, pin, arg);
                break;
        default:
-               printf("unsupported configuration parameter %u\n", param);
+               dev_err(dev, "unsupported configuration parameter %u\n", param);
                return -EINVAL;
        }
 
@@ -190,7 +319,7 @@ static int uniphier_pinconf_group_set(struct udevice *dev,
        int i, ret;
 
        for (i = 0; i < grp->num_pins; i++) {
-               ret = uniphier_pinconf_set_one(dev, grp->pins[i], param, arg);
+               ret = uniphier_pinconf_set(dev, grp->pins[i], param, arg);
                if (ret)
                        return ret;
        }
@@ -268,6 +397,8 @@ static int uniphier_pinmux_group_set(struct udevice *dev,
 }
 
 const struct pinctrl_ops uniphier_pinctrl_ops = {
+       .get_pins_count = uniphier_pinctrl_get_pins_count,
+       .get_pin_name = uniphier_pinctrl_get_pin_name,
        .get_groups_count = uniphier_pinctrl_get_groups_count,
        .get_group_name = uniphier_pinctrl_get_group_name,
        .get_functions_count = uniphier_pinmux_get_functions_count,
@@ -276,6 +407,7 @@ const struct pinctrl_ops uniphier_pinctrl_ops = {
 #if CONFIG_IS_ENABLED(PINCONF)
        .pinconf_num_params = ARRAY_SIZE(uniphier_pinconf_params),
        .pinconf_params = uniphier_pinconf_params,
+       .pinconf_set = uniphier_pinconf_set,
        .pinconf_group_set = uniphier_pinconf_group_set,
 #endif
        .set_state = pinctrl_generic_set_state,
index ecf4355000a891b915183a4b6f8d24cd001fab38..8ec87f285ed402dcb22d327f02bfb3f9d7a2cde5 100644 (file)
 
 #include "pinctrl-uniphier.h"
 
+static const struct uniphier_pinctrl_pin uniphier_ld20_pins[] = {
+       UNIPHIER_PINCTRL_PIN(40, "RGMII_TXCLK", 28, UNIPHIER_PIN_DRV_3BIT),
+       UNIPHIER_PINCTRL_PIN(41, "RGMII_TXD0", 29, UNIPHIER_PIN_DRV_3BIT),
+       UNIPHIER_PINCTRL_PIN(42, "RGMII_TXD1", 30, UNIPHIER_PIN_DRV_3BIT),
+       UNIPHIER_PINCTRL_PIN(43, "RGMII_TXD2", 31, UNIPHIER_PIN_DRV_3BIT),
+       UNIPHIER_PINCTRL_PIN(44, "RGMII_TXD3", 32, UNIPHIER_PIN_DRV_3BIT),
+       UNIPHIER_PINCTRL_PIN(45, "RGMII_TXCTL", 33, UNIPHIER_PIN_DRV_3BIT),
+};
+
 static const unsigned emmc_pins[] = {18, 19, 20, 21, 22, 23, 24, 25};
 static const int emmc_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0};
 static const unsigned emmc_dat8_pins[] = {26, 27, 28, 29};
@@ -102,6 +111,8 @@ static const char * const uniphier_ld20_functions[] = {
 };
 
 static struct uniphier_pinctrl_socdata uniphier_ld20_pinctrl_socdata = {
+       .pins = uniphier_ld20_pins,
+       .pins_count = ARRAY_SIZE(uniphier_ld20_pins),
        .groups = uniphier_ld20_groups,
        .groups_count = ARRAY_SIZE(uniphier_ld20_groups),
        .functions = uniphier_ld20_functions,
index b9076678b2e7f0d6a9088bd20a236012e387c022..30d411694c56fa28f3c795c7f577a3fe90fc0f95 100644 (file)
 
 #include "pinctrl-uniphier.h"
 
-static const struct uniphier_pinctrl_pin uniphier_ld6b_pins[] = {
-       UNIPHIER_PINCTRL_PIN(113, 0),
-       UNIPHIER_PINCTRL_PIN(114, 0),
-       UNIPHIER_PINCTRL_PIN(115, 0),
-       UNIPHIER_PINCTRL_PIN(116, 0),
-       UNIPHIER_PINCTRL_PIN(217, 0),
-       UNIPHIER_PINCTRL_PIN(218, 0),
-       UNIPHIER_PINCTRL_PIN(219, 0),
-       UNIPHIER_PINCTRL_PIN(220, 0),
-};
-
 static const unsigned emmc_pins[] = {36, 37, 38, 39, 40, 41, 42};
 static const int emmc_muxvals[] = {1, 1, 1, 1, 1, 1, 1};
 static const unsigned emmc_dat8_pins[] = {43, 44, 45, 46};
@@ -134,8 +123,6 @@ static const char * const uniphier_ld6b_functions[] = {
 };
 
 static struct uniphier_pinctrl_socdata uniphier_ld6b_pinctrl_socdata = {
-       .pins = uniphier_ld6b_pins,
-       .pins_count = ARRAY_SIZE(uniphier_ld6b_pins),
        .groups = uniphier_ld6b_groups,
        .groups_count = ARRAY_SIZE(uniphier_ld6b_groups),
        .functions = uniphier_ld6b_functions,
index 6557f6a6c7e318ce746b595fd6865dfa15f51c59..8f83ecae7dbabcd31a21f6e3f3beedf0544d1707 100644 (file)
@@ -8,15 +8,48 @@
 #define __PINCTRL_UNIPHIER_H__
 
 #include <linux/bitops.h>
-#include <linux/bug.h>
+#include <linux/build_bug.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
 
-#define UNIPHIER_PIN_ATTR_PACKED(iectrl)       (iectrl)
+/* drive strength control register number */
+#define UNIPHIER_PIN_DRVCTRL_SHIFT     0
+#define UNIPHIER_PIN_DRVCTRL_BITS      9
+#define UNIPHIER_PIN_DRVCTRL_MASK      ((1U << (UNIPHIER_PIN_DRVCTRL_BITS)) \
+                                        - 1)
+
+/* drive control type */
+#define UNIPHIER_PIN_DRV_TYPE_SHIFT    ((UNIPHIER_PIN_DRVCTRL_SHIFT) + \
+                                        (UNIPHIER_PIN_DRVCTRL_BITS))
+#define UNIPHIER_PIN_DRV_TYPE_BITS     2
+#define UNIPHIER_PIN_DRV_TYPE_MASK     ((1U << (UNIPHIER_PIN_DRV_TYPE_BITS)) \
+                                        - 1)
+
+/* drive control type */
+enum uniphier_pin_drv_type {
+       UNIPHIER_PIN_DRV_1BIT,          /* 2 level control: 4/8 mA */
+       UNIPHIER_PIN_DRV_2BIT,          /* 4 level control: 8/12/16/20 mA */
+       UNIPHIER_PIN_DRV_3BIT,          /* 8 level control: 4/5/7/9/11/12/14/16 mA */
+};
+
+#define UNIPHIER_PIN_DRVCTRL(x) \
+       (((x) & (UNIPHIER_PIN_DRVCTRL_MASK)) << (UNIPHIER_PIN_DRVCTRL_SHIFT))
+#define UNIPHIER_PIN_DRV_TYPE(x) \
+       (((x) & (UNIPHIER_PIN_DRV_TYPE_MASK)) << (UNIPHIER_PIN_DRV_TYPE_SHIFT))
 
-static inline unsigned int uniphier_pin_get_iectrl(unsigned long data)
+#define UNIPHIER_PIN_ATTR_PACKED(drvctrl, drv_type)    \
+       UNIPHIER_PIN_DRVCTRL(drvctrl) |                 \
+       UNIPHIER_PIN_DRV_TYPE(drv_type)
+
+static inline unsigned int uniphier_pin_get_drvctrl(unsigned int data)
 {
-       return data;
+       return (data >> UNIPHIER_PIN_DRVCTRL_SHIFT) & UNIPHIER_PIN_DRVCTRL_MASK;
+}
+
+static inline unsigned int uniphier_pin_get_drv_type(unsigned int data)
+{
+       return (data >> UNIPHIER_PIN_DRV_TYPE_SHIFT) &
+                                               UNIPHIER_PIN_DRV_TYPE_MASK;
 }
 
 /**
@@ -27,7 +60,8 @@ static inline unsigned int uniphier_pin_get_iectrl(unsigned long data)
  */
 struct uniphier_pinctrl_pin {
        unsigned number;
-       unsigned long data;
+       const char *name;
+       unsigned int data;
 };
 
 /**
@@ -72,10 +106,11 @@ struct uniphier_pinctrl_socdata {
 #define UNIPHIER_PINCTRL_CAPS_MUX_4BIT         BIT(0)
 };
 
-#define UNIPHIER_PINCTRL_PIN(a, b)                                     \
+#define UNIPHIER_PINCTRL_PIN(a, b, c, d)                               \
 {                                                                      \
        .number = a,                                                    \
-       .data = UNIPHIER_PIN_ATTR_PACKED(b),                            \
+       .name = b,                                                      \
+       .data = UNIPHIER_PIN_ATTR_PACKED(c, d),                         \
 }
 
 #define __UNIPHIER_PINCTRL_GROUP(grp)                                  \
index a765c4f2e9ca2fc421b6540c08277abfc593f425..82351b66137050ec0f836e67e415d293672f3f5b 100644 (file)
 
 #define STMPU1_NUM_OF_REGS 0x100
 
+#ifndef CONFIG_SPL_BUILD
+static const struct pmic_child_info stpmu1_children_info[] = {
+       { .prefix = "ldo", .driver = "stpmu1_ldo" },
+       { .prefix = "buck", .driver = "stpmu1_buck" },
+       { .prefix = "vref_ddr", .driver = "stpmu1_vref_ddr" },
+       { .prefix = "pwr_sw", .driver = "stpmu1_pwr_sw" },
+       { .prefix = "boost", .driver = "stpmu1_boost" },
+       { },
+};
+#endif /* CONFIG_SPL_BUILD */
+
 static int stpmu1_reg_count(struct udevice *dev)
 {
        return STMPU1_NUM_OF_REGS;
@@ -42,6 +53,28 @@ static int stpmu1_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
        return ret;
 }
 
+static int stpmu1_bind(struct udevice *dev)
+{
+#ifndef CONFIG_SPL_BUILD
+       ofnode regulators_node;
+       int children;
+
+       regulators_node = dev_read_subnode(dev, "regulators");
+       if (!ofnode_valid(regulators_node)) {
+               dev_dbg(dev, "regulators subnode not found!");
+               return -ENXIO;
+       }
+       dev_dbg(dev, "found regulators subnode\n");
+
+       children = pmic_bind_children(dev, regulators_node,
+                                     stpmu1_children_info);
+       if (!children)
+               dev_dbg(dev, "no child found\n");
+#endif /* CONFIG_SPL_BUILD */
+
+       return 0;
+}
+
 static struct dm_pmic_ops stpmu1_ops = {
        .reg_count = stpmu1_reg_count,
        .read = stpmu1_read,
@@ -57,5 +90,6 @@ U_BOOT_DRIVER(pmic_stpmu1) = {
        .name = "stpmu1_pmic",
        .id = UCLASS_PMIC,
        .of_match = stpmu1_ids,
+       .bind = stpmu1_bind,
        .ops = &stpmu1_ops,
 };
index 5b4ac10462b4b4c14fd8950747bf438716b4aedd..414f4a53f786827a1c140e40e34a10384ea840c2 100644 (file)
@@ -197,6 +197,15 @@ config DM_REGULATOR_LP87565
        be configured in multi phase modes. The driver implements
        get/set api for value and enable.
 
+config DM_REGULATOR_STM32_VREFBUF
+       bool "Enable driver for STMicroelectronics STM32 VREFBUF"
+       depends on DM_REGULATOR && (STM32H7 || ARCH_STM32MP)
+       help
+       This driver supports STMicroelectronics STM32 VREFBUF (voltage
+       reference buffer) which can be used as voltage reference for
+       internal ADCs, DACs and also for external components through
+       dedicated Vref+ pin.
+
 config DM_REGULATOR_TPS65910
        bool "Enable driver for TPS65910 PMIC regulators"
        depends on DM_PMIC_TPS65910
@@ -204,3 +213,12 @@ config DM_REGULATOR_TPS65910
        The TPS65910 PMIC provides 4 SMPSs and 8 LDOs. This driver supports all
        regulator types of the TPS65910 (BUCK, BOOST and LDO). It implements
        the get/set api for value and enable.
+
+config DM_REGULATOR_STPMU1
+       bool "Enable driver for STPMU1 regulators"
+       depends on DM_REGULATOR && PMIC_STPMU1
+       ---help---
+       Enable support for the regulator functions of the STPMU1 PMIC. The
+       driver implements get/set api for the various BUCKS and LDOs supported
+       by the PMIC device. This driver is controlled by a device tree node
+       which includes voltage limits.
index f7873ad27af16fe26bedfc60f84591a7ddd8d1e7..16208af0694bcba788186014496a99b8c7caf7d3 100644 (file)
@@ -22,4 +22,6 @@ obj-$(CONFIG_$(SPL_)DM_REGULATOR_PALMAS) += palmas_regulator.o
 obj-$(CONFIG_$(SPL_)DM_REGULATOR_PBIAS) += pbias_regulator.o
 obj-$(CONFIG_$(SPL_)DM_REGULATOR_LP873X) += lp873x_regulator.o
 obj-$(CONFIG_$(SPL_)DM_REGULATOR_LP87565) += lp87565_regulator.o
+obj-$(CONFIG_$(SPL_)DM_REGULATOR_STM32_VREFBUF) += stm32-vrefbuf.o
 obj-$(CONFIG_DM_REGULATOR_TPS65910) += tps65910_regulator.o
+obj-$(CONFIG_$(SPL_)DM_REGULATOR_STPMU1) += stpmu1.o
diff --git a/drivers/power/regulator/stm32-vrefbuf.c b/drivers/power/regulator/stm32-vrefbuf.c
new file mode 100644 (file)
index 0000000..0ad6833
--- /dev/null
@@ -0,0 +1,155 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
+ * Author: Fabrice Gasnier <fabrice.gasnier@st.com>
+ *
+ * Originally based on the Linux kernel v4.16 drivers/regulator/stm32-vrefbuf.c
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <asm/io.h>
+#include <linux/iopoll.h>
+#include <linux/kernel.h>
+#include <power/regulator.h>
+
+/* STM32 VREFBUF registers */
+#define STM32_VREFBUF_CSR              0x00
+
+/* STM32 VREFBUF CSR bitfields */
+#define STM32_VRS                      GENMASK(6, 4)
+#define STM32_VRS_SHIFT                        4
+#define STM32_VRR                      BIT(3)
+#define STM32_HIZ                      BIT(1)
+#define STM32_ENVR                     BIT(0)
+
+struct stm32_vrefbuf {
+       void __iomem *base;
+       struct clk clk;
+       struct udevice *vdda_supply;
+};
+
+static const unsigned int stm32_vrefbuf_voltages[] = {
+       /* Matches resp. VRS = 000b, 001b, 010b, 011b */
+       2500000, 2048000, 1800000, 1500000,
+};
+
+static int stm32_vrefbuf_set_enable(struct udevice *dev, bool enable)
+{
+       struct stm32_vrefbuf *priv = dev_get_priv(dev);
+       u32 val;
+       int ret;
+
+       clrsetbits_le32(priv->base + STM32_VREFBUF_CSR, STM32_HIZ | STM32_ENVR,
+                       enable ? STM32_ENVR : STM32_HIZ);
+       if (!enable)
+               return 0;
+
+       /*
+        * Vrefbuf startup time depends on external capacitor: wait here for
+        * VRR to be set. That means output has reached expected value.
+        * ~650us sleep should be enough for caps up to 1.5uF. Use 10ms as
+        * arbitrary timeout.
+        */
+       ret = readl_poll_timeout(priv->base + STM32_VREFBUF_CSR, val,
+                                val & STM32_VRR, 10000);
+       if (ret < 0) {
+               dev_err(dev, "stm32 vrefbuf timed out: %d\n", ret);
+               clrsetbits_le32(priv->base + STM32_VREFBUF_CSR, STM32_ENVR,
+                               STM32_HIZ);
+               return ret;
+       }
+
+       return 0;
+}
+
+static int stm32_vrefbuf_get_enable(struct udevice *dev)
+{
+       struct stm32_vrefbuf *priv = dev_get_priv(dev);
+
+       return readl(priv->base + STM32_VREFBUF_CSR) & STM32_ENVR;
+}
+
+static int stm32_vrefbuf_set_value(struct udevice *dev, int uV)
+{
+       struct stm32_vrefbuf *priv = dev_get_priv(dev);
+       unsigned int i;
+
+       for (i = 0; i < ARRAY_SIZE(stm32_vrefbuf_voltages); i++) {
+               if (uV == stm32_vrefbuf_voltages[i]) {
+                       clrsetbits_le32(priv->base + STM32_VREFBUF_CSR,
+                                       STM32_VRS, i << STM32_VRS_SHIFT);
+                       return 0;
+               }
+       }
+
+       return -EINVAL;
+}
+
+static int stm32_vrefbuf_get_value(struct udevice *dev)
+{
+       struct stm32_vrefbuf *priv = dev_get_priv(dev);
+       u32 val;
+
+       val = readl(priv->base + STM32_VREFBUF_CSR) & STM32_VRS;
+       val >>= STM32_VRS_SHIFT;
+
+       return stm32_vrefbuf_voltages[val];
+}
+
+static const struct dm_regulator_ops stm32_vrefbuf_ops = {
+       .get_value  = stm32_vrefbuf_get_value,
+       .set_value  = stm32_vrefbuf_set_value,
+       .get_enable = stm32_vrefbuf_get_enable,
+       .set_enable = stm32_vrefbuf_set_enable,
+};
+
+static int stm32_vrefbuf_probe(struct udevice *dev)
+{
+       struct stm32_vrefbuf *priv = dev_get_priv(dev);
+       int ret;
+
+       priv->base = dev_read_addr_ptr(dev);
+
+       ret = clk_get_by_index(dev, 0, &priv->clk);
+       if (ret) {
+               dev_err(dev, "Can't get clock: %d\n", ret);
+               return ret;
+       }
+
+       ret = clk_enable(&priv->clk);
+       if (ret) {
+               dev_err(dev, "Can't enable clock: %d\n", ret);
+               return ret;
+       }
+
+       ret = device_get_supply_regulator(dev, "vdda-supply",
+                                         &priv->vdda_supply);
+       if (ret) {
+               dev_dbg(dev, "No vdda-supply: %d\n", ret);
+               return 0;
+       }
+
+       ret = regulator_set_enable(priv->vdda_supply, true);
+       if (ret) {
+               dev_err(dev, "Can't enable vdda-supply: %d\n", ret);
+               clk_disable(&priv->clk);
+       }
+
+       return ret;
+}
+
+static const struct udevice_id stm32_vrefbuf_ids[] = {
+       { .compatible = "st,stm32-vrefbuf" },
+       { }
+};
+
+U_BOOT_DRIVER(stm32_vrefbuf) = {
+       .name  = "stm32-vrefbuf",
+       .id = UCLASS_REGULATOR,
+       .of_match = stm32_vrefbuf_ids,
+       .probe = stm32_vrefbuf_probe,
+       .ops = &stm32_vrefbuf_ops,
+       .priv_auto_alloc_size = sizeof(struct stm32_vrefbuf),
+};
diff --git a/drivers/power/regulator/stpmu1.c b/drivers/power/regulator/stpmu1.c
new file mode 100644 (file)
index 0000000..2dedb80
--- /dev/null
@@ -0,0 +1,667 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
+ * Author: Christophe Kerello <christophe.kerello@st.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <power/pmic.h>
+#include <power/regulator.h>
+#include <power/stpmu1.h>
+
+struct stpmu1_range {
+       int min_uv;
+       int min_sel;
+       int max_sel;
+       int step;
+};
+
+struct stpmu1_output_range {
+       const struct stpmu1_range *ranges;
+       int nbranges;
+};
+
+#define STPMU1_MODE(_id, _val, _name) { \
+       .id = _id,                      \
+       .register_value = _val,         \
+       .name = _name,                  \
+}
+
+#define STPMU1_RANGE(_min_uv, _min_sel, _max_sel, _step) { \
+       .min_uv = _min_uv,              \
+       .min_sel = _min_sel,            \
+       .max_sel = _max_sel,            \
+       .step = _step,                  \
+}
+
+#define STPMU1_OUTPUT_RANGE(_ranges, _nbranges) { \
+       .ranges = _ranges,              \
+       .nbranges = _nbranges,          \
+}
+
+static int stpmu1_output_find_uv(int sel,
+                                const struct stpmu1_output_range *output_range)
+{
+       const struct stpmu1_range *range;
+       int i;
+
+       for (i = 0, range = output_range->ranges;
+            i < output_range->nbranges; i++, range++) {
+               if (sel >= range->min_sel && sel <= range->max_sel)
+                       return range->min_uv +
+                              (sel - range->min_sel) * range->step;
+       }
+
+       return -EINVAL;
+}
+
+static int stpmu1_output_find_sel(int uv,
+                                 const struct stpmu1_output_range *output_range)
+{
+       const struct stpmu1_range *range;
+       int i;
+
+       for (i = 0, range = output_range->ranges;
+            i < output_range->nbranges; i++, range++) {
+               if (uv == range->min_uv && !range->step)
+                       return range->min_sel;
+
+               if (uv >= range->min_uv &&
+                   uv <= range->min_uv +
+                         (range->max_sel - range->min_sel) * range->step)
+                       return range->min_sel +
+                              (uv - range->min_uv) / range->step;
+       }
+
+       return -EINVAL;
+}
+
+/*
+ * BUCK regulators
+ */
+
+static const struct stpmu1_range buck1_ranges[] = {
+       STPMU1_RANGE(600000, 0, 30, 25000),
+       STPMU1_RANGE(1350000, 31, 63, 0),
+};
+
+static const struct stpmu1_range buck2_ranges[] = {
+       STPMU1_RANGE(1000000, 0, 17, 0),
+       STPMU1_RANGE(1050000, 18, 19, 0),
+       STPMU1_RANGE(1100000, 20, 21, 0),
+       STPMU1_RANGE(1150000, 22, 23, 0),
+       STPMU1_RANGE(1200000, 24, 25, 0),
+       STPMU1_RANGE(1250000, 26, 27, 0),
+       STPMU1_RANGE(1300000, 28, 29, 0),
+       STPMU1_RANGE(1350000, 30, 31, 0),
+       STPMU1_RANGE(1400000, 32, 33, 0),
+       STPMU1_RANGE(1450000, 34, 35, 0),
+       STPMU1_RANGE(1500000, 36, 63, 0),
+};
+
+static const struct stpmu1_range buck3_ranges[] = {
+       STPMU1_RANGE(1000000, 0, 19, 0),
+       STPMU1_RANGE(1100000, 20, 23, 0),
+       STPMU1_RANGE(1200000, 24, 27, 0),
+       STPMU1_RANGE(1300000, 28, 31, 0),
+       STPMU1_RANGE(1400000, 32, 35, 0),
+       STPMU1_RANGE(1500000, 36, 55, 100000),
+       STPMU1_RANGE(3400000, 56, 63, 0),
+};
+
+static const struct stpmu1_range buck4_ranges[] = {
+       STPMU1_RANGE(600000, 0, 27, 25000),
+       STPMU1_RANGE(1300000, 28, 29, 0),
+       STPMU1_RANGE(1350000, 30, 31, 0),
+       STPMU1_RANGE(1400000, 32, 33, 0),
+       STPMU1_RANGE(1450000, 34, 35, 0),
+       STPMU1_RANGE(1500000, 36, 60, 100000),
+       STPMU1_RANGE(3900000, 61, 63, 0),
+};
+
+/* BUCK: 1,2,3,4 - voltage ranges */
+static const struct stpmu1_output_range buck_voltage_range[] = {
+       STPMU1_OUTPUT_RANGE(buck1_ranges, ARRAY_SIZE(buck1_ranges)),
+       STPMU1_OUTPUT_RANGE(buck2_ranges, ARRAY_SIZE(buck2_ranges)),
+       STPMU1_OUTPUT_RANGE(buck3_ranges, ARRAY_SIZE(buck3_ranges)),
+       STPMU1_OUTPUT_RANGE(buck4_ranges, ARRAY_SIZE(buck4_ranges)),
+};
+
+/* BUCK modes */
+static const struct dm_regulator_mode buck_modes[] = {
+       STPMU1_MODE(STPMU1_BUCK_MODE_HP, STPMU1_BUCK_MODE_HP, "HP"),
+       STPMU1_MODE(STPMU1_BUCK_MODE_LP, STPMU1_BUCK_MODE_LP, "LP"),
+};
+
+static int stpmu1_buck_get_uv(struct udevice *dev, int buck)
+{
+       int sel;
+
+       sel = pmic_reg_read(dev, STPMU1_BUCKX_CTRL_REG(buck));
+       if (sel < 0)
+               return sel;
+
+       sel &= STPMU1_BUCK_OUTPUT_MASK;
+       sel >>= STPMU1_BUCK_OUTPUT_SHIFT;
+
+       return stpmu1_output_find_uv(sel, &buck_voltage_range[buck]);
+}
+
+static int stpmu1_buck_get_value(struct udevice *dev)
+{
+       return stpmu1_buck_get_uv(dev->parent, dev->driver_data - 1);
+}
+
+static int stpmu1_buck_set_value(struct udevice *dev, int uv)
+{
+       int sel, buck = dev->driver_data - 1;
+
+       sel = stpmu1_output_find_sel(uv, &buck_voltage_range[buck]);
+       if (sel < 0)
+               return sel;
+
+       return pmic_clrsetbits(dev->parent,
+                              STPMU1_BUCKX_CTRL_REG(buck),
+                              STPMU1_BUCK_OUTPUT_MASK,
+                              sel << STPMU1_BUCK_OUTPUT_SHIFT);
+}
+
+static int stpmu1_buck_get_enable(struct udevice *dev)
+{
+       int ret;
+
+       ret = pmic_reg_read(dev->parent,
+                           STPMU1_BUCKX_CTRL_REG(dev->driver_data - 1));
+       if (ret < 0)
+               return false;
+
+       return ret & STPMU1_BUCK_EN ? true : false;
+}
+
+static int stpmu1_buck_set_enable(struct udevice *dev, bool enable)
+{
+       struct dm_regulator_uclass_platdata *uc_pdata;
+       int ret, uv;
+
+       /* if regulator is already in the wanted state, nothing to do */
+       if (stpmu1_buck_get_enable(dev) == enable)
+               return 0;
+
+       if (enable) {
+               uc_pdata = dev_get_uclass_platdata(dev);
+               uv = stpmu1_buck_get_value(dev);
+               if ((uv < uc_pdata->min_uV) || (uv > uc_pdata->max_uV))
+                       stpmu1_buck_set_value(dev, uc_pdata->min_uV);
+       }
+
+       ret = pmic_clrsetbits(dev->parent,
+                             STPMU1_BUCKX_CTRL_REG(dev->driver_data - 1),
+                             STPMU1_BUCK_EN, enable ? STPMU1_BUCK_EN : 0);
+       if (enable)
+               mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS);
+
+       return ret;
+}
+
+static int stpmu1_buck_get_mode(struct udevice *dev)
+{
+       int ret;
+
+       ret = pmic_reg_read(dev->parent,
+                           STPMU1_BUCKX_CTRL_REG(dev->driver_data - 1));
+       if (ret < 0)
+               return ret;
+
+       return ret & STPMU1_BUCK_MODE ? STPMU1_BUCK_MODE_LP :
+                                        STPMU1_BUCK_MODE_HP;
+}
+
+static int stpmu1_buck_set_mode(struct udevice *dev, int mode)
+{
+       return pmic_clrsetbits(dev->parent,
+                              STPMU1_BUCKX_CTRL_REG(dev->driver_data - 1),
+                              STPMU1_BUCK_MODE,
+                              mode ? STPMU1_BUCK_MODE : 0);
+}
+
+static int stpmu1_buck_probe(struct udevice *dev)
+{
+       struct dm_regulator_uclass_platdata *uc_pdata;
+
+       if (!dev->driver_data || dev->driver_data > STPMU1_MAX_BUCK)
+               return -EINVAL;
+
+       uc_pdata = dev_get_uclass_platdata(dev);
+
+       uc_pdata->type = REGULATOR_TYPE_BUCK;
+       uc_pdata->mode = (struct dm_regulator_mode *)buck_modes;
+       uc_pdata->mode_count = ARRAY_SIZE(buck_modes);
+
+       return 0;
+}
+
+static const struct dm_regulator_ops stpmu1_buck_ops = {
+       .get_value  = stpmu1_buck_get_value,
+       .set_value  = stpmu1_buck_set_value,
+       .get_enable = stpmu1_buck_get_enable,
+       .set_enable = stpmu1_buck_set_enable,
+       .get_mode   = stpmu1_buck_get_mode,
+       .set_mode   = stpmu1_buck_set_mode,
+};
+
+U_BOOT_DRIVER(stpmu1_buck) = {
+       .name = "stpmu1_buck",
+       .id = UCLASS_REGULATOR,
+       .ops = &stpmu1_buck_ops,
+       .probe = stpmu1_buck_probe,
+};
+
+/*
+ * LDO regulators
+ */
+
+static const struct stpmu1_range ldo12_ranges[] = {
+       STPMU1_RANGE(1700000, 0, 7, 0),
+       STPMU1_RANGE(1700000, 8, 24, 100000),
+       STPMU1_RANGE(3300000, 25, 31, 0),
+};
+
+static const struct stpmu1_range ldo3_ranges[] = {
+       STPMU1_RANGE(1700000, 0, 7, 0),
+       STPMU1_RANGE(1700000, 8, 24, 100000),
+       STPMU1_RANGE(3300000, 25, 30, 0),
+       /* Sel 31 is special case when LDO3 is in mode sync_source (BUCK2/2) */
+};
+
+static const struct stpmu1_range ldo5_ranges[] = {
+       STPMU1_RANGE(1700000, 0, 7, 0),
+       STPMU1_RANGE(1700000, 8, 30, 100000),
+       STPMU1_RANGE(3900000, 31, 31, 0),
+};
+
+static const struct stpmu1_range ldo6_ranges[] = {
+       STPMU1_RANGE(900000, 0, 24, 100000),
+       STPMU1_RANGE(3300000, 25, 31, 0),
+};
+
+/* LDO: 1,2,3,4,5,6 - voltage ranges */
+static const struct stpmu1_output_range ldo_voltage_range[] = {
+       STPMU1_OUTPUT_RANGE(ldo12_ranges, ARRAY_SIZE(ldo12_ranges)),
+       STPMU1_OUTPUT_RANGE(ldo12_ranges, ARRAY_SIZE(ldo12_ranges)),
+       STPMU1_OUTPUT_RANGE(ldo3_ranges, ARRAY_SIZE(ldo3_ranges)),
+       STPMU1_OUTPUT_RANGE(NULL, 0),
+       STPMU1_OUTPUT_RANGE(ldo5_ranges, ARRAY_SIZE(ldo5_ranges)),
+       STPMU1_OUTPUT_RANGE(ldo6_ranges, ARRAY_SIZE(ldo6_ranges)),
+};
+
+/* LDO modes */
+static const struct dm_regulator_mode ldo_modes[] = {
+       STPMU1_MODE(STPMU1_LDO_MODE_NORMAL,
+                   STPMU1_LDO_MODE_NORMAL, "NORMAL"),
+       STPMU1_MODE(STPMU1_LDO_MODE_BYPASS,
+                   STPMU1_LDO_MODE_BYPASS, "BYPASS"),
+       STPMU1_MODE(STPMU1_LDO_MODE_SINK_SOURCE,
+                   STPMU1_LDO_MODE_SINK_SOURCE, "SINK SOURCE"),
+};
+
+static int stpmu1_ldo_get_value(struct udevice *dev)
+{
+       int sel, ldo = dev->driver_data - 1;
+
+       sel = pmic_reg_read(dev->parent, STPMU1_LDOX_CTRL_REG(ldo));
+       if (sel < 0)
+               return sel;
+
+       /* ldo4 => 3,3V */
+       if (ldo == STPMU1_LDO4)
+               return STPMU1_LDO4_UV;
+
+       sel &= STPMU1_LDO12356_OUTPUT_MASK;
+       sel >>= STPMU1_LDO12356_OUTPUT_SHIFT;
+
+       /* ldo3, sel = 31 => BUCK2/2 */
+       if (ldo == STPMU1_LDO3 && sel == STPMU1_LDO3_DDR_SEL)
+               return stpmu1_buck_get_uv(dev->parent, STPMU1_BUCK2) / 2;
+
+       return stpmu1_output_find_uv(sel, &ldo_voltage_range[ldo]);
+}
+
+static int stpmu1_ldo_set_value(struct udevice *dev, int uv)
+{
+       int sel, ldo = dev->driver_data - 1;
+
+       /* ldo4 => not possible */
+       if (ldo == STPMU1_LDO4)
+               return -EINVAL;
+
+       sel = stpmu1_output_find_sel(uv, &ldo_voltage_range[ldo]);
+       if (sel < 0)
+               return sel;
+
+       return pmic_clrsetbits(dev->parent,
+                              STPMU1_LDOX_CTRL_REG(ldo),
+                              STPMU1_LDO12356_OUTPUT_MASK,
+                              sel << STPMU1_LDO12356_OUTPUT_SHIFT);
+}
+
+static int stpmu1_ldo_get_enable(struct udevice *dev)
+{
+       int ret;
+
+       ret = pmic_reg_read(dev->parent,
+                           STPMU1_LDOX_CTRL_REG(dev->driver_data - 1));
+       if (ret < 0)
+               return false;
+
+       return ret & STPMU1_LDO_EN ? true : false;
+}
+
+static int stpmu1_ldo_set_enable(struct udevice *dev, bool enable)
+{
+       struct dm_regulator_uclass_platdata *uc_pdata;
+       int ret, uv;
+
+       /* if regulator is already in the wanted state, nothing to do */
+       if (stpmu1_ldo_get_enable(dev) == enable)
+               return 0;
+
+       if (enable) {
+               uc_pdata = dev_get_uclass_platdata(dev);
+               uv = stpmu1_ldo_get_value(dev);
+               if ((uv < uc_pdata->min_uV) || (uv > uc_pdata->max_uV))
+                       stpmu1_ldo_set_value(dev, uc_pdata->min_uV);
+       }
+
+       ret = pmic_clrsetbits(dev->parent,
+                             STPMU1_LDOX_CTRL_REG(dev->driver_data - 1),
+                             STPMU1_LDO_EN, enable ? STPMU1_LDO_EN : 0);
+       if (enable)
+               mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS);
+
+       return ret;
+}
+
+static int stpmu1_ldo_get_mode(struct udevice *dev)
+{
+       int ret, ldo = dev->driver_data - 1;
+
+       if (ldo != STPMU1_LDO3)
+               return -EINVAL;
+
+       ret = pmic_reg_read(dev->parent, STPMU1_LDOX_CTRL_REG(ldo));
+       if (ret < 0)
+               return ret;
+
+       if (ret & STPMU1_LDO3_MODE)
+               return STPMU1_LDO_MODE_BYPASS;
+
+       ret &= STPMU1_LDO12356_OUTPUT_MASK;
+       ret >>= STPMU1_LDO12356_OUTPUT_SHIFT;
+
+       return ret == STPMU1_LDO3_DDR_SEL ? STPMU1_LDO_MODE_SINK_SOURCE :
+                                            STPMU1_LDO_MODE_NORMAL;
+}
+
+static int stpmu1_ldo_set_mode(struct udevice *dev, int mode)
+{
+       int ret, ldo = dev->driver_data - 1;
+
+       if (ldo != STPMU1_LDO3)
+               return -EINVAL;
+
+       ret = pmic_reg_read(dev->parent, STPMU1_LDOX_CTRL_REG(ldo));
+       if (ret < 0)
+               return ret;
+
+       switch (mode) {
+       case STPMU1_LDO_MODE_SINK_SOURCE:
+               ret &= ~STPMU1_LDO12356_OUTPUT_MASK;
+               ret |= STPMU1_LDO3_DDR_SEL << STPMU1_LDO12356_OUTPUT_SHIFT;
+       case STPMU1_LDO_MODE_NORMAL:
+               ret &= ~STPMU1_LDO3_MODE;
+               break;
+       case STPMU1_LDO_MODE_BYPASS:
+               ret |= STPMU1_LDO3_MODE;
+               break;
+       }
+
+       return pmic_reg_write(dev->parent, STPMU1_LDOX_CTRL_REG(ldo), ret);
+}
+
+static int stpmu1_ldo_probe(struct udevice *dev)
+{
+       struct dm_regulator_uclass_platdata *uc_pdata;
+
+       if (!dev->driver_data || dev->driver_data > STPMU1_MAX_LDO)
+               return -EINVAL;
+
+       uc_pdata = dev_get_uclass_platdata(dev);
+
+       uc_pdata->type = REGULATOR_TYPE_LDO;
+       if (dev->driver_data - 1 == STPMU1_LDO3) {
+               uc_pdata->mode = (struct dm_regulator_mode *)ldo_modes;
+               uc_pdata->mode_count = ARRAY_SIZE(ldo_modes);
+       } else {
+               uc_pdata->mode_count = 0;
+       }
+
+       return 0;
+}
+
+static const struct dm_regulator_ops stpmu1_ldo_ops = {
+       .get_value  = stpmu1_ldo_get_value,
+       .set_value  = stpmu1_ldo_set_value,
+       .get_enable = stpmu1_ldo_get_enable,
+       .set_enable = stpmu1_ldo_set_enable,
+       .get_mode   = stpmu1_ldo_get_mode,
+       .set_mode   = stpmu1_ldo_set_mode,
+};
+
+U_BOOT_DRIVER(stpmu1_ldo) = {
+       .name = "stpmu1_ldo",
+       .id = UCLASS_REGULATOR,
+       .ops = &stpmu1_ldo_ops,
+       .probe = stpmu1_ldo_probe,
+};
+
+/*
+ * VREF DDR regulator
+ */
+
+static int stpmu1_vref_ddr_get_value(struct udevice *dev)
+{
+       /* BUCK2/2 */
+       return stpmu1_buck_get_uv(dev->parent, STPMU1_BUCK2) / 2;
+}
+
+static int stpmu1_vref_ddr_get_enable(struct udevice *dev)
+{
+       int ret;
+
+       ret = pmic_reg_read(dev->parent, STPMU1_VREF_CTRL_REG);
+       if (ret < 0)
+               return false;
+
+       return ret & STPMU1_VREF_EN ? true : false;
+}
+
+static int stpmu1_vref_ddr_set_enable(struct udevice *dev, bool enable)
+{
+       int ret;
+
+       /* if regulator is already in the wanted state, nothing to do */
+       if (stpmu1_vref_ddr_get_enable(dev) == enable)
+               return 0;
+
+       ret = pmic_clrsetbits(dev->parent, STPMU1_VREF_CTRL_REG,
+                             STPMU1_VREF_EN, enable ? STPMU1_VREF_EN : 0);
+       if (enable)
+               mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS);
+
+       return ret;
+}
+
+static int stpmu1_vref_ddr_probe(struct udevice *dev)
+{
+       struct dm_regulator_uclass_platdata *uc_pdata;
+
+       uc_pdata = dev_get_uclass_platdata(dev);
+
+       uc_pdata->type = REGULATOR_TYPE_FIXED;
+       uc_pdata->mode_count = 0;
+
+       return 0;
+}
+
+static const struct dm_regulator_ops stpmu1_vref_ddr_ops = {
+       .get_value  = stpmu1_vref_ddr_get_value,
+       .get_enable = stpmu1_vref_ddr_get_enable,
+       .set_enable = stpmu1_vref_ddr_set_enable,
+};
+
+U_BOOT_DRIVER(stpmu1_vref_ddr) = {
+       .name = "stpmu1_vref_ddr",
+       .id = UCLASS_REGULATOR,
+       .ops = &stpmu1_vref_ddr_ops,
+       .probe = stpmu1_vref_ddr_probe,
+};
+
+/*
+ * BOOST regulator
+ */
+
+static int stpmu1_boost_get_enable(struct udevice *dev)
+{
+       int ret;
+
+       ret = pmic_reg_read(dev->parent, STPMU1_USB_CTRL_REG);
+       if (ret < 0)
+               return false;
+
+       return ret & STPMU1_USB_BOOST_EN ? true : false;
+}
+
+static int stpmu1_boost_set_enable(struct udevice *dev, bool enable)
+{
+       int ret;
+
+       ret = pmic_reg_read(dev->parent, STPMU1_USB_CTRL_REG);
+       if (ret < 0)
+               return ret;
+
+       if (!enable && ret & STPMU1_USB_PWR_SW_EN)
+               return -EINVAL;
+
+       /* if regulator is already in the wanted state, nothing to do */
+       if (!!(ret & STPMU1_USB_BOOST_EN) == enable)
+               return 0;
+
+       ret = pmic_clrsetbits(dev->parent, STPMU1_USB_CTRL_REG,
+                             STPMU1_USB_BOOST_EN,
+                             enable ? STPMU1_USB_BOOST_EN : 0);
+       if (enable)
+               mdelay(STPMU1_USB_BOOST_START_UP_DELAY_MS);
+
+       return ret;
+}
+
+static int stpmu1_boost_probe(struct udevice *dev)
+{
+       struct dm_regulator_uclass_platdata *uc_pdata;
+
+       uc_pdata = dev_get_uclass_platdata(dev);
+
+       uc_pdata->type = REGULATOR_TYPE_FIXED;
+       uc_pdata->mode_count = 0;
+
+       return 0;
+}
+
+static const struct dm_regulator_ops stpmu1_boost_ops = {
+       .get_enable = stpmu1_boost_get_enable,
+       .set_enable = stpmu1_boost_set_enable,
+};
+
+U_BOOT_DRIVER(stpmu1_boost) = {
+       .name = "stpmu1_boost",
+       .id = UCLASS_REGULATOR,
+       .ops = &stpmu1_boost_ops,
+       .probe = stpmu1_boost_probe,
+};
+
+/*
+ * USB power switch
+ */
+
+static int stpmu1_pwr_sw_get_enable(struct udevice *dev)
+{
+       uint mask = 1 << dev->driver_data;
+       int ret;
+
+       ret = pmic_reg_read(dev->parent, STPMU1_USB_CTRL_REG);
+       if (ret < 0)
+               return false;
+
+       return ret & mask ? true : false;
+}
+
+static int stpmu1_pwr_sw_set_enable(struct udevice *dev, bool enable)
+{
+       uint mask = 1 << dev->driver_data;
+       int ret;
+
+       ret = pmic_reg_read(dev->parent, STPMU1_USB_CTRL_REG);
+       if (ret < 0)
+               return ret;
+
+       /* if regulator is already in the wanted state, nothing to do */
+       if (!!(ret & mask) == enable)
+               return 0;
+
+       /* Boost management */
+       if (enable && !(ret & STPMU1_USB_BOOST_EN)) {
+               pmic_clrsetbits(dev->parent, STPMU1_USB_CTRL_REG,
+                               STPMU1_USB_BOOST_EN, STPMU1_USB_BOOST_EN);
+               mdelay(STPMU1_USB_BOOST_START_UP_DELAY_MS);
+       } else if (!enable && ret & STPMU1_USB_BOOST_EN &&
+                  (ret & STPMU1_USB_PWR_SW_EN) != STPMU1_USB_PWR_SW_EN) {
+               pmic_clrsetbits(dev->parent, STPMU1_USB_CTRL_REG,
+                               STPMU1_USB_BOOST_EN, 0);
+       }
+
+       ret = pmic_clrsetbits(dev->parent, STPMU1_USB_CTRL_REG,
+                             mask, enable ? mask : 0);
+       if (enable)
+               mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS);
+
+       return ret;
+}
+
+static int stpmu1_pwr_sw_probe(struct udevice *dev)
+{
+       struct dm_regulator_uclass_platdata *uc_pdata;
+
+       if (!dev->driver_data || dev->driver_data > STPMU1_MAX_PWR_SW)
+               return -EINVAL;
+
+       uc_pdata = dev_get_uclass_platdata(dev);
+
+       uc_pdata->type = REGULATOR_TYPE_FIXED;
+       uc_pdata->mode_count = 0;
+
+       return 0;
+}
+
+static const struct dm_regulator_ops stpmu1_pwr_sw_ops = {
+       .get_enable = stpmu1_pwr_sw_get_enable,
+       .set_enable = stpmu1_pwr_sw_set_enable,
+};
+
+U_BOOT_DRIVER(stpmu1_pwr_sw) = {
+       .name = "stpmu1_pwr_sw",
+       .id = UCLASS_REGULATOR,
+       .ops = &stpmu1_pwr_sw_ops,
+       .probe = stpmu1_pwr_sw_probe,
+};
index db65f71d4377c957372196454babf93270540016..3a9c1e69925e2ee498fbe4987e3b86529f623f34 100644 (file)
@@ -13,6 +13,6 @@
 
 #define MESON_FDTFILE_SETTING "fdtfile=amlogic/meson-gxl-s905x-khadas-vim.dtb\0"
 
-#include <configs/meson-gxbb-common.h>
+#include <configs/meson-gx-common.h>
 
 #endif /* __CONFIG_H */
index dc778dc66a0036d07ff60d8b040581eda51e359d..b44d3bdd32163651a28f4262950ecc001f32d89a 100644 (file)
@@ -13,6 +13,6 @@
 
 #define MESON_FDTFILE_SETTING "fdtfile=amlogic/meson-gxl-s905x-libretech-cc.dtb\0"
 
-#include <configs/meson-gxbb-common.h>
+#include <configs/meson-gx-common.h>
 
 #endif /* __CONFIG_H */
diff --git a/include/configs/meson-gx-common.h b/include/configs/meson-gx-common.h
new file mode 100644 (file)
index 0000000..6e61b70
--- /dev/null
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Configuration for Amlogic Meson GX SoCs
+ * (C) Copyright 2016 Beniamino Galvani <b.galvani@gmail.com>
+ */
+
+#ifndef __MESON_GX_COMMON_CONFIG_H
+#define __MESON_GX_COMMON_CONFIG_H
+
+#define CONFIG_CPU_ARMV8
+#define CONFIG_REMAKE_ELF
+#define CONFIG_NR_DRAM_BANKS           1
+#define CONFIG_ENV_SIZE                        0x2000
+#define CONFIG_SYS_MAXARGS             32
+#define CONFIG_SYS_MALLOC_LEN          (32 << 20)
+#define CONFIG_SYS_CBSIZE              1024
+
+#define CONFIG_SYS_SDRAM_BASE          0
+#define CONFIG_SYS_INIT_SP_ADDR                0x20000000
+#define CONFIG_SYS_LOAD_ADDR           CONFIG_SYS_TEXT_BASE
+
+/* Generic Interrupt Controller Definitions */
+#define GICD_BASE                      0xc4301000
+#define GICC_BASE                      0xc4302000
+
+#define BOOT_TARGET_DEVICES(func) \
+       func(MMC, mmc, 0) \
+       func(MMC, mmc, 1) \
+       func(MMC, mmc, 2) \
+       func(PXE, pxe, na) \
+       func(DHCP, dhcp, na)
+
+#include <config_distro_bootcmd.h>
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+       "fdt_addr_r=0x01000000\0" \
+       "scriptaddr=0x1f000000\0" \
+       "kernel_addr_r=0x01080000\0" \
+       "pxefile_addr_r=0x01080000\0" \
+       "ramdisk_addr_r=0x13000000\0" \
+       MESON_FDTFILE_SETTING \
+       BOOTENV
+
+#define CONFIG_SYS_BOOTM_LEN    (64 << 20)      /* 64 MiB */
+
+#endif /* __MESON_GX_COMMON_CONFIG_H */
diff --git a/include/configs/meson-gxbb-common.h b/include/configs/meson-gxbb-common.h
deleted file mode 100644 (file)
index 068e36e..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Configuration for Amlogic Meson GXBB SoCs
- * (C) Copyright 2016 Beniamino Galvani <b.galvani@gmail.com>
- */
-
-#ifndef __MESON_GXBB_COMMON_CONFIG_H
-#define __MESON_GXBB_COMMON_CONFIG_H
-
-#define CONFIG_CPU_ARMV8
-#define CONFIG_REMAKE_ELF
-#define CONFIG_NR_DRAM_BANKS           1
-#define CONFIG_ENV_SIZE                        0x2000
-#define CONFIG_SYS_MAXARGS             32
-#define CONFIG_SYS_MALLOC_LEN          (32 << 20)
-#define CONFIG_SYS_CBSIZE              1024
-
-#define CONFIG_SYS_SDRAM_BASE          0
-#define CONFIG_SYS_INIT_SP_ADDR                0x20000000
-#define CONFIG_SYS_LOAD_ADDR           CONFIG_SYS_TEXT_BASE
-
-/* Generic Interrupt Controller Definitions */
-#define GICD_BASE                      0xc4301000
-#define GICC_BASE                      0xc4302000
-
-#define BOOT_TARGET_DEVICES(func) \
-       func(MMC, mmc, 0) \
-       func(MMC, mmc, 1) \
-       func(MMC, mmc, 2) \
-       func(PXE, pxe, na) \
-       func(DHCP, dhcp, na)
-
-#include <config_distro_bootcmd.h>
-
-#define CONFIG_EXTRA_ENV_SETTINGS \
-       "fdt_addr_r=0x01000000\0" \
-       "scriptaddr=0x1f000000\0" \
-       "kernel_addr_r=0x01080000\0" \
-       "pxefile_addr_r=0x01080000\0" \
-       "ramdisk_addr_r=0x13000000\0" \
-       MESON_FDTFILE_SETTING \
-       BOOTENV
-
-#define CONFIG_SYS_BOOTM_LEN    (64 << 20)      /* 64 MiB */
-
-#endif /* __MESON_GXBB_COMMON_CONFIG_H */
index a8ad21edf6fe1fd6f1a238af674fe9ae59e42ecb..913943421af658da80d697c32430d37c2d83096f 100644 (file)
@@ -13,6 +13,6 @@
 
 #define MESON_FDTFILE_SETTING "fdtfile=amlogic/meson-gxbb-odroidc2.dtb\0"
 
-#include <configs/meson-gxbb-common.h>
+#include <configs/meson-gx-common.h>
 
 #endif /* __CONFIG_H */
index 0e494372094e5a1f6c1d23c432be2499f16336e6..53af6bc21c10e1b8e059705b431ae4e94d2abcc4 100644 (file)
@@ -15,6 +15,6 @@
 
 #define MESON_FDTFILE_SETTING "fdtfile=amlogic/meson-gxl-s905x-p212.dtb\0"
 
-#include <configs/meson-gxbb-common.h>
+#include <configs/meson-gx-common.h>
 
 #endif /* __CONFIG_H */
index 31751482d13cb498fb4989a41cb336e8c7e92e13..9d15e2221fdb7fd5f732eaa5a800f7b66112f8a5 100644 (file)
@@ -62,5 +62,6 @@
 #define CLKID_AO_UART1         3
 #define CLKID_AO_UART2         4
 #define CLKID_AO_IR_BLASTER    5
+#define CLKID_AO_CEC_32K       6
 
 #endif
index e3e9f7919c318baed4063fc7199def1a6d684018..8ba99a5e3fd34a64f8581ca51cedd47f11e803c5 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * GXBB clock tree IDs
  */
@@ -5,37 +6,96 @@
 #ifndef __GXBB_CLKC_H
 #define __GXBB_CLKC_H
 
+#define CLKID_SYS_PLL          0
 #define CLKID_HDMI_PLL         2
+#define CLKID_FIXED_PLL                3
 #define CLKID_FCLK_DIV2                4
 #define CLKID_FCLK_DIV3                5
 #define CLKID_FCLK_DIV4                6
+#define CLKID_FCLK_DIV5                7
+#define CLKID_FCLK_DIV7                8
 #define CLKID_GP0_PLL          9
 #define CLKID_CLK81            12
+#define CLKID_MPLL0            13
+#define CLKID_MPLL1            14
 #define CLKID_MPLL2            15
+#define CLKID_DDR              16
+#define CLKID_DOS              17
+#define CLKID_ISA              18
+#define CLKID_PL301            19
+#define CLKID_PERIPHS          20
 #define CLKID_SPICC            21
 #define CLKID_I2C              22
 #define CLKID_SAR_ADC          23
+#define CLKID_SMART_CARD       24
 #define CLKID_RNG0             25
 #define CLKID_UART0            26
+#define CLKID_SDHC             27
+#define CLKID_STREAM           28
+#define CLKID_ASYNC_FIFO       29
+#define CLKID_SDIO             30
+#define CLKID_ABUF             31
+#define CLKID_HIU_IFACE                32
+#define CLKID_ASSIST_MISC      33
 #define CLKID_SPI              34
 #define CLKID_ETH              36
+#define CLKID_I2S_SPDIF                35
+#define CLKID_DEMUX            37
 #define CLKID_AIU_GLUE         38
 #define CLKID_IEC958           39
 #define CLKID_I2S_OUT          40
+#define CLKID_AMCLK            41
+#define CLKID_AIFIFO2          42
+#define CLKID_MIXER            43
 #define CLKID_MIXER_IFACE      44
+#define CLKID_ADC              45
+#define CLKID_BLKMV            46
 #define CLKID_AIU              47
 #define CLKID_UART1            48
+#define CLKID_G2D              49
 #define CLKID_USB0             50
 #define CLKID_USB1             51
+#define CLKID_RESET            52
+#define CLKID_NAND             53
+#define CLKID_DOS_PARSER       54
 #define CLKID_USB              55
+#define CLKID_VDIN1            56
+#define CLKID_AHB_ARB0         57
+#define CLKID_EFUSE            58
+#define CLKID_BOOT_ROM         59
+#define CLKID_AHB_DATA_BUS     60
+#define CLKID_AHB_CTRL_BUS     61
+#define CLKID_HDMI_INTR_SYNC   62
 #define CLKID_HDMI_PCLK                63
 #define CLKID_USB1_DDR_BRIDGE  64
 #define CLKID_USB0_DDR_BRIDGE  65
+#define CLKID_MMC_PCLK         66
+#define CLKID_DVIN             67
 #define CLKID_UART2            68
 #define CLKID_SANA             69
+#define CLKID_VPU_INTR         70
+#define CLKID_SEC_AHB_AHB3_BRIDGE 71
+#define CLKID_CLK81_A53                72
+#define CLKID_VCLK2_VENCI0     73
+#define CLKID_VCLK2_VENCI1     74
+#define CLKID_VCLK2_VENCP0     75
+#define CLKID_VCLK2_VENCP1     76
 #define CLKID_GCLK_VENCI_INT0  77
+#define CLKID_GCLK_VENCI_INT   78
+#define CLKID_DAC_CLK          79
 #define CLKID_AOCLK_GATE       80
 #define CLKID_IEC958_GATE      81
+#define CLKID_ENC480P          82
+#define CLKID_RNG1             83
+#define CLKID_GCLK_VENCI_INT1  84
+#define CLKID_VCLK2_VENCLMCC   85
+#define CLKID_VCLK2_VENCL      86
+#define CLKID_VCLK_OTHER       87
+#define CLKID_EDP              88
+#define CLKID_AO_MEDIA_CPU     89
+#define CLKID_AO_AHB_SRAM      90
+#define CLKID_AO_AHB_BUS       91
+#define CLKID_AO_IFACE         92
 #define CLKID_AO_I2C           93
 #define CLKID_SD_EMMC_A                94
 #define CLKID_SD_EMMC_B                95
 #define CLKID_CTS_AMCLK                107
 #define CLKID_CTS_MCLK_I958    110
 #define CLKID_CTS_I958         113
+#define CLKID_32K_CLK          114
+#define CLKID_SD_EMMC_A_CLK0   119
+#define CLKID_SD_EMMC_B_CLK0   122
+#define CLKID_SD_EMMC_C_CLK0   125
+#define CLKID_VPU_0_SEL                126
+#define CLKID_VPU_0            128
+#define CLKID_VPU_1_SEL                129
+#define CLKID_VPU_1            131
+#define CLKID_VPU              132
+#define CLKID_VAPB_0_SEL       133
+#define CLKID_VAPB_0           135
+#define CLKID_VAPB_1_SEL       136
+#define CLKID_VAPB_1           138
+#define CLKID_VAPB_SEL         139
+#define CLKID_VAPB             140
 
 #endif /* __GXBB_CLKC_H */
index 58654fd7aa1eb964727bb16bca99351121fc442b..43a68a1110f043f3eaab908c554d20f30a9aeb33 100644 (file)
@@ -29,6 +29,7 @@
 #define        GPIOAO_11       11
 #define        GPIOAO_12       12
 #define        GPIOAO_13       13
+#define        GPIO_TEST_N     14
 
 #define        GPIOZ_0         0
 #define        GPIOZ_1         1
 #define        GPIOCLK_1       116
 #define        GPIOCLK_2       117
 #define        GPIOCLK_3       118
-#define        GPIO_TEST_N     119
 
 #endif
index 684d0d7add1c14fb0a531eb3619a541b1e68d850..01f2a2abd35eea91bad49c60c478a47d461502eb 100644 (file)
@@ -25,6 +25,7 @@
 #define        GPIOAO_7        7
 #define        GPIOAO_8        8
 #define        GPIOAO_9        9
+#define        GPIO_TEST_N     10
 
 #define        GPIOZ_0         0
 #define        GPIOZ_1         1
 #define        GPIOX_18        97
 #define        GPIOCLK_0       98
 #define        GPIOCLK_1       99
-#define        GPIO_TEST_N     100
 
 #endif
diff --git a/include/dt-bindings/mfd/st,stpmu1.h b/include/dt-bindings/mfd/st,stpmu1.h
new file mode 100644 (file)
index 0000000..81982eb
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * This file is part of stpmu1 pmic driver
+ *
+ * Copyright (C) 2017, STMicroelectronics - All Rights Reserved
+ * Author: Pascal Paillet <p.paillet@st.com> for STMicroelectronics.
+ *
+ * License type: GPLv2
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __DT_BINDINGS_STPMU1_H__
+#define __DT_BINDINGS_STPMU1_H__
+
+/* IRQ definitions */
+#define IT_PONKEY_F 0
+#define IT_PONKEY_R 1
+#define IT_WAKEUP_F 2
+#define IT_WAKEUP_R 3
+#define IT_VBUS_OTG_F 4
+#define IT_VBUS_OTG_R 5
+#define IT_SWOUT_F 6
+#define IT_SWOUT_R 7
+
+#define IT_CURLIM_BUCK1 8
+#define IT_CURLIM_BUCK2 9
+#define IT_CURLIM_BUCK3 10
+#define IT_CURLIM_BUCK4 11
+#define IT_OCP_OTG 12
+#define IT_OCP_SWOUT 13
+#define IT_OCP_BOOST 14
+#define IT_OVP_BOOST 15
+
+#define IT_CURLIM_LDO1 16
+#define IT_CURLIM_LDO2 17
+#define IT_CURLIM_LDO3 18
+#define IT_CURLIM_LDO4 19
+#define IT_CURLIM_LDO5 20
+#define IT_CURLIM_LDO6 21
+#define IT_SHORT_SWOTG 22
+#define IT_SHORT_SWOUT 23
+
+#define IT_TWARN_F 24
+#define IT_TWARN_R 25
+#define IT_VINLOW_F 26
+#define IT_VINLOW_R 27
+#define IT_SWIN_F 30
+#define IT_SWIN_R 31
+
+#endif /* __DT_BINDINGS_STPMU1_H__ */
index 31042fad6709fbaccd440e1136fe075f91ca1f3b..a0e1cd1656a26be19d6094591cb545d5404b4940 100644 (file)
@@ -36,6 +36,7 @@
                "run mmcboot;\0" \
        "emmc_android_boot=" \
                "echo Trying to boot Android from eMMC ...; " \
+               "run update_to_fit; " \
                "setenv eval_bootargs setenv bootargs $bootargs; " \
                "run eval_bootargs; " \
                "setenv mmcdev 1; " \
@@ -48,7 +49,7 @@
                "part size mmc ${mmcdev} boot boot_size; " \
                "mmc read ${fdtaddr} ${fdt_start} ${fdt_size}; " \
                "mmc read ${loadaddr} ${boot_start} ${boot_size}; " \
-               "bootm $loadaddr $loadaddr $fdtaddr;\0"
+               "bootm ${loadaddr}#${fdtfile};\0 "
 
 #ifdef CONFIG_OMAP54XX
 
index 4d1f91048787d0e489b8885cf056111373c1b929..f39dc16617f32d987882fae7d134ff93f04cd07a 100644 (file)
@@ -22,6 +22,8 @@ struct sparse_storage {
        lbaint_t        (*reserve)(struct sparse_storage *info,
                                 lbaint_t blk,
                                 lbaint_t blkcnt);
+
+       void            (*mssg)(const char *str);
 };
 
 static inline int is_sparse_image(void *buf)
@@ -35,5 +37,5 @@ static inline int is_sparse_image(void *buf)
        return 0;
 }
 
-void write_sparse_image(struct sparse_storage *info, const char *part_name,
-                       void *data, unsigned sz);
+int write_sparse_image(struct sparse_storage *info, const char *part_name,
+                      void *data);
index e96c79dd26a219843d6343fb7d789aa63ae1cad5..6a574eaa41294a740a688f3bc717c0ba68afcf8f 100644 (file)
@@ -42,6 +42,16 @@ int regmap_read(struct regmap *map, uint offset, uint *valp);
 #define regmap_read32(map, ptr, member, valp) \
        regmap_read(map, (uint32_t *)(ptr)->member - (uint32_t *)(ptr), valp)
 
+/**
+ * regmap_update_bits() - Perform a read/modify/write using a mask
+ *
+ * @map:       The map returned by regmap_init_mem*()
+ * @offset:    Offset of the memory
+ * @mask:      Mask to apply to the read value
+ * @val:       Value to apply to the value to write
+ */
+int regmap_update_bits(struct regmap *map, uint offset, uint mask, uint val);
+
 /**
  * regmap_init_mem() - Set up a new register map that uses memory access
  *
index 748c2ebd0c9c4044328a23224600480c89d4e453..71da3c1a87143960dbef3151b26b04db09695820 100644 (file)
@@ -40,7 +40,8 @@ struct stm32_clk_info {
 };
 
 enum soc_family {
-       STM32F4,
+       STM32F42X,
+       STM32F469,
        STM32F7,
 };
 
index 33fb06712f336d09b4d64f61f5d5c2ed364e0779..1590f7afa40250cf3df678fccd57aecaa5e1e940 100644 (file)
@@ -286,6 +286,8 @@ config OF_LIBFDT
 
 config OF_LIBFDT_OVERLAY
        bool "Enable the FDT library overlay support"
+       depends on OF_LIBFDT
+       default y if ARCH_OMAP2PLUS || ARCH_KEYSTONE
        help
          This enables the FDT library (libfdt) overlay support.
 
index 89c0c95855d576f7dac3e6ea6097d59b67d14864..0071f216bb78186ad258c74a3295940e9228ffe9 100644 (file)
@@ -19,12 +19,30 @@ static int dm_test_led_base(struct unit_test_state *uts)
        ut_assertok(uclass_get_device(UCLASS_LED, 0, &dev));
        ut_assertok(uclass_get_device(UCLASS_LED, 1, &dev));
        ut_assertok(uclass_get_device(UCLASS_LED, 2, &dev));
-       ut_asserteq(-ENODEV, uclass_get_device(UCLASS_LED, 3, &dev));
+       ut_assertok(uclass_get_device(UCLASS_LED, 3, &dev));
+       ut_assertok(uclass_get_device(UCLASS_LED, 4, &dev));
+       ut_asserteq(-ENODEV, uclass_get_device(UCLASS_LED, 5, &dev));
 
        return 0;
 }
 DM_TEST(dm_test_led_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
 
+/* Test of the LED 'default-state' device tree property */
+static int dm_test_led_default_state(struct unit_test_state *uts)
+{
+       struct udevice *dev;
+
+       /* Check that we handle the default-state property correctly. */
+       ut_assertok(led_get_by_label("sandbox:default_on", &dev));
+       ut_asserteq(LEDST_ON, led_get_state(dev));
+
+       ut_assertok(led_get_by_label("sandbox:default_off", &dev));
+       ut_asserteq(LEDST_OFF, led_get_state(dev));
+
+       return 0;
+}
+DM_TEST(dm_test_led_default_state, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
 /* Test of the led uclass using the led_gpio driver */
 static int dm_test_led_gpio(struct unit_test_state *uts)
 {
index 5b51a9048877f1489222d4052d053aa292ef45d3..d4b86b3b03c2a61bd5b55100cf58f66fe0961f74 100644 (file)
@@ -91,3 +91,28 @@ static int dm_test_regmap_syscon(struct unit_test_state *uts)
 }
 
 DM_TEST(dm_test_regmap_syscon, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Read/Write/Modify test */
+static int dm_test_regmap_rw(struct unit_test_state *uts)
+{
+       struct udevice *dev;
+       struct regmap *map;
+       uint reg;
+
+       ut_assertok(uclass_get_device(UCLASS_SYSCON, 0, &dev));
+       map = syscon_get_regmap(dev);
+       ut_assertok_ptr(map);
+
+       ut_assertok(regmap_write(map, 0, 0xcacafafa));
+       ut_assertok(regmap_write(map, 3, 0x55aa2211));
+
+       ut_assertok(regmap_read(map, 0, &reg));
+       ut_assertok(regmap_read(map, 3, &reg));
+
+       ut_assertok(regmap_update_bits(map, 0, 0xff00ff00, 0x55aa2211));
+       ut_assertok(regmap_update_bits(map, 3, 0x00ff00ff, 0xcacafada));
+
+       return 0;
+}
+
+DM_TEST(dm_test_regmap_rw, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);