diff options
464 files changed, 23464 insertions, 3586 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 26dd2543e5..a7a62dff81 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -198,6 +198,9 @@ F: drivers/mmc/ca_dw_mmc.c F: drivers/spi/ca_sflash.c F: drivers/i2c/i2c-cortina.c F: drivers/i2c/i2c-cortina.h +F: drivers/mtd/nand/raw/cortina_nand.c +F: drivers/mtd/nand/raw/cortina_nand.h +F: configs/cortina_presidio-asic-pnand_defconfig ARM/CZ.NIC TURRIS MOX SUPPORT M: Marek Behun <marek.behun@nic.cz> @@ -1583,7 +1583,10 @@ u-boot.spr: spl/u-boot-spl.img u-boot.img FORCE ifneq ($(CONFIG_ARCH_SOCFPGA),) quiet_cmd_gensplx4 = GENSPLX4 $@ -cmd_gensplx4 = cat spl/u-boot-spl.sfp spl/u-boot-spl.sfp \ +cmd_gensplx4 = $(OBJCOPY) -I binary -O binary --gap-fill=0x0 \ + --pad-to=$(CONFIG_SPL_PAD_TO) \ + spl/u-boot-spl.sfp spl/u-boot-spl.sfp && \ + cat spl/u-boot-spl.sfp spl/u-boot-spl.sfp \ spl/u-boot-spl.sfp spl/u-boot-spl.sfp > $@ || { rm -f $@; false; } spl/u-boot-splx4.sfp: spl/u-boot-spl.sfp FORCE $(call if_changed,gensplx4) @@ -3153,6 +3153,7 @@ i2c - I2C sub-system sspi - SPI utility commands base - print or set address offset printenv- print environment variables +pwm - control pwm channels setenv - set environment variables saveenv - save environment variables to persistent storage protect - enable or disable FLASH write protection @@ -642,7 +642,7 @@ int syscall(int call, int *retval, ...) return 1; } -void api_init(void) +int api_init(void) { struct api_signature *sig; @@ -679,7 +679,7 @@ void api_init(void) sig = malloc(sizeof(struct api_signature)); if (sig == NULL) { printf("API: could not allocate memory for the signature!\n"); - return; + return -ENOMEM; } env_set_hex("api_address", (unsigned long)sig); @@ -691,6 +691,8 @@ void api_init(void) sig->checksum = crc32(0, (unsigned char *)sig, sizeof(struct api_signature)); debugf("syscall entry: 0x%lX\n", (unsigned long)sig->syscall); + + return 0; } void platform_set_mr(struct sys_info *si, unsigned long start, unsigned long size, diff --git a/api/api_private.h b/api/api_private.h index 07fd50ad3a..bb23821c2c 100644 --- a/api/api_private.h +++ b/api/api_private.h @@ -8,7 +8,7 @@ #ifndef _API_PRIVATE_H_ #define _API_PRIVATE_H_ -void api_init(void); +int api_init(void); void platform_set_mr(struct sys_info *, unsigned long, unsigned long, int); int platform_sys_info(struct sys_info *); diff --git a/arch/arm/cpu/armv8/Makefile b/arch/arm/cpu/armv8/Makefile index f7b4a5ee46..d85ddde430 100644 --- a/arch/arm/cpu/armv8/Makefile +++ b/arch/arm/cpu/armv8/Makefile @@ -9,14 +9,16 @@ obj-y += cpu.o ifndef CONFIG_$(SPL_TPL_)TIMER obj-$(CONFIG_SYS_ARCH_TIMER) += generic_timer.o endif +ifndef CONFIG_$(SPL_)SYS_DCACHE_OFF obj-y += cache_v8.o +obj-y += cache.o +endif ifdef CONFIG_SPL_BUILD obj-$(CONFIG_ARMV8_SPL_EXCEPTION_VECTORS) += exceptions.o else obj-y += exceptions.o obj-y += exception_level.o endif -obj-y += cache.o obj-y += tlb.o obj-y += transition.o ifndef CONFIG_ARMV8_PSCI diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 0f738c224f..ebdda1a8f2 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -110,6 +110,7 @@ dtb-$(CONFIG_ROCKCHIP_RK3308) += \ dtb-$(CONFIG_ROCKCHIP_RK3328) += \ rk3328-evb.dtb \ + rk3328-nanopi-r2s.dtb \ rk3328-roc-cc.dtb \ rk3328-rock64.dtb \ rk3328-rock-pi-e.dtb @@ -161,14 +162,19 @@ dtb-$(CONFIG_ARCH_MESON) += \ meson-gxl-s905x-p212.dtb \ meson-gxl-s805x-libretech-ac.dtb \ meson-gxl-s905x-libretech-cc.dtb \ + meson-gxl-s905x-libretech-cc-v2.dtb \ meson-gxl-s905x-khadas-vim.dtb \ meson-gxl-s905d-libretech-pc.dtb \ meson-gxm-khadas-vim2.dtb \ meson-gxm-s912-libretech-pc.dtb \ + meson-gxm-wetek-core2.dtb \ meson-axg-s400.dtb \ meson-g12a-u200.dtb \ meson-g12a-sei510.dtb \ + meson-g12b-gtking.dtb \ + meson-g12b-gtking-pro.dtb \ meson-g12b-odroid-n2.dtb \ + meson-g12b-odroid-n2-plus.dtb \ meson-g12b-a311d-khadas-vim3.dtb \ meson-sm1-khadas-vim3l.dtb \ meson-sm1-odroid-c4.dtb \ @@ -955,6 +961,7 @@ dtb-$(CONFIG_ARCH_BCM6858) += \ dtb-$(CONFIG_TARGET_BCMNS3) += ns3-board.dtb dtb-$(CONFIG_ASPEED_AST2500) += ast2500-evb.dtb +dtb-$(CONFIG_ASPEED_AST2600) += ast2600-evb.dtb dtb-$(CONFIG_ARCH_STI) += stih410-b2260.dtb diff --git a/arch/arm/dts/ast2600-evb.dts b/arch/arm/dts/ast2600-evb.dts new file mode 100644 index 0000000000..2abd31341c --- /dev/null +++ b/arch/arm/dts/ast2600-evb.dts @@ -0,0 +1,179 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/dts-v1/; + +#include "ast2600-u-boot.dtsi" + +/ { + memory { + device_type = "memory"; + reg = <0x80000000 0x40000000>; + }; + + chosen { + stdout-path = &uart5; + }; + + aliases { + mmc0 = &emmc_slot0; + mmc1 = &sdhci_slot0; + mmc2 = &sdhci_slot1; + spi0 = &fmc; + spi1 = &spi1; + spi2 = &spi2; + ethernet0 = &mac0; + ethernet1 = &mac1; + ethernet2 = &mac2; + ethernet3 = &mac3; + }; + + cpus { + cpu@0 { + clock-frequency = <800000000>; + }; + cpu@1 { + clock-frequency = <800000000>; + }; + }; +}; + +&uart5 { + u-boot,dm-pre-reloc; + status = "okay"; +}; + +&sdrammc { + clock-frequency = <400000000>; +}; + +&wdt1 { + status = "okay"; +}; + +&fmc { + status = "okay"; + + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fmcquad_default>; + + flash@0 { + compatible = "spi-flash", "sst,w25q256"; + status = "okay"; + spi-max-frequency = <50000000>; + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + }; + + flash@1 { + compatible = "spi-flash", "sst,w25q256"; + status = "okay"; + spi-max-frequency = <50000000>; + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + }; + + flash@2 { + compatible = "spi-flash", "sst,w25q256"; + status = "okay"; + spi-max-frequency = <50000000>; + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + }; +}; + +&spi1 { + status = "okay"; + + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_spi1_default &pinctrl_spi1abr_default + &pinctrl_spi1cs1_default &pinctrl_spi1wp_default + &pinctrl_spi1wp_default &pinctrl_spi1quad_default>; + + flash@0 { + compatible = "spi-flash", "sst,w25q256"; + status = "okay"; + spi-max-frequency = <50000000>; + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + }; +}; + +&spi2 { + status = "okay"; + + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_spi2_default &pinctrl_spi2cs1_default + &pinctrl_spi2cs2_default &pinctrl_spi2quad_default>; + + flash@0 { + compatible = "spi-flash", "sst,w25q256"; + status = "okay"; + spi-max-frequency = <50000000>; + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + }; +}; + +&emmc { + u-boot,dm-pre-reloc; + timing-phase = <0x700ff>; +}; + +&emmc_slot0 { + u-boot,dm-pre-reloc; + status = "okay"; + bus-width = <4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_emmc_default>; + sdhci-drive-type = <1>; +}; + +&i2c4 { + status = "okay"; + + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c5_default>; +}; + +&i2c5 { + status = "okay"; + + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c6_default>; +}; + +&i2c6 { + status = "okay"; + + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c7_default>; +}; + +&i2c7 { + status = "okay"; + + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c8_default>; +}; + +&i2c8 { + status = "okay"; + + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c9_default>; +}; + +&scu { + mac0-clk-delay = <0x1d 0x1c + 0x10 0x17 + 0x10 0x17>; + mac1-clk-delay = <0x1d 0x10 + 0x10 0x10 + 0x10 0x10>; + mac2-clk-delay = <0x0a 0x04 + 0x08 0x04 + 0x08 0x04>; + mac3-clk-delay = <0x0a 0x04 + 0x08 0x04 + 0x08 0x04>; +}; diff --git a/arch/arm/dts/ast2600-u-boot.dtsi b/arch/arm/dts/ast2600-u-boot.dtsi new file mode 100644 index 0000000000..4648c07437 --- /dev/null +++ b/arch/arm/dts/ast2600-u-boot.dtsi @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: GPL-2.0+ +#include <dt-bindings/clock/ast2600-clock.h> +#include <dt-bindings/reset/ast2600-reset.h> + +#include "ast2600.dtsi" + +/ { + scu: clock-controller@1e6e2000 { + compatible = "aspeed,ast2600-scu"; + reg = <0x1e6e2000 0x1000>; + u-boot,dm-pre-reloc; + #clock-cells = <1>; + #reset-cells = <1>; + uart-clk-source = <0x0>; /* uart clock source selection: 0: uxclk 1: huxclk*/ + }; + + rst: reset-controller { + u-boot,dm-pre-reloc; + compatible = "aspeed,ast2600-reset"; + aspeed,wdt = <&wdt1>; + #reset-cells = <1>; + }; + + sdrammc: sdrammc@1e6e0000 { + u-boot,dm-pre-reloc; + compatible = "aspeed,ast2600-sdrammc"; + reg = <0x1e6e0000 0x100 + 0x1e6e0100 0x300 + 0x1e6e0400 0x200 >; + #reset-cells = <1>; + clocks = <&scu ASPEED_CLK_MPLL>; + resets = <&rst ASPEED_RESET_SDRAM>; + }; + + ahb { + u-boot,dm-pre-reloc; + + apb { + u-boot,dm-pre-reloc; + }; + + }; +}; + diff --git a/arch/arm/dts/ast2600.dtsi b/arch/arm/dts/ast2600.dtsi new file mode 100644 index 0000000000..ac0f08b7ea --- /dev/null +++ b/arch/arm/dts/ast2600.dtsi @@ -0,0 +1,1946 @@ +// SPDX-License-Identifier: GPL-2.0+ +#include <dt-bindings/interrupt-controller/arm-gic.h> +#include "skeleton.dtsi" + +/ { + model = "Aspeed BMC"; + compatible = "aspeed,ast2600"; + #address-cells = <1>; + #size-cells = <1>; + interrupt-parent = <&gic>; + + aliases { + i2c0 = &i2c0; + i2c1 = &i2c1; + i2c2 = &i2c2; + i2c3 = &i2c3; + i2c4 = &i2c4; + i2c5 = &i2c5; + i2c6 = &i2c6; + i2c7 = &i2c7; + i2c8 = &i2c8; + i2c9 = &i2c9; + i2c10 = &i2c10; + i2c11 = &i2c11; + i2c12 = &i2c12; + i2c13 = &i2c13; + i2c14 = &i2c14; + i2c15 = &i2c15; + serial0 = &uart1; + serial1 = &uart2; + serial2 = &uart3; + serial3 = &uart4; + serial4 = &uart5; + serial5 = &uart6; + serial6 = &uart7; + serial7 = &uart8; + serial8 = &uart9; + serial9 = &uart10; + serial10 = &uart11; + serial11 = &uart12; + serial12 = &uart13; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + enable-method = "aspeed,ast2600-smp"; + + cpu@0 { + compatible = "arm,cortex-a7"; + device_type = "cpu"; + reg = <0xf00>; + }; + + cpu@1 { + compatible = "arm,cortex-a7"; + device_type = "cpu"; + reg = <0xf01>; + }; + + }; + + timer { + compatible = "arm,armv7-timer"; + interrupt-parent = <&gic>; + interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>; + }; + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + gfx_memory: framebuffer { + size = <0x01000000>; + alignment = <0x01000000>; + compatible = "shared-dma-pool"; + reusable; + }; + + video_memory: video { + size = <0x04000000>; + alignment = <0x01000000>; + compatible = "shared-dma-pool"; + no-map; + }; + }; + + ahb { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + device_type = "soc"; + ranges; + + gic: interrupt-controller@40461000 { + compatible = "arm,cortex-a7-gic"; + interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>; + #interrupt-cells = <3>; + interrupt-controller; + interrupt-parent = <&gic>; + reg = <0x40461000 0x1000>, + <0x40462000 0x1000>, + <0x40464000 0x2000>, + <0x40466000 0x2000>; + }; + + ahbc: ahbc@1e600000 { + compatible = "aspeed,aspeed-ahbc"; + reg = < 0x1e600000 0x100>; + }; + + fmc: flash-controller@1e620000 { + reg = < 0x1e620000 0xc4 + 0x20000000 0x10000000 >; + #address-cells = <1>; + #size-cells = <0>; + compatible = "aspeed,ast2600-fmc"; + status = "disabled"; + interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&scu ASPEED_CLK_AHB>; + num-cs = <3>; + flash@0 { + reg = < 0 >; + compatible = "jedec,spi-nor"; + status = "disabled"; + }; + flash@1 { + reg = < 1 >; + compatible = "jedec,spi-nor"; + status = "disabled"; + }; + flash@2 { + reg = < 2 >; + compatible = "jedec,spi-nor"; + status = "disabled"; + }; + }; + + spi1: flash-controller@1e630000 { + reg = < 0x1e630000 0xc4 + 0x30000000 0x08000000 >; + #address-cells = <1>; + #size-cells = <0>; + compatible = "aspeed,ast2600-spi"; + clocks = <&scu ASPEED_CLK_AHB>; + num-cs = <2>; + status = "disabled"; + flash@0 { + reg = < 0 >; + compatible = "jedec,spi-nor"; + status = "disabled"; + }; + flash@1 { + reg = < 1 >; + compatible = "jedec,spi-nor"; + status = "disabled"; + }; + }; + + spi2: flash-controller@1e631000 { + reg = < 0x1e631000 0xc4 + 0x50000000 0x08000000 >; + #address-cells = <1>; + #size-cells = <0>; + compatible = "aspeed,ast2600-spi"; + clocks = <&scu ASPEED_CLK_AHB>; + num-cs = <3>; + status = "disabled"; + flash@0 { + reg = < 0 >; + compatible = "jedec,spi-nor"; + status = "disabled"; + }; + flash@1 { + reg = < 1 >; + compatible = "jedec,spi-nor"; + status = "disabled"; + }; + flash@2 { + reg = < 2 >; + compatible = "jedec,spi-nor"; + status = "disabled"; + }; + }; + + edac: sdram@1e6e0000 { + compatible = "aspeed,ast2600-sdram-edac"; + reg = <0x1e6e0000 0x174>; + interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>; + }; + + mdio: ethernet@1e650000 { + compatible = "aspeed,aspeed-mdio"; + reg = <0x1e650000 0x40>; + resets = <&rst ASPEED_RESET_MII>; + status = "disabled"; + }; + + mac0: ftgmac@1e660000 { + compatible = "aspeed,ast2600-mac", "faraday,ftgmac100"; + reg = <0x1e660000 0x180>, <0x1e650000 0x4>; + interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&scu ASPEED_CLK_GATE_MAC1CLK>; + status = "disabled"; + }; + + mac1: ftgmac@1e680000 { + compatible = "aspeed,ast2600-mac", "faraday,ftgmac100"; + reg = <0x1e680000 0x180>, <0x1e650008 0x4>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&scu ASPEED_CLK_GATE_MAC2CLK>; + status = "disabled"; + }; + + mac2: ftgmac@1e670000 { + compatible = "aspeed,ast2600-mac", "faraday,ftgmac100"; + reg = <0x1e670000 0x180>, <0x1e650010 0x4>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&scu ASPEED_CLK_GATE_MAC3CLK>; + status = "disabled"; + }; + + mac3: ftgmac@1e690000 { + compatible = "aspeed,ast2600-mac", "faraday,ftgmac100"; + reg = <0x1e690000 0x180>, <0x1e650018 0x4>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&scu ASPEED_CLK_GATE_MAC4CLK>; + status = "disabled"; + }; + + ehci0: usb@1e6a1000 { + compatible = "aspeed,aspeed-ehci", "usb-ehci"; + reg = <0x1e6a1000 0x100>; + interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&scu ASPEED_CLK_GATE_USBPORT1CLK>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb2ah_default>; + status = "disabled"; + }; + + ehci1: usb@1e6a3000 { + compatible = "aspeed,aspeed-ehci", "usb-ehci"; + reg = <0x1e6a3000 0x100>; + interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&scu ASPEED_CLK_GATE_USBPORT2CLK>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb2bh_default>; + status = "disabled"; + }; + + apb { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + syscon: syscon@1e6e2000 { + compatible = "aspeed,g6-scu", "syscon", "simple-mfd"; + reg = <0x1e6e2000 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + #clock-cells = <1>; + #reset-cells = <1>; + ranges = <0 0x1e6e2000 0x1000>; + + pinctrl: pinctrl { + compatible = "aspeed,g6-pinctrl"; + aspeed,external-nodes = <&gfx &lhc>; + + }; + + vga_scratch: scratch { + compatible = "aspeed,bmc-misc"; + }; + + scu_ic0: interrupt-controller@0 { + #interrupt-cells = <1>; + compatible = "aspeed,ast2600-scu-ic"; + reg = <0x560 0x10>; + interrupt-parent = <&gic>; + interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>; + interrupt-controller; + }; + + scu_ic1: interrupt-controller@1 { + #interrupt-cells = <1>; + compatible = "aspeed,ast2600-scu-ic"; + reg = <0x570 0x10>; + interrupt-parent = <&gic>; + interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>; + interrupt-controller; + }; + + }; + + smp-memram@0 { + compatible = "aspeed,ast2600-smpmem", "syscon"; + reg = <0x1e6e2180 0x40>; + }; + + gfx: display@1e6e6000 { + compatible = "aspeed,ast2500-gfx", "syscon"; + reg = <0x1e6e6000 0x1000>; + reg-io-width = <4>; + }; + + pcie_bridge0: pcie@1e6ed000 { + compatible = "aspeed,ast2600-pcie"; + #address-cells = <3>; + #size-cells = <2>; + reg = <0x1e6ed000 0x100>; + ranges = <0x81000000 0x0 0x0 0x0 0x0 0x10000>, + <0x82000000 0x0 0x60000000 0x60000000 0x0 0x10000000>; + device_type = "pci"; + bus-range = <0x00 0xff>; + resets = <&rst ASPEED_RESET_PCIE_DEV_O>; + cfg-handle = <&pcie_cfg0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie0rc_default>; + + status = "disabled"; + }; + + pcie_bridge1: pcie@1e6ed200 { + compatible = "aspeed,ast2600-pcie"; + #address-cells = <3>; + #size-cells = <2>; + reg = <0x1e6ed200 0x100>; + ranges = <0x81000000 0x0 0x0 0x10000 0x00 0x10000>, + <0x82000000 0x0 0x70000000 0x70000000 0x0 0x10000000>; + device_type = "pci"; + bus-range = <0x00 0xff>; + resets = <&rst ASPEED_RESET_PCIE_RC_O>; + cfg-handle = <&pcie_cfg1>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie1rc_default>; + + status = "disabled"; + }; + + sdhci: sdhci@1e740000 { + #interrupt-cells = <1>; + compatible = "aspeed,aspeed-sdhci-irq", "simple-mfd"; + reg = <0x1e740000 0x1000>; + interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>; + interrupt-controller; + clocks = <&scu ASPEED_CLK_GATE_SDCLK>, + <&scu ASPEED_CLK_GATE_SDEXTCLK>; + clock-names = "ctrlclk", "extclk"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x1e740000 0x1000>; + + sdhci_slot0: sdhci_slot0@100 { + compatible = "aspeed,sdhci-ast2600"; + reg = <0x100 0x100>; + interrupts = <0>; + interrupt-parent = <&sdhci>; + sdhci,auto-cmd12; + clocks = <&scu ASPEED_CLK_SDIO>; + status = "disabled"; + }; + + sdhci_slot1: sdhci_slot1@200 { + compatible = "aspeed,sdhci-ast2600"; + reg = <0x200 0x100>; + interrupts = <1>; + interrupt-parent = <&sdhci>; + sdhci,auto-cmd12; + clocks = <&scu ASPEED_CLK_SDIO>; + status = "disabled"; + }; + }; + + emmc: emmc@1e750000 { + #interrupt-cells = <1>; + compatible = "aspeed,aspeed-emmc-irq", "simple-mfd"; + reg = <0x1e750000 0x1000>; + interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>; + interrupt-controller; + clocks = <&scu ASPEED_CLK_GATE_EMMCCLK>, + <&scu ASPEED_CLK_GATE_EMMCEXTCLK>; + clock-names = "ctrlclk", "extclk"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x1e750000 0x1000>; + + emmc_slot0: emmc_slot0@100 { + compatible = "aspeed,emmc-ast2600"; + reg = <0x100 0x100>; + interrupts = <0>; + interrupt-parent = <&emmc>; + clocks = <&scu ASPEED_CLK_EMMC>; + status = "disabled"; + }; + }; + + h2x: h2x@1e770000 { + compatible = "aspeed,ast2600-h2x"; + reg = <0x1e770000 0x100>; + interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>; + resets = <&rst ASPEED_RESET_H2X>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x1e770000 0x100>; + + status = "disabled"; + + pcie_cfg0: cfg0@80 { + reg = <0x80 0x80>; + compatible = "aspeed,ast2600-pcie-cfg"; + }; + + pcie_cfg1: cfg1@C0 { + compatible = "aspeed,ast2600-pcie-cfg"; + reg = <0xC0 0x80>; + }; + }; + + gpio0: gpio@1e780000 { + compatible = "aspeed,ast2600-gpio"; + reg = <0x1e780000 0x1000>; + interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + gpio-ranges = <&pinctrl 0 0 220>; + ngpios = <208>; + }; + + gpio1: gpio@1e780800 { + compatible = "aspeed,ast2600-gpio"; + reg = <0x1e780800 0x800>; + interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + gpio-ranges = <&pinctrl 0 0 208>; + ngpios = <36>; + }; + + uart1: serial@1e783000 { + compatible = "ns16550a"; + reg = <0x1e783000 0x20>; + reg-shift = <2>; + interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&scu ASPEED_CLK_GATE_UART1CLK>; + clock-frequency = <1846154>; + no-loopback-test; + status = "disabled"; + }; + + uart5: serial@1e784000 { + compatible = "ns16550a"; + reg = <0x1e784000 0x1000>; + reg-shift = <2>; + interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&scu ASPEED_CLK_GATE_UART5CLK>; + clock-frequency = <1846154>; + no-loopback-test; + status = "disabled"; + }; + + wdt1: watchdog@1e785000 { + compatible = "aspeed,ast2600-wdt"; + reg = <0x1e785000 0x40>; + }; + + wdt2: watchdog@1e785040 { + compatible = "aspeed,ast2600-wdt"; + reg = <0x1e785040 0x40>; + }; + + wdt3: watchdog@1e785080 { + compatible = "aspeed,ast2600-wdt"; + reg = <0x1e785080 0x40>; + }; + + wdt4: watchdog@1e7850C0 { + compatible = "aspeed,ast2600-wdt"; + reg = <0x1e7850C0 0x40>; + }; + + lpc: lpc@1e789000 { + compatible = "aspeed,ast2600-lpc", "simple-mfd", "syscon"; + reg = <0x1e789000 0x1000>; + + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x1e789000 0x1000>; + + kcs1: kcs1@0 { + compatible = "aspeed,ast2600-kcs-bmc"; + reg = <0x0 0x80>; + interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>; + kcs_chan = <1>; + kcs_addr = <0xCA0>; + status = "disabled"; + }; + + kcs2: kcs2@0 { + compatible = "aspeed,ast2600-kcs-bmc"; + reg = <0x0 0x80>; + interrupts = <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>; + kcs_chan = <2>; + kcs_addr = <0xCA8>; + status = "disabled"; + }; + + kcs3: kcs3@0 { + compatible = "aspeed,ast2600-kcs-bmc"; + reg = <0x0 0x80>; + interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>; + kcs_chan = <3>; + kcs_addr = <0xCA2>; + }; + + kcs4: kcs4@0 { + compatible = "aspeed,ast2600-kcs-bmc"; + reg = <0x0 0x120>; + interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>; + kcs_chan = <4>; + kcs_addr = <0xCA4>; + status = "disabled"; + }; + + lpc_ctrl: lpc-ctrl@80 { + compatible = "aspeed,ast2600-lpc-ctrl"; + reg = <0x80 0x80>; + status = "disabled"; + }; + + lpc_snoop: lpc-snoop@80 { + compatible = "aspeed,ast2600-lpc-snoop"; + reg = <0x80 0x80>; + interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + + lhc: lhc@a0 { + compatible = "aspeed,ast2600-lhc"; + reg = <0xa0 0x24 0xc8 0x8>; + }; + + lpc_reset: reset-controller@98 { + compatible = "aspeed,ast2600-lpc-reset"; + reg = <0x98 0x4>; + #reset-cells = <1>; + status = "disabled"; + }; + + ibt: ibt@140 { + compatible = "aspeed,ast2600-ibt-bmc"; + reg = <0x140 0x18>; + interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + + sio_regs: regs { + compatible = "aspeed,bmc-misc"; + }; + + mbox: mbox@200 { + compatible = "aspeed,ast2600-mbox"; + reg = <0x200 0x5c>; + interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>; + #mbox-cells = <1>; + status = "disabled"; + }; + }; + + uart2: serial@1e78d000 { + compatible = "ns16550a"; + reg = <0x1e78d000 0x20>; + reg-shift = <2>; + interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&scu ASPEED_CLK_GATE_UART2CLK>; + clock-frequency = <1846154>; + no-loopback-test; + status = "disabled"; + }; + + uart3: serial@1e78e000 { + compatible = "ns16550a"; + reg = <0x1e78e000 0x20>; + reg-shift = <2>; + interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&scu ASPEED_CLK_GATE_UART3CLK>; + clock-frequency = <1846154>; + no-loopback-test; + status = "disabled"; + }; + + uart4: serial@1e78f000 { + compatible = "ns16550a"; + reg = <0x1e78f000 0x20>; + reg-shift = <2>; + interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&scu ASPEED_CLK_GATE_UART4CLK>; + clock-frequency = <1846154>; + no-loopback-test; + status = "disabled"; + }; + + i2c: bus@1e78a000 { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x1e78a000 0x1000>; + }; + + fsim0: fsi@1e79b000 { + compatible = "aspeed,ast2600-fsi-master", "fsi-master"; + reg = <0x1e79b000 0x94>; + interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fsi1_default>; + clocks = <&scu ASPEED_CLK_GATE_FSICLK>; + status = "disabled"; + }; + + fsim1: fsi@1e79b100 { + compatible = "aspeed,ast2600-fsi-master", "fsi-master"; + reg = <0x1e79b100 0x94>; + interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fsi2_default>; + clocks = <&scu ASPEED_CLK_GATE_FSICLK>; + status = "disabled"; + }; + + uart6: serial@1e790000 { + compatible = "ns16550a"; + reg = <0x1e790000 0x20>; + reg-shift = <2>; + interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&scu ASPEED_CLK_GATE_UART6CLK>; + clock-frequency = <1846154>; + no-loopback-test; + status = "disabled"; + }; + + uart7: serial@1e790100 { + compatible = "ns16550a"; + reg = <0x1e790100 0x20>; + reg-shift = <2>; + interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&scu ASPEED_CLK_GATE_UART7CLK>; + clock-frequency = <1846154>; + no-loopback-test; + status = "disabled"; + }; + + uart8: serial@1e790200 { + compatible = "ns16550a"; + reg = <0x1e790200 0x20>; + reg-shift = <2>; + interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&scu ASPEED_CLK_GATE_UART8CLK>; + clock-frequency = <1846154>; + no-loopback-test; + status = "disabled"; + }; + + uart9: serial@1e790300 { + compatible = "ns16550a"; + reg = <0x1e790300 0x20>; + reg-shift = <2>; + interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&scu ASPEED_CLK_GATE_UART9CLK>; + clock-frequency = <1846154>; + no-loopback-test; + status = "disabled"; + }; + + uart10: serial@1e790400 { + compatible = "ns16550a"; + reg = <0x1e790400 0x20>; + reg-shift = <2>; + interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&scu ASPEED_CLK_GATE_UART10CLK>; + clock-frequency = <1846154>; + no-loopback-test; + status = "disabled"; + }; + + uart11: serial@1e790500 { + compatible = "ns16550a"; + reg = <0x1e790400 0x20>; + reg-shift = <2>; + interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&scu ASPEED_CLK_GATE_UART11CLK>; + clock-frequency = <1846154>; + no-loopback-test; + status = "disabled"; + }; + + uart12: serial@1e790600 { + compatible = "ns16550a"; + reg = <0x1e790600 0x20>; + reg-shift = <2>; + interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&scu ASPEED_CLK_GATE_UART12CLK>; + clock-frequency = <1846154>; + no-loopback-test; + status = "disabled"; + }; + + uart13: serial@1e790700 { + compatible = "ns16550a"; + reg = <0x1e790700 0x20>; + reg-shift = <2>; + interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&scu ASPEED_CLK_GATE_UART13CLK>; + clock-frequency = <1846154>; + no-loopback-test; + status = "disabled"; + }; + + display_port: dp@1e6eb000 { + compatible = "aspeed,ast2600-displayport"; + reg = <0x1e6eb000 0x200>; + interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>; + resets = <&rst ASPEED_RESET_DP> ,<&rst ASPEED_RESET_DP_MCU>; + status = "disabled"; + }; + + }; + + }; + +}; + +&i2c { + i2cglobal: i2cg@00 { + compatible = "aspeed,ast2600-i2c-global"; + reg = <0x0 0x40>; + resets = <&rst ASPEED_RESET_I2C>; +#if 0 + new-mode; +#endif + }; + + i2c0: i2c@80 { + #address-cells = <1>; + #size-cells = <0>; + #interrupt-cells = <1>; + + reg = <0x80 0x80 0xC00 0x20>; + compatible = "aspeed,ast2600-i2c-bus"; + bus-frequency = <100000>; + interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&scu ASPEED_CLK_APB2>; + status = "disabled"; + }; + + i2c1: i2c@100 { + #address-cells = <1>; + #size-cells = <0>; + #interrupt-cells = <1>; + + reg = <0x100 0x80 0xC20 0x20>; + compatible = "aspeed,ast2600-i2c-bus"; + bus-frequency = <100000>; + interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&scu ASPEED_CLK_APB2>; + status = "disabled"; + }; + + i2c2: i2c@180 { + #address-cells = <1>; + #size-cells = <0>; + #interrupt-cells = <1>; + + reg = <0x180 0x80 0xC40 0x20>; + compatible = "aspeed,ast2600-i2c-bus"; + bus-frequency = <100000>; + interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&scu ASPEED_CLK_APB2>; + }; + + i2c3: i2c@200 { + #address-cells = <1>; + #size-cells = <0>; + #interrupt-cells = <1>; + + reg = <0x200 0x40 0xC60 0x20>; + compatible = "aspeed,ast2600-i2c-bus"; + bus-frequency = <100000>; + interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&scu ASPEED_CLK_APB2>; + }; + + i2c4: i2c@280 { + #address-cells = <1>; + #size-cells = <0>; + #interrupt-cells = <1>; + + reg = <0x280 0x80 0xC80 0x20>; + compatible = "aspeed,ast2600-i2c-bus"; + bus-frequency = <100000>; + interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&scu ASPEED_CLK_APB2>; + }; + + i2c5: i2c@300 { + #address-cells = <1>; + #size-cells = <0>; + #interrupt-cells = <1>; + + reg = <0x300 0x40 0xCA0 0x20>; + compatible = "aspeed,ast2600-i2c-bus"; + bus-frequency = <100000>; + interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&scu ASPEED_CLK_APB2>; + }; + + i2c6: i2c@380 { + #address-cells = <1>; + #size-cells = <0>; + #interrupt-cells = <1>; + + reg = <0x380 0x80 0xCC0 0x20>; + compatible = "aspeed,ast2600-i2c-bus"; + bus-frequency = <100000>; + interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&scu ASPEED_CLK_APB2>; + }; + + i2c7: i2c@400 { + #address-cells = <1>; + #size-cells = <0>; + #interrupt-cells = <1>; + + reg = <0x400 0x80 0xCE0 0x20>; + compatible = "aspeed,ast2600-i2c-bus"; + bus-frequency = <100000>; + interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&scu ASPEED_CLK_APB2>; + }; + + i2c8: i2c@480 { + #address-cells = <1>; + #size-cells = <0>; + #interrupt-cells = <1>; + + reg = <0x480 0x80 0xD00 0x20>; + compatible = "aspeed,ast2600-i2c-bus"; + bus-frequency = <100000>; + interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&scu ASPEED_CLK_APB2>; + }; + + i2c9: i2c@500 { + #address-cells = <1>; + #size-cells = <0>; + #interrupt-cells = <1>; + + reg = <0x500 0x80 0xD20 0x20>; + compatible = "aspeed,ast2600-i2c-bus"; + bus-frequency = <100000>; + interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&scu ASPEED_CLK_APB2>; + status = "disabled"; + }; + + i2c10: i2c@580 { + #address-cells = <1>; + #size-cells = <0>; + #interrupt-cells = <1>; + + reg = <0x580 0x80 0xD40 0x20>; + compatible = "aspeed,ast2600-i2c-bus"; + bus-frequency = <100000>; + interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&scu ASPEED_CLK_APB2>; + status = "disabled"; + }; + + i2c11: i2c@600 { + #address-cells = <1>; + #size-cells = <0>; + #interrupt-cells = <1>; + + reg = <0x600 0x80 0xD60 0x20>; + compatible = "aspeed,ast2600-i2c-bus"; + bus-frequency = <100000>; + interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&scu ASPEED_CLK_APB2>; + status = "disabled"; + }; + + i2c12: i2c@680 { + #address-cells = <1>; + #size-cells = <0>; + #interrupt-cells = <1>; + + reg = <0x680 0x80 0xD80 0x20>; + compatible = "aspeed,ast2600-i2c-bus"; + bus-frequency = <100000>; + interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&scu ASPEED_CLK_APB2>; + status = "disabled"; + }; + + i2c13: i2c@700 { + #address-cells = <1>; + #size-cells = <0>; + #interrupt-cells = <1>; + + reg = <0x700 0x80 0xDA0 0x20>; + compatible = "aspeed,ast2600-i2c-bus"; + bus-frequency = <100000>; + interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&scu ASPEED_CLK_APB2>; + status = "disabled"; + }; + + i2c14: i2c@780 { + #address-cells = <1>; + #size-cells = <0>; + #interrupt-cells = <1>; + + reg = <0x780 0x80 0xDC0 0x20>; + compatible = "aspeed,ast2600-i2c-bus"; + bus-frequency = <100000>; + interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&scu ASPEED_CLK_APB2>; + status = "disabled"; + }; + + i2c15: i2c@800 { + #address-cells = <1>; + #size-cells = <0>; + #interrupt-cells = <1>; + + reg = <0x800 0x80 0xDE0 0x20>; + compatible = "aspeed,ast2600-i2c-bus"; + bus-frequency = <100000>; + interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&scu ASPEED_CLK_APB2>; + status = "disabled"; + }; + +}; + +&pinctrl { + pinctrl_fmcquad_default: fmcquad_default { + function = "FMCQUAD"; + groups = "FMCQUAD"; + }; + + pinctrl_spi1_default: spi1_default { + function = "SPI1"; + groups = "SPI1"; + }; + + pinctrl_spi1abr_default: spi1abr_default { + function = "SPI1ABR"; + groups = "SPI1ABR"; + }; + + pinctrl_spi1cs1_default: spi1cs1_default { + function = "SPI1CS1"; + groups = "SPI1CS1"; + }; + + pinctrl_spi1wp_default: spi1wp_default { + function = "SPI1WP"; + groups = "SPI1WP"; + }; + + pinctrl_spi1quad_default: spi1quad_default { + function = "SPI1QUAD"; + groups = "SPI1QUAD"; + }; + + pinctrl_spi2_default: spi2_default { + function = "SPI2"; + groups = "SPI2"; + }; + + pinctrl_spi2cs1_default: spi2cs1_default { + function = "SPI2CS1"; + groups = "SPI2CS1"; + }; + + pinctrl_spi2cs2_default: spi2cs2_default { + function = "SPI2CS2"; + groups = "SPI2CS2"; + }; + + pinctrl_spi2quad_default: spi2quad_default { + function = "SPI2QUAD"; + groups = "SPI2QUAD"; + }; + + pinctrl_acpi_default: acpi_default { + function = "ACPI"; + groups = "ACPI"; + }; + + pinctrl_adc0_default: adc0_default { + function = "ADC0"; + groups = "ADC0"; + }; + + pinctrl_adc1_default: adc1_default { + function = "ADC1"; + groups = "ADC1"; + }; + + pinctrl_adc10_default: adc10_default { + function = "ADC10"; + groups = "ADC10"; + }; + + pinctrl_adc11_default: adc11_default { + function = "ADC11"; + groups = "ADC11"; + }; + + pinctrl_adc12_default: adc12_default { + function = "ADC12"; + groups = "ADC12"; + }; + + pinctrl_adc13_default: adc13_default { + function = "ADC13"; + groups = "ADC13"; + }; + + pinctrl_adc14_default: adc14_default { + function = "ADC14"; + groups = "ADC14"; + }; + + pinctrl_adc15_default: adc15_default { + function = "ADC15"; + groups = "ADC15"; + }; + + pinctrl_adc2_default: adc2_default { + function = "ADC2"; + groups = "ADC2"; + }; + + pinctrl_adc3_default: adc3_default { + function = "ADC3"; + groups = "ADC3"; + }; + + pinctrl_adc4_default: adc4_default { + function = "ADC4"; + groups = "ADC4"; + }; + + pinctrl_adc5_default: adc5_default { + function = "ADC5"; + groups = "ADC5"; + }; + + pinctrl_adc6_default: adc6_default { + function = "ADC6"; + groups = "ADC6"; + }; + + pinctrl_adc7_default: adc7_default { + function = "ADC7"; + groups = "ADC7"; + }; + + pinctrl_adc8_default: adc8_default { + function = "ADC8"; + groups = "ADC8"; + }; + + pinctrl_adc9_default: adc9_default { + function = "ADC9"; + groups = "ADC9"; + }; + + pinctrl_bmcint_default: bmcint_default { + function = "BMCINT"; + groups = "BMCINT"; + }; + + pinctrl_ddcclk_default: ddcclk_default { + function = "DDCCLK"; + groups = "DDCCLK"; + }; + + pinctrl_ddcdat_default: ddcdat_default { + function = "DDCDAT"; + groups = "DDCDAT"; + }; + + pinctrl_espi_default: espi_default { + function = "ESPI"; + groups = "ESPI"; + }; + + pinctrl_fsi1_default: fsi1_default { + function = "FSI1"; + groups = "FSI1"; + }; + + pinctrl_fsi2_default: fsi2_default { + function = "FSI2"; + groups = "FSI2"; + }; + + pinctrl_fwspics1_default: fwspics1_default { + function = "FWSPICS1"; + groups = "FWSPICS1"; + }; + + pinctrl_fwspics2_default: fwspics2_default { + function = "FWSPICS2"; + groups = "FWSPICS2"; + }; + + pinctrl_gpid0_default: gpid0_default { + function = "GPID0"; + groups = "GPID0"; + }; + + pinctrl_gpid2_default: gpid2_default { + function = "GPID2"; + groups = "GPID2"; + }; + + pinctrl_gpid4_default: gpid4_default { + function = "GPID4"; + groups = "GPID4"; + }; + + pinctrl_gpid6_default: gpid6_default { + function = "GPID6"; + groups = "GPID6"; + }; + + pinctrl_gpie0_default: gpie0_default { + function = "GPIE0"; + groups = "GPIE0"; + }; + + pinctrl_gpie2_default: gpie2_default { + function = "GPIE2"; + groups = "GPIE2"; + }; + + pinctrl_gpie4_default: gpie4_default { + function = "GPIE4"; + groups = "GPIE4"; + }; + + pinctrl_gpie6_default: gpie6_default { + function = "GPIE6"; + groups = "GPIE6"; + }; + + pinctrl_i2c1_default: i2c1_default { + function = "I2C1"; + groups = "I2C1"; + }; + pinctrl_i2c2_default: i2c2_default { + function = "I2C2"; + groups = "I2C2"; + }; + + pinctrl_i2c3_default: i2c3_default { + function = "I2C3"; + groups = "I2C3"; + }; + + pinctrl_i2c4_default: i2c4_default { + function = "I2C4"; + groups = "I2C4"; + }; + + pinctrl_i2c5_default: i2c5_default { + function = "I2C5"; + groups = "I2C5"; + }; + + pinctrl_i2c6_default: i2c6_default { + function = "I2C6"; + groups = "I2C6"; + }; + + pinctrl_i2c7_default: i2c7_default { + function = "I2C7"; + groups = "I2C7"; + }; + + pinctrl_i2c8_default: i2c8_default { + function = "I2C8"; + groups = "I2C8"; + }; + + pinctrl_i2c9_default: i2c9_default { + function = "I2C9"; + groups = "I2C9"; + }; + + pinctrl_i2c10_default: i2c10_default { + function = "I2C10"; + groups = "I2C10"; + }; + + pinctrl_i2c11_default: i2c11_default { + function = "I2C11"; + groups = "I2C11"; + }; + + pinctrl_i2c12_default: i2c12_default { + function = "I2C12"; + groups = "I2C12"; + }; + + pinctrl_i2c13_default: i2c13_default { + function = "I2C13"; + groups = "I2C13"; + }; + + pinctrl_i2c14_default: i2c14_default { + function = "I2C14"; + groups = "I2C14"; + }; + + pinctrl_i2c15_default: i2c15_default { + function = "I2C15"; + groups = "I2C15"; + }; + + pinctrl_i2c16_default: i2c16_default { + function = "I2C16"; + groups = "I2C16"; + }; + + pinctrl_lad0_default: lad0_default { + function = "LAD0"; + groups = "LAD0"; + }; + + pinctrl_lad1_default: lad1_default { + function = "LAD1"; + groups = "LAD1"; + }; + + pinctrl_lad2_default: lad2_default { + function = "LAD2"; + groups = "LAD2"; + }; + + pinctrl_lad3_default: lad3_default { + function = "LAD3"; + groups = "LAD3"; + }; + + pinctrl_lclk_default: lclk_default { + function = "LCLK"; + groups = "LCLK"; + }; + + pinctrl_lframe_default: lframe_default { + function = "LFRAME"; + groups = "LFRAME"; + }; + + pinctrl_lpchc_default: lpchc_default { + function = "LPCHC"; + groups = "LPCHC"; + }; + + pinctrl_lpcpd_default: lpcpd_default { + function = "LPCPD"; + groups = "LPCPD"; + }; + + pinctrl_lpcplus_default: lpcplus_default { + function = "LPCPLUS"; + groups = "LPCPLUS"; + }; + + pinctrl_lpcpme_default: lpcpme_default { + function = "LPCPME"; + groups = "LPCPME"; + }; + + pinctrl_lpcrst_default: lpcrst_default { + function = "LPCRST"; + groups = "LPCRST"; + }; + + pinctrl_lpcsmi_default: lpcsmi_default { + function = "LPCSMI"; + groups = "LPCSMI"; + }; + + pinctrl_lsirq_default: lsirq_default { + function = "LSIRQ"; + groups = "LSIRQ"; + }; + + pinctrl_mac1link_default: mac1link_default { + function = "MAC1LINK"; + groups = "MAC1LINK"; + }; + + pinctrl_mac2link_default: mac2link_default { + function = "MAC2LINK"; + groups = "MAC2LINK"; + }; + + pinctrl_mac3link_default: mac3link_default { + function = "MAC3LINK"; + groups = "MAC3LINK"; + }; + + pinctrl_mac4link_default: mac4link_default { + function = "MAC4LINK"; + groups = "MAC4LINK"; + }; + + pinctrl_mdio1_default: mdio1_default { + function = "MDIO1"; + groups = "MDIO1"; + }; + + pinctrl_mdio2_default: mdio2_default { + function = "MDIO2"; + groups = "MDIO2"; + }; + + pinctrl_mdio3_default: mdio3_default { + function = "MDIO3"; + groups = "MDIO3"; + }; + + pinctrl_mdio4_default: mdio4_default { + function = "MDIO4"; + groups = "MDIO4"; + }; + + pinctrl_rmii1_default: rmii1_default { + function = "RMII1"; + groups = "RMII1"; + }; + + pinctrl_rmii2_default: rmii2_default { + function = "RMII2"; + groups = "RMII2"; + }; + + pinctrl_rmii3_default: rmii3_default { + function = "RMII3"; + groups = "RMII3"; + }; + + pinctrl_rmii4_default: rmii4_default { + function = "RMII4"; + groups = "RMII4"; + }; + + pinctrl_rmii1rclk_default: rmii1rclk_default { + function = "RMII1RCLK"; + groups = "RMII1RCLK"; + }; + + pinctrl_rmii2rclk_default: rmii2rclk_default { + function = "RMII2RCLK"; + groups = "RMII2RCLK"; + }; + + pinctrl_rmii3rclk_default: rmii3rclk_default { + function = "RMII3RCLK"; + groups = "RMII3RCLK"; + }; + + pinctrl_rmii4rclk_default: rmii4rclk_default { + function = "RMII4RCLK"; + groups = "RMII4RCLK"; + }; + + pinctrl_ncts1_default: ncts1_default { + function = "NCTS1"; + groups = "NCTS1"; + }; + + pinctrl_ncts2_default: ncts2_default { + function = "NCTS2"; + groups = "NCTS2"; + }; + + pinctrl_ncts3_default: ncts3_default { + function = "NCTS3"; + groups = "NCTS3"; + }; + + pinctrl_ncts4_default: ncts4_default { + function = "NCTS4"; + groups = "NCTS4"; + }; + + pinctrl_ndcd1_default: ndcd1_default { + function = "NDCD1"; + groups = "NDCD1"; + }; + + pinctrl_ndcd2_default: ndcd2_default { + function = "NDCD2"; + groups = "NDCD2"; + }; + + pinctrl_ndcd3_default: ndcd3_default { + function = "NDCD3"; + groups = "NDCD3"; + }; + + pinctrl_ndcd4_default: ndcd4_default { + function = "NDCD4"; + groups = "NDCD4"; + }; + + pinctrl_ndsr1_default: ndsr1_default { + function = "NDSR1"; + groups = "NDSR1"; + }; + + pinctrl_ndsr2_default: ndsr2_default { + function = "NDSR2"; + groups = "NDSR2"; + }; + + pinctrl_ndsr3_default: ndsr3_default { + function = "NDSR3"; + groups = "NDSR3"; + }; + + pinctrl_ndsr4_default: ndsr4_default { + function = "NDSR4"; + groups = "NDSR4"; + }; + + pinctrl_ndtr1_default: ndtr1_default { + function = "NDTR1"; + groups = "NDTR1"; + }; + + pinctrl_ndtr2_default: ndtr2_default { + function = "NDTR2"; + groups = "NDTR2"; + }; + + pinctrl_ndtr3_default: ndtr3_default { + function = "NDTR3"; + groups = "NDTR3"; + }; + + pinctrl_ndtr4_default: ndtr4_default { + function = "NDTR4"; + groups = "NDTR4"; + }; + + pinctrl_nri1_default: nri1_default { + function = "NRI1"; + groups = "NRI1"; + }; + + pinctrl_nri2_default: nri2_default { + function = "NRI2"; + groups = "NRI2"; + }; + + pinctrl_nri3_default: nri3_default { + function = "NRI3"; + groups = "NRI3"; + }; + + pinctrl_nri4_default: nri4_default { + function = "NRI4"; + groups = "NRI4"; + }; + + pinctrl_nrts1_default: nrts1_default { + function = "NRTS1"; + groups = "NRTS1"; + }; + + pinctrl_nrts2_default: nrts2_default { + function = "NRTS2"; + groups = "NRTS2"; + }; + + pinctrl_nrts3_default: nrts3_default { + function = "NRTS3"; + groups = "NRTS3"; + }; + + pinctrl_nrts4_default: nrts4_default { + function = "NRTS4"; + groups = "NRTS4"; + }; + + pinctrl_oscclk_default: oscclk_default { + function = "OSCCLK"; + groups = "OSCCLK"; + }; + + pinctrl_pewake_default: pewake_default { + function = "PEWAKE"; + groups = "PEWAKE"; + }; + + pinctrl_pnor_default: pnor_default { + function = "PNOR"; + groups = "PNOR"; + }; + + pinctrl_pwm0_default: pwm0_default { + function = "PWM0"; + groups = "PWM0"; + }; + + pinctrl_pwm1_default: pwm1_default { + function = "PWM1"; + groups = "PWM1"; + }; + + pinctrl_pwm2_default: pwm2_default { + function = "PWM2"; + groups = "PWM2"; + }; + + pinctrl_pwm3_default: pwm3_default { + function = "PWM3"; + groups = "PWM3"; + }; + + pinctrl_pwm4_default: pwm4_default { + function = "PWM4"; + groups = "PWM4"; + }; + + pinctrl_pwm5_default: pwm5_default { + function = "PWM5"; + groups = "PWM5"; + }; + + pinctrl_pwm6_default: pwm6_default { + function = "PWM6"; + groups = "PWM6"; + }; + + pinctrl_pwm7_default: pwm7_default { + function = "PWM7"; + groups = "PWM7"; + }; + + pinctrl_rgmii1_default: rgmii1_default { + function = "RGMII1"; + groups = "RGMII1"; + }; + + pinctrl_rgmii2_default: rgmii2_default { + function = "RGMII2"; + groups = "RGMII2"; + }; + + pinctrl_rgmii3_default: rgmii3_default { + function = "RGMII3"; + groups = "RGMII3"; + }; + + pinctrl_rgmii4_default: rgmii4_default { + function = "RGMII4"; + groups = "RGMII4"; + }; + + pinctrl_rmii1_default: rmii1_default { + function = "RMII1"; + groups = "RMII1"; + }; + + pinctrl_rmii2_default: rmii2_default { + function = "RMII2"; + groups = "RMII2"; + }; + + pinctrl_rxd1_default: rxd1_default { + function = "RXD1"; + groups = "RXD1"; + }; + + pinctrl_rxd2_default: rxd2_default { + function = "RXD2"; + groups = "RXD2"; + }; + + pinctrl_rxd3_default: rxd3_default { + function = "RXD3"; + groups = "RXD3"; + }; + + pinctrl_rxd4_default: rxd4_default { + function = "RXD4"; + groups = "RXD4"; + }; + + pinctrl_salt1_default: salt1_default { + function = "SALT1"; + groups = "SALT1"; + }; + + pinctrl_salt10_default: salt10_default { + function = "SALT10"; + groups = "SALT10"; + }; + + pinctrl_salt11_default: salt11_default { + function = "SALT11"; + groups = "SALT11"; + }; + + pinctrl_salt12_default: salt12_default { + function = "SALT12"; + groups = "SALT12"; + }; + + pinctrl_salt13_default: salt13_default { + function = "SALT13"; + groups = "SALT13"; + }; + + pinctrl_salt14_default: salt14_default { + function = "SALT14"; + groups = "SALT14"; + }; + + pinctrl_salt2_default: salt2_default { + function = "SALT2"; + groups = "SALT2"; + }; + + pinctrl_salt3_default: salt3_default { + function = "SALT3"; + groups = "SALT3"; + }; + + pinctrl_salt4_default: salt4_default { + function = "SALT4"; + groups = "SALT4"; + }; + + pinctrl_salt5_default: salt5_default { + function = "SALT5"; + groups = "SALT5"; + }; + + pinctrl_salt6_default: salt6_default { + function = "SALT6"; + groups = "SALT6"; + }; + + pinctrl_salt7_default: salt7_default { + function = "SALT7"; + groups = "SALT7"; + }; + + pinctrl_salt8_default: salt8_default { + function = "SALT8"; + groups = "SALT8"; + }; + + pinctrl_salt9_default: salt9_default { + function = "SALT9"; + groups = "SALT9"; + }; + + pinctrl_scl1_default: scl1_default { + function = "SCL1"; + groups = "SCL1"; + }; + + pinctrl_scl2_default: scl2_default { + function = "SCL2"; + groups = "SCL2"; + }; + + pinctrl_sd1_default: sd1_default { + function = "SD1"; + groups = "SD1"; + }; + + pinctrl_sd2_default: sd2_default { + function = "SD2"; + groups = "SD2"; + }; + + pinctrl_emmc_default: emmc_default { + function = "EMMC"; + groups = "EMMC"; + }; + + pinctrl_emmcg8_default: emmcg8_default { + function = "EMMCG8"; + groups = "EMMCG8"; + }; + + pinctrl_sda1_default: sda1_default { + function = "SDA1"; + groups = "SDA1"; + }; + + pinctrl_sda2_default: sda2_default { + function = "SDA2"; + groups = "SDA2"; + }; + + pinctrl_sgps1_default: sgps1_default { + function = "SGPS1"; + groups = "SGPS1"; + }; + + pinctrl_sgps2_default: sgps2_default { + function = "SGPS2"; + groups = "SGPS2"; + }; + + pinctrl_sioonctrl_default: sioonctrl_default { + function = "SIOONCTRL"; + groups = "SIOONCTRL"; + }; + + pinctrl_siopbi_default: siopbi_default { + function = "SIOPBI"; + groups = "SIOPBI"; + }; + + pinctrl_siopbo_default: siopbo_default { + function = "SIOPBO"; + groups = "SIOPBO"; + }; + + pinctrl_siopwreq_default: siopwreq_default { + function = "SIOPWREQ"; + groups = "SIOPWREQ"; + }; + + pinctrl_siopwrgd_default: siopwrgd_default { + function = "SIOPWRGD"; + groups = "SIOPWRGD"; + }; + + pinctrl_sios3_default: sios3_default { + function = "SIOS3"; + groups = "SIOS3"; + }; + + pinctrl_sios5_default: sios5_default { + function = "SIOS5"; + groups = "SIOS5"; + }; + + pinctrl_siosci_default: siosci_default { + function = "SIOSCI"; + groups = "SIOSCI"; + }; + + pinctrl_spi1_default: spi1_default { + function = "SPI1"; + groups = "SPI1"; + }; + + pinctrl_spi1cs1_default: spi1cs1_default { + function = "SPI1CS1"; + groups = "SPI1CS1"; + }; + + pinctrl_spi1debug_default: spi1debug_default { + function = "SPI1DEBUG"; + groups = "SPI1DEBUG"; + }; + + pinctrl_spi1passthru_default: spi1passthru_default { + function = "SPI1PASSTHRU"; + groups = "SPI1PASSTHRU"; + }; + + pinctrl_spi2ck_default: spi2ck_default { + function = "SPI2CK"; + groups = "SPI2CK"; + }; + + pinctrl_spi2cs0_default: spi2cs0_default { + function = "SPI2CS0"; + groups = "SPI2CS0"; + }; + + pinctrl_spi2cs1_default: spi2cs1_default { + function = "SPI2CS1"; + groups = "SPI2CS1"; + }; + + pinctrl_spi2miso_default: spi2miso_default { + function = "SPI2MISO"; + groups = "SPI2MISO"; + }; + + pinctrl_spi2mosi_default: spi2mosi_default { + function = "SPI2MOSI"; + groups = "SPI2MOSI"; + }; + + pinctrl_timer3_default: timer3_default { + function = "TIMER3"; + groups = "TIMER3"; + }; + + pinctrl_timer4_default: timer4_default { + function = "TIMER4"; + groups = "TIMER4"; + }; + + pinctrl_timer5_default: timer5_default { + function = "TIMER5"; + groups = "TIMER5"; + }; + + pinctrl_timer6_default: timer6_default { + function = "TIMER6"; + groups = "TIMER6"; + }; + + pinctrl_timer7_default: timer7_default { + function = "TIMER7"; + groups = "TIMER7"; + }; + + pinctrl_timer8_default: timer8_default { + function = "TIMER8"; + groups = "TIMER8"; + }; + + pinctrl_txd1_default: txd1_default { + function = "TXD1"; + groups = "TXD1"; + }; + + pinctrl_txd2_default: txd2_default { + function = "TXD2"; + groups = "TXD2"; + }; + + pinctrl_txd3_default: txd3_default { + function = "TXD3"; + groups = "TXD3"; + }; + + pinctrl_txd4_default: txd4_default { + function = "TXD4"; + groups = "TXD4"; + }; + + pinctrl_uart6_default: uart6_default { + function = "UART6"; + groups = "UART6"; + }; + + pinctrl_usbcki_default: usbcki_default { + function = "USBCKI"; + groups = "USBCKI"; + }; + + pinctrl_usb2ah_default: usb2ah_default { + function = "USB2AH"; + groups = "USB2AH"; + }; + + pinctrl_usb11bhid_default: usb11bhid_default { + function = "USB11BHID"; + groups = "USB11BHID"; + }; + + pinctrl_usb2bh_default: usb2bh_default { + function = "USB2BH"; + groups = "USB2BH"; + }; + + pinctrl_vgabiosrom_default: vgabiosrom_default { + function = "VGABIOSROM"; + groups = "VGABIOSROM"; + }; + + pinctrl_vgahs_default: vgahs_default { + function = "VGAHS"; + groups = "VGAHS"; + }; + + pinctrl_vgavs_default: vgavs_default { + function = "VGAVS"; + groups = "VGAVS"; + }; + + pinctrl_vpi24_default: vpi24_default { + function = "VPI24"; + groups = "VPI24"; + }; + + pinctrl_vpo_default: vpo_default { + function = "VPO"; + groups = "VPO"; + }; + + pinctrl_wdtrst1_default: wdtrst1_default { + function = "WDTRST1"; + groups = "WDTRST1"; + }; + + pinctrl_wdtrst2_default: wdtrst2_default { + function = "WDTRST2"; + groups = "WDTRST2"; + }; + + pinctrl_pcie0rc_default: pcie0rc_default { + function = "PCIE0RC"; + groups = "PCIE0RC"; + }; + + pinctrl_pcie1rc_default: pcie1rc_default { + function = "PCIE1RC"; + groups = "PCIE1RC"; + }; +}; diff --git a/arch/arm/dts/ca-presidio-engboard.dts b/arch/arm/dts/ca-presidio-engboard.dts index eef433e768..0ab52fdfda 100644 --- a/arch/arm/dts/ca-presidio-engboard.dts +++ b/arch/arm/dts/ca-presidio-engboard.dts @@ -52,6 +52,20 @@ clock-frequency = <400000>; }; + nand: nand-controller@f4324000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "cortina,ca-nand"; + reg = <0 0xf4324000 0x3b0>, /* NAND controller */ + <0 0xf7001000 0xb4>, /* DMA_GLOBAL */ + <0 0xf7001a00 0x80>; /* DMA channel0 for FLASH */ + status = "okay"; + nand-ecc-mode = "hw"; + nand-ecc-strength = <16>; + nand-ecc-step-size = <1024>; /* Must be 1024 */ + nand_flash_base_addr = <0xe0000000>; + }; + sflash: sflash-controller@f4324000 { #address-cells = <2>; #size-cells = <1>; diff --git a/arch/arm/dts/meson-axg.dtsi b/arch/arm/dts/meson-axg.dtsi index 8e6281c685..b9efc84692 100644 --- a/arch/arm/dts/meson-axg.dtsi +++ b/arch/arm/dts/meson-axg.dtsi @@ -181,8 +181,10 @@ interrupt-names = "macirq"; clocks = <&clkc CLKID_ETH>, <&clkc CLKID_FCLK_DIV2>, - <&clkc CLKID_MPLL2>; - clock-names = "stmmaceth", "clkin0", "clkin1"; + <&clkc CLKID_MPLL2>, + <&clkc CLKID_FCLK_DIV2>; + clock-names = "stmmaceth", "clkin0", "clkin1", + "timing-adjustment"; rx-fifo-depth = <4096>; tx-fifo-depth = <2048>; status = "disabled"; diff --git a/arch/arm/dts/meson-g12b-gtking-pro.dts b/arch/arm/dts/meson-g12b-gtking-pro.dts new file mode 100644 index 0000000000..f0c56a16af --- /dev/null +++ b/arch/arm/dts/meson-g12b-gtking-pro.dts @@ -0,0 +1,125 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 BayLibre, SAS + * Author: Neil Armstrong <narmstrong@baylibre.com> + * Copyright (c) 2019 Christian Hewitt <christianshewitt@gmail.com> + */ + +/dts-v1/; + +#include "meson-g12b-w400.dtsi" +#include <dt-bindings/sound/meson-g12a-tohdmitx.h> + +/ { + compatible = "azw,gtking", "amlogic,g12b"; + model = "Beelink GT-King Pro"; + + gpio-keys-polled { + compatible = "gpio-keys-polled"; + #address-cells = <1>; + #size-cells = <0>; + poll-interval = <100>; + + power-button { + label = "power"; + linux,code = <KEY_POWER>; + gpios = <&gpio_ao GPIOAO_3 GPIO_ACTIVE_HIGH>; + }; + }; + + leds { + compatible = "gpio-leds"; + + white { + label = "power:white"; + gpios = <&gpio_ao GPIOAO_11 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + }; + + sound { + compatible = "amlogic,axg-sound-card"; + model = "G12B-GTKING-PRO"; + audio-aux-devs = <&tdmout_b>; + audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1", + "TDMOUT_B IN 1", "FRDDR_B OUT 1", + "TDMOUT_B IN 2", "FRDDR_C OUT 1", + "TDM_B Playback", "TDMOUT_B OUT"; + + assigned-clocks = <&clkc CLKID_MPLL2>, + <&clkc CLKID_MPLL0>, + <&clkc CLKID_MPLL1>; + assigned-clock-parents = <0>, <0>, <0>; + assigned-clock-rates = <294912000>, + <270950400>, + <393216000>; + status = "okay"; + + dai-link-0 { + sound-dai = <&frddr_a>; + }; + + dai-link-1 { + sound-dai = <&frddr_b>; + }; + + dai-link-2 { + sound-dai = <&frddr_c>; + }; + + /* 8ch hdmi interface */ + dai-link-3 { + sound-dai = <&tdmif_b>; + dai-format = "i2s"; + dai-tdm-slot-tx-mask-0 = <1 1>; + dai-tdm-slot-tx-mask-1 = <1 1>; + dai-tdm-slot-tx-mask-2 = <1 1>; + dai-tdm-slot-tx-mask-3 = <1 1>; + mclk-fs = <256>; + + codec { + sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>; + }; + }; + + dai-link-4 { + sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>; + + codec { + sound-dai = <&hdmi_tx>; + }; + }; + }; +}; + +&arb { + status = "okay"; +}; + +&clkc_audio { + status = "okay"; +}; + +&frddr_a { + status = "okay"; +}; + +&frddr_b { + status = "okay"; +}; + +&frddr_c { + status = "okay"; +}; + +&tdmif_b { + status = "okay"; +}; + +&tdmout_b { + status = "okay"; +}; + +&tohdmitx { + status = "okay"; +}; diff --git a/arch/arm/dts/meson-g12b-gtking.dts b/arch/arm/dts/meson-g12b-gtking.dts new file mode 100644 index 0000000000..eeb7bc5539 --- /dev/null +++ b/arch/arm/dts/meson-g12b-gtking.dts @@ -0,0 +1,145 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 BayLibre, SAS + * Author: Neil Armstrong <narmstrong@baylibre.com> + * Copyright (c) 2019 Christian Hewitt <christianshewitt@gmail.com> + */ + +/dts-v1/; + +#include "meson-g12b-w400.dtsi" +#include <dt-bindings/sound/meson-g12a-tohdmitx.h> + +/ { + compatible = "azw,gtking", "amlogic,g12b"; + model = "Beelink GT-King"; + + spdif_dit: audio-codec-1 { + #sound-dai-cells = <0>; + compatible = "linux,spdif-dit"; + status = "okay"; + sound-name-prefix = "DIT"; + }; + + sound { + compatible = "amlogic,axg-sound-card"; + model = "G12B-GTKING"; + audio-aux-devs = <&tdmout_b>; + audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1", + "TDMOUT_B IN 1", "FRDDR_B OUT 1", + "TDMOUT_B IN 2", "FRDDR_C OUT 1", + "TDM_B Playback", "TDMOUT_B OUT", + "SPDIFOUT IN 0", "FRDDR_A OUT 3", + "SPDIFOUT IN 1", "FRDDR_B OUT 3", + "SPDIFOUT IN 2", "FRDDR_C OUT 3"; + + assigned-clocks = <&clkc CLKID_MPLL2>, + <&clkc CLKID_MPLL0>, + <&clkc CLKID_MPLL1>; + assigned-clock-parents = <0>, <0>, <0>; + assigned-clock-rates = <294912000>, + <270950400>, + <393216000>; + status = "okay"; + + dai-link-0 { + sound-dai = <&frddr_a>; + }; + + dai-link-1 { + sound-dai = <&frddr_b>; + }; + + dai-link-2 { + sound-dai = <&frddr_c>; + }; + + /* 8ch hdmi interface */ + dai-link-3 { + sound-dai = <&tdmif_b>; + dai-format = "i2s"; + dai-tdm-slot-tx-mask-0 = <1 1>; + dai-tdm-slot-tx-mask-1 = <1 1>; + dai-tdm-slot-tx-mask-2 = <1 1>; + dai-tdm-slot-tx-mask-3 = <1 1>; + mclk-fs = <256>; + + codec { + sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>; + }; + }; + + /* spdif hdmi or toslink interface */ + dai-link-4 { + sound-dai = <&spdifout>; + + codec-0 { + sound-dai = <&spdif_dit>; + }; + + codec-1 { + sound-dai = <&tohdmitx TOHDMITX_SPDIF_IN_A>; + }; + }; + + /* spdif hdmi interface */ + dai-link-5 { + sound-dai = <&spdifout_b>; + + codec { + sound-dai = <&tohdmitx TOHDMITX_SPDIF_IN_B>; + }; + }; + + /* hdmi glue */ + dai-link-6 { + sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>; + + codec { + sound-dai = <&hdmi_tx>; + }; + }; + }; +}; + +&arb { + status = "okay"; +}; + +&clkc_audio { + status = "okay"; +}; + +&frddr_a { + status = "okay"; +}; + +&frddr_b { + status = "okay"; +}; + +&frddr_c { + status = "okay"; +}; + +&spdifout { + pinctrl-0 = <&spdif_out_h_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + +&spdifout_b { + status = "okay"; +}; + +&tdmif_b { + status = "okay"; +}; + +&tdmout_b { + status = "okay"; +}; + +&tohdmitx { + status = "okay"; +}; diff --git a/arch/arm/dts/meson-g12b-khadas-vim3.dtsi b/arch/arm/dts/meson-g12b-khadas-vim3.dtsi index 224c890d32..f42cf4b8af 100644 --- a/arch/arm/dts/meson-g12b-khadas-vim3.dtsi +++ b/arch/arm/dts/meson-g12b-khadas-vim3.dtsi @@ -5,8 +5,6 @@ * Copyright (c) 2019 Christian Hewitt <christianshewitt@gmail.com> */ -#include <dt-bindings/sound/meson-g12a-tohdmitx.h> - / { model = "Khadas VIM3"; @@ -47,69 +45,6 @@ regulator-boot-on; regulator-always-on; }; - - sound { - compatible = "amlogic,axg-sound-card"; - model = "G12B-KHADAS-VIM3"; - audio-aux-devs = <&tdmout_a>; - audio-routing = "TDMOUT_A IN 0", "FRDDR_A OUT 0", - "TDMOUT_A IN 1", "FRDDR_B OUT 0", - "TDMOUT_A IN 2", "FRDDR_C OUT 0", - "TDM_A Playback", "TDMOUT_A OUT"; - - assigned-clocks = <&clkc CLKID_MPLL2>, - <&clkc CLKID_MPLL0>, - <&clkc CLKID_MPLL1>; - assigned-clock-parents = <0>, <0>, <0>; - assigned-clock-rates = <294912000>, - <270950400>, - <393216000>; - status = "okay"; - - dai-link-0 { - sound-dai = <&frddr_a>; - }; - - dai-link-1 { - sound-dai = <&frddr_b>; - }; - - dai-link-2 { - sound-dai = <&frddr_c>; - }; - - /* 8ch hdmi interface */ - dai-link-3 { - sound-dai = <&tdmif_a>; - dai-format = "i2s"; - dai-tdm-slot-tx-mask-0 = <1 1>; - dai-tdm-slot-tx-mask-1 = <1 1>; - dai-tdm-slot-tx-mask-2 = <1 1>; - dai-tdm-slot-tx-mask-3 = <1 1>; - mclk-fs = <256>; - - codec { - sound-dai = <&tohdmitx TOHDMITX_I2S_IN_A>; - }; - }; - - /* hdmi glue */ - dai-link-4 { - sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>; - - codec { - sound-dai = <&hdmi_tx>; - }; - }; - }; -}; - -&arb { - status = "okay"; -}; - -&clkc_audio { - status = "okay"; }; &cpu0 { @@ -154,18 +89,6 @@ clock-latency = <50000>; }; -&frddr_a { - status = "okay"; -}; - -&frddr_b { - status = "okay"; -}; - -&frddr_c { - status = "okay"; -}; - &pwm_ab { pinctrl-0 = <&pwm_a_e_pins>; pinctrl-names = "default"; @@ -182,14 +105,3 @@ status = "okay"; }; -&tdmif_a { - status = "okay"; -}; - -&tdmout_a { - status = "okay"; -}; - -&tohdmitx { - status = "okay"; -}; diff --git a/arch/arm/dts/meson-g12b-odroid-n2-plus.dts b/arch/arm/dts/meson-g12b-odroid-n2-plus.dts new file mode 100644 index 0000000000..5de2815ba9 --- /dev/null +++ b/arch/arm/dts/meson-g12b-odroid-n2-plus.dts @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 BayLibre, SAS + * Author: Neil Armstrong <narmstrong@baylibre.com> + */ + +/dts-v1/; + +/* The Amlogic S922X Rev. C supports the same OPPs as the A311D variant */ +#include "meson-g12b-a311d.dtsi" +#include "meson-g12b-odroid-n2.dtsi" + +/ { + compatible = "hardkernel,odroid-n2-plus", "amlogic,s922x", "amlogic,g12b"; + model = "Hardkernel ODROID-N2Plus"; +}; + +&vddcpu_a { + regulator-min-microvolt = <680000>; + regulator-max-microvolt = <1040000>; + + pwms = <&pwm_AO_cd 1 1500 0>; +}; + +&vddcpu_b { + regulator-min-microvolt = <680000>; + regulator-max-microvolt = <1040000>; + + pwms = <&pwm_AO_cd 1 1500 0>; +}; + diff --git a/arch/arm/dts/meson-g12b-odroid-n2.dts b/arch/arm/dts/meson-g12b-odroid-n2.dts index 34fffa6d85..a198a91259 100644 --- a/arch/arm/dts/meson-g12b-odroid-n2.dts +++ b/arch/arm/dts/meson-g12b-odroid-n2.dts @@ -7,625 +7,9 @@ /dts-v1/; #include "meson-g12b-s922x.dtsi" -#include <dt-bindings/input/input.h> -#include <dt-bindings/gpio/meson-g12a-gpio.h> -#include <dt-bindings/sound/meson-g12a-toacodec.h> -#include <dt-bindings/sound/meson-g12a-tohdmitx.h> +#include "meson-g12b-odroid-n2.dtsi" / { compatible = "hardkernel,odroid-n2", "amlogic,s922x", "amlogic,g12b"; model = "Hardkernel ODROID-N2"; - - aliases { - serial0 = &uart_AO; - ethernet0 = ðmac; - }; - - dioo2133: audio-amplifier-0 { - compatible = "simple-audio-amplifier"; - enable-gpios = <&gpio_ao GPIOAO_2 GPIO_ACTIVE_HIGH>; - VCC-supply = <&vcc_5v>; - sound-name-prefix = "U19"; - status = "okay"; - }; - - chosen { - stdout-path = "serial0:115200n8"; - }; - - memory@0 { - device_type = "memory"; - reg = <0x0 0x0 0x0 0x40000000>; - }; - - emmc_pwrseq: emmc-pwrseq { - compatible = "mmc-pwrseq-emmc"; - reset-gpios = <&gpio BOOT_12 GPIO_ACTIVE_LOW>; - }; - - leds { - compatible = "gpio-leds"; - - blue { - label = "n2:blue"; - gpios = <&gpio_ao GPIOAO_11 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "heartbeat"; - }; - }; - - tflash_vdd: regulator-tflash_vdd { - compatible = "regulator-fixed"; - - regulator-name = "TFLASH_VDD"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - - gpio = <&gpio_ao GPIOAO_8 GPIO_ACTIVE_HIGH>; - enable-active-high; - regulator-always-on; - }; - - tf_io: gpio-regulator-tf_io { - compatible = "regulator-gpio"; - - regulator-name = "TF_IO"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <3300000>; - - gpios = <&gpio_ao GPIOAO_9 GPIO_ACTIVE_HIGH>; - gpios-states = <0>; - - states = <3300000 0>, - <1800000 1>; - }; - - flash_1v8: regulator-flash_1v8 { - compatible = "regulator-fixed"; - regulator-name = "FLASH_1V8"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - vin-supply = <&vcc_3v3>; - regulator-always-on; - }; - - main_12v: regulator-main_12v { - compatible = "regulator-fixed"; - regulator-name = "12V"; - regulator-min-microvolt = <12000000>; - regulator-max-microvolt = <12000000>; - regulator-always-on; - }; - - vcc_5v: regulator-vcc_5v { - compatible = "regulator-fixed"; - regulator-name = "5V"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - regulator-always-on; - vin-supply = <&main_12v>; - }; - - vcc_1v8: regulator-vcc_1v8 { - compatible = "regulator-fixed"; - regulator-name = "VCC_1V8"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - vin-supply = <&vcc_3v3>; - regulator-always-on; - }; - - vcc_3v3: regulator-vcc_3v3 { - compatible = "regulator-fixed"; - regulator-name = "VCC_3V3"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - vin-supply = <&vddao_3v3>; - regulator-always-on; - /* FIXME: actually controlled by VDDCPU_B_EN */ - }; - - vddcpu_a: regulator-vddcpu-a { - /* - * MP8756GD Regulator. - */ - compatible = "pwm-regulator"; - - regulator-name = "VDDCPU_A"; - regulator-min-microvolt = <721000>; - regulator-max-microvolt = <1022000>; - - vin-supply = <&main_12v>; - - pwms = <&pwm_ab 0 1250 0>; - pwm-dutycycle-range = <100 0>; - - regulator-boot-on; - regulator-always-on; - }; - - vddcpu_b: regulator-vddcpu-b { - /* - * Silergy SY8120B1ABC Regulator. - */ - compatible = "pwm-regulator"; - - regulator-name = "VDDCPU_B"; - regulator-min-microvolt = <721000>; - regulator-max-microvolt = <1022000>; - - vin-supply = <&main_12v>; - - pwms = <&pwm_AO_cd 1 1250 0>; - pwm-dutycycle-range = <100 0>; - - regulator-boot-on; - regulator-always-on; - }; - - hub_5v: regulator-hub_5v { - compatible = "regulator-fixed"; - regulator-name = "HUB_5V"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - vin-supply = <&vcc_5v>; - - /* Connected to the Hub CHIPENABLE, LOW sets low power state */ - gpio = <&gpio GPIOH_5 GPIO_ACTIVE_HIGH>; - enable-active-high; - }; - - usb_pwr_en: regulator-usb_pwr_en { - compatible = "regulator-fixed"; - regulator-name = "USB_PWR_EN"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - vin-supply = <&vcc_5v>; - - /* Connected to the microUSB port power enable */ - gpio = <&gpio GPIOH_6 GPIO_ACTIVE_HIGH>; - enable-active-high; - }; - - vddao_1v8: regulator-vddao_1v8 { - compatible = "regulator-fixed"; - regulator-name = "VDDAO_1V8"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - vin-supply = <&vddao_3v3>; - regulator-always-on; - }; - - vddao_3v3: regulator-vddao_3v3 { - compatible = "regulator-fixed"; - regulator-name = "VDDAO_3V3"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - vin-supply = <&main_12v>; - regulator-always-on; - }; - - hdmi-connector { - compatible = "hdmi-connector"; - type = "a"; - - port { - hdmi_connector_in: endpoint { - remote-endpoint = <&hdmi_tx_tmds_out>; - }; - }; - }; - - sound { - compatible = "amlogic,axg-sound-card"; - model = "G12B-ODROID-N2"; - audio-widgets = "Line", "Lineout"; - audio-aux-devs = <&tdmout_b>, <&tdmout_c>, <&tdmin_a>, - <&tdmin_b>, <&tdmin_c>, <&tdmin_lb>, - <&dioo2133>; - audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1", - "TDMOUT_B IN 1", "FRDDR_B OUT 1", - "TDMOUT_B IN 2", "FRDDR_C OUT 1", - "TDM_B Playback", "TDMOUT_B OUT", - "TDMOUT_C IN 0", "FRDDR_A OUT 2", - "TDMOUT_C IN 1", "FRDDR_B OUT 2", - "TDMOUT_C IN 2", "FRDDR_C OUT 2", - "TDM_C Playback", "TDMOUT_C OUT", - "TDMIN_A IN 4", "TDM_B Loopback", - "TDMIN_B IN 4", "TDM_B Loopback", - "TDMIN_C IN 4", "TDM_B Loopback", - "TDMIN_LB IN 1", "TDM_B Loopback", - "TDMIN_A IN 5", "TDM_C Loopback", - "TDMIN_B IN 5", "TDM_C Loopback", - "TDMIN_C IN 5", "TDM_C Loopback", - "TDMIN_LB IN 2", "TDM_C Loopback", - "TODDR_A IN 0", "TDMIN_A OUT", - "TODDR_B IN 0", "TDMIN_A OUT", - "TODDR_C IN 0", "TDMIN_A OUT", - "TODDR_A IN 1", "TDMIN_B OUT", - "TODDR_B IN 1", "TDMIN_B OUT", - "TODDR_C IN 1", "TDMIN_B OUT", - "TODDR_A IN 2", "TDMIN_C OUT", - "TODDR_B IN 2", "TDMIN_C OUT", - "TODDR_C IN 2", "TDMIN_C OUT", - "TODDR_A IN 6", "TDMIN_LB OUT", - "TODDR_B IN 6", "TDMIN_LB OUT", - "TODDR_C IN 6", "TDMIN_LB OUT", - "U19 INL", "ACODEC LOLP", - "U19 INR", "ACODEC LORP", - "Lineout", "U19 OUTL", - "Lineout", "U19 OUTR"; - - assigned-clocks = <&clkc CLKID_MPLL2>, - <&clkc CLKID_MPLL0>, - <&clkc CLKID_MPLL1>; - assigned-clock-parents = <0>, <0>, <0>; - assigned-clock-rates = <294912000>, - <270950400>, - <393216000>; - status = "okay"; - - dai-link-0 { - sound-dai = <&frddr_a>; - }; - - dai-link-1 { - sound-dai = <&frddr_b>; - }; - - dai-link-2 { - sound-dai = <&frddr_c>; - }; - - dai-link-3 { - sound-dai = <&toddr_a>; - }; - - dai-link-4 { - sound-dai = <&toddr_b>; - }; - - dai-link-5 { - sound-dai = <&toddr_c>; - }; - - /* 8ch hdmi interface */ - dai-link-6 { - sound-dai = <&tdmif_b>; - dai-format = "i2s"; - dai-tdm-slot-tx-mask-0 = <1 1>; - dai-tdm-slot-tx-mask-1 = <1 1>; - dai-tdm-slot-tx-mask-2 = <1 1>; - dai-tdm-slot-tx-mask-3 = <1 1>; - mclk-fs = <256>; - - codec-0 { - sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>; - }; - - codec-1 { - sound-dai = <&toacodec TOACODEC_IN_B>; - }; - }; - - /* i2s jack output interface */ - dai-link-7 { - sound-dai = <&tdmif_c>; - dai-format = "i2s"; - dai-tdm-slot-tx-mask-0 = <1 1>; - mclk-fs = <256>; - - codec-0 { - sound-dai = <&tohdmitx TOHDMITX_I2S_IN_C>; - }; - - codec-1 { - sound-dai = <&toacodec TOACODEC_IN_C>; - }; - }; - - /* hdmi glue */ - dai-link-8 { - sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>; - - codec { - sound-dai = <&hdmi_tx>; - }; - }; - - /* acodec glue */ - dai-link-9 { - sound-dai = <&toacodec TOACODEC_OUT>; - - codec { - sound-dai = <&acodec>; - }; - }; - }; -}; - -&acodec { - AVDD-supply = <&vddao_1v8>; - status = "okay"; -}; - -&arb { - status = "okay"; -}; - -&cec_AO { - pinctrl-0 = <&cec_ao_a_h_pins>; - pinctrl-names = "default"; - status = "disabled"; - hdmi-phandle = <&hdmi_tx>; -}; - -&cecb_AO { - pinctrl-0 = <&cec_ao_b_h_pins>; - pinctrl-names = "default"; - status = "okay"; - hdmi-phandle = <&hdmi_tx>; -}; - -&clkc_audio { - status = "okay"; -}; - -&cpu0 { - cpu-supply = <&vddcpu_b>; - operating-points-v2 = <&cpu_opp_table_0>; - clocks = <&clkc CLKID_CPU_CLK>; - clock-latency = <50000>; -}; - -&cpu1 { - cpu-supply = <&vddcpu_b>; - operating-points-v2 = <&cpu_opp_table_0>; - clocks = <&clkc CLKID_CPU_CLK>; - clock-latency = <50000>; -}; - -&cpu100 { - cpu-supply = <&vddcpu_a>; - operating-points-v2 = <&cpub_opp_table_1>; - clocks = <&clkc CLKID_CPUB_CLK>; - clock-latency = <50000>; -}; - -&cpu101 { - cpu-supply = <&vddcpu_a>; - operating-points-v2 = <&cpub_opp_table_1>; - clocks = <&clkc CLKID_CPUB_CLK>; - clock-latency = <50000>; -}; - -&cpu102 { - cpu-supply = <&vddcpu_a>; - operating-points-v2 = <&cpub_opp_table_1>; - clocks = <&clkc CLKID_CPUB_CLK>; - clock-latency = <50000>; -}; - -&cpu103 { - cpu-supply = <&vddcpu_a>; - operating-points-v2 = <&cpub_opp_table_1>; - clocks = <&clkc CLKID_CPUB_CLK>; - clock-latency = <50000>; -}; - -&ext_mdio { - external_phy: ethernet-phy@0 { - /* Realtek RTL8211F (0x001cc916) */ - reg = <0>; - max-speed = <1000>; - - reset-assert-us = <10000>; - reset-deassert-us = <30000>; - reset-gpios = <&gpio GPIOZ_15 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>; - - interrupt-parent = <&gpio_intc>; - /* MAC_INTR on GPIOZ_14 */ - interrupts = <26 IRQ_TYPE_LEVEL_LOW>; - }; -}; - -ðmac { - pinctrl-0 = <ð_pins>, <ð_rgmii_pins>; - pinctrl-names = "default"; - status = "okay"; - phy-mode = "rgmii"; - phy-handle = <&external_phy>; - amlogic,tx-delay-ns = <2>; -}; - -&frddr_a { - status = "okay"; -}; - -&frddr_b { - status = "okay"; -}; - -&frddr_c { - status = "okay"; -}; - -&gpio { - /* - * WARNING: The USB Hub on the Odroid-N2 needs a reset signal - * to be turned high in order to be detected by the USB Controller - * This signal should be handled by a USB specific power sequence - * in order to reset the Hub when USB bus is powered down. - */ - usb-hub { - gpio-hog; - gpios = <GPIOH_4 GPIO_ACTIVE_HIGH>; - output-high; - line-name = "usb-hub-reset"; - }; -}; - -&hdmi_tx { - status = "okay"; - pinctrl-0 = <&hdmitx_hpd_pins>, <&hdmitx_ddc_pins>; - pinctrl-names = "default"; - hdmi-supply = <&vcc_5v>; -}; - -&hdmi_tx_tmds_port { - hdmi_tx_tmds_out: endpoint { - remote-endpoint = <&hdmi_connector_in>; - }; -}; - -&ir { - status = "okay"; - pinctrl-0 = <&remote_input_ao_pins>; - pinctrl-names = "default"; - linux,rc-map-name = "rc-odroid"; -}; - -&pwm_ab { - pinctrl-0 = <&pwm_a_e_pins>; - pinctrl-names = "default"; - clocks = <&xtal>; - clock-names = "clkin0"; - status = "okay"; -}; - -&pwm_AO_cd { - pinctrl-0 = <&pwm_ao_d_e_pins>; - pinctrl-names = "default"; - clocks = <&xtal>; - clock-names = "clkin1"; - status = "okay"; -}; - -/* SD card */ -&sd_emmc_b { - status = "okay"; - pinctrl-0 = <&sdcard_c_pins>; - pinctrl-1 = <&sdcard_clk_gate_c_pins>; - pinctrl-names = "default", "clk-gate"; - - bus-width = <4>; - cap-sd-highspeed; - max-frequency = <50000000>; - disable-wp; - - cd-gpios = <&gpio GPIOC_6 GPIO_ACTIVE_LOW>; - vmmc-supply = <&tflash_vdd>; - vqmmc-supply = <&tf_io>; - -}; - -/* eMMC */ -&sd_emmc_c { - status = "okay"; - pinctrl-0 = <&emmc_ctrl_pins>, <&emmc_data_8b_pins>, <&emmc_ds_pins>; - pinctrl-1 = <&emmc_clk_gate_pins>; - pinctrl-names = "default", "clk-gate"; - - bus-width = <8>; - cap-mmc-highspeed; - mmc-ddr-1_8v; - mmc-hs200-1_8v; - max-frequency = <200000000>; - disable-wp; - - mmc-pwrseq = <&emmc_pwrseq>; - vmmc-supply = <&vcc_3v3>; - vqmmc-supply = <&flash_1v8>; -}; - -/* - * EMMC_D4, EMMC_D5, EMMC_D6 and EMMC_D7 pins are shared between SPI NOR pins - * and eMMC Data 4 to 7 pins. - * Replace emmc_data_8b_pins to emmc_data_4b_pins from sd_emmc_c pinctrl-0, - * and change bus-width to 4 then spifc can be enabled. - * The SW1 slide should also be set to the correct position. - */ -&spifc { - status = "disabled"; - pinctrl-0 = <&nor_pins>; - pinctrl-names = "default"; - - mx25u64: spi-flash@0 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "mxicy,mx25u6435f", "jedec,spi-nor"; - reg = <0>; - spi-max-frequency = <104000000>; - }; -}; - -&tdmif_b { - status = "okay"; -}; - -&tdmif_c { - status = "okay"; -}; - -&tdmin_a { - status = "okay"; -}; - -&tdmin_b { - status = "okay"; -}; - -&tdmin_c { - status = "okay"; -}; - -&tdmin_lb { - status = "okay"; -}; - -&tdmout_b { - status = "okay"; -}; - -&tdmout_c { - status = "okay"; -}; - -&toacodec { - status = "okay"; -}; - -&tohdmitx { - status = "okay"; -}; - -&toddr_a { - status = "okay"; -}; - -&toddr_b { - status = "okay"; -}; - -&toddr_c { - status = "okay"; -}; - -&uart_AO { - status = "okay"; - pinctrl-0 = <&uart_ao_a_pins>; - pinctrl-names = "default"; -}; - -&usb { - status = "okay"; - vbus-supply = <&usb_pwr_en>; -}; - -&usb2_phy0 { - phy-supply = <&vcc_5v>; -}; - -&usb2_phy1 { - /* Enable the hub which is connected to this port */ - phy-supply = <&hub_5v>; }; diff --git a/arch/arm/dts/meson-g12b-odroid-n2.dtsi b/arch/arm/dts/meson-g12b-odroid-n2.dtsi new file mode 100644 index 0000000000..6982632ae6 --- /dev/null +++ b/arch/arm/dts/meson-g12b-odroid-n2.dtsi @@ -0,0 +1,625 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 BayLibre, SAS + * Author: Neil Armstrong <narmstrong@baylibre.com> + */ + +#include <dt-bindings/input/input.h> +#include <dt-bindings/gpio/meson-g12a-gpio.h> +#include <dt-bindings/sound/meson-g12a-toacodec.h> +#include <dt-bindings/sound/meson-g12a-tohdmitx.h> + +/ { + aliases { + serial0 = &uart_AO; + ethernet0 = ðmac; + }; + + dioo2133: audio-amplifier-0 { + compatible = "simple-audio-amplifier"; + enable-gpios = <&gpio_ao GPIOAO_2 GPIO_ACTIVE_HIGH>; + VCC-supply = <&vcc_5v>; + sound-name-prefix = "U19"; + status = "okay"; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x40000000>; + }; + + emmc_pwrseq: emmc-pwrseq { + compatible = "mmc-pwrseq-emmc"; + reset-gpios = <&gpio BOOT_12 GPIO_ACTIVE_LOW>; + }; + + leds { + compatible = "gpio-leds"; + + blue { + label = "n2:blue"; + gpios = <&gpio_ao GPIOAO_11 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + }; + }; + + tflash_vdd: regulator-tflash_vdd { + compatible = "regulator-fixed"; + + regulator-name = "TFLASH_VDD"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&gpio_ao GPIOAO_8 GPIO_ACTIVE_HIGH>; + enable-active-high; + regulator-always-on; + }; + + tf_io: gpio-regulator-tf_io { + compatible = "regulator-gpio"; + + regulator-name = "TF_IO"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + + gpios = <&gpio_ao GPIOAO_9 GPIO_ACTIVE_HIGH>; + gpios-states = <0>; + + states = <3300000 0>, + <1800000 1>; + }; + + flash_1v8: regulator-flash_1v8 { + compatible = "regulator-fixed"; + regulator-name = "FLASH_1V8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vcc_3v3>; + regulator-always-on; + }; + + main_12v: regulator-main_12v { + compatible = "regulator-fixed"; + regulator-name = "12V"; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + regulator-always-on; + }; + + vcc_5v: regulator-vcc_5v { + compatible = "regulator-fixed"; + regulator-name = "5V"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + vin-supply = <&main_12v>; + }; + + vcc_1v8: regulator-vcc_1v8 { + compatible = "regulator-fixed"; + regulator-name = "VCC_1V8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vcc_3v3>; + regulator-always-on; + }; + + vcc_3v3: regulator-vcc_3v3 { + compatible = "regulator-fixed"; + regulator-name = "VCC_3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vddao_3v3>; + regulator-always-on; + /* FIXME: actually controlled by VDDCPU_B_EN */ + }; + + vddcpu_a: regulator-vddcpu-a { + /* + * MP8756GD Regulator. + */ + compatible = "pwm-regulator"; + + regulator-name = "VDDCPU_A"; + regulator-min-microvolt = <721000>; + regulator-max-microvolt = <1022000>; + + vin-supply = <&main_12v>; + + pwms = <&pwm_ab 0 1250 0>; + pwm-dutycycle-range = <100 0>; + + regulator-boot-on; + regulator-always-on; + }; + + vddcpu_b: regulator-vddcpu-b { + /* + * Silergy SY8120B1ABC Regulator. + */ + compatible = "pwm-regulator"; + + regulator-name = "VDDCPU_B"; + regulator-min-microvolt = <721000>; + regulator-max-microvolt = <1022000>; + + vin-supply = <&main_12v>; + + pwms = <&pwm_AO_cd 1 1250 0>; + pwm-dutycycle-range = <100 0>; + + regulator-boot-on; + regulator-always-on; + }; + + hub_5v: regulator-hub_5v { + compatible = "regulator-fixed"; + regulator-name = "HUB_5V"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc_5v>; + + /* Connected to the Hub CHIPENABLE, LOW sets low power state */ + gpio = <&gpio GPIOH_5 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + usb_pwr_en: regulator-usb_pwr_en { + compatible = "regulator-fixed"; + regulator-name = "USB_PWR_EN"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc_5v>; + + /* Connected to the microUSB port power enable */ + gpio = <&gpio GPIOH_6 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + vddao_1v8: regulator-vddao_1v8 { + compatible = "regulator-fixed"; + regulator-name = "VDDAO_1V8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vddao_3v3>; + regulator-always-on; + }; + + vddao_3v3: regulator-vddao_3v3 { + compatible = "regulator-fixed"; + regulator-name = "VDDAO_3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&main_12v>; + regulator-always-on; + }; + + hdmi-connector { + compatible = "hdmi-connector"; + type = "a"; + + port { + hdmi_connector_in: endpoint { + remote-endpoint = <&hdmi_tx_tmds_out>; + }; + }; + }; + + sound { + compatible = "amlogic,axg-sound-card"; + model = "G12B-ODROID-N2"; + audio-widgets = "Line", "Lineout"; + audio-aux-devs = <&tdmout_b>, <&tdmout_c>, <&tdmin_a>, + <&tdmin_b>, <&tdmin_c>, <&tdmin_lb>, + <&dioo2133>; + audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1", + "TDMOUT_B IN 1", "FRDDR_B OUT 1", + "TDMOUT_B IN 2", "FRDDR_C OUT 1", + "TDM_B Playback", "TDMOUT_B OUT", + "TDMOUT_C IN 0", "FRDDR_A OUT 2", + "TDMOUT_C IN 1", "FRDDR_B OUT 2", + "TDMOUT_C IN 2", "FRDDR_C OUT 2", + "TDM_C Playback", "TDMOUT_C OUT", + "TDMIN_A IN 4", "TDM_B Loopback", + "TDMIN_B IN 4", "TDM_B Loopback", + "TDMIN_C IN 4", "TDM_B Loopback", + "TDMIN_LB IN 1", "TDM_B Loopback", + "TDMIN_A IN 5", "TDM_C Loopback", + "TDMIN_B IN 5", "TDM_C Loopback", + "TDMIN_C IN 5", "TDM_C Loopback", + "TDMIN_LB IN 2", "TDM_C Loopback", + "TODDR_A IN 0", "TDMIN_A OUT", + "TODDR_B IN 0", "TDMIN_A OUT", + "TODDR_C IN 0", "TDMIN_A OUT", + "TODDR_A IN 1", "TDMIN_B OUT", + "TODDR_B IN 1", "TDMIN_B OUT", + "TODDR_C IN 1", "TDMIN_B OUT", + "TODDR_A IN 2", "TDMIN_C OUT", + "TODDR_B IN 2", "TDMIN_C OUT", + "TODDR_C IN 2", "TDMIN_C OUT", + "TODDR_A IN 6", "TDMIN_LB OUT", + "TODDR_B IN 6", "TDMIN_LB OUT", + "TODDR_C IN 6", "TDMIN_LB OUT", + "U19 INL", "ACODEC LOLP", + "U19 INR", "ACODEC LORP", + "Lineout", "U19 OUTL", + "Lineout", "U19 OUTR"; + + assigned-clocks = <&clkc CLKID_MPLL2>, + <&clkc CLKID_MPLL0>, + <&clkc CLKID_MPLL1>; + assigned-clock-parents = <0>, <0>, <0>; + assigned-clock-rates = <294912000>, + <270950400>, + <393216000>; + status = "okay"; + + dai-link-0 { + sound-dai = <&frddr_a>; + }; + + dai-link-1 { + sound-dai = <&frddr_b>; + }; + + dai-link-2 { + sound-dai = <&frddr_c>; + }; + + dai-link-3 { + sound-dai = <&toddr_a>; + }; + + dai-link-4 { + sound-dai = <&toddr_b>; + }; + + dai-link-5 { + sound-dai = <&toddr_c>; + }; + + /* 8ch hdmi interface */ + dai-link-6 { + sound-dai = <&tdmif_b>; + dai-format = "i2s"; + dai-tdm-slot-tx-mask-0 = <1 1>; + dai-tdm-slot-tx-mask-1 = <1 1>; + dai-tdm-slot-tx-mask-2 = <1 1>; + dai-tdm-slot-tx-mask-3 = <1 1>; + mclk-fs = <256>; + + codec-0 { + sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>; + }; + + codec-1 { + sound-dai = <&toacodec TOACODEC_IN_B>; + }; + }; + + /* i2s jack output interface */ + dai-link-7 { + sound-dai = <&tdmif_c>; + dai-format = "i2s"; + dai-tdm-slot-tx-mask-0 = <1 1>; + mclk-fs = <256>; + + codec-0 { + sound-dai = <&tohdmitx TOHDMITX_I2S_IN_C>; + }; + + codec-1 { + sound-dai = <&toacodec TOACODEC_IN_C>; + }; + }; + + /* hdmi glue */ + dai-link-8 { + sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>; + + codec { + sound-dai = <&hdmi_tx>; + }; + }; + + /* acodec glue */ + dai-link-9 { + sound-dai = <&toacodec TOACODEC_OUT>; + + codec { + sound-dai = <&acodec>; + }; + }; + }; +}; + +&acodec { + AVDD-supply = <&vddao_1v8>; + status = "okay"; +}; + +&arb { + status = "okay"; +}; + +&cec_AO { + pinctrl-0 = <&cec_ao_a_h_pins>; + pinctrl-names = "default"; + status = "disabled"; + hdmi-phandle = <&hdmi_tx>; +}; + +&cecb_AO { + pinctrl-0 = <&cec_ao_b_h_pins>; + pinctrl-names = "default"; + status = "okay"; + hdmi-phandle = <&hdmi_tx>; +}; + +&clkc_audio { + status = "okay"; +}; + +&cpu0 { + cpu-supply = <&vddcpu_b>; + operating-points-v2 = <&cpu_opp_table_0>; + clocks = <&clkc CLKID_CPU_CLK>; + clock-latency = <50000>; +}; + +&cpu1 { + cpu-supply = <&vddcpu_b>; + operating-points-v2 = <&cpu_opp_table_0>; + clocks = <&clkc CLKID_CPU_CLK>; + clock-latency = <50000>; +}; + +&cpu100 { + cpu-supply = <&vddcpu_a>; + operating-points-v2 = <&cpub_opp_table_1>; + clocks = <&clkc CLKID_CPUB_CLK>; + clock-latency = <50000>; +}; + +&cpu101 { + cpu-supply = <&vddcpu_a>; + operating-points-v2 = <&cpub_opp_table_1>; + clocks = <&clkc CLKID_CPUB_CLK>; + clock-latency = <50000>; +}; + +&cpu102 { + cpu-supply = <&vddcpu_a>; + operating-points-v2 = <&cpub_opp_table_1>; + clocks = <&clkc CLKID_CPUB_CLK>; + clock-latency = <50000>; +}; + +&cpu103 { + cpu-supply = <&vddcpu_a>; + operating-points-v2 = <&cpub_opp_table_1>; + clocks = <&clkc CLKID_CPUB_CLK>; + clock-latency = <50000>; +}; + +&ext_mdio { + external_phy: ethernet-phy@0 { + /* Realtek RTL8211F (0x001cc916) */ + reg = <0>; + max-speed = <1000>; + + reset-assert-us = <10000>; + reset-deassert-us = <30000>; + reset-gpios = <&gpio GPIOZ_15 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>; + + interrupt-parent = <&gpio_intc>; + /* MAC_INTR on GPIOZ_14 */ + interrupts = <26 IRQ_TYPE_LEVEL_LOW>; + }; +}; + +ðmac { + pinctrl-0 = <ð_pins>, <ð_rgmii_pins>; + pinctrl-names = "default"; + status = "okay"; + phy-mode = "rgmii"; + phy-handle = <&external_phy>; + amlogic,tx-delay-ns = <2>; +}; + +&frddr_a { + status = "okay"; +}; + +&frddr_b { + status = "okay"; +}; + +&frddr_c { + status = "okay"; +}; + +&gpio { + /* + * WARNING: The USB Hub on the Odroid-N2 needs a reset signal + * to be turned high in order to be detected by the USB Controller + * This signal should be handled by a USB specific power sequence + * in order to reset the Hub when USB bus is powered down. + */ + usb-hub { + gpio-hog; + gpios = <GPIOH_4 GPIO_ACTIVE_HIGH>; + output-high; + line-name = "usb-hub-reset"; + }; +}; + +&hdmi_tx { + status = "okay"; + pinctrl-0 = <&hdmitx_hpd_pins>, <&hdmitx_ddc_pins>; + pinctrl-names = "default"; + hdmi-supply = <&vcc_5v>; +}; + +&hdmi_tx_tmds_port { + hdmi_tx_tmds_out: endpoint { + remote-endpoint = <&hdmi_connector_in>; + }; +}; + +&ir { + status = "okay"; + pinctrl-0 = <&remote_input_ao_pins>; + pinctrl-names = "default"; + linux,rc-map-name = "rc-odroid"; +}; + +&pwm_ab { + pinctrl-0 = <&pwm_a_e_pins>; + pinctrl-names = "default"; + clocks = <&xtal>; + clock-names = "clkin0"; + status = "okay"; +}; + +&pwm_AO_cd { + pinctrl-0 = <&pwm_ao_d_e_pins>; + pinctrl-names = "default"; + clocks = <&xtal>; + clock-names = "clkin1"; + status = "okay"; +}; + +/* SD card */ +&sd_emmc_b { + status = "okay"; + pinctrl-0 = <&sdcard_c_pins>; + pinctrl-1 = <&sdcard_clk_gate_c_pins>; + pinctrl-names = "default", "clk-gate"; + + bus-width = <4>; + cap-sd-highspeed; + max-frequency = <50000000>; + disable-wp; + + cd-gpios = <&gpio GPIOC_6 GPIO_ACTIVE_LOW>; + vmmc-supply = <&tflash_vdd>; + vqmmc-supply = <&tf_io>; + +}; + +/* eMMC */ +&sd_emmc_c { + status = "okay"; + pinctrl-0 = <&emmc_ctrl_pins>, <&emmc_data_8b_pins>, <&emmc_ds_pins>; + pinctrl-1 = <&emmc_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; + + bus-width = <8>; + cap-mmc-highspeed; + mmc-ddr-1_8v; + mmc-hs200-1_8v; + max-frequency = <200000000>; + disable-wp; + + mmc-pwrseq = <&emmc_pwrseq>; + vmmc-supply = <&vcc_3v3>; + vqmmc-supply = <&flash_1v8>; +}; + +/* + * EMMC_D4, EMMC_D5, EMMC_D6 and EMMC_D7 pins are shared between SPI NOR pins + * and eMMC Data 4 to 7 pins. + * Replace emmc_data_8b_pins to emmc_data_4b_pins from sd_emmc_c pinctrl-0, + * and change bus-width to 4 then spifc can be enabled. + * The SW1 slide should also be set to the correct position. + */ +&spifc { + status = "disabled"; + pinctrl-0 = <&nor_pins>; + pinctrl-names = "default"; + + mx25u64: spi-flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "mxicy,mx25u6435f", "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <104000000>; + }; +}; + +&tdmif_b { + status = "okay"; +}; + +&tdmif_c { + status = "okay"; +}; + +&tdmin_a { + status = "okay"; +}; + +&tdmin_b { + status = "okay"; +}; + +&tdmin_c { + status = "okay"; +}; + +&tdmin_lb { + status = "okay"; +}; + +&tdmout_b { + status = "okay"; +}; + +&tdmout_c { + status = "okay"; +}; + +&toacodec { + status = "okay"; +}; + +&tohdmitx { + status = "okay"; +}; + +&toddr_a { + status = "okay"; +}; + +&toddr_b { + status = "okay"; +}; + +&toddr_c { + status = "okay"; +}; + +&uart_AO { + status = "okay"; + pinctrl-0 = <&uart_ao_a_pins>; + pinctrl-names = "default"; +}; + +&usb { + status = "okay"; + vbus-supply = <&usb_pwr_en>; +}; + +&usb2_phy0 { + phy-supply = <&vcc_5v>; +}; + +&usb2_phy1 { + /* Enable the hub which is connected to this port */ + phy-supply = <&hub_5v>; +}; diff --git a/arch/arm/dts/meson-g12b-w400.dtsi b/arch/arm/dts/meson-g12b-w400.dtsi new file mode 100644 index 0000000000..2802ddbb83 --- /dev/null +++ b/arch/arm/dts/meson-g12b-w400.dtsi @@ -0,0 +1,425 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 BayLibre, SAS + * Author: Neil Armstrong <narmstrong@baylibre.com> + * Copyright (c) 2019 Christian Hewitt <christianshewitt@gmail.com> + */ + +/dts-v1/; + +#include "meson-g12b.dtsi" +#include "meson-g12b-s922x.dtsi" +#include <dt-bindings/input/input.h> +#include <dt-bindings/gpio/meson-g12a-gpio.h> + +/ { + aliases { + serial0 = &uart_AO; + ethernet0 = ðmac; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x40000000>; + }; + + emmc_pwrseq: emmc-pwrseq { + compatible = "mmc-pwrseq-emmc"; + reset-gpios = <&gpio BOOT_12 GPIO_ACTIVE_LOW>; + }; + + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>; + clocks = <&wifi32k>; + clock-names = "ext_clock"; + }; + + flash_1v8: regulator-flash_1v8 { + compatible = "regulator-fixed"; + regulator-name = "FLASH_1V8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vcc_3v3>; + regulator-always-on; + }; + + main_12v: regulator-main_12v { + compatible = "regulator-fixed"; + regulator-name = "12V"; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + regulator-always-on; + }; + + vcc_5v: regulator-vcc_5v { + compatible = "regulator-fixed"; + regulator-name = "VCC_5V"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&main_12v>; + + gpio = <&gpio GPIOH_8 GPIO_OPEN_DRAIN>; + enable-active-high; + }; + + vcc_1v8: regulator-vcc_1v8 { + compatible = "regulator-fixed"; + regulator-name = "VCC_1V8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vcc_3v3>; + regulator-always-on; + }; + + vcc_3v3: regulator-vcc_3v3 { + compatible = "regulator-fixed"; + regulator-name = "VCC_3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vddao_3v3>; + regulator-always-on; + /* FIXME: actually controlled by VDDCPU_B_EN */ + }; + + vddcpu_a: regulator-vddcpu-a { + /* + * MP1653 Regulator. + */ + compatible = "pwm-regulator"; + + regulator-name = "VDDCPU_A"; + regulator-min-microvolt = <721000>; + regulator-max-microvolt = <1022000>; + + vin-supply = <&main_12v>; + + pwms = <&pwm_ab 0 1250 0>; + pwm-dutycycle-range = <100 0>; + + regulator-boot-on; + regulator-always-on; + }; + + vddcpu_b: regulator-vddcpu-b { + /* + * MP1652 Regulator. + */ + compatible = "pwm-regulator"; + + regulator-name = "VDDCPU_B"; + regulator-min-microvolt = <721000>; + regulator-max-microvolt = <1022000>; + + vin-supply = <&main_12v>; + + pwms = <&pwm_AO_cd 1 1250 0>; + pwm-dutycycle-range = <100 0>; + + regulator-boot-on; + regulator-always-on; + }; + + usb1_pow: regulator-usb1-pow { + compatible = "regulator-fixed"; + regulator-name = "USB1_POW"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc_5v>; + + /* connected to SY6280A Power Switch */ + gpio = <&gpio GPIOA_8 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + usb_pwr_en: regulator-usb-pwr-en { + compatible = "regulator-fixed"; + regulator-name = "USB_PWR_EN"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc_5v>; + + /* Connected to USB3 Type-A Port power enable */ + gpio = <&gpio GPIOAO_7 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + vddao_1v8: regulator-vddao-1v8 { + compatible = "regulator-fixed"; + regulator-name = "VDDAO_1V8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vddao_3v3>; + regulator-always-on; + }; + + vddao_3v3: regulator-vddao-3v3 { + compatible = "regulator-fixed"; + regulator-name = "VDDAO_3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&main_12v>; + regulator-always-on; + }; + + cvbs-connector { + compatible = "composite-video-connector"; + + port { + cvbs_connector_in: endpoint { + remote-endpoint = <&cvbs_vdac_out>; + }; + }; + }; + + hdmi-connector { + compatible = "hdmi-connector"; + type = "a"; + + port { + hdmi_connector_in: endpoint { + remote-endpoint = <&hdmi_tx_tmds_out>; + }; + }; + }; + + wifi32k: wifi32k { + compatible = "pwm-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + pwms = <&pwm_ef 0 30518 0>; /* PWM_E at 32.768KHz */ + }; +}; + +&cec_AO { + pinctrl-0 = <&cec_ao_a_h_pins>; + pinctrl-names = "default"; + status = "disabled"; + hdmi-phandle = <&hdmi_tx>; +}; + +&cecb_AO { + pinctrl-0 = <&cec_ao_b_h_pins>; + pinctrl-names = "default"; + status = "okay"; + hdmi-phandle = <&hdmi_tx>; +}; + +&cpu0 { + cpu-supply = <&vddcpu_b>; + operating-points-v2 = <&cpu_opp_table_0>; + clocks = <&clkc CLKID_CPU_CLK>; + clock-latency = <50000>; +}; + +&cpu1 { + cpu-supply = <&vddcpu_b>; + operating-points-v2 = <&cpu_opp_table_0>; + clocks = <&clkc CLKID_CPU_CLK>; + clock-latency = <50000>; +}; + +&cpu100 { + cpu-supply = <&vddcpu_a>; + operating-points-v2 = <&cpub_opp_table_1>; + clocks = <&clkc CLKID_CPUB_CLK>; + clock-latency = <50000>; +}; + +&cpu101 { + cpu-supply = <&vddcpu_a>; + operating-points-v2 = <&cpub_opp_table_1>; + clocks = <&clkc CLKID_CPUB_CLK>; + clock-latency = <50000>; +}; + +&cpu102 { + cpu-supply = <&vddcpu_a>; + operating-points-v2 = <&cpub_opp_table_1>; + clocks = <&clkc CLKID_CPUB_CLK>; + clock-latency = <50000>; +}; + +&cpu103 { + cpu-supply = <&vddcpu_a>; + operating-points-v2 = <&cpub_opp_table_1>; + clocks = <&clkc CLKID_CPUB_CLK>; + clock-latency = <50000>; +}; + +&cvbs_vdac_port { + cvbs_vdac_out: endpoint { + remote-endpoint = <&cvbs_connector_in>; + }; +}; + +&ext_mdio { + external_phy: ethernet-phy@0 { + /* Realtek RTL8211F (0x001cc916) */ + reg = <0>; + max-speed = <1000>; + + reset-assert-us = <10000>; + reset-deassert-us = <30000>; + reset-gpios = <&gpio GPIOZ_15 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>; + + interrupt-parent = <&gpio_intc>; + /* MAC_INTR on GPIOZ_14 */ + interrupts = <26 IRQ_TYPE_LEVEL_LOW>; + }; +}; + +ðmac { + pinctrl-0 = <ð_pins>, <ð_rgmii_pins>; + pinctrl-names = "default"; + status = "okay"; + phy-mode = "rgmii"; + phy-handle = <&external_phy>; + amlogic,tx-delay-ns = <2>; +}; + +&hdmi_tx { + status = "okay"; + pinctrl-0 = <&hdmitx_hpd_pins>, <&hdmitx_ddc_pins>; + pinctrl-names = "default"; + hdmi-supply = <&vcc_5v>; +}; + +&hdmi_tx_tmds_port { + hdmi_tx_tmds_out: endpoint { + remote-endpoint = <&hdmi_connector_in>; + }; +}; + +&ir { + status = "okay"; + pinctrl-0 = <&remote_input_ao_pins>; + pinctrl-names = "default"; +}; + +&pwm_ab { + pinctrl-0 = <&pwm_a_e_pins>; + pinctrl-names = "default"; + clocks = <&xtal>; + clock-names = "clkin0"; + status = "okay"; +}; + +&pwm_AO_cd { + pinctrl-0 = <&pwm_ao_d_e_pins>; + pinctrl-names = "default"; + clocks = <&xtal>; + clock-names = "clkin1"; + status = "okay"; +}; + +&pwm_ef { + pinctrl-0 = <&pwm_e_pins>; + pinctrl-names = "default"; + clocks = <&xtal>; + clock-names = "clkin0"; + status = "okay"; +}; + +/* SDIO */ +&sd_emmc_a { + status = "okay"; + pinctrl-0 = <&sdio_pins>; + pinctrl-1 = <&sdio_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; + #address-cells = <1>; + #size-cells = <0>; + + bus-width = <4>; + cap-sd-highspeed; + max-frequency = <100000000>; + + /* WiFi firmware requires power to be kept while in suspend */ + keep-power-in-suspend; + + non-removable; + disable-wp; + + mmc-pwrseq = <&sdio_pwrseq>; + + vmmc-supply = <&vddao_3v3>; + vqmmc-supply = <&vddao_1v8>; + + brcmf: wifi@1 { + reg = <1>; + compatible = "brcm,bcm4329-fmac"; + }; +}; + +/* SD card */ +&sd_emmc_b { + status = "okay"; + pinctrl-0 = <&sdcard_c_pins>; + pinctrl-1 = <&sdcard_clk_gate_c_pins>; + pinctrl-names = "default", "clk-gate"; + + bus-width = <4>; + cap-sd-highspeed; + max-frequency = <50000000>; + disable-wp; + + cd-gpios = <&gpio GPIOC_6 GPIO_ACTIVE_LOW>; + vmmc-supply = <&vddao_3v3>; + vqmmc-supply = <&vddao_3v3>; +}; + +/* eMMC */ +&sd_emmc_c { + status = "okay"; + pinctrl-0 = <&emmc_ctrl_pins>, <&emmc_data_8b_pins>, <&emmc_ds_pins>; + pinctrl-1 = <&emmc_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; + + bus-width = <8>; + cap-mmc-highspeed; + max-frequency = <100000000>; + disable-wp; + + mmc-pwrseq = <&emmc_pwrseq>; + vmmc-supply = <&vcc_3v3>; + vqmmc-supply = <&flash_1v8>; +}; + +&uart_A { + status = "okay"; + pinctrl-0 = <&uart_a_pins>, <&uart_a_cts_rts_pins>; + pinctrl-names = "default"; + uart-has-rtscts; + + bluetooth { + compatible = "brcm,bcm43438-bt"; + shutdown-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>; + max-speed = <2000000>; + clocks = <&wifi32k>; + clock-names = "lpo"; + }; +}; + +&uart_AO { + status = "okay"; + pinctrl-0 = <&uart_ao_a_pins>; + pinctrl-names = "default"; +}; + +&usb { + status = "okay"; + dr_mode = "host"; + vbus-supply = <&usb_pwr_en>; +}; + +&usb2_phy0 { + phy-supply = <&usb1_pow>; +}; + +&usb2_phy1 { + phy-supply = <&usb1_pow>; +}; diff --git a/arch/arm/dts/meson-gx-mali450.dtsi b/arch/arm/dts/meson-gx-mali450.dtsi new file mode 100644 index 0000000000..f9771b51c8 --- /dev/null +++ b/arch/arm/dts/meson-gx-mali450.dtsi @@ -0,0 +1,61 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2017 BayLibre SAS + * Author: Neil Armstrong <narmstrong@baylibre.com> + */ + +/ { + gpu_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-125000000 { + opp-hz = /bits/ 64 <125000000>; + opp-microvolt = <950000>; + }; + opp-250000000 { + opp-hz = /bits/ 64 <250000000>; + opp-microvolt = <950000>; + }; + opp-285714285 { + opp-hz = /bits/ 64 <285714285>; + opp-microvolt = <950000>; + }; + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + opp-microvolt = <950000>; + }; + opp-500000000 { + opp-hz = /bits/ 64 <500000000>; + opp-microvolt = <950000>; + }; + opp-666666666 { + opp-hz = /bits/ 64 <666666666>; + opp-microvolt = <950000>; + }; + opp-744000000 { + opp-hz = /bits/ 64 <744000000>; + opp-microvolt = <950000>; + }; + }; +}; + +&apb { + mali: gpu@c0000 { + compatible = "arm,mali-450"; + reg = <0x0 0xc0000 0x0 0x40000>; + interrupts = <GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "gp", "gpmmu", "pp", "pmu", + "pp0", "ppmmu0", "pp1", "ppmmu1", + "pp2", "ppmmu2"; + operating-points-v2 = <&gpu_opp_table>; + }; +}; diff --git a/arch/arm/dts/meson-gx-p23x-q20x.dtsi b/arch/arm/dts/meson-gx-p23x-q20x.dtsi new file mode 100644 index 0000000000..6b57e15aad --- /dev/null +++ b/arch/arm/dts/meson-gx-p23x-q20x.dtsi @@ -0,0 +1,324 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2016 Endless Computers, Inc. + * Author: Carlo Caione <carlo@endlessm.com> + */ + +/* Common DTSI for same Amlogic Q200/Q201 and P230/P231 boards using either + * the pin-compatible S912 (GXM) or S905D (GXL) SoCs. + */ + +#include <dt-bindings/sound/meson-aiu.h> + +/ { + aliases { + serial0 = &uart_AO; + ethernet0 = ðmac; + }; + + dio2133: analog-amplifier { + compatible = "simple-audio-amplifier"; + sound-name-prefix = "AU2"; + VCC-supply = <&hdmi_5v>; + enable-gpios = <&gpio GPIOH_5 GPIO_ACTIVE_HIGH>; + }; + + spdif_dit: audio-codec-0 { + #sound-dai-cells = <0>; + compatible = "linux,spdif-dit"; + status = "okay"; + sound-name-prefix = "DIT"; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + memory@0 { + device_type = "memory"; + 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_ao18: regulator-vddio_ao18 { + compatible = "regulator-fixed"; + regulator-name = "VDDIO_AO18"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + vddio_boot: regulator-vddio_boot { + compatible = "regulator-fixed"; + regulator-name = "VDDIO_BOOT"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + vddao_3v3: regulator-vddao_3v3 { + compatible = "regulator-fixed"; + regulator-name = "VDDAO_3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + vcc_3v3: regulator-vcc_3v3 { + compatible = "regulator-fixed"; + regulator-name = "VCC_3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + emmc_pwrseq: emmc-pwrseq { + compatible = "mmc-pwrseq-emmc"; + reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>; + }; + + wifi32k: wifi32k { + compatible = "pwm-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + pwms = <&pwm_ef 0 30518 0>; /* PWM_E at 32.768KHz */ + }; + + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>; + clocks = <&wifi32k>; + clock-names = "ext_clock"; + }; + + cvbs-connector { + compatible = "composite-video-connector"; + + port { + cvbs_connector_in: endpoint { + remote-endpoint = <&cvbs_vdac_out>; + }; + }; + }; + + hdmi-connector { + compatible = "hdmi-connector"; + type = "a"; + + port { + hdmi_connector_in: endpoint { + remote-endpoint = <&hdmi_tx_tmds_out>; + }; + }; + }; + + sound { + compatible = "amlogic,gx-sound-card"; + model = "GX-P230-Q200"; + audio-aux-devs = <&dio2133>; + audio-widgets = "Line", "Lineout"; + audio-routing = "AU2 INL", "ACODEC LOLP", + "AU2 INR", "ACODEC LORP", + "AU2 INL", "ACODEC LOLN", + "AU2 INR", "ACODEC LORN", + "Lineout", "AU2 OUTL", + "Lineout", "AU2 OUTR"; + assigned-clocks = <&clkc CLKID_MPLL0>, + <&clkc CLKID_MPLL1>, + <&clkc CLKID_MPLL2>; + assigned-clock-parents = <0>, <0>, <0>; + assigned-clock-rates = <294912000>, + <270950400>, + <393216000>; + status = "okay"; + + dai-link-0 { + sound-dai = <&aiu AIU_CPU CPU_I2S_FIFO>; + }; + + dai-link-1 { + sound-dai = <&aiu AIU_CPU CPU_SPDIF_FIFO>; + }; + + dai-link-2 { + sound-dai = <&aiu AIU_CPU CPU_I2S_ENCODER>; + dai-format = "i2s"; + mclk-fs = <256>; + + codec-0 { + sound-dai = <&aiu AIU_HDMI CTRL_I2S>; + }; + + codec-1 { + sound-dai = <&aiu AIU_ACODEC CTRL_I2S>; + }; + }; + + dai-link-3 { + sound-dai = <&aiu AIU_CPU CPU_SPDIF_ENCODER>; + + codec-0 { + sound-dai = <&spdif_dit>; + }; + }; + + dai-link-4 { + sound-dai = <&aiu AIU_HDMI CTRL_OUT>; + + codec-0 { + sound-dai = <&hdmi_tx>; + }; + }; + + dai-link-5 { + sound-dai = <&aiu AIU_ACODEC CTRL_OUT>; + + codec-0 { + sound-dai = <&acodec>; + }; + }; + }; +}; + +&acodec { + AVDD-supply = <&vddio_ao18>; + status = "okay"; +}; + +&aiu { + status = "okay"; + pinctrl-0 = <&spdif_out_h_pins>; + pinctrl-names = "default"; + +}; + +&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>; + }; +}; + +ðmac { + status = "okay"; +}; + +&hdmi_tx { + status = "okay"; + pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>; + pinctrl-names = "default"; + hdmi-supply = <&hdmi_5v>; +}; + +&hdmi_tx_tmds_port { + hdmi_tx_tmds_out: endpoint { + remote-endpoint = <&hdmi_connector_in>; + }; +}; + +&ir { + status = "okay"; + pinctrl-0 = <&remote_input_ao_pins>; + pinctrl-names = "default"; +}; + +&pwm_ef { + status = "okay"; + pinctrl-0 = <&pwm_e_pins>; + pinctrl-names = "default"; + clocks = <&clkc CLKID_FCLK_DIV4>; + clock-names = "clkin0"; +}; + +&saradc { + status = "okay"; + vref-supply = <&vddio_ao18>; +}; + +/* Wireless SDIO Module */ +&sd_emmc_a { + status = "okay"; + pinctrl-0 = <&sdio_pins>; + pinctrl-1 = <&sdio_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; + #address-cells = <1>; + #size-cells = <0>; + + bus-width = <4>; + cap-sd-highspeed; + max-frequency = <50000000>; + + non-removable; + disable-wp; + + /* WiFi firmware requires power to be kept while in suspend */ + keep-power-in-suspend; + + mmc-pwrseq = <&sdio_pwrseq>; + + vmmc-supply = <&vddao_3v3>; + vqmmc-supply = <&vddio_boot>; +}; + +/* SD card */ +&sd_emmc_b { + status = "okay"; + pinctrl-0 = <&sdcard_pins>; + pinctrl-1 = <&sdcard_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; + + bus-width = <4>; + cap-sd-highspeed; + max-frequency = <50000000>; + disable-wp; + + cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_LOW>; + + vmmc-supply = <&vddao_3v3>; + vqmmc-supply = <&vddio_boot>; +}; + +/* eMMC */ +&sd_emmc_c { + status = "okay"; + pinctrl-0 = <&emmc_pins>, <&emmc_ds_pins>; + pinctrl-1 = <&emmc_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; + + bus-width = <8>; + cap-mmc-highspeed; + max-frequency = <200000000>; + non-removable; + disable-wp; + mmc-ddr-1_8v; + mmc-hs200-1_8v; + + mmc-pwrseq = <&emmc_pwrseq>; + vmmc-supply = <&vcc_3v3>; + vqmmc-supply = <&vddio_boot>; +}; + +/* This UART is brought out to the DB9 connector */ +&uart_AO { + status = "okay"; + pinctrl-0 = <&uart_ao_a_pins>; + pinctrl-names = "default"; +}; + +&usb { + status = "okay"; + dr_mode = "otg"; +}; diff --git a/arch/arm/dts/meson-gx.dtsi b/arch/arm/dts/meson-gx.dtsi index ba63c36b22..0edd137151 100644 --- a/arch/arm/dts/meson-gx.dtsi +++ b/arch/arm/dts/meson-gx.dtsi @@ -12,6 +12,7 @@ #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/interrupt-controller/irq.h> #include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/power/meson-gxbb-power.h> #include <dt-bindings/thermal/thermal.h> / { @@ -60,7 +61,7 @@ compatible = "amlogic,simple-framebuffer", "simple-framebuffer"; amlogic,pipeline = "vpu-cvbs"; - power-domains = <&pwrc_vpu>; + power-domains = <&pwrc PWRC_GXBB_VPU_ID>; status = "disabled"; }; @@ -68,7 +69,7 @@ compatible = "amlogic,simple-framebuffer", "simple-framebuffer"; amlogic,pipeline = "vpu-hdmi"; - power-domains = <&pwrc_vpu>; + power-domains = <&pwrc PWRC_GXBB_VPU_ID>; status = "disabled"; }; }; @@ -438,12 +439,6 @@ compatible = "amlogic,meson-gx-ao-sysctrl", "simple-mfd", "syscon"; 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>; @@ -552,6 +547,12 @@ sysctrl: system-controller@0 { compatible = "amlogic,meson-gx-hhi-sysctrl", "simple-mfd", "syscon"; reg = <0 0 0 0x400>; + + pwrc: power-controller { + compatible = "amlogic,meson-gxbb-pwrc"; + #power-domain-cells = <1>; + amlogic,ao-sysctrl = <&sysctrl_AO>; + }; }; mailbox: mailbox@404 { @@ -574,6 +575,7 @@ interrupt-names = "macirq"; rx-fifo-depth = <4096>; tx-fifo-depth = <2048>; + power-domains = <&pwrc PWRC_GXBB_ETHERNET_MEM_ID>; status = "disabled"; }; diff --git a/arch/arm/dts/meson-gxbb.dtsi b/arch/arm/dts/meson-gxbb.dtsi index 234490d3ee..7c029f552a 100644 --- a/arch/arm/dts/meson-gxbb.dtsi +++ b/arch/arm/dts/meson-gxbb.dtsi @@ -4,6 +4,7 @@ */ #include "meson-gx.dtsi" +#include "meson-gx-mali450.dtsi" #include <dt-bindings/gpio/meson-gxbb-gpio.h> #include <dt-bindings/reset/amlogic,meson-gxbb-reset.h> #include <dt-bindings/clock/gxbb-clkc.h> @@ -264,46 +265,6 @@ }; }; -&apb { - mali: gpu@c0000 { - compatible = "amlogic,meson-gxbb-mali", "arm,mali-450"; - reg = <0x0 0xc0000 0x0 0x40000>; - interrupts = <GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>; - interrupt-names = "gp", "gpmmu", "pp", "pmu", - "pp0", "ppmmu0", "pp1", "ppmmu1", - "pp2", "ppmmu2"; - clocks = <&clkc CLKID_CLK81>, <&clkc CLKID_MALI>; - clock-names = "bus", "core"; - - /* - * Mali clocking is provided by two identical clock paths - * MALI_0 and MALI_1 muxed to a single clock by a glitch - * free mux to safely change frequency while running. - */ - assigned-clocks = <&clkc CLKID_GP0_PLL>, - <&clkc CLKID_MALI_0_SEL>, - <&clkc CLKID_MALI_0>, - <&clkc CLKID_MALI>; /* Glitch free mux */ - assigned-clock-parents = <0>, /* Do Nothing */ - <&clkc CLKID_GP0_PLL>, - <0>, /* Do Nothing */ - <&clkc CLKID_MALI_0>; - assigned-clock-rates = <744000000>, - <0>, /* Do Nothing */ - <744000000>, - <0>; /* Do Nothing */ - }; -}; - &cbus { spifc: spi@8c80 { compatible = "amlogic,meson-gxbb-spifc"; @@ -333,8 +294,9 @@ ðmac { clocks = <&clkc CLKID_ETH>, <&clkc CLKID_FCLK_DIV2>, - <&clkc CLKID_MPLL2>; - clock-names = "stmmaceth", "clkin0", "clkin1"; + <&clkc CLKID_MPLL2>, + <&clkc CLKID_FCLK_DIV2>; + clock-names = "stmmaceth", "clkin0", "clkin1", "timing-adjustment"; }; &gpio_intc { @@ -385,6 +347,16 @@ clocks = <&clkc CLKID_I2C>; }; +&mali { + compatible = "amlogic,meson-gxbb-mali", "arm,mali-450"; + + clocks = <&clkc CLKID_CLK81>, <&clkc CLKID_MALI>; + clock-names = "bus", "core"; + + assigned-clocks = <&clkc CLKID_GP0_PLL>; + assigned-clock-rates = <744000000>; +}; + &periphs { pinctrl_periphs: pinctrl@4b0 { compatible = "amlogic,meson-gxbb-periphs-pinctrl"; @@ -747,7 +719,7 @@ }; }; -&pwrc_vpu { +&pwrc { resets = <&reset RESET_VIU>, <&reset RESET_VENC>, <&reset RESET_VCBUS>, @@ -760,6 +732,9 @@ <&reset RESET_VDI6>, <&reset RESET_VENCL>, <&reset RESET_VID_LOCK>; + reset-names = "viu", "venc", "vcbus", "bt656", + "dvin", "rdma", "venci", "vencp", + "vdac", "vdi6", "vencl", "vid_lock"; clocks = <&clkc CLKID_VPU>, <&clkc CLKID_VAPB>; clock-names = "vpu", "vapb"; @@ -866,7 +841,7 @@ &vpu { compatible = "amlogic,meson-gxbb-vpu", "amlogic,meson-gx-vpu"; - power-domains = <&pwrc_vpu>; + power-domains = <&pwrc PWRC_GXBB_VPU_ID>; }; &vdec { diff --git a/arch/arm/dts/meson-gxl-mali.dtsi b/arch/arm/dts/meson-gxl-mali.dtsi index 6aaafff674..478e755cc8 100644 --- a/arch/arm/dts/meson-gxl-mali.dtsi +++ b/arch/arm/dts/meson-gxl-mali.dtsi @@ -4,42 +4,14 @@ * Author: Neil Armstrong <narmstrong@baylibre.com> */ -&apb { - mali: gpu@c0000 { - compatible = "amlogic,meson-gxl-mali", "arm,mali-450"; - reg = <0x0 0xc0000 0x0 0x40000>; - interrupts = <GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>; - interrupt-names = "gp", "gpmmu", "pp", "pmu", - "pp0", "ppmmu0", "pp1", "ppmmu1", - "pp2", "ppmmu2"; - clocks = <&clkc CLKID_CLK81>, <&clkc CLKID_MALI>; - clock-names = "bus", "core"; +#include "meson-gx-mali450.dtsi" - /* - * Mali clocking is provided by two identical clock paths - * MALI_0 and MALI_1 muxed to a single clock by a glitch - * free mux to safely change frequency while running. - */ - assigned-clocks = <&clkc CLKID_GP0_PLL>, - <&clkc CLKID_MALI_0_SEL>, - <&clkc CLKID_MALI_0>, - <&clkc CLKID_MALI>; /* Glitch free mux */ - assigned-clock-parents = <0>, /* Do Nothing */ - <&clkc CLKID_GP0_PLL>, - <0>, /* Do Nothing */ - <&clkc CLKID_MALI_0>; - assigned-clock-rates = <744000000>, - <0>, /* Do Nothing */ - <744000000>, - <0>; /* Do Nothing */ - }; +&mali { + compatible = "amlogic,meson-gxl-mali", "arm,mali-450"; + + clocks = <&clkc CLKID_CLK81>, <&clkc CLKID_MALI>; + clock-names = "bus", "core"; + + assigned-clocks = <&clkc CLKID_GP0_PLL>; + assigned-clock-rates = <744000000>; }; diff --git a/arch/arm/dts/meson-gxl-s805x-libretech-ac.dts b/arch/arm/dts/meson-gxl-s805x-libretech-ac.dts index 6a226faab1..9e43f4dca9 100644 --- a/arch/arm/dts/meson-gxl-s805x-libretech-ac.dts +++ b/arch/arm/dts/meson-gxl-s805x-libretech-ac.dts @@ -10,7 +10,7 @@ #include <dt-bindings/input/input.h> #include <dt-bindings/sound/meson-aiu.h> -#include "meson-gxl-s905x.dtsi" +#include "meson-gxl-s805x.dtsi" / { compatible = "libretech,aml-s805x-ac", "amlogic,s805x", diff --git a/arch/arm/dts/meson-gxl-s805x.dtsi b/arch/arm/dts/meson-gxl-s805x.dtsi new file mode 100644 index 0000000000..2997584982 --- /dev/null +++ b/arch/arm/dts/meson-gxl-s805x.dtsi @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2020 BayLibre SAS + * Author: Neil Armstrong <narmstrong@baylibre.com> + */ + +#include "meson-gxl-s905x.dtsi" + +/ { + compatible = "amlogic,s805x", "amlogic,meson-gxl"; +}; + +/* The S805X Package doesn't seem to handle the 744MHz OPP correctly */ +&gpu_opp_table { + opp-744000000 { + status = "disabled"; + }; +}; + +&mali { + /delete-property/ assigned-clocks; + /delete-property/ assigned-clock-rates; +}; diff --git a/arch/arm/dts/meson-gxl-s905x-libretech-cc-v2-u-boot.dtsi b/arch/arm/dts/meson-gxl-s905x-libretech-cc-v2-u-boot.dtsi new file mode 100644 index 0000000000..8ff5a0ef2b --- /dev/null +++ b/arch/arm/dts/meson-gxl-s905x-libretech-cc-v2-u-boot.dtsi @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2020 BayLibre, SAS. + * Author: Jerome Brunet <jbrunet@baylibre.com> + */ + +#include "meson-gxl-u-boot.dtsi" diff --git a/arch/arm/dts/meson-gxl-s905x-libretech-cc-v2.dts b/arch/arm/dts/meson-gxl-s905x-libretech-cc-v2.dts new file mode 100644 index 0000000000..675eaa8796 --- /dev/null +++ b/arch/arm/dts/meson-gxl-s905x-libretech-cc-v2.dts @@ -0,0 +1,318 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2020 BayLibre, SAS. + * Author: Jerome Brunet <jbrunet@baylibre.com> + */ + +/dts-v1/; + +#include <dt-bindings/input/input.h> +#include <dt-bindings/leds/common.h> +#include <dt-bindings/sound/meson-aiu.h> + +#include "meson-gxl-s905x.dtsi" + +/ { + compatible = "libretech,aml-s905x-cc-v2", "amlogic,s905x", + "amlogic,meson-gxl"; + model = "Libre Computer AML-S905X-CC V2"; + + aliases { + serial0 = &uart_AO; + ethernet0 = ðmac; + spi0 = &spifc; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + emmc_pwrseq: emmc-pwrseq { + 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>; + }; + }; + }; + + leds { + compatible = "gpio-leds"; + + led-blue { + color = <LED_COLOR_ID_BLUE>; + function = LED_FUNCTION_STATUS; + gpios = <&gpio GPIODV_24 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + panic-indicator; + }; + + led-green { + color = <LED_COLOR_ID_GREEN>; + function = LED_FUNCTION_DISK_ACTIVITY; + gpios = <&gpio_ao GPIOAO_2 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "disk-activity"; + }; + }; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x80000000>; + }; + + ao_5v: regulator-ao_5v { + compatible = "regulator-fixed"; + regulator-name = "AO_5V"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&dc_in>; + regulator-always-on; + }; + + dc_in: regulator-dc_in { + compatible = "regulator-fixed"; + regulator-name = "DC_IN"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + }; + + + vcck: regulator-vcck { + compatible = "regulator-fixed"; + regulator-name = "VCCK"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&ao_5v>; + regulator-always-on; + }; + + vcc_card: regulator-vcc_card { + compatible = "regulator-fixed"; + regulator-name = "VCC_CARD"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vddio_ao3v3>; + + gpio = <&gpio GPIOCLK_1 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + vcc5v: regulator-vcc5v { + compatible = "regulator-fixed"; + regulator-name = "VCC5V"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&ao_5v>; + + gpio = <&gpio GPIOH_3 GPIO_OPEN_DRAIN>; + }; + + vddio_ao3v3: regulator-vddio_ao3v3 { + compatible = "regulator-fixed"; + regulator-name = "VDDIO_AO3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&ao_5v>; + regulator-always-on; + }; + + + vddio_card: regulator-vddio-card { + compatible = "regulator-gpio"; + regulator-name = "VDDIO_CARD"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + + gpios = <&gpio_ao GPIOAO_3 GPIO_ACTIVE_HIGH>; + gpios-states = <0>; + + 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>; + vin-supply = <&vddio_ao3v3>; + regulator-always-on; + }; + + vcc_1v8: regulator-vcc_1v8 { + compatible = "regulator-fixed"; + regulator-name = "VCC 1V8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vddio_ao3v3>; + regulator-always-on; + }; + + sound { + compatible = "amlogic,gx-sound-card"; + model = "GXL-LIBRETECH-S905X-CC-V2"; + assigned-clocks = <&clkc CLKID_MPLL0>, + <&clkc CLKID_MPLL1>, + <&clkc CLKID_MPLL2>; + assigned-clock-parents = <0>, <0>, <0>; + assigned-clock-rates = <294912000>, + <270950400>, + <393216000>; + status = "okay"; + + dai-link-0 { + sound-dai = <&aiu AIU_CPU CPU_I2S_FIFO>; + }; + + dai-link-1 { + sound-dai = <&aiu AIU_CPU CPU_I2S_ENCODER>; + dai-format = "i2s"; + mclk-fs = <256>; + + codec-0 { + sound-dai = <&aiu AIU_HDMI CTRL_I2S>; + }; + }; + + dai-link-2 { + sound-dai = <&aiu AIU_HDMI CTRL_OUT>; + + codec-0 { + sound-dai = <&hdmi_tx>; + }; + }; + }; +}; + + +&aiu { + status = "okay"; +}; + +&cec_AO { + status = "okay"; + pinctrl-0 = <&ao_cec_pins>; + pinctrl-names = "default"; + hdmi-phandle = <&hdmi_tx>; +}; + + +ðmac { + status = "okay"; +}; + +&internal_phy { + pinctrl-0 = <ð_link_led_pins>, <ð_act_led_pins>; + pinctrl-names = "default"; +}; + +&ir { + status = "okay"; + pinctrl-0 = <&remote_input_ao_pins>; + pinctrl-names = "default"; +}; + +&hdmi_tx { + status = "okay"; + pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>; + hdmi-supply = <&vcc5v>; + pinctrl-names = "default"; +}; + +&hdmi_tx_tmds_port { + hdmi_tx_tmds_out: endpoint { + remote-endpoint = <&hdmi_connector_in>; + }; +}; + +&saradc { + status = "okay"; + vref-supply = <&vddio_ao18>; +}; + +/* SD card */ +&sd_emmc_b { + pinctrl-0 = <&sdcard_pins>; + 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; + sd-uhs-ddr50; + max-frequency = <100000000>; + disable-wp; + + cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_LOW>; + + vmmc-supply = <&vcc_card>; + vqmmc-supply = <&vddio_card>; + + status = "okay"; +}; + +/* eMMC */ +&sd_emmc_c { + pinctrl-0 = <&emmc_pins>; + pinctrl-1 = <&emmc_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; + + bus-width = <8>; + cap-mmc-highspeed; + mmc-hs200-1_8v; + max-frequency = <200000000>; + disable-wp; + + mmc-pwrseq = <&emmc_pwrseq>; + vmmc-supply = <&vddio_ao3v3>; + vqmmc-supply = <&vcc_1v8>; + + status = "okay"; +}; + +&spifc { + status = "okay"; + pinctrl-0 = <&nor_pins>; + pinctrl-names = "default"; + + nor_4u1: spi-flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <3000000>; + }; +}; + +&uart_AO { + status = "okay"; + pinctrl-0 = <&uart_ao_a_pins>; + pinctrl-names = "default"; +}; + +&usb { + status = "okay"; + dr_mode = "host"; +}; + +&usb2_phy0 { + pinctrl-names = "default"; + phy-supply = <&vcc5v>; +}; + +&usb2_phy1 { + phy-supply = <&vcc5v>; +}; diff --git a/arch/arm/dts/meson-gxl.dtsi b/arch/arm/dts/meson-gxl.dtsi index fc59c8534c..c3ac531c4f 100644 --- a/arch/arm/dts/meson-gxl.dtsi +++ b/arch/arm/dts/meson-gxl.dtsi @@ -131,8 +131,9 @@ ðmac { clocks = <&clkc CLKID_ETH>, <&clkc CLKID_FCLK_DIV2>, - <&clkc CLKID_MPLL2>; - clock-names = "stmmaceth", "clkin0", "clkin1"; + <&clkc CLKID_MPLL2>, + <&clkc CLKID_FCLK_DIV2>; + clock-names = "stmmaceth", "clkin0", "clkin1", "timing-adjustment"; mdio0: mdio { #address-cells = <1>; @@ -337,6 +338,11 @@ }; }; +&hwrng { + clocks = <&clkc CLKID_RNG0>; + clock-names = "core"; +}; + &i2c_A { clocks = <&clkc CLKID_I2C>; }; @@ -782,7 +788,7 @@ }; }; -&pwrc_vpu { +&pwrc { resets = <&reset RESET_VIU>, <&reset RESET_VENC>, <&reset RESET_VCBUS>, @@ -795,6 +801,9 @@ <&reset RESET_VDI6>, <&reset RESET_VENCL>, <&reset RESET_VID_LOCK>; + reset-names = "viu", "venc", "vcbus", "bt656", + "dvin", "rdma", "venci", "vencp", + "vdac", "vdi6", "vencl", "vid_lock"; clocks = <&clkc CLKID_VPU>, <&clkc CLKID_VAPB>; clock-names = "vpu", "vapb"; @@ -901,7 +910,7 @@ &vpu { compatible = "amlogic,meson-gxl-vpu", "amlogic,meson-gx-vpu"; - power-domains = <&pwrc_vpu>; + power-domains = <&pwrc PWRC_GXBB_VPU_ID>; }; &vdec { diff --git a/arch/arm/dts/meson-gxm-wetek-core2-u-boot.dtsi b/arch/arm/dts/meson-gxm-wetek-core2-u-boot.dtsi new file mode 100644 index 0000000000..39270ea71c --- /dev/null +++ b/arch/arm/dts/meson-gxm-wetek-core2-u-boot.dtsi @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 BayLibre, SAS. + * Author: Neil Armstrong <narmstrong@baylibre.com> + */ + +#include "meson-gxl-u-boot.dtsi" diff --git a/arch/arm/dts/meson-gxm-wetek-core2.dts b/arch/arm/dts/meson-gxm-wetek-core2.dts new file mode 100644 index 0000000000..ec794c134c --- /dev/null +++ b/arch/arm/dts/meson-gxm-wetek-core2.dts @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2020 Christian Hewitt <christianshewitt@gmail.com> + */ + +/dts-v1/; + +#include "meson-gxm.dtsi" +#include "meson-gx-p23x-q20x.dtsi" +#include <dt-bindings/input/input.h> +#include <dt-bindings/leds/common.h> + +/ { + compatible = "wetek,core2", "amlogic,s912", "amlogic,meson-gxm"; + model = "WeTek Core 2"; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x80000000>; /* 2 GiB or 3 GiB */ + }; + + leds { + compatible = "gpio-leds"; + + blue { + color = <LED_COLOR_ID_BLUE>; + function = LED_FUNCTION_STATUS; + gpios = <&gpio GPIODV_24 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + }; + + adc-keys { + compatible = "adc-keys"; + io-channels = <&saradc 0>; + io-channel-names = "buttons"; + keyup-threshold-microvolt = <1710000>; + + button-update { + label = "update"; + linux,code = <KEY_VENDOR>; + press-threshold-microvolt = <10000>; + }; + }; + + gpio-keys-polled { + compatible = "gpio-keys-polled"; + #address-cells = <1>; + #size-cells = <0>; + poll-interval = <100>; + + button-power { + label = "power"; + linux,code = <KEY_POWER>; + gpios = <&gpio_ao GPIOAO_2 GPIO_ACTIVE_LOW>; + }; + }; +}; + +/* Disabled as Realtek RTL8152 USB provides Ethernet */ +ðmac { + status = "disabled"; +}; + +&internal_phy { + status = "disabled"; +}; + +&ir { + linux,rc-map-name = "rc-wetek-play2"; +}; + +/* This is connected to the Bluetooth module: */ +&uart_A { + status = "okay"; + pinctrl-0 = <&uart_a_pins>, <&uart_a_cts_rts_pins>; + pinctrl-names = "default"; + uart-has-rtscts; + + bluetooth { + compatible = "brcm,bcm43438-bt"; + shutdown-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>; + max-speed = <2000000>; + clocks = <&wifi32k>; + clock-names = "lpo"; + }; +}; diff --git a/arch/arm/dts/meson-gxm.dtsi b/arch/arm/dts/meson-gxm.dtsi index 40e3e123e0..fe41451122 100644 --- a/arch/arm/dts/meson-gxm.dtsi +++ b/arch/arm/dts/meson-gxm.dtsi @@ -82,6 +82,35 @@ #cooling-cells = <2>; }; }; + + gpu_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-125000000 { + opp-hz = /bits/ 64 <125000000>; + opp-microvolt = <950000>; + }; + opp-250000000 { + opp-hz = /bits/ 64 <250000000>; + opp-microvolt = <950000>; + }; + opp-285714285 { + opp-hz = /bits/ 64 <285714285>; + opp-microvolt = <950000>; + }; + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + opp-microvolt = <950000>; + }; + opp-500000000 { + opp-hz = /bits/ 64 <500000000>; + opp-microvolt = <950000>; + }; + opp-666666666 { + opp-hz = /bits/ 64 <666666666>; + opp-microvolt = <950000>; + }; + }; }; &apb { @@ -106,21 +135,7 @@ interrupt-names = "job", "mmu", "gpu"; clocks = <&clkc CLKID_MALI>; resets = <&reset RESET_MALI_CAPB3>, <&reset RESET_MALI>; - - /* - * Mali clocking is provided by two identical clock paths - * MALI_0 and MALI_1 muxed to a single clock by a glitch - * free mux to safely change frequency while running. - */ - assigned-clocks = <&clkc CLKID_MALI_0_SEL>, - <&clkc CLKID_MALI_0>, - <&clkc CLKID_MALI>; /* Glitch free mux */ - assigned-clock-parents = <&clkc CLKID_FCLK_DIV3>, - <0>, /* Do Nothing */ - <&clkc CLKID_MALI_0>; - assigned-clock-rates = <0>, /* Do Nothing */ - <666666666>, - <0>; /* Do Nothing */ + operating-points-v2 = <&gpu_opp_table>; }; }; diff --git a/arch/arm/dts/meson-khadas-vim3.dtsi b/arch/arm/dts/meson-khadas-vim3.dtsi index 94f75b4465..7b46555ac5 100644 --- a/arch/arm/dts/meson-khadas-vim3.dtsi +++ b/arch/arm/dts/meson-khadas-vim3.dtsi @@ -7,6 +7,7 @@ #include <dt-bindings/input/input.h> #include <dt-bindings/gpio/meson-g12a-gpio.h> +#include <dt-bindings/sound/meson-g12a-tohdmitx.h> / { aliases { @@ -41,13 +42,13 @@ led-white { label = "vim3:white:sys"; - gpios = <&gpio_ao GPIOAO_4 GPIO_ACTIVE_LOW>; + gpios = <&gpio_ao GPIOAO_4 GPIO_ACTIVE_HIGH>; linux,default-trigger = "heartbeat"; }; led-red { label = "vim3:red"; - gpios = <&gpio_expander 5 GPIO_ACTIVE_LOW>; + gpios = <&gpio_expander 5 GPIO_ACTIVE_HIGH>; }; }; @@ -161,6 +162,62 @@ }; }; + + sound { + compatible = "amlogic,axg-sound-card"; + model = "G12B-KHADAS-VIM3"; + audio-aux-devs = <&tdmout_a>; + audio-routing = "TDMOUT_A IN 0", "FRDDR_A OUT 0", + "TDMOUT_A IN 1", "FRDDR_B OUT 0", + "TDMOUT_A IN 2", "FRDDR_C OUT 0", + "TDM_A Playback", "TDMOUT_A OUT"; + + assigned-clocks = <&clkc CLKID_MPLL2>, + <&clkc CLKID_MPLL0>, + <&clkc CLKID_MPLL1>; + assigned-clock-parents = <0>, <0>, <0>; + assigned-clock-rates = <294912000>, + <270950400>, + <393216000>; + status = "okay"; + + dai-link-0 { + sound-dai = <&frddr_a>; + }; + + dai-link-1 { + sound-dai = <&frddr_b>; + }; + + dai-link-2 { + sound-dai = <&frddr_c>; + }; + + /* 8ch hdmi interface */ + dai-link-3 { + sound-dai = <&tdmif_a>; + dai-format = "i2s"; + dai-tdm-slot-tx-mask-0 = <1 1>; + dai-tdm-slot-tx-mask-1 = <1 1>; + dai-tdm-slot-tx-mask-2 = <1 1>; + dai-tdm-slot-tx-mask-3 = <1 1>; + mclk-fs = <256>; + + codec { + sound-dai = <&tohdmitx TOHDMITX_I2S_IN_A>; + }; + }; + + /* hdmi glue */ + dai-link-4 { + sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>; + + codec { + sound-dai = <&hdmi_tx>; + }; + }; + }; + wifi32k: wifi32k { compatible = "pwm-clock"; #clock-cells = <0>; @@ -169,6 +226,14 @@ }; }; +&arb { + status = "okay"; +}; + +&clkc_audio { + status = "okay"; +}; + &cec_AO { pinctrl-0 = <&cec_ao_a_h_pins>; pinctrl-names = "default"; @@ -221,6 +286,18 @@ amlogic,tx-delay-ns = <2>; }; +&frddr_a { + status = "okay"; +}; + +&frddr_b { + status = "okay"; +}; + +&frddr_c { + status = "okay"; +}; + &hdmi_tx { status = "okay"; pinctrl-0 = <&hdmitx_hpd_pins>, <&hdmitx_ddc_pins>; @@ -368,6 +445,19 @@ }; }; + +&tdmif_a { + status = "okay"; +}; + +&tdmout_a { + status = "okay"; +}; + +&tohdmitx { + status = "okay"; +}; + &uart_A { status = "okay"; pinctrl-0 = <&uart_a_pins>, <&uart_a_cts_rts_pins>; diff --git a/arch/arm/dts/meson-sm1-khadas-vim3l.dts b/arch/arm/dts/meson-sm1-khadas-vim3l.dts index 0da56c051a..4b517ca720 100644 --- a/arch/arm/dts/meson-sm1-khadas-vim3l.dts +++ b/arch/arm/dts/meson-sm1-khadas-vim3l.dts @@ -32,69 +32,6 @@ regulator-boot-on; regulator-always-on; }; - - sound { - compatible = "amlogic,axg-sound-card"; - model = "SM1-KHADAS-VIM3L"; - audio-aux-devs = <&tdmout_a>; - audio-routing = "TDMOUT_A IN 0", "FRDDR_A OUT 0", - "TDMOUT_A IN 1", "FRDDR_B OUT 0", - "TDMOUT_A IN 2", "FRDDR_C OUT 0", - "TDM_A Playback", "TDMOUT_A OUT"; - - assigned-clocks = <&clkc CLKID_MPLL2>, - <&clkc CLKID_MPLL0>, - <&clkc CLKID_MPLL1>; - assigned-clock-parents = <0>, <0>, <0>; - assigned-clock-rates = <294912000>, - <270950400>, - <393216000>; - status = "okay"; - - dai-link-0 { - sound-dai = <&frddr_a>; - }; - - dai-link-1 { - sound-dai = <&frddr_b>; - }; - - dai-link-2 { - sound-dai = <&frddr_c>; - }; - - /* 8ch hdmi interface */ - dai-link-3 { - sound-dai = <&tdmif_a>; - dai-format = "i2s"; - dai-tdm-slot-tx-mask-0 = <1 1>; - dai-tdm-slot-tx-mask-1 = <1 1>; - dai-tdm-slot-tx-mask-2 = <1 1>; - dai-tdm-slot-tx-mask-3 = <1 1>; - mclk-fs = <256>; - - codec { - sound-dai = <&tohdmitx TOHDMITX_I2S_IN_A>; - }; - }; - - /* hdmi glue */ - dai-link-4 { - sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>; - - codec { - sound-dai = <&hdmi_tx>; - }; - }; - }; -}; - -&arb { - status = "okay"; -}; - -&clkc_audio { - status = "okay"; }; &cpu0 { @@ -125,18 +62,6 @@ clock-latency = <50000>; }; -&frddr_a { - status = "okay"; -}; - -&frddr_b { - status = "okay"; -}; - -&frddr_c { - status = "okay"; -}; - &pwm_AO_cd { pinctrl-0 = <&pwm_ao_d_e_pins>; pinctrl-names = "default"; @@ -174,14 +99,3 @@ }; */ -&tdmif_a { - status = "okay"; -}; - -&tdmout_a { - status = "okay"; -}; - -&tohdmitx { - status = "okay"; -}; diff --git a/arch/arm/dts/mt7622.dtsi b/arch/arm/dts/mt7622.dtsi index d888545809..5c2e0251de 100644 --- a/arch/arm/dts/mt7622.dtsi +++ b/arch/arm/dts/mt7622.dtsi @@ -71,16 +71,10 @@ compatible = "mediatek,timer"; reg = <0x10004000 0x80>; interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_LOW>; - clocks = <&system_clk>; + clocks = <&infracfg CLK_INFRA_APXGPT_PD>; clock-names = "system-clk"; }; - system_clk: dummy13m { - compatible = "fixed-clock"; - clock-frequency = <13000000>; - #clock-cells = <0>; - }; - infracfg: infracfg@10000000 { compatible = "mediatek,mt7622-infracfg", "syscon"; diff --git a/arch/arm/dts/mt8516-pumpkin.dts b/arch/arm/dts/mt8516-pumpkin.dts index cd43c1f5e3..292b00f0ff 100644 --- a/arch/arm/dts/mt8516-pumpkin.dts +++ b/arch/arm/dts/mt8516-pumpkin.dts @@ -108,3 +108,13 @@ &watchdog { status = "okay"; }; + +&usb0 { + status = "okay"; + dr_mode = "peripheral"; + + usb_con_c: connector { + compatible = "usb-c-connector"; + label = "USB-C"; + }; +}; diff --git a/arch/arm/dts/mt8516.dtsi b/arch/arm/dts/mt8516.dtsi index 1c33582086..c4577ceea3 100644 --- a/arch/arm/dts/mt8516.dtsi +++ b/arch/arm/dts/mt8516.dtsi @@ -123,6 +123,20 @@ status = "disabled"; }; + usb0: usb@11100000 { + compatible = "mediatek,mt8516-musb", + "mediatek,mt8518-musb"; + reg = <0x11100000 0x1000>; + interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_LOW>; + interrupt-names = "mc"; + clocks = <&topckgen CLK_TOP_USB_PHY48M>, + <&topckgen_cg CLK_TOP_USBIF>, + <&topckgen_cg CLK_TOP_USB>, + <&topckgen_cg CLK_TOP_USB_1P>; + clock-names = "usbpll", "usbmcu", "usb", "icusb"; + status = "disabled"; + }; + uart0: serial@11005000 { compatible = "mediatek,hsuart"; reg = <0x11005000 0x1000>; diff --git a/arch/arm/dts/r7s72100-gr-peach-u-boot.dts b/arch/arm/dts/r7s72100-gr-peach-u-boot.dts index 30e35e47d6..f48121a9a8 100644 --- a/arch/arm/dts/r7s72100-gr-peach-u-boot.dts +++ b/arch/arm/dts/r7s72100-gr-peach-u-boot.dts @@ -46,7 +46,7 @@ }; - rpc: rpc@0xee200000 { + rpc: rpc@ee200000 { compatible = "renesas,rpc-r7s72100", "renesas,rpc"; reg = <0x3fefa000 0x100>, <0x18000000 0x08000000>; bank-width = <2>; diff --git a/arch/arm/dts/r8a77950-u-boot.dtsi b/arch/arm/dts/r8a77950-u-boot.dtsi index 0317f47f0f..5a11651464 100644 --- a/arch/arm/dts/r8a77950-u-boot.dtsi +++ b/arch/arm/dts/r8a77950-u-boot.dtsi @@ -13,7 +13,7 @@ / { soc { - rpc: rpc@0xee200000 { + rpc: rpc@ee200000 { compatible = "renesas,rpc-r8a7795", "renesas,rpc"; reg = <0 0xee200000 0 0x100>, <0 0x08000000 0 0>; clocks = <&cpg CPG_MOD 917>; diff --git a/arch/arm/dts/r8a77960-u-boot.dtsi b/arch/arm/dts/r8a77960-u-boot.dtsi index 826c2384bc..f1cae1c359 100644 --- a/arch/arm/dts/r8a77960-u-boot.dtsi +++ b/arch/arm/dts/r8a77960-u-boot.dtsi @@ -13,7 +13,7 @@ / { soc { - rpc: rpc@0xee200000 { + rpc: rpc@ee200000 { compatible = "renesas,rpc-r8a7796", "renesas,rpc"; reg = <0 0xee200000 0 0x100>, <0 0x08000000 0 0>; clocks = <&cpg CPG_MOD 917>; diff --git a/arch/arm/dts/r8a77965-u-boot.dtsi b/arch/arm/dts/r8a77965-u-boot.dtsi index 33ff5b148b..9cc6f20537 100644 --- a/arch/arm/dts/r8a77965-u-boot.dtsi +++ b/arch/arm/dts/r8a77965-u-boot.dtsi @@ -13,7 +13,7 @@ / { soc { - rpc: rpc@0xee200000 { + rpc: rpc@ee200000 { compatible = "renesas,rpc-r8a77965", "renesas,rpc"; reg = <0 0xee200000 0 0x100>, <0 0x08000000 0 0>; clocks = <&cpg CPG_MOD 917>; diff --git a/arch/arm/dts/r8a77970-u-boot.dtsi b/arch/arm/dts/r8a77970-u-boot.dtsi index eabab7ce58..ac3c6be4ad 100644 --- a/arch/arm/dts/r8a77970-u-boot.dtsi +++ b/arch/arm/dts/r8a77970-u-boot.dtsi @@ -13,7 +13,7 @@ / { soc { - rpc: rpc@0xee200000 { + rpc: rpc@ee200000 { compatible = "renesas,rpc-r8a77970", "renesas,rpc"; reg = <0 0xee200000 0 0x100>, <0 0x08000000 0 0>; clocks = <&cpg CPG_MOD 917>; diff --git a/arch/arm/dts/r8a77980-u-boot.dtsi b/arch/arm/dts/r8a77980-u-boot.dtsi index 1050f6e991..365d40ac49 100644 --- a/arch/arm/dts/r8a77980-u-boot.dtsi +++ b/arch/arm/dts/r8a77980-u-boot.dtsi @@ -13,7 +13,7 @@ / { soc { - rpc: rpc@0xee200000 { + rpc: rpc@ee200000 { compatible = "renesas,rpc-r8a77980", "renesas,rpc"; reg = <0 0xee200000 0 0x100>, <0 0x08000000 0 0>; clocks = <&cpg CPG_MOD 917>; diff --git a/arch/arm/dts/r8a77990-u-boot.dtsi b/arch/arm/dts/r8a77990-u-boot.dtsi index ddf8b62627..6655abe875 100644 --- a/arch/arm/dts/r8a77990-u-boot.dtsi +++ b/arch/arm/dts/r8a77990-u-boot.dtsi @@ -9,7 +9,7 @@ / { soc { - rpc: rpc@0xee200000 { + rpc: rpc@ee200000 { compatible = "renesas,rpc-r8a77990", "renesas,rpc"; reg = <0 0xee200000 0 0x100>, <0 0x08000000 0 0>; clocks = <&cpg CPG_MOD 917>; diff --git a/arch/arm/dts/r8a77995-u-boot.dtsi b/arch/arm/dts/r8a77995-u-boot.dtsi index 8e9f6b7a7d..0917a80f09 100644 --- a/arch/arm/dts/r8a77995-u-boot.dtsi +++ b/arch/arm/dts/r8a77995-u-boot.dtsi @@ -9,7 +9,7 @@ / { soc { - rpc: rpc@0xee200000 { + rpc: rpc@ee200000 { compatible = "renesas,rpc-r8a77995", "renesas,rpc"; reg = <0 0xee200000 0 0x100>, <0 0x08000000 0 0>; clocks = <&cpg CPG_MOD 917>; diff --git a/arch/arm/dts/rk3328-nanopi-r2s-u-boot.dtsi b/arch/arm/dts/rk3328-nanopi-r2s-u-boot.dtsi new file mode 100644 index 0000000000..9e2ced1541 --- /dev/null +++ b/arch/arm/dts/rk3328-nanopi-r2s-u-boot.dtsi @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2018-2019 Rockchip Electronics Co., Ltd + * (C) Copyright 2020 David Bauer + */ + +#include "rk3328-u-boot.dtsi" +#include "rk3328-sdram-ddr4-666.dtsi" +/ { + chosen { + u-boot,spl-boot-order = "same-as-spl", &sdmmc, &emmc; + }; +}; + +&gpio0 { + u-boot,dm-spl; +}; + +&pinctrl { + u-boot,dm-spl; +}; + +&sdmmc0m1_gpio { + u-boot,dm-spl; +}; + +&pcfg_pull_up_4ma { + u-boot,dm-spl; +}; + +/* Need this and all the pinctrl/gpio stuff above to set pinmux */ +&vcc_sd { + u-boot,dm-spl; +}; + +&gmac2io { + snps,reset-gpio = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; + snps,reset-active-low; + snps,reset-delays-us = <0 10000 50000>; +}; diff --git a/arch/arm/dts/rk3328-nanopi-r2s.dts b/arch/arm/dts/rk3328-nanopi-r2s.dts new file mode 100644 index 0000000000..5445c5cb3d --- /dev/null +++ b/arch/arm/dts/rk3328-nanopi-r2s.dts @@ -0,0 +1,370 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2020 David Bauer <mail@david-bauer.net> + */ + +/dts-v1/; + +#include <dt-bindings/input/input.h> +#include <dt-bindings/gpio/gpio.h> +#include "rk3328.dtsi" + +/ { + model = "FriendlyElec NanoPi R2S"; + compatible = "friendlyarm,nanopi-r2s", "rockchip,rk3328"; + + chosen { + stdout-path = "serial2:1500000n8"; + }; + + gmac_clk: gmac-clock { + compatible = "fixed-clock"; + clock-frequency = <125000000>; + clock-output-names = "gmac_clkin"; + #clock-cells = <0>; + }; + + keys { + compatible = "gpio-keys"; + pinctrl-0 = <&reset_button_pin>; + pinctrl-names = "default"; + + reset { + label = "reset"; + gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_LOW>; + linux,code = <KEY_RESTART>; + debounce-interval = <50>; + }; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-0 = <&lan_led_pin>, <&sys_led_pin>, <&wan_led_pin>; + pinctrl-names = "default"; + + lan_led: led-0 { + gpios = <&gpio2 RK_PB7 GPIO_ACTIVE_HIGH>; + label = "nanopi-r2s:green:lan"; + }; + + sys_led: led-1 { + gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>; + label = "nanopi-r2s:red:sys"; + }; + + wan_led: led-2 { + gpios = <&gpio2 RK_PC2 GPIO_ACTIVE_HIGH>; + label = "nanopi-r2s:green:wan"; + }; + }; + + vcc_io_sdio: sdmmcio-regulator { + compatible = "regulator-gpio"; + enable-active-high; + gpios = <&gpio1 RK_PD4 GPIO_ACTIVE_HIGH>; + pinctrl-0 = <&sdio_vcc_pin>; + pinctrl-names = "default"; + regulator-name = "vcc_io_sdio"; + regulator-always-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-settling-time-us = <5000>; + regulator-type = "voltage"; + startup-delay-us = <2000>; + states = <1800000 0x1 + 3300000 0x0>; + vin-supply = <&vcc_io_33>; + }; + + vcc_sd: sdmmc-regulator { + compatible = "regulator-fixed"; + gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&sdmmc0m1_gpio>; + pinctrl-names = "default"; + regulator-name = "vcc_sd"; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc_io_33>; + }; + + vdd_5v: vdd-5v { + compatible = "regulator-fixed"; + regulator-name = "vdd_5v"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; +}; + +&cpu0 { + cpu-supply = <&vdd_arm>; +}; + +&cpu1 { + cpu-supply = <&vdd_arm>; +}; + +&cpu2 { + cpu-supply = <&vdd_arm>; +}; + +&cpu3 { + cpu-supply = <&vdd_arm>; +}; + +&gmac2io { + assigned-clocks = <&cru SCLK_MAC2IO>, <&cru SCLK_MAC2IO_EXT>; + assigned-clock-parents = <&gmac_clk>, <&gmac_clk>; + clock_in_out = "input"; + phy-handle = <&rtl8211e>; + phy-mode = "rgmii"; + phy-supply = <&vcc_io_33>; + pinctrl-0 = <&rgmiim1_pins>; + pinctrl-names = "default"; + rx_delay = <0x18>; + snps,aal; + tx_delay = <0x24>; + status = "okay"; + + mdio { + compatible = "snps,dwmac-mdio"; + #address-cells = <1>; + #size-cells = <0>; + + rtl8211e: ethernet-phy@1 { + compatible = "ethernet-phy-id001c.c915", + "ethernet-phy-ieee802.3-c22"; + reg = <1>; + pinctrl-0 = <ð_phy_reset_pin>; + pinctrl-names = "default"; + reset-assert-us = <10000>; + reset-deassert-us = <50000>; + reset-gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&i2c1 { + status = "okay"; + + rk805: pmic@18 { + compatible = "rockchip,rk805"; + reg = <0x18>; + interrupt-parent = <&gpio1>; + interrupts = <24 IRQ_TYPE_LEVEL_LOW>; + #clock-cells = <1>; + clock-output-names = "xin32k", "rk805-clkout2"; + gpio-controller; + #gpio-cells = <2>; + pinctrl-0 = <&pmic_int_l>; + pinctrl-names = "default"; + rockchip,system-power-controller; + wakeup-source; + + vcc1-supply = <&vdd_5v>; + vcc2-supply = <&vdd_5v>; + vcc3-supply = <&vdd_5v>; + vcc4-supply = <&vdd_5v>; + vcc5-supply = <&vcc_io_33>; + vcc6-supply = <&vdd_5v>; + + regulators { + vdd_log: DCDC_REG1 { + regulator-name = "vdd_log"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <712500>; + regulator-max-microvolt = <1450000>; + regulator-ramp-delay = <12500>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vdd_arm: DCDC_REG2 { + regulator-name = "vdd_arm"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <712500>; + regulator-max-microvolt = <1450000>; + regulator-ramp-delay = <12500>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <950000>; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-name = "vcc_ddr"; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_io_33: DCDC_REG4 { + regulator-name = "vcc_io_33"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_18: LDO_REG1 { + regulator-name = "vcc_18"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcc18_emmc: LDO_REG2 { + regulator-name = "vcc18_emmc"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vdd_10: LDO_REG3 { + regulator-name = "vdd_10"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + }; + }; +}; + +&io_domains { + pmuio-supply = <&vcc_io_33>; + vccio1-supply = <&vcc_io_33>; + vccio2-supply = <&vcc18_emmc>; + vccio3-supply = <&vcc_io_sdio>; + vccio4-supply = <&vcc_18>; + vccio5-supply = <&vcc_io_33>; + vccio6-supply = <&vcc_io_33>; + status = "okay"; +}; + +&pinctrl { + button { + reset_button_pin: reset-button-pin { + rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + ethernet-phy { + eth_phy_reset_pin: eth-phy-reset-pin { + rockchip,pins = <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_down>; + }; + }; + + leds { + lan_led_pin: lan-led-pin { + rockchip,pins = <2 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + sys_led_pin: sys-led-pin { + rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + wan_led_pin: wan-led-pin { + rockchip,pins = <2 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + pmic { + pmic_int_l: pmic-int-l { + rockchip,pins = <1 RK_PD0 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + sd { + sdio_vcc_pin: sdio-vcc-pin { + rockchip,pins = <1 RK_PD4 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; +}; + +&pwm2 { + status = "okay"; +}; + +&sdmmc { + bus-width = <4>; + cap-sd-highspeed; + disable-wp; + pinctrl-0 = <&sdmmc0_clk>, <&sdmmc0_cmd>, <&sdmmc0_dectn>, <&sdmmc0_bus4>; + pinctrl-names = "default"; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vmmc-supply = <&vcc_sd>; + vqmmc-supply = <&vcc_io_sdio>; + status = "okay"; +}; + +&tsadc { + rockchip,hw-tshut-mode = <0>; + rockchip,hw-tshut-polarity = <0>; + status = "okay"; +}; + +&u2phy { + status = "okay"; +}; + +&u2phy_host { + status = "okay"; +}; + +&u2phy_otg { + status = "okay"; +}; + +&uart2 { + status = "okay"; +}; + +&usb20_otg { + status = "okay"; + dr_mode = "host"; +}; + +&usb_host0_ehci { + status = "okay"; +}; + +&usb_host0_ohci { + status = "okay"; +}; diff --git a/arch/arm/dts/rk3399-evb-u-boot.dtsi b/arch/arm/dts/rk3399-evb-u-boot.dtsi index 8056dc843e..5e39b1493d 100644 --- a/arch/arm/dts/rk3399-evb-u-boot.dtsi +++ b/arch/arm/dts/rk3399-evb-u-boot.dtsi @@ -13,10 +13,6 @@ }; }; -&rng { - status = "okay"; -}; - &i2c0 { u-boot,dm-pre-reloc; }; @@ -38,6 +34,10 @@ status = "okay"; }; +&vdd_center { + regulator-init-microvolt = <900000>; +}; + &sdmmc { u-boot,dm-pre-reloc; bus-width = <4>; diff --git a/arch/arm/dts/rk3399-firefly-u-boot.dtsi b/arch/arm/dts/rk3399-firefly-u-boot.dtsi index 38e0897db9..c58ad95d12 100644 --- a/arch/arm/dts/rk3399-firefly-u-boot.dtsi +++ b/arch/arm/dts/rk3399-firefly-u-boot.dtsi @@ -11,3 +11,7 @@ u-boot,spl-boot-order = "same-as-spl", &sdhci, &sdmmc; }; }; + +&vdd_log { + regulator-init-microvolt = <950000>; +}; diff --git a/arch/arm/dts/rk3399-leez-p710-u-boot.dtsi b/arch/arm/dts/rk3399-leez-p710-u-boot.dtsi index f8b2a1d56e..c638ce2597 100644 --- a/arch/arm/dts/rk3399-leez-p710-u-boot.dtsi +++ b/arch/arm/dts/rk3399-leez-p710-u-boot.dtsi @@ -11,3 +11,7 @@ u-boot,spl-boot-order = "same-as-spl", &sdhci, &sdmmc; }; }; + +&vdd_log { + regulator-init-microvolt = <950000>; +}; diff --git a/arch/arm/dts/rk3399-pinebook-pro-u-boot.dtsi b/arch/arm/dts/rk3399-pinebook-pro-u-boot.dtsi index ee3b98698e..1eafb40ce3 100644 --- a/arch/arm/dts/rk3399-pinebook-pro-u-boot.dtsi +++ b/arch/arm/dts/rk3399-pinebook-pro-u-boot.dtsi @@ -24,10 +24,6 @@ u-boot,dm-pre-reloc; }; -&rng { - status = "okay"; -}; - &sdhci { max-frequency = <25000000>; u-boot,dm-pre-reloc; diff --git a/arch/arm/dts/rk3399-puma-haikou-u-boot.dtsi b/arch/arm/dts/rk3399-puma-haikou-u-boot.dtsi index 29846c4b00..e7a1aea3a5 100644 --- a/arch/arm/dts/rk3399-puma-haikou-u-boot.dtsi +++ b/arch/arm/dts/rk3399-puma-haikou-u-boot.dtsi @@ -28,8 +28,7 @@ }; aliases { - spi0 = &spi1; - spi1 = &spi5; + spi5 = &spi5; }; /* diff --git a/arch/arm/dts/rk3399-roc-pc-u-boot.dtsi b/arch/arm/dts/rk3399-roc-pc-u-boot.dtsi index fc155e6903..e3c9364e35 100644 --- a/arch/arm/dts/rk3399-roc-pc-u-boot.dtsi +++ b/arch/arm/dts/rk3399-roc-pc-u-boot.dtsi @@ -7,10 +7,6 @@ #include "rk3399-sdram-lpddr4-100.dtsi" / { - aliases { - spi0 = &spi1; - }; - chosen { u-boot,spl-boot-order = "same-as-spl", &spi_flash, &sdhci, &sdmmc; }; diff --git a/arch/arm/dts/rk3399-rockpro64-u-boot.dtsi b/arch/arm/dts/rk3399-rockpro64-u-boot.dtsi index 6317b47e41..37dff04adf 100644 --- a/arch/arm/dts/rk3399-rockpro64-u-boot.dtsi +++ b/arch/arm/dts/rk3399-rockpro64-u-boot.dtsi @@ -15,10 +15,6 @@ }; }; -&rng { - status = "okay"; -}; - &spi1 { spi_flash: flash@0 { u-boot,dm-pre-reloc; diff --git a/arch/arm/dts/rk3399-u-boot.dtsi b/arch/arm/dts/rk3399-u-boot.dtsi index ecd230c720..73922c328a 100644 --- a/arch/arm/dts/rk3399-u-boot.dtsi +++ b/arch/arm/dts/rk3399-u-boot.dtsi @@ -32,7 +32,7 @@ rng: rng@ff8b8000 { compatible = "rockchip,cryptov1-rng"; reg = <0x0 0xff8b8000 0x0 0x1000>; - status = "disabled"; + status = "okay"; }; dmc: dmc { diff --git a/arch/arm/dts/socfpga_agilex-u-boot.dtsi b/arch/arm/dts/socfpga_agilex-u-boot.dtsi index f0528a9ad9..08f7cf7f7a 100644 --- a/arch/arm/dts/socfpga_agilex-u-boot.dtsi +++ b/arch/arm/dts/socfpga_agilex-u-boot.dtsi @@ -2,9 +2,11 @@ /* * U-Boot additions * - * Copyright (C) 2019 Intel Corporation <www.intel.com> + * Copyright (C) 2019-2020 Intel Corporation <www.intel.com> */ +#include "socfpga_soc64_fit-u-boot.dtsi" + /{ memory { #address-cells = <2>; diff --git a/arch/arm/dts/socfpga_soc64_fit-u-boot.dtsi b/arch/arm/dts/socfpga_soc64_fit-u-boot.dtsi new file mode 100644 index 0000000000..cf365590a8 --- /dev/null +++ b/arch/arm/dts/socfpga_soc64_fit-u-boot.dtsi @@ -0,0 +1,120 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * U-Boot additions + * + * Copyright (C) 2020 Intel Corporation <www.intel.com> + */ + +#if defined(CONFIG_FIT) + +/ { + binman: binman { + multiple-images; + }; +}; + +&binman { + u-boot { + filename = "u-boot.itb"; + fit { + fit,external-offset = <CONFIG_FIT_EXTERNAL_OFFSET>; + description = "FIT with firmware and bootloader"; + #address-cells = <1>; + + images { + uboot { + description = "U-Boot SoC64"; + type = "standalone"; + os = "U-Boot"; + arch = "arm64"; + compression = "none"; + load = <0x00200000>; + + uboot_blob: blob-ext { + filename = "u-boot-nodtb.bin"; + }; + }; + + atf { + description = "ARM Trusted Firmware"; + type = "firmware"; + os = "arm-trusted-firmware"; + arch = "arm64"; + compression = "none"; + load = <0x00001000>; + entry = <0x00001000>; + + atf_blob: blob-ext { + filename = "bl31.bin"; + }; + }; + + fdt { + description = "U-Boot SoC64 flat device-tree"; + type = "flat_dt"; + compression = "none"; + + uboot_fdt_blob: blob-ext { + filename = "u-boot.dtb"; + }; + }; + }; + + configurations { + default = "conf"; + conf { + description = "Intel SoC64 FPGA"; + firmware = "atf"; + loadables = "uboot"; + fdt = "fdt"; + }; + }; + }; + }; + + kernel { + filename = "kernel.itb"; + fit { + description = "FIT with Linux kernel image and FDT blob"; + #address-cells = <1>; + + images { + kernel { + description = "Linux Kernel"; + type = "kernel"; + arch = "arm64"; + os = "linux"; + compression = "none"; + load = <0x4080000>; + entry = <0x4080000>; + + kernel_blob: blob-ext { + filename = "Image"; + }; + }; + + fdt { + description = "Linux DTB"; + type = "flat_dt"; + arch = "arm64"; + compression = "none"; + + kernel_fdt_blob: blob-ext { + filename = "linux.dtb"; + }; + }; + }; + + configurations { + default = "conf"; + conf { + description = "Intel SoC64 FPGA"; + kernel = "kernel"; + fdt = "fdt"; + }; + }; + }; + }; +}; + +#endif diff --git a/arch/arm/dts/socfpga_stratix10-u-boot.dtsi b/arch/arm/dts/socfpga_stratix10-u-boot.dtsi new file mode 100644 index 0000000000..3e3a378046 --- /dev/null +++ b/arch/arm/dts/socfpga_stratix10-u-boot.dtsi @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * U-Boot additions + * + * Copyright (C) 2020 Intel Corporation <www.intel.com> + */ + +#include "socfpga_soc64_fit-u-boot.dtsi" diff --git a/arch/arm/dts/socfpga_stratix10_socdk-u-boot.dtsi b/arch/arm/dts/socfpga_stratix10_socdk-u-boot.dtsi index 2669abb383..61df425f14 100755 --- a/arch/arm/dts/socfpga_stratix10_socdk-u-boot.dtsi +++ b/arch/arm/dts/socfpga_stratix10_socdk-u-boot.dtsi @@ -2,9 +2,11 @@ /* * U-Boot additions * - * Copyright (C) 2019 Intel Corporation <www.intel.com> + * Copyright (C) 2019-2020 Intel Corporation <www.intel.com> */ +#include "socfpga_stratix10-u-boot.dtsi" + /{ aliases { spi0 = &qspi; diff --git a/arch/arm/dts/stih410-b2260-u-boot.dtsi b/arch/arm/dts/stih410-b2260-u-boot.dtsi index 897c42146a..3b080ac7a1 100644 --- a/arch/arm/dts/stih410-b2260-u-boot.dtsi +++ b/arch/arm/dts/stih410-b2260-u-boot.dtsi @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2018, STMicroelectronics - All Rights Reserved - * Author(s): Patrice Chotard, <patrice.chotard@st.com> for STMicroelectronics. + * Author(s): Patrice Chotard, <patrice.chotard@foss.st.com> for STMicroelectronics. * */ diff --git a/arch/arm/dts/stih410-b2260.dts b/arch/arm/dts/stih410-b2260.dts index 4fbd8e9eb5..8c4155b622 100644 --- a/arch/arm/dts/stih410-b2260.dts +++ b/arch/arm/dts/stih410-b2260.dts @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) 2016 STMicroelectronics (R&D) Limited. - * Author: Patrice Chotard <patrice.chotard@st.com> + * Author: Patrice Chotard <patrice.chotard@foss.st.com> */ /dts-v1/; #include "stih410.dtsi" diff --git a/arch/arm/dts/stm32429i-eval-u-boot.dtsi b/arch/arm/dts/stm32429i-eval-u-boot.dtsi index e75cf99f8f..09d9d9ab9b 100644 --- a/arch/arm/dts/stm32429i-eval-u-boot.dtsi +++ b/arch/arm/dts/stm32429i-eval-u-boot.dtsi @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2018, STMicroelectronics - All Rights Reserved - * Author(s): Patrice Chotard, <patrice.chotard@st.com> for STMicroelectronics. + * Author(s): Patrice Chotard, <patrice.chotard@foss.st.com> for STMicroelectronics. */ #include <dt-bindings/memory/stm32-sdram.h> diff --git a/arch/arm/dts/stm32f429-disco-u-boot.dtsi b/arch/arm/dts/stm32f429-disco-u-boot.dtsi index df99e01393..297cc56144 100644 --- a/arch/arm/dts/stm32f429-disco-u-boot.dtsi +++ b/arch/arm/dts/stm32f429-disco-u-boot.dtsi @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2017, STMicroelectronics - All Rights Reserved - * Author(s): Patrice Chotard, <patrice.chotard@st.com> for STMicroelectronics. + * Author(s): Patrice Chotard, <patrice.chotard@foss.st.com> for STMicroelectronics. */ #include <dt-bindings/memory/stm32-sdram.h> diff --git a/arch/arm/dts/stm32f469-disco-u-boot.dtsi b/arch/arm/dts/stm32f469-disco-u-boot.dtsi index 7223ba4a60..9eda8f535b 100644 --- a/arch/arm/dts/stm32f469-disco-u-boot.dtsi +++ b/arch/arm/dts/stm32f469-disco-u-boot.dtsi @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2017, STMicroelectronics - All Rights Reserved - * Author(s): Patrice Chotard, <patrice.chotard@st.com> for STMicroelectronics. + * Author(s): Patrice Chotard, <patrice.chotard@foss.st.com> for STMicroelectronics. */ #include <dt-bindings/memory/stm32-sdram.h> diff --git a/arch/arm/dts/stm32h743i-disco.dts b/arch/arm/dts/stm32h743i-disco.dts index 81007161e7..7927310d8e 100644 --- a/arch/arm/dts/stm32h743i-disco.dts +++ b/arch/arm/dts/stm32h743i-disco.dts @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ OR X11 /* - * Copyright 2017 - Patrice Chotard <patrice.chotard@st.com> + * Copyright 2017 - Patrice Chotard <patrice.chotard@foss.st.com> * */ diff --git a/arch/arm/dts/stm32mp15xx-dhcom-u-boot.dtsi b/arch/arm/dts/stm32mp15xx-dhcom-u-boot.dtsi index 92345b7ba3..6868769c6e 100644 --- a/arch/arm/dts/stm32mp15xx-dhcom-u-boot.dtsi +++ b/arch/arm/dts/stm32mp15xx-dhcom-u-boot.dtsi @@ -72,8 +72,8 @@ &pinctrl { /* These should bound to FMC2 bus driver, but we do not have one */ - pinctrl-0 = <&fmc_pins_b>; - pinctrl-1 = <&fmc_sleep_pins_b>; + pinctrl-0 = <&fmc_pins_b &mco2_pins_a>; + pinctrl-1 = <&fmc_sleep_pins_b &mco2_sleep_pins_a>; pinctrl-names = "default", "sleep"; fmc_pins_b: fmc-0 { @@ -130,6 +130,21 @@ <STM32_PINMUX('G', 12, ANALOG)>; /* FMC_NE4 */ }; }; + + mco2_pins_a: mco2-0 { + pins { + pinmux = <STM32_PINMUX('G', 2, AF1)>; /* MCO2 */ + bias-disable; + drive-push-pull; + slew-rate = <2>; + }; + }; + + mco2_sleep_pins_a: mco2-sleep-0 { + pins { + pinmux = <STM32_PINMUX('G', 2, ANALOG)>; /* MCO2 */ + }; + }; }; &pmic { @@ -181,7 +196,7 @@ CLK_PLL4_HSE CLK_RTC_LSE CLK_MCO1_DISABLED - CLK_MCO2_DISABLED + CLK_MCO2_PLL4P >; st,clkdiv = < @@ -195,7 +210,7 @@ 2 /*APB5*/ 23 /*RTC*/ 0 /*MCO1*/ - 0 /*MCO2*/ + 1 /*MCO2*/ >; st,pkcs = < @@ -258,7 +273,7 @@ pll4: st,pll@3 { compatible = "st,stm32mp1-pll"; reg = <3>; - cfg = < 1 49 11 11 11 PQR(1,1,1) >; + cfg = < 1 49 5 11 11 PQR(1,1,1) >; u-boot,dm-pre-reloc; }; }; diff --git a/arch/arm/dts/stm32mp15xx-dhcom.dtsi b/arch/arm/dts/stm32mp15xx-dhcom.dtsi index dafcce4323..a1d1b8dec7 100644 --- a/arch/arm/dts/stm32mp15xx-dhcom.dtsi +++ b/arch/arm/dts/stm32mp15xx-dhcom.dtsi @@ -58,7 +58,6 @@ phy-mode = "rmii"; max-speed = <100>; phy-handle = <&phy0>; - st,eth_ref_clk_sel; phy-reset-gpios = <&gpioh 15 GPIO_ACTIVE_LOW>; mdio0 { @@ -267,7 +266,7 @@ pinmux = <STM32_PINMUX('G', 13, AF11)>, /* ETH1_RMII_TXD0 */ <STM32_PINMUX('G', 14, AF11)>, /* ETH1_RMII_TXD1 */ <STM32_PINMUX('B', 11, AF11)>, /* ETH1_RMII_TX_EN */ - <STM32_PINMUX('A', 1, AF0)>, /* ETH1_RMII_REF_CLK */ + <STM32_PINMUX('A', 1, AF11)>, /* ETH1_RMII_REF_CLK */ <STM32_PINMUX('A', 2, AF11)>, /* ETH1_MDIO */ <STM32_PINMUX('C', 1, AF11)>; /* ETH1_MDC */ bias-disable; diff --git a/arch/arm/include/asm/acpi_table.h b/arch/arm/include/asm/acpi_table.h new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/arch/arm/include/asm/acpi_table.h diff --git a/arch/arm/include/asm/arch-aspeed/boot0.h b/arch/arm/include/asm/arch-aspeed/boot0.h new file mode 100644 index 0000000000..368becc87a --- /dev/null +++ b/arch/arm/include/asm/arch-aspeed/boot0.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) Aspeed Technology Inc. + */ + +#ifndef _ASM_ARCH_BOOT0_H +#define _ASM_ARCH_BOOT0_H + +_start: + ARM_VECTORS + + .word 0x0 /* key location */ + .word 0x0 /* start address of image */ + .word 0xfc00 /* maximum image size: 63KB */ + .word 0x0 /* signature address */ + .word 0x0 /* header revision ID low */ + .word 0x0 /* header revision ID high */ + .word 0x0 /* reserved */ + .word 0x0 /* checksum */ + .word 0x0 /* BL2 secure header */ + .word 0x0 /* public key or digest offset for BL2 */ + +#endif diff --git a/arch/arm/include/asm/arch-aspeed/platform.h b/arch/arm/include/asm/arch-aspeed/platform.h index 6cee036f54..d50ec5f8a9 100644 --- a/arch/arm/include/asm/arch-aspeed/platform.h +++ b/arch/arm/include/asm/arch-aspeed/platform.h @@ -13,6 +13,11 @@ #define ASPEED_DRAM_BASE 0x80000000 #define ASPEED_SRAM_BASE 0x1e720000 #define ASPEED_SRAM_SIZE 0x9000 +#elif defined(CONFIG_ASPEED_AST2600) +#define ASPEED_MAC_COUNT 4 +#define ASPEED_DRAM_BASE 0x80000000 +#define ASPEED_SRAM_BASE 0x10000000 +#define ASPEED_SRAM_SIZE 0x10000 #else #err "Unrecognized Aspeed platform." #endif diff --git a/arch/arm/include/asm/arch-aspeed/scu_ast2600.h b/arch/arm/include/asm/arch-aspeed/scu_ast2600.h new file mode 100644 index 0000000000..a205fb1f76 --- /dev/null +++ b/arch/arm/include/asm/arch-aspeed/scu_ast2600.h @@ -0,0 +1,338 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) Aspeed Technology Inc. + */ +#ifndef _ASM_ARCH_SCU_AST2600_H +#define _ASM_ARCH_SCU_AST2600_H + +#define SCU_UNLOCK_KEY 0x1688a8a8 + +#define SCU_CLKGATE1_EMMC BIT(27) +#define SCU_CLKGATE1_MAC2 BIT(21) +#define SCU_CLKGATE1_MAC1 BIT(20) +#define SCU_CLKGATE1_USB_HUB BIT(14) +#define SCU_CLKGATE1_USB_HOST2 BIT(7) + +#define SCU_CLKGATE2_FSI BIT(30) +#define SCU_CLKGATE2_MAC4 BIT(21) +#define SCU_CLKGATE2_MAC3 BIT(20) +#define SCU_CLKGATE2_SDIO BIT(4) + +#define SCU_DRAM_HDSHK_SOC_INIT BIT(7) +#define SCU_DRAM_HDSHK_RDY BIT(6) + +#define SCU_CLKSRC1_ECC_RSA_DIV_MASK GENMASK(27, 26) +#define SCU_CLKSRC1_ECC_RSA_DIV_SHIFT 26 +#define SCU_CLKSRC1_PCLK_DIV_MASK GENMASK(25, 23) +#define SCU_CLKSRC1_PCLK_DIV_SHIFT 23 +#define SCU_CLKSRC1_BCLK_DIV_MASK GENMASK(22, 20) +#define SCU_CLKSRC1_BCLK_DIV_SHIFT 20 +#define SCU_CLKSRC1_ECC_RSA BIT(19) +#define SCU_CLKSRC1_MAC_DIV_MASK GENMASK(18, 16) +#define SCU_CLKSRC1_MAC_DIV_SHIFT 16 +#define SCU_CLKSRC1_EMMC_EN BIT(15) +#define SCU_CLKSRC1_EMMC_DIV_MASK GENMASK(14, 12) +#define SCU_CLKSRC1_EMMC_DIV_SHIFT 12 +#define SCU_CLKSRC1_EMMC BIT(11) + +#define SCU_CLKSRC2_RMII12 BIT(19) +#define SCU_CLKSRC2_RMII12_DIV_MASK GENMASK(18, 16) +#define SCU_CLKSRC2_RMII12_DIV_SHIFT 16 +#define SCU_CLKSRC2_UART5 BIT(14) + +#define SCU_CLKSRC4_SDIO_EN BIT(31) +#define SCU_CLKSRC4_SDIO_DIV_MASK GENMASK(30, 28) +#define SCU_CLKSRC4_SDIO_DIV_SHIFT 28 +#define SCU_CLKSRC4_MAC_DIV_MASK GENMASK(26, 24) +#define SCU_CLKSRC4_MAC_DIV_SHIFT 24 +#define SCU_CLKSRC4_RMII34_DIV_MASK GENMASK(18, 16) +#define SCU_CLKSRC4_RMII34_DIV_SHIFT 16 +#define SCU_CLKSRC4_PCLK_DIV_MASK GENMASK(11, 9) +#define SCU_CLKSRC4_PCLK_DIV_SHIFT 9 +#define SCU_CLKSRC4_SDIO BIT(8) +#define SCU_CLKSRC4_UART6 BIT(5) +#define SCU_CLKSRC4_UART4 BIT(3) +#define SCU_CLKSRC4_UART3 BIT(2) +#define SCU_CLKSRC4_UART2 BIT(1) +#define SCU_CLKSRC4_UART1 BIT(0) + +#define SCU_CLKSRC5_UART13 BIT(12) +#define SCU_CLKSRC5_UART12 BIT(11) +#define SCU_CLKSRC5_UART11 BIT(10) +#define SCU_CLKSRC5_UART10 BIT(9) +#define SCU_CLKSRC5_UART9 BIT(8) +#define SCU_CLKSRC5_UART8 BIT(7) +#define SCU_CLKSRC5_UART7 BIT(6) +#define SCU_CLKSRC5_HUXCLK_MASK GENMASK(5, 3) +#define SCU_CLKSRC5_HUXCLK_SHIFT 3 +#define SCU_CLKSRC5_UXCLK_MASK GENMASK(2, 0) +#define SCU_CLKSRC5_UXCLK_SHIFT 0 + +#define SCU_PINCTRL1_EMMC_MASK GENMASK(31, 24) +#define SCU_PINCTRL1_EMMC_SHIFT 24 + +#define SCU_PINCTRL16_MAC4_DRIVING_MASK GENMASK(3, 2) +#define SCU_PINCTRL16_MAC4_DRIVING_SHIFT 2 +#define SCU_PINCTRL16_MAC3_DRIVING_MASK GENMASK(1, 0) +#define SCU_PINCTRL16_MAC3_DRIVING_SHIFT 0 + +#define SCU_HWSTRAP1_CPU_AXI_CLK_RATIO BIT(16) +#define SCU_HWSTRAP1_VGA_MEM_MASK GENMASK(14, 13) +#define SCU_HWSTRAP1_VGA_MEM_SHIFT 13 +#define SCU_HWSTRAP1_AXI_AHB_CLK_RATIO_MASK GENMASK(12, 11) +#define SCU_HWSTRAP1_AXI_AHB_CLK_RATIO_SHIFT 11 +#define SCU_HWSTRAP1_CPU_FREQ_MASK GENMASK(10, 8) +#define SCU_HWSTRAP1_CPU_FREQ_SHIFT 8 +#define SCU_HWSTRAP1_MAC2_INTF BIT(7) +#define SCU_HWSTRAP1_MAC1_INTF BIT(6) + +#define SCU_EFUSE_DIS_DP BIT(17) +#define SCU_EFUSE_DIS_VGA BIT(14) +#define SCU_EFUSE_DIS_PCIE_EP BIT(13) +#define SCU_EFUSE_DIS_USB BIT(12) +#define SCU_EFUSE_DIS_RVAS BIT(10) +#define SCU_EFUSE_DIS_VIDEO_DEC BIT(9) +#define SCU_EFUSE_DIS_VIDEO BIT(8) +#define SCU_EFUSE_DIS_PCIE_RC BIT(7) +#define SCU_EFUSE_DIS_CM3 BIT(6) +#define SCU_EFUSE_DIS_CA7 BIT(5) + +#define SCU_PLL_RST BIT(25) +#define SCU_PLL_BYPASS BIT(24) +#define SCU_PLL_OFF BIT(23) +#define SCU_PLL_DIV_MASK GENMASK(22, 19) +#define SCU_PLL_DIV_SHIFT 19 +#define SCU_PLL_DENUM_MASK GENMASK(18, 13) +#define SCU_PLL_DENUM_SHIFT 13 +#define SCU_PLL_NUM_MASK GENMASK(12, 0) +#define SCU_PLL_NUM_SHIFT 0 + +#define SCU_UART_CLKGEN_N_MASK GENMASK(17, 8) +#define SCU_UART_CLKGEN_N_SHIFT 8 +#define SCU_UART_CLKGEN_R_MASK GENMASK(7, 0) +#define SCU_UART_CLKGEN_R_SHIFT 0 + +#define SCU_HUART_CLKGEN_N_MASK GENMASK(17, 8) +#define SCU_HUART_CLKGEN_N_SHIFT 8 +#define SCU_HUART_CLKGEN_R_MASK GENMASK(7, 0) +#define SCU_HUART_CLKGEN_R_SHIFT 0 + +#define SCU_MISC_CTRL1_UART5_DIV BIT(12) + +#ifndef __ASSEMBLY__ +struct ast2600_scu { + uint32_t prot_key1; /* 0x000 */ + uint32_t chip_id1; /* 0x004 */ + uint32_t rsv_0x08; /* 0x008 */ + uint32_t rsv_0x0c; /* 0x00C */ + uint32_t prot_key2; /* 0x010 */ + uint32_t chip_id2; /* 0x014 */ + uint32_t rsv_0x18[10]; /* 0x018 ~ 0x03C */ + uint32_t modrst_ctrl1; /* 0x040 */ + uint32_t modrst_clr1; /* 0x044 */ + uint32_t rsv_0x48; /* 0x048 */ + uint32_t rsv_0x4C; /* 0x04C */ + uint32_t modrst_ctrl2; /* 0x050 */ + uint32_t modrst_clr2; /* 0x054 */ + uint32_t rsv_0x58; /* 0x058 */ + uint32_t rsv_0x5C; /* 0x05C */ + uint32_t extrst_sel1; /* 0x060 */ + uint32_t sysrst_sts1_1; /* 0x064 */ + uint32_t sysrst_sts1_2; /* 0x068 */ + uint32_t sysrst_sts1_3; /* 0x06C */ + uint32_t extrst_sel2; /* 0x070 */ + uint32_t sysrst_sts2_1; /* 0x074 */ + uint32_t sysrst_sts2_2; /* 0x078 */ + uint32_t stsrst_sts3_2; /* 0x07C */ + uint32_t clkgate_ctrl1; /* 0x080 */ + uint32_t clkgate_clr1; /* 0x084 */ + uint32_t rsv_0x88; /* 0x088 */ + uint32_t rsv_0x8C; /* 0x08C */ + uint32_t clkgate_ctrl2; /* 0x090 */ + uint32_t clkgate_clr2; /* 0x094 */ + uint32_t rsv_0x98[10]; /* 0x098 ~ 0x0BC */ + uint32_t misc_ctrl1; /* 0x0C0 */ + uint32_t misc_ctrl2; /* 0x0C4 */ + uint32_t debug_ctrl1; /* 0x0C8 */ + uint32_t rsv_0xCC; /* 0x0CC */ + uint32_t misc_ctrl3; /* 0x0D0 */ + uint32_t misc_ctrl4; /* 0x0D4 */ + uint32_t debug_ctrl2; /* 0x0D8 */ + uint32_t rsv_0xdc[9]; /* 0x0DC ~ 0x0FC */ + uint32_t dram_hdshk; /* 0x100 */ + uint32_t soc_scratch[3]; /* 0x104 ~ 0x10C */ + uint32_t rsv_0x110[4]; /* 0x110 ~ 0x11C*/ + uint32_t cpu_scratch_wp; /* 0x120 */ + uint32_t rsv_0x124[23]; /* 0x124 */ + uint32_t smp_boot[12]; /* 0x180 */ + uint32_t cpu_scratch[20]; /* 0x1b0 */ + uint32_t hpll; /* 0x200 */ + uint32_t hpll_ext; /* 0x204 */ + uint32_t rsv_0x208[2]; /* 0x208 ~ 0x20C */ + uint32_t apll; /* 0x210 */ + uint32_t apll_ext; /* 0x214 */ + uint32_t rsv_0x218[2]; /* 0x218 ~ 0x21C */ + uint32_t mpll; /* 0x220 */ + uint32_t mpll_ext; /* 0x224 */ + uint32_t rsv_0x228[6]; /* 0x228 ~ 0x23C */ + uint32_t epll; /* 0x240 */ + uint32_t epll_ext; /* 0x244 */ + uint32_t rsv_0x248[6]; /* 0x248 ~ 0x25C */ + uint32_t dpll; /* 0x260 */ + uint32_t dpll_ext; /* 0x264 */ + uint32_t rsv_0x268[38]; /* 0x268 ~ 0x2FC */ + uint32_t clksrc1; /* 0x300 */ + uint32_t clksrc2; /* 0x304 */ + uint32_t clksrc3; /* 0x308 */ + uint32_t rsv_0x30c; /* 0x30C */ + uint32_t clksrc4; /* 0x310 */ + uint32_t clksrc5; /* 0x314 */ + uint32_t rsv_0x318[2]; /* 0x318 ~ 0x31C */ + uint32_t freq_counter_ctrl1; /* 0x320 */ + uint32_t freq_counter_cmp1; /* 0x324 */ + uint32_t rsv_0x328[2]; /* 0x328 ~ 0x32C */ + uint32_t freq_counter_ctrl2; /* 0x330 */ + uint32_t freq_counter_cmp2; /* 0x334 */ + uint32_t uart_clkgen; /* 0x338 */ + uint32_t huart_clkgen; /* 0x33C */ + uint32_t mac12_clk_delay; /* 0x340 */ + uint32_t rsv_0x344; /* 0x344 */ + uint32_t mac12_clk_delay_100M; /* 0x348 */ + uint32_t mac12_clk_delay_10M; /* 0x34C */ + uint32_t mac34_clk_delay; /* 0x350 */ + uint32_t rsv_0x354; /* 0x354 */ + uint32_t mac34_clk_delay_100M; /* 0x358 */ + uint32_t mac34_clk_delay_10M; /* 0x35C */ + uint32_t clkduty_meas_ctrl; /* 0x360 */ + uint32_t clkduty1; /* 0x364 */ + uint32_t clkduty2; /* 0x368 */ + uint32_t clkduty_meas_res; /* 0x36C */ + uint32_t clkduty_meas_ctrl2; /* 0x370 */ + uint32_t clkduty3; /* 0x374 */ + uint32_t rsv_0x378[34]; /* 0x378 ~ 0x3FC */ + uint32_t pinmux1; /* 0x400 */ + uint32_t pinmux2; /* 0x404 */ + uint32_t rsv_0x408; /* 0x408 */ + uint32_t pinmux3; /* 0x40C */ + uint32_t pinmux4; /* 0x410 */ + uint32_t pinmux5; /* 0x414 */ + uint32_t pinmux6; /* 0x418 */ + uint32_t pinmux7; /* 0x41C */ + uint32_t rsv_0x420[4]; /* 0x420 ~ 0x42C */ + uint32_t pinmux8; /* 0x430 */ + uint32_t pinmux9; /* 0x434 */ + uint32_t pinmux10; /* 0x438 */ + uint32_t rsv_0x43c; /* 0x43C */ + uint32_t pinmux12; /* 0x440 */ + uint32_t pinmux13; /* 0x444 */ + uint32_t rsv_0x448[2]; /* 0x448 ~ 0x44C */ + uint32_t pinmux14; /* 0x450 */ + uint32_t pinmux15; /* 0x454 */ + uint32_t pinmux16; /* 0x458 */ + uint32_t rsv_0x45c[21]; /* 0x45C ~ 0x4AC */ + uint32_t pinmux17; /* 0x4B0 */ + uint32_t pinmux18; /* 0x4B4 */ + uint32_t pinmux19; /* 0x4B8 */ + uint32_t pinmux20; /* 0x4BC */ + uint32_t rsv_0x4c0[5]; /* 0x4C0 ~ 0x4D0 */ + uint32_t pinmux22; /* 0x4D4 */ + uint32_t pinmux23; /* 0x4D8 */ + uint32_t rsv_0x4dc[9]; /* 0x4DC ~ 0x4FC */ + uint32_t hwstrap1; /* 0x500 */ + uint32_t hwstrap_clr1; /* 0x504 */ + uint32_t hwstrap_prot1; /* 0x508 */ + uint32_t rsv_0x50c; /* 0x50C */ + uint32_t hwstrap2; /* 0x510 */ + uint32_t hwstrap_clr2; /* 0x514 */ + uint32_t hwstrap_prot2; /* 0x518 */ + uint32_t rsv_0x51c; /* 0x51C */ + uint32_t rng_ctrl; /* 0x520 */ + uint32_t rng_data; /* 0x524 */ + uint32_t rsv_0x528[6]; /* 0x528 ~ 0x53C */ + uint32_t pwr_save_wakeup_en1; /* 0x540 */ + uint32_t pwr_save_wakeup_ctrl1; /* 0x544 */ + uint32_t rsv_0x548[2]; /* 0x548 */ + uint32_t pwr_save_wakeup_en2; /* 0x550 */ + uint32_t pwr_save_wakeup_ctrl2; /* 0x554 */ + uint32_t rsv_0x558[2]; /* 0x558 */ + uint32_t intr1_ctrl_sts; /* 0x560 */ + uint32_t rsv_0x564[3]; /* 0x564 */ + uint32_t intr2_ctrl_sts; /* 0x570 */ + uint32_t rsv_0x574[7]; /* 0x574 ~ 0x58C */ + uint32_t otp_ctrl; /* 0x590 */ + uint32_t efuse; /* 0x594 */ + uint32_t rsv_0x598[6]; /* 0x598 */ + uint32_t chip_unique_id[8]; /* 0x5B0 */ + uint32_t rsv_0x5e0[8]; /* 0x5E0 ~ 0x5FC */ + uint32_t disgpio_in_pull_down0; /* 0x610 */ + uint32_t disgpio_in_pull_down1; /* 0x614 */ + uint32_t disgpio_in_pull_down2; /* 0x618 */ + uint32_t disgpio_in_pull_down3; /* 0x61C */ + uint32_t rsv_0x620[4]; /* 0x620 ~ 0x62C */ + uint32_t disgpio_in_pull_down4; /* 0x630 */ + uint32_t disgpio_in_pull_down5; /* 0x634 */ + uint32_t disgpio_in_pull_down6; /* 0x638 */ + uint32_t rsv_0x63c[5]; /* 0x63C ~ 0x64C */ + uint32_t sli_driving_strength; /* 0x650 */ + uint32_t rsv_0x654[107]; /* 0x654 ~ 0x7FC */ + uint32_t ca7_ctrl1; /* 0x800 */ + uint32_t ca7_ctrl2; /* 0x804 */ + uint32_t ca7_ctrl3; /* 0x808 */ + uint32_t ca7_ctrl4; /* 0x80C */ + uint32_t rsv_0x810[4]; /* 0x810 ~ 0x81C */ + uint32_t ca7_parity_chk; /* 0x820 */ + uint32_t ca7_parity_clr; /* 0x824 */ + uint32_t rsv_0x828[118]; /* 0x828 ~ 0x9FC */ + uint32_t cm3_ctrl; /* 0xA00 */ + uint32_t cm3_base; /* 0xA04 */ + uint32_t cm3_imem_addr; /* 0xA08 */ + uint32_t cm3_dmem_addr; /* 0xA0C */ + uint32_t rsv_0xa10[12]; /* 0xA10 ~ 0xA3C */ + uint32_t cm3_cache_area; /* 0xA40 */ + uint32_t cm3_cache_invd_ctrl; /* 0xA44 */ + uint32_t cm3_cache_func_ctrl; /* 0xA48 */ + uint32_t rsv_0xa4c[108]; /* 0xA4C ~ 0xBFC */ + uint32_t pci_cfg[3]; /* 0xC00 */ + uint32_t rsv_0xc0c[5]; /* 0xC0C ~ 0xC1C */ + uint32_t pcie_cfg; /* 0xC20 */ + uint32_t mmio_decode; /* 0xC24 */ + uint32_t reloc_ctrl_decode[2]; /* 0xC28 */ + uint32_t rsv_0xc30[4]; /* 0xC30 ~ 0xC3C */ + uint32_t mbox_decode; /* 0xC40 */ + uint32_t shared_sram_decode[2]; /* 0xC44 */ + uint32_t bmc_rev_id; /* 0xC4C */ + uint32_t rsv_0xc50[5]; /* 0xC50 ~ 0xC60 */ + uint32_t bmc_device_id; /* 0xC64 */ + uint32_t rsv_0xc68[102]; /* 0xC68 ~ 0xDFC */ + uint32_t vga_scratch1; /* 0xE00 */ + uint32_t vga_scratch2; /* 0xE04 */ + uint32_t vga_scratch3; /* 0xE08 */ + uint32_t vga_scratch4; /* 0xE0C */ + uint32_t rsv_0xe10[4]; /* 0xE10 ~ 0xE1C */ + uint32_t vga_scratch5; /* 0xE20 */ + uint32_t vga_scratch6; /* 0xE24 */ + uint32_t vga_scratch7; /* 0xE28 */ + uint32_t vga_scratch8; /* 0xE2C */ + uint32_t rsv_0xe30[52]; /* 0xE30 ~ 0xEFC */ + uint32_t wr_prot1; /* 0xF00 */ + uint32_t wr_prot2; /* 0xF04 */ + uint32_t wr_prot3; /* 0xF08 */ + uint32_t wr_prot4; /* 0xF0C */ + uint32_t wr_prot5; /* 0xF10 */ + uint32_t wr_prot6; /* 0xF18 */ + uint32_t wr_prot7; /* 0xF1C */ + uint32_t wr_prot8; /* 0xF20 */ + uint32_t wr_prot9; /* 0xF24 */ + uint32_t rsv_0xf28[2]; /* 0xF28 ~ 0xF2C */ + uint32_t wr_prot10; /* 0xF30 */ + uint32_t wr_prot11; /* 0xF34 */ + uint32_t wr_prot12; /* 0xF38 */ + uint32_t wr_prot13; /* 0xF3C */ + uint32_t wr_prot14; /* 0xF40 */ + uint32_t rsv_0xf44; /* 0xF44 */ + uint32_t wr_prot15; /* 0xF48 */ + uint32_t rsv_0xf4c[5]; /* 0xF4C ~ 0xF5C */ + uint32_t wr_prot16; /* 0xF60 */ +}; +#endif +#endif diff --git a/arch/arm/include/asm/arch-aspeed/sdram_ast2600.h b/arch/arm/include/asm/arch-aspeed/sdram_ast2600.h new file mode 100644 index 0000000000..d2408c0020 --- /dev/null +++ b/arch/arm/include/asm/arch-aspeed/sdram_ast2600.h @@ -0,0 +1,163 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) Aspeed Technology Inc. + */ +#ifndef _ASM_ARCH_SDRAM_AST2600_H +#define _ASM_ARCH_SDRAM_AST2600_H + +/* keys for unlocking HW */ +#define SDRAM_UNLOCK_KEY 0xFC600309 +#define SDRAM_VIDEO_UNLOCK_KEY 0x00440003 + +/* Fixed priority DRAM Requests mask */ +#define REQ_PRI_VGA_HW_CURSOR_R 0 +#define REQ_PRI_VGA_CRT_R 1 +#define REQ_PRI_SOC_DISPLAY_CTRL_R 2 +#define REQ_PRI_PCIE_BUS1_RW 3 +#define REQ_PRI_VIDEO_HIGH_PRI_W 4 +#define REQ_PRI_CPU_RW 5 +#define REQ_PRI_SLI_RW 6 +#define REQ_PRI_PCIE_BUS2_RW 7 +#define REQ_PRI_USB2_0_HUB_EHCI1_DMA_RW 8 +#define REQ_PRI_USB2_0_DEV_EHCI2_DMA_RW 9 +#define REQ_PRI_USB1_1_UHCI_HOST_RW 10 +#define REQ_PRI_AHB_BUS_RW 11 +#define REQ_PRI_CM3_DATA_RW 12 +#define REQ_PRI_CM3_INST_R 13 +#define REQ_PRI_MAC0_DMA_RW 14 +#define REQ_PRI_MAC1_DMA_RW 15 +#define REQ_PRI_SDIO_DMA_RW 16 +#define REQ_PRI_PILOT_ENGINE_RW 17 +#define REQ_PRI_XDMA1_RW 18 +#define REQ_PRI_MCTP1_RW 19 +#define REQ_PRI_VIDEO_FLAG_RW 20 +#define REQ_PRI_VIDEO_LOW_PRI_W 21 +#define REQ_PRI_2D_ENGINE_DATA_RW 22 +#define REQ_PRI_ENC_ENGINE_RW 23 +#define REQ_PRI_MCTP2_RW 24 +#define REQ_PRI_XDMA2_RW 25 +#define REQ_PRI_ECC_RSA_RW 26 + +#define MCR30_RESET_DLL_DELAY_EN BIT(4) +#define MCR30_MODE_REG_SEL_SHIFT 1 +#define MCR30_MODE_REG_SEL_MASK GENMASK(3, 1) +#define MCR30_SET_MODE_REG BIT(0) + +#define MCR30_SET_MR(mr) ((mr << MCR30_MODE_REG_SEL_SHIFT) | MCR30_SET_MODE_REG) + +#define MCR34_SELF_REFRESH_STATUS_MASK GENMASK(30, 28) + +#define MCR34_ODT_DELAY_SHIFT 12 +#define MCR34_ODT_DELAY_MASK GENMASK(15, 12) +#define MCR34_ODT_EXT_SHIFT 10 +#define MCR34_ODT_EXT_MASK GENMASK(11, 10) +#define MCR34_ODT_AUTO_ON BIT(9) +#define MCR34_ODT_EN BIT(8) +#define MCR34_RESETN_DIS BIT(7) +#define MCR34_MREQI_DIS BIT(6) +#define MCR34_MREQ_BYPASS_DIS BIT(5) +#define MCR34_RGAP_CTRL_EN BIT(4) +#define MCR34_CKE_OUT_IN_SELF_REF_DIS BIT(3) +#define MCR34_FOURCE_SELF_REF_EN BIT(2) +#define MCR34_AUTOPWRDN_EN BIT(1) +#define MCR34_CKE_EN BIT(0) + +#define MCR38_RW_MAX_GRANT_CNT_RQ_SHIFT 16 +#define MCR38_RW_MAX_GRANT_CNT_RQ_MASK GENMASK(20, 16) + +/* default request queued limitation mask (0xFFBBFFF4) */ +#define MCR3C_DEFAULT_MASK \ + ~(REQ_PRI_VGA_HW_CURSOR_R | REQ_PRI_VGA_CRT_R | REQ_PRI_PCIE_BUS1_RW | \ + REQ_PRI_XDMA1_RW | REQ_PRI_2D_ENGINE_DATA_RW) + +#define MCR50_RESET_ALL_INTR BIT(31) +#define SDRAM_CONF_ECC_AUTO_SCRUBBING BIT(9) +#define SDRAM_CONF_SCRAMBLE BIT(8) +#define SDRAM_CONF_ECC_EN BIT(7) +#define SDRAM_CONF_DUALX8 BIT(5) +#define SDRAM_CONF_DDR4 BIT(4) +#define SDRAM_CONF_VGA_SIZE_SHIFT 2 +#define SDRAM_CONF_VGA_SIZE_MASK GENMASK(3, 2) +#define SDRAM_CONF_CAP_SHIFT 0 +#define SDRAM_CONF_CAP_MASK GENMASK(1, 0) + +#define SDRAM_CONF_CAP_256M 0 +#define SDRAM_CONF_CAP_512M 1 +#define SDRAM_CONF_CAP_1024M 2 +#define SDRAM_CONF_CAP_2048M 3 +#define SDRAM_CONF_ECC_SETUP (SDRAM_CONF_ECC_AUTO_SCRUBBING | SDRAM_CONF_ECC_EN) + +#define SDRAM_MISC_DDR4_TREFRESH (1 << 3) + +#define SDRAM_PHYCTRL0_PLL_LOCKED BIT(4) +#define SDRAM_PHYCTRL0_NRST BIT(2) +#define SDRAM_PHYCTRL0_INIT BIT(0) + +/* MCR0C */ +#define SDRAM_REFRESH_PERIOD_ZQCS_SHIFT 16 +#define SDRAM_REFRESH_PERIOD_ZQCS_MASK GENMASK(31, 16) +#define SDRAM_REFRESH_PERIOD_SHIFT 8 +#define SDRAM_REFRESH_PERIOD_MASK GENMASK(15, 8) +#define SDRAM_REFRESH_ZQCS_EN BIT(7) +#define SDRAM_RESET_DLL_ZQCL_EN BIT(6) +#define SDRAM_LOW_PRI_REFRESH_EN BIT(5) +#define SDRAM_FORCE_PRECHARGE_EN BIT(4) +#define SDRAM_REFRESH_EN BIT(0) + +#define SDRAM_TEST_LEN_SHIFT 4 +#define SDRAM_TEST_LEN_MASK 0xfffff +#define SDRAM_TEST_START_ADDR_SHIFT 24 +#define SDRAM_TEST_START_ADDR_MASK 0x3f + +#define SDRAM_TEST_EN (1 << 0) +#define SDRAM_TEST_MODE_SHIFT 1 +#define SDRAM_TEST_MODE_MASK (0x3 << SDRAM_TEST_MODE_SHIFT) +#define SDRAM_TEST_MODE_WO (0x0 << SDRAM_TEST_MODE_SHIFT) +#define SDRAM_TEST_MODE_RB (0x1 << SDRAM_TEST_MODE_SHIFT) +#define SDRAM_TEST_MODE_RW (0x2 << SDRAM_TEST_MODE_SHIFT) + +#define SDRAM_TEST_GEN_MODE_SHIFT 3 +#define SDRAM_TEST_GEN_MODE_MASK (7 << SDRAM_TEST_GEN_MODE_SHIFT) +#define SDRAM_TEST_TWO_MODES (1 << 6) +#define SDRAM_TEST_ERRSTOP (1 << 7) +#define SDRAM_TEST_DONE (1 << 12) +#define SDRAM_TEST_FAIL (1 << 13) + +#define SDRAM_AC_TRFC_SHIFT 0 +#define SDRAM_AC_TRFC_MASK 0xff + +#define SDRAM_ECC_RANGE_ADDR_MASK GENMASK(30, 20) +#define SDRAM_ECC_RANGE_ADDR_SHIFT 20 + +#ifndef __ASSEMBLY__ +struct ast2600_sdrammc_regs { + u32 protection_key; /* offset 0x00 */ + u32 config; /* offset 0x04 */ + u32 gm_protection_key; /* offset 0x08 */ + u32 refresh_timing; /* offset 0x0C */ + u32 ac_timing[4]; /* offset 0x10 ~ 0x1C */ + u32 mr01_mode_setting; /* offset 0x20 */ + u32 mr23_mode_setting; /* offset 0x24 */ + u32 mr45_mode_setting; /* offset 0x28 */ + u32 mr6_mode_setting; /* offset 0x2C */ + u32 mode_setting_control; /* offset 0x30 */ + u32 power_ctrl; /* offset 0x34 */ + u32 arbitration_ctrl; /* offset 0x38 */ + u32 req_limit_mask; /* offset 0x3C */ + u32 max_grant_len[4]; /* offset 0x40 ~ 0x4C */ + u32 intr_ctrl; /* offset 0x50 */ + u32 ecc_range_ctrl; /* offset 0x54 */ + u32 first_ecc_err_addr; /* offset 0x58 */ + u32 last_ecc_err_addr; /* offset 0x5C */ + u32 phy_ctrl[4]; /* offset 0x60 ~ 0x6C */ + u32 ecc_test_ctrl; /* offset 0x70 */ + u32 test_addr; /* offset 0x74 */ + u32 test_fail_dq_bit; /* offset 0x78 */ + u32 test_init_val; /* offset 0x7C */ + u32 req_input_ctrl; /* offset 0x80 */ + u32 req_high_pri_ctrl; /* offset 0x84 */ + u32 reserved0[6]; /* offset 0x88 ~ 0x9C */ +}; +#endif /* __ASSEMBLY__ */ + +#endif /* _ASM_ARCH_SDRAM_AST2600_H */ diff --git a/arch/arm/include/asm/arch-aspeed/wdt_ast2600.h b/arch/arm/include/asm/arch-aspeed/wdt_ast2600.h new file mode 100644 index 0000000000..96e8ca07e3 --- /dev/null +++ b/arch/arm/include/asm/arch-aspeed/wdt_ast2600.h @@ -0,0 +1,129 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2020 Aspeed Technology Inc. + */ + +#ifndef _ASM_ARCH_WDT_AST2600_H +#define _ASM_ARCH_WDT_AST2600_H + +#define WDT_BASE 0x1e785000 + +/* + * Special value that needs to be written to counter_restart register to + * (re)start the timer + */ +#define WDT_COUNTER_RESTART_VAL 0x4755 + +/* reset mode */ +#define WDT_RESET_MODE_SOC 0 +#define WDT_RESET_MODE_CHIP 1 +#define WDT_RESET_MODE_CPU 2 + +/* bit-fields of WDT control register */ +#define WDT_CTRL_2ND_BOOT BIT(7) +#define WDT_CTRL_RESET_MODE_MASK GENMASK(6, 5) +#define WDT_CTRL_RESET_MODE_SHIFT 5 +#define WDT_CTRL_CLK1MHZ BIT(4) +#define WDT_CTRL_RESET BIT(1) +#define WDT_CTRL_EN BIT(0) + +/* bit-fields of WDT reset mask1 register */ +#define WDT_RESET_MASK1_RVAS BIT(25) +#define WDT_RESET_MASK1_GPIO1 BIT(24) +#define WDT_RESET_MASK1_XDMA2 BIT(23) +#define WDT_RESET_MASK1_XDMA1 BIT(22) +#define WDT_RESET_MASK1_MCTP2 BIT(21) +#define WDT_RESET_MASK1_MCTP1 BIT(20) +#define WDT_RESET_MASK1_JTAG1 BIT(19) +#define WDT_RESET_MASK1_SD_SDIO1 BIT(18) +#define WDT_RESET_MASK1_MAC2 BIT(17) +#define WDT_RESET_MASK1_MAC1 BIT(16) +#define WDT_RESET_MASK1_GPMCU BIT(15) +#define WDT_RESET_MASK1_DPMCU BIT(14) +#define WDT_RESET_MASK1_DP BIT(13) +#define WDT_RESET_MASK1_HAC BIT(12) +#define WDT_RESET_MASK1_VIDEO BIT(11) +#define WDT_RESET_MASK1_CRT BIT(10) +#define WDT_RESET_MASK1_GCRT BIT(9) +#define WDT_RESET_MASK1_USB11_UHCI BIT(8) +#define WDT_RESET_MASK1_USB_PORTA BIT(7) +#define WDT_RESET_MASK1_USB_PORTB BIT(6) +#define WDT_RESET_MASK1_COPROC BIT(5) +#define WDT_RESET_MASK1_SOC BIT(4) +#define WDT_RESET_MASK1_SLI BIT(3) +#define WDT_RESET_MASK1_AHB BIT(2) +#define WDT_RESET_MASK1_SDRAM BIT(1) +#define WDT_RESET_MASK1_ARM BIT(0) + +/* bit-fields of WDT reset mask2 register */ +#define WDT_RESET_MASK2_ESPI BIT(26) +#define WDT_RESET_MASK2_I3C_BUS8 BIT(25) +#define WDT_RESET_MASK2_I3C_BUS7 BIT(24) +#define WDT_RESET_MASK2_I3C_BUS6 BIT(23) +#define WDT_RESET_MASK2_I3C_BUS5 BIT(22) +#define WDT_RESET_MASK2_I3C_BUS4 BIT(21) +#define WDT_RESET_MASK2_I3C_BUS3 BIT(20) +#define WDT_RESET_MASK2_I3C_BUS2 BIT(19) +#define WDT_RESET_MASK2_I3C_BUS1 BIT(18) +#define WDT_RESET_MASK2_I3C_GLOBAL BIT(17) +#define WDT_RESET_MASK2_I2C BIT(16) +#define WDT_RESET_MASK2_FSI BIT(15) +#define WDT_RESET_MASK2_ADC BIT(14) +#define WDT_RESET_MASK2_PWM BIT(13) +#define WDT_RESET_MASK2_PECI BIT(12) +#define WDT_RESET_MASK2_LPC BIT(11) +#define WDT_RESET_MASK2_MDC_MDIO BIT(10) +#define WDT_RESET_MASK2_GPIO2 BIT(9) +#define WDT_RESET_MASK2_JTAG2 BIT(8) +#define WDT_RESET_MASK2_SD_SDIO2 BIT(7) +#define WDT_RESET_MASK2_MAC4 BIT(6) +#define WDT_RESET_MASK2_MAC3 BIT(5) +#define WDT_RESET_MASK2_SOC BIT(4) +#define WDT_RESET_MASK2_SLI2 BIT(3) +#define WDT_RESET_MASK2_AHB2 BIT(2) +#define WDT_RESET_MASK2_SPI1_SPI2 BIT(1) +#define WDT_RESET_MASK2_ARM BIT(0) + +#define WDT_RESET_MASK1_DEFAULT \ + (WDT_RESET_MASK1_RVAS | WDT_RESET_MASK1_GPIO1 | \ + WDT_RESET_MASK1_JTAG1 | WDT_RESET_MASK1_SD_SDIO1 | \ + WDT_RESET_MASK1_MAC2 | WDT_RESET_MASK1_MAC1 | \ + WDT_RESET_MASK1_HAC | WDT_RESET_MASK1_VIDEO | \ + WDT_RESET_MASK1_CRT | WDT_RESET_MASK1_GCRT | \ + WDT_RESET_MASK1_USB11_UHCI | WDT_RESET_MASK1_USB_PORTA | \ + WDT_RESET_MASK1_USB_PORTB | WDT_RESET_MASK1_COPROC | \ + WDT_RESET_MASK1_SOC | WDT_RESET_MASK1_ARM) + +#define WDT_RESET_MASK2_DEFAULT \ + (WDT_RESET_MASK2_I3C_BUS8 | WDT_RESET_MASK2_I3C_BUS7 | \ + WDT_RESET_MASK2_I3C_BUS6 | WDT_RESET_MASK2_I3C_BUS5 | \ + WDT_RESET_MASK2_I3C_BUS4 | WDT_RESET_MASK2_I3C_BUS3 | \ + WDT_RESET_MASK2_I3C_BUS2 | WDT_RESET_MASK2_I3C_BUS1 | \ + WDT_RESET_MASK2_I3C_GLOBAL | WDT_RESET_MASK2_I2C | \ + WDT_RESET_MASK2_FSI | WDT_RESET_MASK2_ADC | \ + WDT_RESET_MASK2_PWM | WDT_RESET_MASK2_PECI | \ + WDT_RESET_MASK2_LPC | WDT_RESET_MASK2_MDC_MDIO | \ + WDT_RESET_MASK2_GPIO2 | WDT_RESET_MASK2_JTAG2 | \ + WDT_RESET_MASK2_SD_SDIO2 | WDT_RESET_MASK2_MAC4 | \ + WDT_RESET_MASK2_MAC3 | WDT_RESET_MASK2_SOC | \ + WDT_RESET_MASK2_ARM) + +#ifndef __ASSEMBLY__ +struct ast2600_wdt { + u32 counter_status; + u32 counter_reload_val; + u32 counter_restart; + u32 ctrl; + u32 timeout_status; + u32 clr_timeout_status; + u32 reset_width; + u32 reset_mask1; + u32 reset_mask2; + u32 sw_reset_ctrl; + u32 sw_reset_mask1; + u32 sw_reset_mask2; + u32 sw_reset_disable; +}; +#endif /* __ASSEMBLY__ */ + +#endif /* _ASM_ARCH_WDT_AST2600_H */ diff --git a/arch/arm/include/asm/arch-meson/boot.h b/arch/arm/include/asm/arch-meson/boot.h index a90fe55081..c67d12d06c 100644 --- a/arch/arm/include/asm/arch-meson/boot.h +++ b/arch/arm/include/asm/arch-meson/boot.h @@ -7,6 +7,8 @@ #ifndef __MESON_BOOT_H__ #define __MESON_BOOT_H__ +#include <linux/types.h> + /* Boot device */ #define BOOT_DEVICE_RESERVED 0 #define BOOT_DEVICE_EMMC 1 @@ -17,4 +19,6 @@ int meson_get_boot_device(void); +int meson_get_soc_rev(char *buff, size_t buff_len); + #endif /* __MESON_BOOT_H__ */ diff --git a/arch/arm/include/asm/gpio.h b/arch/arm/include/asm/gpio.h index 6ecb876eda..7609367884 100644 --- a/arch/arm/include/asm/gpio.h +++ b/arch/arm/include/asm/gpio.h @@ -3,7 +3,8 @@ !defined(CONFIG_ARCH_BCM6858) && !defined(CONFIG_ARCH_BCM63158) && \ !defined(CONFIG_ARCH_ROCKCHIP) && !defined(CONFIG_ARCH_ASPEED) && \ !defined(CONFIG_ARCH_U8500) && !defined(CONFIG_CORTINA_PLATFORM) && \ - !defined(CONFIG_TARGET_BCMNS3) && !defined(CONFIG_TARGET_TOTAL_COMPUTE) + !defined(CONFIG_TARGET_BCMNS3) && !defined(CONFIG_TARGET_TOTAL_COMPUTE) && \ + !defined(CONFIG_ARCH_QEMU) #include <asm/arch/gpio.h> #endif #include <asm-generic/gpio.h> diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h index ce552944b7..5fe83699f4 100644 --- a/arch/arm/include/asm/system.h +++ b/arch/arm/include/asm/system.h @@ -628,7 +628,18 @@ void mmu_set_region_dcache_behaviour(phys_addr_t start, size_t size, enum dcache_option option); #ifdef CONFIG_SYS_NONCACHED_MEMORY -void noncached_init(void); +/** + * noncached_init() - Initialize non-cached memory region + * + * Initialize non-cached memory area. This memory region will be typically + * located right below the malloc() area and mapped uncached in the MMU. + * + * It is called during the generic post-relocation init sequence. + * + * Return: 0 if OK + */ +int noncached_init(void); + phys_addr_t noncached_alloc(size_t size, size_t align); #endif /* CONFIG_SYS_NONCACHED_MEMORY */ diff --git a/arch/arm/lib/cache.c b/arch/arm/lib/cache.c index ee7d14b2d3..bdde9cdad5 100644 --- a/arch/arm/lib/cache.c +++ b/arch/arm/lib/cache.c @@ -86,7 +86,7 @@ void noncached_set_region(void) #endif } -void noncached_init(void) +int noncached_init(void) { phys_addr_t start, end; size_t size; @@ -103,6 +103,8 @@ void noncached_init(void) noncached_next = start; noncached_set_region(); + + return 0; } phys_addr_t noncached_alloc(size_t size, size_t align) diff --git a/arch/arm/mach-aspeed/Kconfig b/arch/arm/mach-aspeed/Kconfig index 4f021baa06..9a725f195a 100644 --- a/arch/arm/mach-aspeed/Kconfig +++ b/arch/arm/mach-aspeed/Kconfig @@ -9,6 +9,11 @@ config SYS_SOC config SYS_TEXT_BASE default 0x00000000 +choice + prompt "Aspeed SoC select" + depends on ARCH_ASPEED + default ASPEED_AST2500 + config ASPEED_AST2500 bool "Support Aspeed AST2500 SoC" depends on DM_RESET @@ -18,6 +23,21 @@ config ASPEED_AST2500 It is used as Board Management Controller on many server boards, which is enabled by support of LPC and eSPI peripherals. +config ASPEED_AST2600 + bool "Support Aspeed AST2600 SoC" + select CPU_V7A + select CPU_V7_HAS_NONSEC + select SYS_ARCH_TIMER + select SUPPORT_SPL + select ENABLE_ARM_SOC_BOOT0_HOOK + help + The Aspeed AST2600 is a ARM-based SoC with Cortex-A7 CPU. + It is used as Board Management Controller on many server boards, + which is enabled by support of LPC and eSPI peripherals. + +endchoice + source "arch/arm/mach-aspeed/ast2500/Kconfig" +source "arch/arm/mach-aspeed/ast2600/Kconfig" endif diff --git a/arch/arm/mach-aspeed/Makefile b/arch/arm/mach-aspeed/Makefile index 33f65b50b2..42599c125b 100644 --- a/arch/arm/mach-aspeed/Makefile +++ b/arch/arm/mach-aspeed/Makefile @@ -4,3 +4,4 @@ obj-$(CONFIG_ARCH_ASPEED) += ast_wdt.o obj-$(CONFIG_ASPEED_AST2500) += ast2500/ +obj-$(CONFIG_ASPEED_AST2600) += ast2600/ diff --git a/arch/arm/mach-aspeed/ast2600/Kconfig b/arch/arm/mach-aspeed/ast2600/Kconfig new file mode 100644 index 0000000000..f3a53387a1 --- /dev/null +++ b/arch/arm/mach-aspeed/ast2600/Kconfig @@ -0,0 +1,17 @@ +if ASPEED_AST2600 + +config SYS_CPU + default "armv7" + +config TARGET_EVB_AST2600 + bool "EVB-AST2600" + depends on ASPEED_AST2600 + help + EVB-AST2600 is Aspeed evaluation board for AST2600A0 chip. + It has 512M of RAM, 32M of SPI flash, two Ethernet ports, + 4 Serial ports, 4 USB ports, VGA port, PCIe, SD card slot, + 20 pin JTAG, pinouts for 14 I2Cs, 3 SPIs and eSPI, 8 PWMs. + +source "board/aspeed/evb_ast2600/Kconfig" + +endif diff --git a/arch/arm/mach-aspeed/ast2600/Makefile b/arch/arm/mach-aspeed/ast2600/Makefile new file mode 100644 index 0000000000..448d3201af --- /dev/null +++ b/arch/arm/mach-aspeed/ast2600/Makefile @@ -0,0 +1,2 @@ +obj-y += lowlevel_init.o board_common.o +obj-$(CONFIG_SPL_BUILD) += spl.o diff --git a/arch/arm/mach-aspeed/ast2600/board_common.c b/arch/arm/mach-aspeed/ast2600/board_common.c new file mode 100644 index 0000000000..a53e1632f6 --- /dev/null +++ b/arch/arm/mach-aspeed/ast2600/board_common.c @@ -0,0 +1,105 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) Aspeed Technology Inc. + */ +#include <common.h> +#include <dm.h> +#include <ram.h> +#include <timer.h> +#include <asm/io.h> +#include <asm/arch/timer.h> +#include <linux/bitops.h> +#include <linux/err.h> +#include <dm/uclass.h> +#include <asm/arch/scu_ast2600.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* Memory Control registers */ +#define MCR_BASE 0x1e6e0000 +#define MCR_CONF (MCR_BASE + 0x004) + +/* bit fields of MCR_CONF */ +#define MCR_CONF_ECC_EN BIT(7) +#define MCR_CONF_VGA_MEMSZ_MASK GENMASK(3, 2) +#define MCR_CONF_VGA_MEMSZ_SHIFT 2 +#define MCR_CONF_MEMSZ_MASK GENMASK(1, 0) +#define MCR_CONF_MEMSZ_SHIFT 0 + +int dram_init(void) +{ + int ret; + struct udevice *dev; + struct ram_info ram; + + ret = uclass_get_device(UCLASS_RAM, 0, &dev); + if (ret) { + debug("cannot get DRAM driver\n"); + return ret; + } + + ret = ram_get_info(dev, &ram); + if (ret) { + debug("cannot get DRAM information\n"); + return ret; + } + + gd->ram_size = ram.size; + return 0; +} + +int board_init(void) +{ + int i = 0, rc; + struct udevice *dev; + + gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100; + + while (1) { + rc = uclass_get_device(UCLASS_MISC, i++, &dev); + if (rc) + break; + } + + return 0; +} + +void board_add_ram_info(int use_default) +{ + int rc; + uint32_t conf; + uint32_t ecc, act_size, vga_rsvd; + struct udevice *scu_dev; + struct ast2600_scu *scu; + + rc = uclass_get_device_by_driver(UCLASS_CLK, + DM_DRIVER_GET(aspeed_ast2600_scu), &scu_dev); + if (rc) { + debug("%s: cannot find SCU device, rc=%d\n", __func__, rc); + return; + } + + scu = devfdt_get_addr_ptr(scu_dev); + if (IS_ERR_OR_NULL(scu)) { + debug("%s: cannot get SCU address pointer\n", __func__); + return; + } + + conf = readl(MCR_CONF); + + ecc = conf & MCR_CONF_ECC_EN; + act_size = 0x100 << ((conf & MCR_CONF_MEMSZ_MASK) >> MCR_CONF_MEMSZ_SHIFT); + vga_rsvd = 0x8 << ((conf & MCR_CONF_VGA_MEMSZ_MASK) >> MCR_CONF_VGA_MEMSZ_SHIFT); + + /* no VGA reservation if efuse VGA disable bit is set */ + if (readl(scu->efuse) & SCU_EFUSE_DIS_VGA) + vga_rsvd = 0; + + printf(" (capacity:%d MiB, VGA:%d MiB), ECC %s", act_size, + vga_rsvd, (ecc) ? "on" : "off"); +} + +void enable_caches(void) +{ + /* get rid of the warning message */ +} diff --git a/arch/arm/mach-aspeed/ast2600/lowlevel_init.S b/arch/arm/mach-aspeed/ast2600/lowlevel_init.S new file mode 100644 index 0000000000..594963d039 --- /dev/null +++ b/arch/arm/mach-aspeed/ast2600/lowlevel_init.S @@ -0,0 +1,233 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) ASPEED Technology Inc. + */ +#include <config.h> +#include <asm/armv7.h> +#include <linux/linkage.h> +#include <asm/arch/scu_ast2600.h> + +/* SCU register offsets */ +#define SCU_BASE 0x1e6e2000 +#define SCU_PROT_KEY1 (SCU_BASE + 0x000) +#define SCU_PROT_KEY2 (SCU_BASE + 0x010) +#define SCU_SMP_BOOT (SCU_BASE + 0x180) +#define SCU_HWSTRAP1 (SCU_BASE + 0x510) +#define SCU_CA7_PARITY_CHK (SCU_BASE + 0x820) +#define SCU_CA7_PARITY_CLR (SCU_BASE + 0x824) +#define SCU_MMIO_DEC (SCU_BASE + 0xc24) + +/* FMC SPI register offsets */ +#define FMC_BASE 0x1e620000 +#define FMC_CE0_CTRL (FMC_BASE + 0x010) +#define FMC_SW_RST_CTRL (FMC_BASE + 0x050) +#define FMC_WDT1_CTRL_MODE (FMC_BASE + 0x060) +#define FMC_WDT2_CTRL_MODE (FMC_BASE + 0x064) + +/* + * The SMP mailbox provides a space with few instructions in it + * for secondary cores to execute on and wait for the signal of + * SMP core bring up. + * + * SMP mailbox + * +----------------------+ + * | | + * | mailbox insn. for | + * | cpuN polling SMP go | + * | | + * +----------------------+ 0xC + * | mailbox ready signal | + * +----------------------+ 0x8 + * | cpuN GO signal | + * +----------------------+ 0x4 + * | cpuN entrypoint | + * +----------------------+ SMP_MAILBOX_BASE + */ +#define SMP_MBOX_BASE (SCU_SMP_BOOT) +#define SMP_MBOX_FIELD_ENTRY (SMP_MBOX_BASE + 0x0) +#define SMP_MBOX_FIELD_GOSIGN (SMP_MBOX_BASE + 0x4) +#define SMP_MBOX_FIELD_READY (SMP_MBOX_BASE + 0x8) +#define SMP_MBOX_FIELD_POLLINSN (SMP_MBOX_BASE + 0xc) + +.macro scu_unlock + movw r0, #(SCU_UNLOCK_KEY & 0xffff) + movt r0, #(SCU_UNLOCK_KEY >> 16) + + ldr r1, =SCU_PROT_KEY1 + str r0, [r1] + ldr r1, =SCU_PROT_KEY2 + str r0, [r1] +.endm + +.macro timer_init + ldr r1, =SCU_HWSTRAP1 + ldr r1, [r1] + and r1, #0x700 + lsr r1, #0x8 + + /* 1.2GHz */ + cmp r1, #0x0 + movweq r0, #0x8c00 + movteq r0, #0x4786 + + /* 1.6GHz */ + cmp r1, #0x1 + movweq r0, #0x1000 + movteq r0, #0x5f5e + + /* 1.2GHz */ + cmp r1, #0x2 + movweq r0, #0x8c00 + movteq r0, #0x4786 + + /* 1.6GHz */ + cmp r1, #0x3 + movweq r0, #0x1000 + movteq r0, #0x5f5e + + /* 800MHz */ + cmp r1, #0x4 + movwge r0, #0x0800 + movtge r0, #0x2faf + + mcr p15, 0, r0, c14, c0, 0 @; update CNTFRQ +.endm + + +.globl lowlevel_init + +lowlevel_init: +#if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD) + mov pc, lr +#else + /* setup ARM arch timer frequency */ + timer_init + + /* reset SMP mailbox as early as possible */ + mov r0, #0x0 + ldr r1, =SMP_MBOX_FIELD_READY + str r0, [r1] + + /* set ACTLR.SMP to enable cache use */ + mrc p15, 0, r0, c1, c0, 1 + orr r0, #0x40 + mcr p15, 0, r0, c1, c0, 1 + + /* + * we treat cpu0 as the primary core and + * put secondary core (cpuN) to sleep + */ + mrc p15, 0, r0, c0, c0, 5 @; Read CPU ID register + ands r0, #0xff @; Mask off, leaving the CPU ID field + movw r2, #0xab00 + movt r2, #0xabba + orr r2, r0 + + beq do_primary_core_setup + + /* hold cpuN until mailbox is ready */ +poll_mailbox_ready: + wfe + ldr r0, =SMP_MBOX_FIELD_READY + ldr r0, [r0] + movw r1, #0xcafe + movt r1, #0xbabe + cmp r1, r0 + bne poll_mailbox_ready + + /* parameters for relocated SMP go polling insn. */ + ldr r0, =SMP_MBOX_FIELD_GOSIGN + ldr r1, =SMP_MBOX_FIELD_ENTRY + + /* no return */ + ldr pc, =SMP_MBOX_FIELD_POLLINSN + +do_primary_core_setup: + scu_unlock + + /* MMIO decode setting */ + ldr r0, =SCU_MMIO_DEC + mov r1, #0x2000 + str r1, [r0] + + /* enable CA7 cache parity check */ + mov r0, #0 + ldr r1, =SCU_CA7_PARITY_CLR + str r0, [r1] + + mov r0, #0x1 + ldr r1, =SCU_CA7_PARITY_CHK + str r0, [r1] + + /* do not fill FMC50[1] if boot from eMMC */ + ldr r0, =SCU_HWSTRAP1 + ldr r1, [r0] + ands r1, #0x04 + bne skip_fill_wip_bit + + /* fill FMC50[1] for waiting WIP idle */ + mov r0, #0x02 + ldr r1, =FMC_SW_RST_CTRL + str r0, [r1] + +skip_fill_wip_bit: + /* disable FMC WDT for SPI address mode detection */ + mov r0, #0 + ldr r1, =FMC_WDT1_CTRL_MODE + str r0, [r1] + + /* relocate mailbox insn. for cpuN polling SMP go signal */ + adrl r0, mailbox_insn + adrl r1, mailbox_insn_end + + ldr r2, =#SMP_MBOX_FIELD_POLLINSN + +relocate_mailbox_insn: + ldr r3, [r0], #0x4 + str r3, [r2], #0x4 + cmp r0, r1 + bne relocate_mailbox_insn + + /* reset SMP go sign */ + mov r0, #0 + ldr r1, =SMP_MBOX_FIELD_GOSIGN + str r0, [r1] + + /* notify cpuN mailbox is ready */ + movw r0, #0xCAFE + movt r0, #0xBABE + ldr r1, =SMP_MBOX_FIELD_READY + str r0, [r1] + sev + + /* back to arch calling code */ + mov pc, lr + +/* + * insn. inside mailbox to poll SMP go signal. + * + * Note that as this code will be relocated, any + * pc-relative assembly should NOT be used. + */ +mailbox_insn: + /* + * r0 ~ r3 are parameters: + * r0 = SMP_MBOX_FIELD_GOSIGN + * r1 = SMP_MBOX_FIELD_ENTRY + * r2 = per-cpu go sign value + * r3 = no used now + */ +poll_mailbox_smp_go: + wfe + ldr r4, [r0] + cmp r2, r4 + bne poll_mailbox_smp_go + + /* SMP GO signal confirmed, release cpuN */ + ldr pc, [r1] + +mailbox_insn_end: + /* should never reach */ + b . + +#endif diff --git a/arch/arm/mach-aspeed/ast2600/spl.c b/arch/arm/mach-aspeed/ast2600/spl.c new file mode 100644 index 0000000000..9201d4a4d4 --- /dev/null +++ b/arch/arm/mach-aspeed/ast2600/spl.c @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) Aspeed Technology Inc. + */ +#include <common.h> +#include <debug_uart.h> +#include <dm.h> +#include <spl.h> +#include <init.h> +#include <asm/io.h> +#include <asm/arch/scu_ast2600.h> + +DECLARE_GLOBAL_DATA_PTR; + +void board_init_f(ulong dummy) +{ + spl_early_init(); + preloader_console_init(); + timer_init(); + dram_init(); +} + +u32 spl_boot_device(void) +{ + return BOOT_DEVICE_RAM; +} + +struct image_header *spl_get_load_buffer(ssize_t offset, size_t size) +{ + /* + * When boot from SPI, AST2600 already remap 0x00000000 ~ 0x0fffffff + * to BMC SPI memory space 0x20000000 ~ 0x2fffffff. The next stage BL + * has been located in SPI for XIP. In this case, the load buffer for + * SPL image loading will be set to the remapped address of the next + * BL instead of the DRAM space CONFIG_SYS_LOAD_ADDR + */ + return (struct image_header *)(CONFIG_SYS_TEXT_BASE); +} + +#ifdef CONFIG_SPL_OS_BOOT +int spl_start_uboot(void) +{ + /* boot linux */ + return 0; +} +#endif + +#ifdef CONFIG_SPL_LOAD_FIT +int board_fit_config_name_match(const char *name) +{ + /* just empty function now - can't decide what to choose */ + debug("%s: %s\n", __func__, name); + return 0; +} +#endif diff --git a/arch/arm/mach-meson/board-info.c b/arch/arm/mach-meson/board-info.c index e61d1adb10..90e7dfaa3c 100644 --- a/arch/arm/mach-meson/board-info.c +++ b/arch/arm/mach-meson/board-info.c @@ -131,7 +131,7 @@ static void print_board_model(void) printf("Model: %s\n", model ? model : "Unknown"); } -int show_board_info(void) +static unsigned int get_socinfo(void) { struct regmap *regmap; int nodeoffset, ret; @@ -163,8 +163,20 @@ int show_board_info(void) return 0; } + return socinfo; +} + +int show_board_info(void) +{ + unsigned int socinfo; + /* print board information */ print_board_model(); + + socinfo = get_socinfo(); + if (!socinfo) + return 0; + printf("SoC: Amlogic Meson %s (%s) Revision %x:%x (%x:%x)\n", socinfo_to_soc_id(socinfo), socinfo_to_package_id(socinfo), @@ -175,3 +187,15 @@ int show_board_info(void) return 0; } + +int meson_get_soc_rev(char *buff, size_t buff_len) +{ + unsigned int socinfo; + + socinfo = get_socinfo(); + if (!socinfo) + return -1; + + /* Write SoC info */ + return snprintf(buff, buff_len, "%x", socinfo_to_minor(socinfo)); +} diff --git a/arch/arm/mach-socfpga/Kconfig b/arch/arm/mach-socfpga/Kconfig index 26f2cf8e47..4d4ff16337 100644 --- a/arch/arm/mach-socfpga/Kconfig +++ b/arch/arm/mach-socfpga/Kconfig @@ -33,7 +33,7 @@ config TARGET_SOCFPGA_AGILEX bool select ARMV8_MULTIENTRY select ARMV8_SET_SMPEN - select ARMV8_SPIN_TABLE + select BINMAN if SPL_ATF select CLK select FPGA_INTEL_SDM_MAILBOX select NCORE_CACHE @@ -79,7 +79,7 @@ config TARGET_SOCFPGA_STRATIX10 bool select ARMV8_MULTIENTRY select ARMV8_SET_SMPEN - select ARMV8_SPIN_TABLE + select BINMAN if SPL_ATF select FPGA_INTEL_SDM_MAILBOX choice diff --git a/arch/arm/mach-socfpga/Makefile b/arch/arm/mach-socfpga/Makefile index 418f543b20..82b681d870 100644 --- a/arch/arm/mach-socfpga/Makefile +++ b/arch/arm/mach-socfpga/Makefile @@ -29,6 +29,7 @@ endif ifdef CONFIG_TARGET_SOCFPGA_STRATIX10 obj-y += clock_manager_s10.o +obj-y += lowlevel_init_soc64.o obj-y += mailbox_s10.o obj-y += misc_s10.o obj-y += mmu-arm64_s10.o @@ -41,6 +42,7 @@ endif ifdef CONFIG_TARGET_SOCFPGA_AGILEX obj-y += clock_manager_agilex.o +obj-y += lowlevel_init_soc64.o obj-y += mailbox_s10.o obj-y += misc_s10.o obj-y += mmu-arm64_s10.o @@ -70,6 +72,9 @@ ifdef CONFIG_TARGET_SOCFPGA_AGILEX obj-y += firewall.o obj-y += spl_agilex.o endif +else +obj-$(CONFIG_SPL_ATF) += secure_reg_helper.o +obj-$(CONFIG_SPL_ATF) += smc_api.o endif ifdef CONFIG_TARGET_SOCFPGA_GEN5 diff --git a/arch/arm/mach-socfpga/board.c b/arch/arm/mach-socfpga/board.c index 340abf9305..7993c27646 100644 --- a/arch/arm/mach-socfpga/board.c +++ b/arch/arm/mach-socfpga/board.c @@ -13,7 +13,7 @@ #include <asm/arch/clock_manager.h> #include <asm/arch/misc.h> #include <asm/io.h> - +#include <log.h> #include <usb.h> #include <usb/dwc2_udc.h> @@ -87,3 +87,13 @@ int g_dnl_board_usb_cable_connected(void) return 1; } #endif + +#ifdef CONFIG_SPL_BUILD +__weak int board_fit_config_name_match(const char *name) +{ + /* Just empty function now - can't decide what to choose */ + debug("%s: %s\n", __func__, name); + + return 0; +} +#endif diff --git a/arch/arm/mach-socfpga/include/mach/secure_reg_helper.h b/arch/arm/mach-socfpga/include/mach/secure_reg_helper.h new file mode 100644 index 0000000000..d5a11122c7 --- /dev/null +++ b/arch/arm/mach-socfpga/include/mach/secure_reg_helper.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0 + * + * Copyright (C) 2020 Intel Corporation <www.intel.com> + * + */ + +#ifndef _SECURE_REG_HELPER_H_ +#define _SECURE_REG_HELPER_H_ + +#define SOCFPGA_SECURE_REG_SYSMGR_SOC64_SDMMC 1 +#define SOCFPGA_SECURE_REG_SYSMGR_SOC64_EMAC0 2 +#define SOCFPGA_SECURE_REG_SYSMGR_SOC64_EMAC1 3 +#define SOCFPGA_SECURE_REG_SYSMGR_SOC64_EMAC2 4 + +int socfpga_secure_reg_read32(u32 id, u32 *val); +int socfpga_secure_reg_write32(u32 id, u32 val); +int socfpga_secure_reg_update32(u32 id, u32 mask, u32 val); + +#endif /* _SECURE_REG_HELPER_H_ */ diff --git a/arch/arm/mach-socfpga/include/mach/smc_api.h b/arch/arm/mach-socfpga/include/mach/smc_api.h new file mode 100644 index 0000000000..bbefdd8dd9 --- /dev/null +++ b/arch/arm/mach-socfpga/include/mach/smc_api.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2020 Intel Corporation + */ + +#ifndef _SMC_API_H_ +#define _SMC_API_H_ + +int invoke_smc(u32 func_id, u64 *args, int arg_len, u64 *ret_arg, int ret_len); +int smc_send_mailbox(u32 cmd, u32 len, u32 *arg, u8 urgent, u32 *resp_buf_len, + u32 *resp_buf); + +#endif /* _SMC_API_H_ */ diff --git a/arch/arm/mach-socfpga/lowlevel_init_soc64.S b/arch/arm/mach-socfpga/lowlevel_init_soc64.S new file mode 100644 index 0000000000..612ea8a037 --- /dev/null +++ b/arch/arm/mach-socfpga/lowlevel_init_soc64.S @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2020 Intel Corporation. All rights reserved + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <asm-offsets.h> +#include <config.h> +#include <linux/linkage.h> +#include <asm/macro.h> + +ENTRY(lowlevel_init) + mov x29, lr /* Save LR */ + +#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3) +#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_ATF) +wait_for_atf: + ldr x4, =CPU_RELEASE_ADDR + ldr x5, [x4] + cbz x5, slave_wait_atf + br x5 +slave_wait_atf: + branch_if_slave x0, wait_for_atf +#else + branch_if_slave x0, 1f +#endif + ldr x0, =GICD_BASE + bl gic_init_secure +1: +#if defined(CONFIG_GICV3) + ldr x0, =GICR_BASE + bl gic_init_secure_percpu +#elif defined(CONFIG_GICV2) + ldr x0, =GICD_BASE + ldr x1, =GICC_BASE + bl gic_init_secure_percpu +#endif +#endif + +#ifdef CONFIG_ARMV8_MULTIENTRY + branch_if_master x0, x1, 2f + + /* + * Slave should wait for master clearing spin table. + * This sync prevent slaves observing incorrect + * value of spin table and jumping to wrong place. + */ +#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3) +#ifdef CONFIG_GICV2 + ldr x0, =GICC_BASE +#endif + bl gic_wait_for_interrupt +#endif + + /* + * All slaves will enter EL2 and optionally EL1. + */ + adr x4, lowlevel_in_el2 + ldr x5, =ES_TO_AARCH64 + bl armv8_switch_to_el2 + +lowlevel_in_el2: +#ifdef CONFIG_ARMV8_SWITCH_TO_EL1 + adr x4, lowlevel_in_el1 + ldr x5, =ES_TO_AARCH64 + bl armv8_switch_to_el1 + +lowlevel_in_el1: +#endif + +#endif /* CONFIG_ARMV8_MULTIENTRY */ + +2: + mov lr, x29 /* Restore LR */ + ret +ENDPROC(lowlevel_init) diff --git a/arch/arm/mach-socfpga/mailbox_s10.c b/arch/arm/mach-socfpga/mailbox_s10.c index 18d44924e6..429444f069 100644 --- a/arch/arm/mach-socfpga/mailbox_s10.c +++ b/arch/arm/mach-socfpga/mailbox_s10.c @@ -11,6 +11,7 @@ #include <asm/arch/mailbox_s10.h> #include <asm/arch/system_manager.h> #include <asm/secure.h> +#include <asm/system.h> DECLARE_GLOBAL_DATA_PTR; @@ -398,6 +399,9 @@ error: int mbox_reset_cold(void) { +#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_ATF) + psci_system_reset(); +#else int ret; ret = mbox_send_cmd(MBOX_ID_UBOOT, MBOX_REBOOT_HPS, MBOX_CMD_DIRECT, @@ -406,6 +410,7 @@ int mbox_reset_cold(void) /* mailbox sent failure, wait for watchdog to kick in */ hang(); } +#endif return 0; } diff --git a/arch/arm/mach-socfpga/reset_manager_s10.c b/arch/arm/mach-socfpga/reset_manager_s10.c index 3746e6a60c..af8f2c0873 100644 --- a/arch/arm/mach-socfpga/reset_manager_s10.c +++ b/arch/arm/mach-socfpga/reset_manager_s10.c @@ -5,11 +5,14 @@ */ #include <common.h> +#include <hang.h> #include <asm/io.h> #include <asm/arch/reset_manager.h> +#include <asm/arch/smc_api.h> #include <asm/arch/system_manager.h> #include <dt-bindings/reset/altr,rst-mgr-s10.h> #include <linux/iopoll.h> +#include <linux/intel-smc.h> DECLARE_GLOBAL_DATA_PTR; @@ -55,6 +58,15 @@ void socfpga_per_reset_all(void) void socfpga_bridges_reset(int enable) { +#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_ATF) + u64 arg = enable; + + int ret = invoke_smc(INTEL_SIP_SMC_HPS_SET_BRIDGES, &arg, 1, NULL, 0); + if (ret) { + printf("SMC call failed with error %d in %s.\n", ret, __func__); + return; + } +#else u32 reg; if (enable) { @@ -101,6 +113,7 @@ void socfpga_bridges_reset(int enable) /* Disable NOC timeout */ writel(0, socfpga_get_sysmgr_addr() + SYSMGR_SOC64_NOC_TIMEOUT); } +#endif } /* diff --git a/arch/arm/mach-socfpga/secure_reg_helper.c b/arch/arm/mach-socfpga/secure_reg_helper.c new file mode 100644 index 0000000000..0d4f45f33d --- /dev/null +++ b/arch/arm/mach-socfpga/secure_reg_helper.c @@ -0,0 +1,89 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2020 Intel Corporation <www.intel.com> + * + */ + +#include <common.h> +#include <hang.h> +#include <asm/io.h> +#include <asm/system.h> +#include <asm/arch/misc.h> +#include <asm/arch/secure_reg_helper.h> +#include <asm/arch/smc_api.h> +#include <asm/arch/system_manager.h> +#include <linux/errno.h> +#include <linux/intel-smc.h> + +int socfpga_secure_convert_reg_id_to_addr(u32 id, phys_addr_t *reg_addr) +{ + switch (id) { + case SOCFPGA_SECURE_REG_SYSMGR_SOC64_SDMMC: + *reg_addr = socfpga_get_sysmgr_addr() + SYSMGR_SOC64_SDMMC; + break; + case SOCFPGA_SECURE_REG_SYSMGR_SOC64_EMAC0: + *reg_addr = socfpga_get_sysmgr_addr() + SYSMGR_SOC64_EMAC0; + break; + case SOCFPGA_SECURE_REG_SYSMGR_SOC64_EMAC1: + *reg_addr = socfpga_get_sysmgr_addr() + SYSMGR_SOC64_EMAC1; + break; + case SOCFPGA_SECURE_REG_SYSMGR_SOC64_EMAC2: + *reg_addr = socfpga_get_sysmgr_addr() + SYSMGR_SOC64_EMAC2; + break; + default: + return -EADDRNOTAVAIL; + } + return 0; +} + +int socfpga_secure_reg_read32(u32 id, u32 *val) +{ + int ret; + u64 ret_arg; + u64 args[1]; + + phys_addr_t reg_addr; + ret = socfpga_secure_convert_reg_id_to_addr(id, ®_addr); + if (ret) + return ret; + + args[0] = (u64)reg_addr; + ret = invoke_smc(INTEL_SIP_SMC_REG_READ, args, 1, &ret_arg, 1); + if (ret) + return ret; + + *val = (u32)ret_arg; + + return 0; +} + +int socfpga_secure_reg_write32(u32 id, u32 val) +{ + int ret; + u64 args[2]; + + phys_addr_t reg_addr; + ret = socfpga_secure_convert_reg_id_to_addr(id, ®_addr); + if (ret) + return ret; + + args[0] = (u64)reg_addr; + args[1] = val; + return invoke_smc(INTEL_SIP_SMC_REG_WRITE, args, 2, NULL, 0); +} + +int socfpga_secure_reg_update32(u32 id, u32 mask, u32 val) +{ + int ret; + u64 args[3]; + + phys_addr_t reg_addr; + ret = socfpga_secure_convert_reg_id_to_addr(id, ®_addr); + if (ret) + return ret; + + args[0] = (u64)reg_addr; + args[1] = mask; + args[2] = val; + return invoke_smc(INTEL_SIP_SMC_REG_UPDATE, args, 3, NULL, 0); +} diff --git a/arch/arm/mach-socfpga/smc_api.c b/arch/arm/mach-socfpga/smc_api.c new file mode 100644 index 0000000000..085daba162 --- /dev/null +++ b/arch/arm/mach-socfpga/smc_api.c @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2020 Intel Corporation <www.intel.com> + * + */ + +#include <common.h> +#include <asm/ptrace.h> +#include <asm/system.h> +#include <linux/intel-smc.h> + +int invoke_smc(u32 func_id, u64 *args, int arg_len, u64 *ret_arg, int ret_len) +{ + struct pt_regs regs; + + memset(®s, 0, sizeof(regs)); + regs.regs[0] = func_id; + + if (args) + memcpy(®s.regs[1], args, arg_len * sizeof(*args)); + + smc_call(®s); + + if (ret_arg) + memcpy(ret_arg, ®s.regs[1], ret_len * sizeof(*ret_arg)); + + return regs.regs[0]; +} + +int smc_send_mailbox(u32 cmd, u32 len, u32 *arg, u8 urgent, u32 *resp_buf_len, + u32 *resp_buf) +{ + int ret; + u64 args[6]; + u64 resp[3]; + + args[0] = cmd; + args[1] = (u64)arg; + args[2] = len; + args[3] = urgent; + args[4] = (u64)resp_buf; + if (resp_buf_len) + args[5] = *resp_buf_len; + else + args[5] = 0; + + ret = invoke_smc(INTEL_SIP_SMC_MBOX_SEND_CMD, args, ARRAY_SIZE(args), + resp, ARRAY_SIZE(resp)); + + if (ret == INTEL_SIP_SMC_STATUS_OK && resp_buf && resp_buf_len) { + if (!resp[0]) + *resp_buf_len = resp[1]; + } + + return (int)resp[0]; +} diff --git a/arch/arm/mach-socfpga/wrap_pll_config_s10.c b/arch/arm/mach-socfpga/wrap_pll_config_s10.c index 3da85791a1..049c5711a8 100644 --- a/arch/arm/mach-socfpga/wrap_pll_config_s10.c +++ b/arch/arm/mach-socfpga/wrap_pll_config_s10.c @@ -12,6 +12,7 @@ const struct cm_config * const cm_get_default_config(void) { +#ifdef CONFIG_SPL_BUILD struct cm_config *cm_handoff_cfg = (struct cm_config *) (S10_HANDOFF_CLOCK + S10_HANDOFF_OFFSET_DATA); u32 *conversion = (u32 *)cm_handoff_cfg; @@ -26,7 +27,7 @@ const struct cm_config * const cm_get_default_config(void) } else if (handoff_clk == S10_HANDOFF_MAGIC_CLOCK) { return cm_handoff_cfg; } - +#endif return NULL; } diff --git a/arch/arm/mach-stm32mp/boot_params.c b/arch/arm/mach-stm32mp/boot_params.c index 37ee9e1612..13322e34d6 100644 --- a/arch/arm/mach-stm32mp/boot_params.c +++ b/arch/arm/mach-stm32mp/boot_params.c @@ -3,6 +3,8 @@ * Copyright (C) 2019, STMicroelectronics - All Rights Reserved */ +#define LOG_CATEGORY LOGC_ARCH + #include <common.h> #include <log.h> #include <asm/sections.h> @@ -32,15 +34,15 @@ void save_boot_params(unsigned long r0, unsigned long r1, unsigned long r2, */ void *board_fdt_blob_setup(void) { - debug("%s: nt_fw_dtb=%lx\n", __func__, nt_fw_dtb); + log_debug("%s: nt_fw_dtb=%lx\n", __func__, nt_fw_dtb); /* use external device tree only if address is valid */ if (nt_fw_dtb >= STM32_DDR_BASE) { if (fdt_magic(nt_fw_dtb) == FDT_MAGIC) return (void *)nt_fw_dtb; - debug("%s: DTB not found.\n", __func__); + log_debug("%s: DTB not found.\n", __func__); } - debug("%s: fall back to builtin DTB, %p\n", __func__, &_end); + log_debug("%s: fall back to builtin DTB, %p\n", __func__, &_end); return (void *)&_end; } diff --git a/arch/arm/mach-stm32mp/bsec.c b/arch/arm/mach-stm32mp/bsec.c index 84e0bddcd4..88c7aec8b4 100644 --- a/arch/arm/mach-stm32mp/bsec.c +++ b/arch/arm/mach-stm32mp/bsec.c @@ -3,6 +3,8 @@ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved */ +#define LOG_CATEGORY UCLASS_MISC + #include <common.h> #include <dm.h> #include <log.h> @@ -10,6 +12,7 @@ #include <asm/io.h> #include <asm/arch/bsec.h> #include <asm/arch/stm32mp1_smc.h> +#include <dm/device_compat.h> #include <linux/arm-smccc.h> #include <linux/iopoll.h> @@ -160,7 +163,7 @@ static int bsec_power_safmem(u32 base, bool power) * @otp: otp number (0 - BSEC_OTP_MAX_VALUE) * Return: 0 if no error */ -static int bsec_shadow_register(u32 base, u32 otp) +static int bsec_shadow_register(struct udevice *dev, u32 base, u32 otp) { u32 val; int ret; @@ -168,7 +171,8 @@ static int bsec_shadow_register(u32 base, u32 otp) /* check if shadowing of otp is locked */ if (bsec_read_SR_lock(base, otp)) - pr_debug("bsec : OTP %d is locked and refreshed with 0\n", otp); + dev_dbg(dev, "OTP %d is locked and refreshed with 0\n", + otp); /* check if safemem is power up */ val = readl(base + BSEC_OTP_STATUS_OFF); @@ -203,7 +207,7 @@ static int bsec_shadow_register(u32 base, u32 otp) * @otp: otp number (0 - BSEC_OTP_MAX_VALUE) * Return: 0 if no error */ -static int bsec_read_shadow(u32 base, u32 *val, u32 otp) +static int bsec_read_shadow(struct udevice *dev, u32 base, u32 *val, u32 otp) { *val = readl(base + BSEC_OTP_DATA_OFF + otp * sizeof(u32)); @@ -217,11 +221,11 @@ static int bsec_read_shadow(u32 base, u32 *val, u32 otp) * @otp: otp number (0 - BSEC_OTP_MAX_VALUE) * Return: 0 if no error */ -static int bsec_write_shadow(u32 base, u32 val, u32 otp) +static int bsec_write_shadow(struct udevice *dev, u32 base, u32 val, u32 otp) { /* check if programming of otp is locked */ if (bsec_read_SW_lock(base, otp)) - pr_debug("bsec : OTP %d is lock, write will be ignore\n", otp); + dev_dbg(dev, "OTP %d is lock, write will be ignore\n", otp); writel(val, base + BSEC_OTP_DATA_OFF + otp * sizeof(u32)); @@ -236,16 +240,16 @@ static int bsec_write_shadow(u32 base, u32 val, u32 otp) * after the function the otp data is not refreshed in shadow * Return: 0 if no error */ -static int bsec_program_otp(long base, u32 val, u32 otp) +static int bsec_program_otp(struct udevice *dev, long base, u32 val, u32 otp) { u32 ret; bool power_up = false; if (bsec_read_SP_lock(base, otp)) - pr_debug("bsec : OTP %d locked, prog will be ignore\n", otp); + dev_dbg(dev, "OTP %d locked, prog will be ignore\n", otp); if (readl(base + BSEC_OTP_LOCK_OFF) & (1 << BSEC_LOCK_PROGRAM)) - pr_debug("bsec : Global lock, prog will be ignore\n"); + dev_dbg(dev, "Global lock, prog will be ignore\n"); /* check if safemem is power up */ if (!(readl(base + BSEC_OTP_STATUS_OFF) & BSEC_MODE_PWR_MASK)) { @@ -298,21 +302,21 @@ static int stm32mp_bsec_read_otp(struct udevice *dev, u32 *val, u32 otp) plat = dev_get_plat(dev); /* read current shadow value */ - ret = bsec_read_shadow(plat->base, &tmp_data, otp); + ret = bsec_read_shadow(dev, plat->base, &tmp_data, otp); if (ret) return ret; /* copy otp in shadow */ - ret = bsec_shadow_register(plat->base, otp); + ret = bsec_shadow_register(dev, plat->base, otp); if (ret) return ret; - ret = bsec_read_shadow(plat->base, val, otp); + ret = bsec_read_shadow(dev, plat->base, val, otp); if (ret) return ret; /* restore shadow value */ - ret = bsec_write_shadow(plat->base, tmp_data, otp); + ret = bsec_write_shadow(dev, plat->base, tmp_data, otp); return ret; } @@ -328,7 +332,7 @@ static int stm32mp_bsec_read_shadow(struct udevice *dev, u32 *val, u32 otp) plat = dev_get_plat(dev); - return bsec_read_shadow(plat->base, val, otp); + return bsec_read_shadow(dev, plat->base, val, otp); } static int stm32mp_bsec_read_lock(struct udevice *dev, u32 *val, u32 otp) @@ -352,7 +356,7 @@ static int stm32mp_bsec_write_otp(struct udevice *dev, u32 val, u32 otp) plat = dev_get_plat(dev); - return bsec_program_otp(plat->base, val, otp); + return bsec_program_otp(dev, plat->base, val, otp); } @@ -367,7 +371,7 @@ static int stm32mp_bsec_write_shadow(struct udevice *dev, u32 val, u32 otp) plat = dev_get_plat(dev); - return bsec_write_shadow(plat->base, val, otp); + return bsec_write_shadow(dev, plat->base, val, otp); } static int stm32mp_bsec_write_lock(struct udevice *dev, u32 val, u32 otp) @@ -497,7 +501,7 @@ static int stm32mp_bsec_probe(struct udevice *dev) for (otp = 57; otp <= BSEC_OTP_MAX_VALUE; otp++) if (!bsec_read_SR_lock(plat->base, otp)) - bsec_shadow_register(plat->base, otp); + bsec_shadow_register(dev, plat->base, otp); } return 0; @@ -527,7 +531,7 @@ bool bsec_dbgswenable(void) ret = uclass_get_device_by_driver(UCLASS_MISC, DM_DRIVER_GET(stm32mp_bsec), &dev); if (ret || !dev) { - pr_debug("bsec driver not available\n"); + log_debug("bsec driver not available\n"); return false; } diff --git a/arch/arm/mach-stm32mp/cmd_stm32key.c b/arch/arm/mach-stm32mp/cmd_stm32key.c index 544bab3848..42fdc11238 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32key.c +++ b/arch/arm/mach-stm32mp/cmd_stm32key.c @@ -6,6 +6,7 @@ #include <common.h> #include <command.h> #include <console.h> +#include <log.h> #include <misc.h> #include <dm/device.h> #include <dm/uclass.h> @@ -34,7 +35,7 @@ static void fuse_hash_value(u32 addr, bool print) DM_DRIVER_GET(stm32mp_bsec), &dev); if (ret) { - pr_err("Can't find stm32mp_bsec driver\n"); + log_err("Can't find stm32mp_bsec driver\n"); return; } diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c index 49dd25b28f..34a6be66c3 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c @@ -56,7 +56,7 @@ static int do_stm32prog(struct cmd_tbl *cmdtp, int flag, int argc, link = LINK_SERIAL; if (link == LINK_UNDEFINED) { - pr_err("not supported link=%s\n", argv[1]); + log_err("not supported link=%s\n", argv[1]); return CMD_RET_USAGE; } @@ -90,7 +90,7 @@ static int do_stm32prog(struct cmd_tbl *cmdtp, int flag, int argc, data = (struct stm32prog_data *)malloc(sizeof(*data)); if (!data) { - pr_err("Alloc failed."); + log_err("Alloc failed."); return CMD_RET_FAILURE; } stm32prog_data = data; diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c index fc9a2af545..a8e7158c1f 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c @@ -97,28 +97,28 @@ u8 stm32prog_header_check(struct raw_header_s *raw_header, header->image_length = 0x0; if (!raw_header || !header) { - pr_debug("%s:no header data\n", __func__); + log_debug("%s:no header data\n", __func__); return -1; } if (raw_header->magic_number != (('S' << 0) | ('T' << 8) | ('M' << 16) | (0x32 << 24))) { - pr_debug("%s:invalid magic number : 0x%x\n", - __func__, raw_header->magic_number); + log_debug("%s:invalid magic number : 0x%x\n", + __func__, raw_header->magic_number); return -2; } /* only header v1.0 supported */ if (raw_header->header_version != 0x00010000) { - pr_debug("%s:invalid header version : 0x%x\n", - __func__, raw_header->header_version); + log_debug("%s:invalid header version : 0x%x\n", + __func__, raw_header->header_version); return -3; } if (raw_header->reserved1 != 0x0 || raw_header->reserved2) { - pr_debug("%s:invalid reserved field\n", __func__); + log_debug("%s:invalid reserved field\n", __func__); return -4; } for (i = 0; i < (sizeof(raw_header->padding) / 4); i++) { if (raw_header->padding[i] != 0) { - pr_debug("%s:invalid padding field\n", __func__); + log_debug("%s:invalid padding field\n", __func__); return -5; } } @@ -376,7 +376,7 @@ static int parse_flash_layout(struct stm32prog_data *data, last = start + size; *last = 0x0; /* force null terminated string */ - pr_debug("flash layout =\n%s\n", start); + log_debug("flash layout =\n%s\n", start); /* calculate expected number of partitions */ part_list_size = 1; @@ -584,11 +584,11 @@ static int init_device(struct stm32prog_data *data, last_addr = (u64)(block_dev->lba - GPT_HEADER_SZ - 1) * block_dev->blksz; } - pr_debug("MMC %d: lba=%ld blksz=%ld\n", dev->dev_id, - block_dev->lba, block_dev->blksz); - pr_debug(" available address = 0x%llx..0x%llx\n", - first_addr, last_addr); - pr_debug(" full_update = %d\n", dev->full_update); + log_debug("MMC %d: lba=%ld blksz=%ld\n", dev->dev_id, + block_dev->lba, block_dev->blksz); + log_debug(" available address = 0x%llx..0x%llx\n", + first_addr, last_addr); + log_debug(" full_update = %d\n", dev->full_update); break; case STM32PROG_NOR: case STM32PROG_NAND: @@ -598,7 +598,7 @@ static int init_device(struct stm32prog_data *data, return -ENODEV; } get_mtd_by_target(mtd_id, dev->target, dev->dev_id); - pr_debug("%s\n", mtd_id); + log_debug("%s\n", mtd_id); mtdparts_init(); mtd = get_mtd_device_nm(mtd_id); @@ -609,10 +609,10 @@ static int init_device(struct stm32prog_data *data, first_addr = 0; last_addr = mtd->size; dev->erase_size = mtd->erasesize; - pr_debug("MTD device %s: size=%lld erasesize=%d\n", - mtd_id, mtd->size, mtd->erasesize); - pr_debug(" available address = 0x%llx..0x%llx\n", - first_addr, last_addr); + log_debug("MTD device %s: size=%lld erasesize=%d\n", + mtd_id, mtd->size, mtd->erasesize); + log_debug(" available address = 0x%llx..0x%llx\n", + first_addr, last_addr); dev->mtd = mtd; break; case STM32PROG_RAM: @@ -624,13 +624,13 @@ static int init_device(struct stm32prog_data *data, stm32prog_err("unknown device type = %d", dev->target); return -ENODEV; } - pr_debug(" erase size = 0x%x\n", dev->erase_size); - pr_debug(" full_update = %d\n", dev->full_update); + log_debug(" erase size = 0x%x\n", dev->erase_size); + log_debug(" full_update = %d\n", dev->full_update); /* order partition list in offset order */ list_sort(NULL, &dev->part_list, &part_cmp); part_id = 1; - pr_debug("id : Opt Phase Name target.n dev.n addr size part_off part_size\n"); + log_debug("id : Opt Phase Name target.n dev.n addr size part_off part_size\n"); list_for_each_entry(part, &dev->part_list, list) { if (part->bin_nb > 1) { if ((dev->target != STM32PROG_NAND && @@ -650,10 +650,10 @@ static int init_device(struct stm32prog_data *data, part->size = block_dev->lba * block_dev->blksz; else part->size = last_addr; - pr_debug("-- : %1d %02x %14s %02d.%d %02d.%02d %08llx %08llx\n", - part->option, part->id, part->name, - part->part_type, part->bin_nb, part->target, - part->dev_id, part->addr, part->size); + log_debug("-- : %1d %02x %14s %02d.%d %02d.%02d %08llx %08llx\n", + part->option, part->id, part->name, + part->part_type, part->bin_nb, part->target, + part->dev_id, part->addr, part->size); continue; } if (part->part_id < 0) { /* boot hw partition for eMMC */ @@ -709,10 +709,10 @@ static int init_device(struct stm32prog_data *data, part->dev->erase_size); return -EINVAL; } - pr_debug("%02d : %1d %02x %14s %02d.%d %02d.%02d %08llx %08llx", - part->part_id, part->option, part->id, part->name, - part->part_type, part->bin_nb, part->target, - part->dev_id, part->addr, part->size); + log_debug("%02d : %1d %02x %14s %02d.%d %02d.%02d %08llx %08llx", + part->part_id, part->option, part->id, part->name, + part->part_type, part->bin_nb, part->target, + part->dev_id, part->addr, part->size); part_addr = 0; part_size = 0; @@ -726,7 +726,7 @@ static int init_device(struct stm32prog_data *data, * created for full update */ if (dev->full_update || part->part_id < 0) { - pr_debug("\n"); + log_debug("\n"); continue; } struct disk_partition partinfo; @@ -770,11 +770,11 @@ static int init_device(struct stm32prog_data *data, /* no partition for this device */ if (!part_found) { - pr_debug("\n"); + log_debug("\n"); continue; } - pr_debug(" %08llx %08llx\n", part_addr, part_size); + log_debug(" %08llx %08llx\n", part_addr, part_size); if (part->addr != part_addr) { stm32prog_err("%s (0x%x): Bad address for partition %d (%s) = 0x%llx <> 0x%llx expected", @@ -910,8 +910,8 @@ static int create_gpt_partitions(struct stm32prog_data *data) continue; if (offset + 100 > buflen) { - pr_debug("\n%s: buffer too small, %s skippped", - __func__, part->name); + log_debug("\n%s: buffer too small, %s skippped", + __func__, part->name); continue; } @@ -959,7 +959,7 @@ static int create_gpt_partitions(struct stm32prog_data *data) if (offset) { offset += snprintf(buf + offset, buflen - offset, "\""); - pr_debug("\ncmd: %s\n", buf); + log_debug("\ncmd: %s\n", buf); if (run_command(buf, 0)) { stm32prog_err("GPT partitionning fail: %s", buf); @@ -974,7 +974,7 @@ static int create_gpt_partitions(struct stm32prog_data *data) #ifdef DEBUG sprintf(buf, "gpt verify mmc %d", data->dev[i].dev_id); - pr_debug("\ncmd: %s", buf); + log_debug("\ncmd: %s", buf); if (run_command(buf, 0)) printf("fail !\n"); else @@ -1098,10 +1098,10 @@ static int stm32prog_alt_add(struct stm32prog_data *data, stm32prog_err("invalid target: %d", part->target); return ret; } - pr_debug("dfu_alt_add(%s,%s,%s)\n", dfustr, devstr, buf); + log_debug("dfu_alt_add(%s,%s,%s)\n", dfustr, devstr, buf); ret = dfu_alt_add(dfu, dfustr, devstr, buf); - pr_debug("dfu_alt_add(%s,%s,%s) result %d\n", - dfustr, devstr, buf, ret); + log_debug("dfu_alt_add(%s,%s,%s) result %d\n", + dfustr, devstr, buf, ret); return ret; } @@ -1116,7 +1116,7 @@ static int stm32prog_alt_add_virt(struct dfu_entity *dfu, sprintf(devstr, "%d", phase); sprintf(buf, "@%s/0x%02x/1*%dBe", name, phase, size); ret = dfu_alt_add(dfu, "virt", devstr, buf); - pr_debug("dfu_alt_add(virt,%s,%s) result %d\n", devstr, buf, ret); + log_debug("dfu_alt_add(virt,%s,%s) result %d\n", devstr, buf, ret); return ret; } @@ -1171,7 +1171,7 @@ static int dfu_init_entities(struct stm32prog_data *data) sprintf(buf, "@FlashLayout/0x%02x/1*256Ke ram %x 40000", PHASE_FLASHLAYOUT, STM32_DDR_BASE); ret = dfu_alt_add(dfu, "ram", NULL, buf); - pr_debug("dfu_alt_add(ram, NULL,%s) result %d\n", buf, ret); + log_debug("dfu_alt_add(ram, NULL,%s) result %d\n", buf, ret); } if (!ret) @@ -1196,7 +1196,7 @@ static int dfu_init_entities(struct stm32prog_data *data) int stm32prog_otp_write(struct stm32prog_data *data, u32 offset, u8 *buffer, long *size) { - pr_debug("%s: %x %lx\n", __func__, offset, *size); + log_debug("%s: %x %lx\n", __func__, offset, *size); if (!data->otp_part) { data->otp_part = memalign(CONFIG_SYS_CACHELINE_SIZE, OTP_SIZE); @@ -1226,7 +1226,7 @@ int stm32prog_otp_read(struct stm32prog_data *data, u32 offset, u8 *buffer, return -1; } - pr_debug("%s: %x %lx\n", __func__, offset, *size); + log_debug("%s: %x %lx\n", __func__, offset, *size); /* alway read for first packet */ if (!offset) { if (!data->otp_part) @@ -1258,7 +1258,7 @@ int stm32prog_otp_read(struct stm32prog_data *data, u32 offset, u8 *buffer, memcpy(buffer, (void *)((u32)data->otp_part + offset), *size); end_otp_read: - pr_debug("%s: result %i\n", __func__, result); + log_debug("%s: result %i\n", __func__, result); return result; } @@ -1292,20 +1292,20 @@ int stm32prog_otp_start(struct stm32prog_data *data) result = 0; break; default: - pr_err("%s: OTP incorrect value (err = %ld)\n", - __func__, res.a1); + log_err("%s: OTP incorrect value (err = %ld)\n", + __func__, res.a1); result = -EINVAL; break; } } else { - pr_err("%s: Failed to exec svc=%x op=%x in secure mode (err = %ld)\n", - __func__, STM32_SMC_BSEC, STM32_SMC_WRITE_ALL, res.a0); + log_err("%s: Failed to exec svc=%x op=%x in secure mode (err = %ld)\n", + __func__, STM32_SMC_BSEC, STM32_SMC_WRITE_ALL, res.a0); result = -EINVAL; } free(data->otp_part); data->otp_part = NULL; - pr_debug("%s: result %i\n", __func__, result); + log_debug("%s: result %i\n", __func__, result); return result; } @@ -1313,7 +1313,7 @@ int stm32prog_otp_start(struct stm32prog_data *data) int stm32prog_pmic_write(struct stm32prog_data *data, u32 offset, u8 *buffer, long *size) { - pr_debug("%s: %x %lx\n", __func__, offset, *size); + log_debug("%s: %x %lx\n", __func__, offset, *size); if (!offset) memset(data->pmic_part, 0, PMIC_SIZE); @@ -1338,7 +1338,7 @@ int stm32prog_pmic_read(struct stm32prog_data *data, u32 offset, u8 *buffer, return -EOPNOTSUPP; } - pr_debug("%s: %x %lx\n", __func__, offset, *size); + log_debug("%s: %x %lx\n", __func__, offset, *size); ret = uclass_get_device_by_driver(UCLASS_MISC, DM_DRIVER_GET(stpmic1_nvm), &dev); @@ -1373,7 +1373,7 @@ int stm32prog_pmic_read(struct stm32prog_data *data, u32 offset, u8 *buffer, memcpy(buffer, &data->pmic_part[offset], *size); end_pmic_read: - pr_debug("%s: result %i\n", __func__, result); + log_debug("%s: result %i\n", __func__, result); return result; } @@ -1429,7 +1429,7 @@ static int stm32prog_copy_fsbl(struct stm32prog_part_t *part) if (!fsbl) return -ENOMEM; ret = dfu->read_medium(dfu, 0, fsbl, &size); - pr_debug("%s read size=%lx ret=%d\n", __func__, size, ret); + log_debug("%s read size=%lx ret=%d\n", __func__, size, ret); if (ret) goto error; @@ -1439,8 +1439,8 @@ static int stm32prog_copy_fsbl(struct stm32prog_part_t *part) offset += size; /* write to the next erase block */ ret = dfu->write_medium(dfu, offset, fsbl, &size); - pr_debug("%s copy at ofset=%lx size=%lx ret=%d", - __func__, offset, size, ret); + log_debug("%s copy at ofset=%lx size=%lx ret=%d", + __func__, offset, size, ret); if (ret) goto error; } @@ -1751,6 +1751,6 @@ void dfu_initiated_callback(struct dfu_entity *dfu) if (dfu->alt == stm32prog_data->cur_part->alt_id) { dfu->offset = stm32prog_data->offset; stm32prog_data->dfu_seq = 0; - pr_debug("dfu offset = 0x%llx\n", dfu->offset); + log_debug("dfu offset = 0x%llx\n", dfu->offset); } } diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h index bae4e91c01..be482c3402 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h @@ -172,7 +172,7 @@ char *stm32prog_get_error(struct stm32prog_data *data); if (data->phase != PHASE_RESET) { \ sprintf(data->error, args); \ data->phase = PHASE_RESET; \ - pr_err("Error: %s\n", data->error); } \ + log_err("Error: %s\n", data->error); } \ } /* Main function */ diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c index 8aad4be467..68d841bd9d 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c @@ -159,8 +159,8 @@ static int stm32prog_read(struct stm32prog_data *data, u8 phase, u32 offset, dfu_entity->offset = offset; data->offset = offset; data->read_phase = phase; - pr_debug("\nSTM32 download read %s offset=0x%x\n", - dfu_entity->name, offset); + log_debug("\nSTM32 download read %s offset=0x%x\n", + dfu_entity->name, offset); ret = dfu_read(dfu_entity, buffer, buffer_size, dfu_entity->i_blk_seq_num); if (ret < 0) { @@ -198,7 +198,7 @@ int stm32prog_serial_init(struct stm32prog_data *data, int link_dev) sprintf(alias, "serial%d", link_dev); path = fdt_get_alias(gd->fdt_blob, alias); if (!path) { - pr_err("%s alias not found", alias); + log_err("%s alias not found", alias); return -ENODEV; } node = fdt_path_offset(gd->fdt_blob, path); @@ -212,7 +212,7 @@ int stm32prog_serial_init(struct stm32prog_data *data, int link_dev) down_serial_dev = dev; } if (!down_serial_dev) { - pr_err("%s = %s device not found", alias, path); + log_err("%s = %s device not found", alias, path); return -ENODEV; } @@ -225,11 +225,11 @@ int stm32prog_serial_init(struct stm32prog_data *data, int link_dev) ops = serial_get_ops(down_serial_dev); if (!ops) { - pr_err("%s = %s missing ops", alias, path); + log_err("%s = %s missing ops", alias, path); return -ENODEV; } if (!ops->setconfig) { - pr_err("%s = %s missing setconfig", alias, path); + log_err("%s = %s missing setconfig", alias, path); return -ENODEV; } @@ -397,14 +397,13 @@ static u8 stm32prog_start(struct stm32prog_data *data, u32 address) if (!dfu_entity) return -ENODEV; - if (data->dfu_seq) { - ret = dfu_flush(dfu_entity, NULL, 0, data->dfu_seq); - data->dfu_seq = 0; - if (ret) { - stm32prog_err("DFU flush failed [%d]", ret); - return ret; - } + ret = dfu_flush(dfu_entity, NULL, 0, data->dfu_seq); + if (ret) { + stm32prog_err("DFU flush failed [%d]", ret); + return ret; } + data->dfu_seq = 0; + printf("\n received length = 0x%x\n", data->cursor); if (data->header.present) { if (data->cursor != @@ -815,7 +814,7 @@ static void download_command(struct stm32prog_data *data) if (data->cursor > image_header->image_length + BL_HEADER_SIZE) { - pr_err("expected size exceeded\n"); + log_err("expected size exceeded\n"); result = ABORT_BYTE; goto end; } @@ -859,8 +858,8 @@ static void read_partition_command(struct stm32prog_data *data) rcv_data = stm32prog_serial_getc(); if (rcv_data != tmp_xor) { - pr_debug("1st checksum received = %x, computed %x\n", - rcv_data, tmp_xor); + log_debug("1st checksum received = %x, computed %x\n", + rcv_data, tmp_xor); goto error; } stm32prog_serial_putc(ACK_BYTE); @@ -872,12 +871,12 @@ static void read_partition_command(struct stm32prog_data *data) rcv_data = stm32prog_serial_getc(); if ((rcv_data ^ tmp_xor) != 0xFF) { - pr_debug("2nd checksum received = %x, computed %x\n", - rcv_data, tmp_xor); + log_debug("2nd checksum received = %x, computed %x\n", + rcv_data, tmp_xor); goto error; } - pr_debug("%s : %x\n", __func__, part_id); + log_debug("%s : %x\n", __func__, part_id); rcv_data = 0; switch (part_id) { case PHASE_OTP: diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c index 30547f94c9..bc44d9fc8f 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c @@ -47,11 +47,11 @@ static int stm32prog_cmd_write(u64 offset, void *buf, long *len) int ret; if (*len < 5) { - pr_err("size not allowed\n"); + log_err("size not allowed\n"); return -EINVAL; } if (offset) { - pr_err("invalid offset\n"); + log_err("invalid offset\n"); return -EINVAL; } phase = pt[0]; @@ -66,7 +66,7 @@ static int stm32prog_cmd_write(u64 offset, void *buf, long *len) /* set phase and offset */ ret = stm32prog_set_phase(stm32prog_data, phase, address); if (ret) - pr_err("failed: %d\n", ret); + log_err("failed: %d\n", ret); return ret; } @@ -81,7 +81,7 @@ static int stm32prog_cmd_read(u64 offset, void *buf, long *len) int length; if (*len < PHASE_MIN_SIZE) { - pr_err("request exceeds allowed area\n"); + log_err("request exceeds allowed area\n"); return -EINVAL; } if (offset) { @@ -171,8 +171,8 @@ int stm32prog_get_medium_size_virt(struct dfu_entity *dfu, u64 *size) { if (dfu->dev_type != DFU_DEV_VIRT) { *size = 0; - pr_debug("%s, invalid dev_type = %d\n", - __func__, dfu->dev_type); + log_debug("%s, invalid dev_type = %d\n", + __func__, dfu->dev_type); return -EINVAL; } @@ -227,6 +227,6 @@ bool stm32prog_usb_loop(struct stm32prog_data *data, int dev) int g_dnl_get_board_bcd_device_number(int gcnum) { - pr_debug("%s\n", __func__); + log_debug("%s\n", __func__); return 0x200; } diff --git a/arch/arm/mach-stm32mp/cpu.c b/arch/arm/mach-stm32mp/cpu.c index 29c0d92195..717f80e9ff 100644 --- a/arch/arm/mach-stm32mp/cpu.c +++ b/arch/arm/mach-stm32mp/cpu.c @@ -2,6 +2,9 @@ /* * Copyright (C) 2018, STMicroelectronics - All Rights Reserved */ + +#define LOG_CATEGORY LOGC_ARCH + #include <common.h> #include <clk.h> #include <cpu_func.h> @@ -463,8 +466,8 @@ static void setup_boot_mode(void) struct udevice *dev; int alias; - pr_debug("%s: boot_ctx=0x%x => boot_mode=%x, instance=%d forced=%x\n", - __func__, boot_ctx, boot_mode, instance, forced_mode); + log_debug("%s: boot_ctx=0x%x => boot_mode=%x, instance=%d forced=%x\n", + __func__, boot_ctx, boot_mode, instance, forced_mode); switch (boot_mode & TAMP_BOOT_DEVICE_MASK) { case BOOT_SERIAL_UART: if (instance > ARRAY_SIZE(serial_addr)) @@ -510,7 +513,7 @@ static void setup_boot_mode(void) env_set("boot_instance", "0"); break; default: - pr_debug("unexpected boot mode = %x\n", boot_mode); + log_debug("unexpected boot mode = %x\n", boot_mode); break; } @@ -537,7 +540,7 @@ static void setup_boot_mode(void) case BOOT_NORMAL: break; default: - pr_debug("unexpected forced boot mode = %x\n", forced_mode); + log_debug("unexpected forced boot mode = %x\n", forced_mode); break; } @@ -577,14 +580,13 @@ __weak int setup_mac_address(void) enetaddr[i] = ((uint8_t *)&otp)[i]; if (!is_valid_ethaddr(enetaddr)) { - pr_err("invalid MAC address in OTP %pM\n", enetaddr); + log_err("invalid MAC address in OTP %pM\n", enetaddr); return -EINVAL; } - pr_debug("OTP MAC address = %pM\n", enetaddr); + log_debug("OTP MAC address = %pM\n", enetaddr); ret = eth_env_set_enetaddr("ethaddr", enetaddr); if (ret) - pr_err("Failed to set mac address %pM from OTP: %d\n", - enetaddr, ret); + log_err("Failed to set mac address %pM from OTP: %d\n", enetaddr, ret); #endif return 0; diff --git a/arch/arm/mach-stm32mp/dram_init.c b/arch/arm/mach-stm32mp/dram_init.c index 0e8ce63f4a..32b177bb79 100644 --- a/arch/arm/mach-stm32mp/dram_init.c +++ b/arch/arm/mach-stm32mp/dram_init.c @@ -3,6 +3,8 @@ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved */ +#define LOG_CATEGORY LOGC_ARCH + #include <common.h> #include <dm.h> #include <image.h> @@ -21,15 +23,15 @@ int dram_init(void) ret = uclass_get_device(UCLASS_RAM, 0, &dev); if (ret) { - debug("RAM init failed: %d\n", ret); + log_debug("RAM init failed: %d\n", ret); return ret; } ret = ram_get_info(dev, &ram); if (ret) { - debug("Cannot get RAM size: %d\n", ret); + log_debug("Cannot get RAM size: %d\n", ret); return ret; } - debug("RAM init base=%lx, size=%x\n", ram.base, ram.size); + log_debug("RAM init base=%lx, size=%x\n", ram.base, ram.size); gd->ram_size = ram.size; diff --git a/arch/arm/mach-stm32mp/fdt.c b/arch/arm/mach-stm32mp/fdt.c index 0de1d82291..aaedeac8d5 100644 --- a/arch/arm/mach-stm32mp/fdt.c +++ b/arch/arm/mach-stm32mp/fdt.c @@ -3,6 +3,8 @@ * Copyright (C) 2019-2020, STMicroelectronics - All Rights Reserved */ +#define LOG_CATEGORY LOGC_ARCH + #include <common.h> #include <fdt_support.h> #include <log.h> @@ -172,15 +174,15 @@ static int stm32_fdt_fixup_etzpc(void *fdt, int soc_node) status = (decprot[offset] >> shift) & DECPROT_MASK; addr = array[i]; - debug("ETZPC: 0x%08x decprot %d=%d\n", addr, i, status); + log_debug("ETZPC: 0x%08x decprot %d=%d\n", addr, i, status); if (addr == ETZPC_RESERVED || status == DECPROT_NON_SECURED) continue; if (fdt_disable_subnode_by_address(fdt, soc_node, addr)) - printf("ETZPC: 0x%08x node disabled, decprot %d=%d\n", - addr, i, status); + log_notice("ETZPC: 0x%08x node disabled, decprot %d=%d\n", + addr, i, status); } return 0; @@ -194,7 +196,7 @@ static void stm32_fdt_fixup_cpu(void *blob, char *name) off = fdt_path_offset(blob, "/cpus"); if (off < 0) { - printf("%s: couldn't find /cpus node\n", __func__); + log_warning("%s: couldn't find /cpus node\n", __func__); return; } @@ -203,7 +205,8 @@ static void stm32_fdt_fixup_cpu(void *blob, char *name) reg = fdtdec_get_addr(blob, off, "reg"); if (reg != 0) { fdt_del_node(blob, off); - printf("FDT: cpu %d node remove for %s\n", reg, name); + log_notice("FDT: cpu %d node remove for %s\n", + reg, name); /* after delete we can't trust the offsets anymore */ off = -1; } @@ -216,8 +219,8 @@ static void stm32_fdt_disable(void *fdt, int offset, u32 addr, const char *string, const char *name) { if (fdt_disable_subnode_by_address(fdt, offset, addr)) - printf("FDT: %s@%08x node disabled for %s\n", - string, addr, name); + log_notice("FDT: %s@%08x node disabled for %s\n", + string, addr, name); } static void stm32_fdt_disable_optee(void *blob) diff --git a/arch/arm/mach-stm32mp/pwr_regulator.c b/arch/arm/mach-stm32mp/pwr_regulator.c index 766ed95f1a..846637ab16 100644 --- a/arch/arm/mach-stm32mp/pwr_regulator.c +++ b/arch/arm/mach-stm32mp/pwr_regulator.c @@ -3,6 +3,8 @@ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved */ +#define LOG_CATEGORY UCLASS_REGULATOR + #include <common.h> #include <dm.h> #include <errno.h> diff --git a/arch/arm/mach-stm32mp/spl.c b/arch/arm/mach-stm32mp/spl.c index 66a634654e..0c50ad54df 100644 --- a/arch/arm/mach-stm32mp/spl.c +++ b/arch/arm/mach-stm32mp/spl.c @@ -3,6 +3,8 @@ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved */ +#define LOG_CATEGORY LOGC_ARCH + #include <common.h> #include <cpu_func.h> #include <dm.h> @@ -80,7 +82,7 @@ void spl_display_print(void) */ model = fdt_getprop(gd->fdt_blob, 0, "model", NULL); if (model) - printf("Model: %s\n", model); + log_info("Model: %s\n", model); } #endif @@ -98,25 +100,25 @@ void board_init_f(ulong dummy) ret = spl_early_init(); if (ret) { - debug("spl_early_init() failed: %d\n", ret); + log_debug("spl_early_init() failed: %d\n", ret); hang(); } ret = uclass_get_device(UCLASS_CLK, 0, &dev); if (ret) { - debug("Clock init failed: %d\n", ret); + log_debug("Clock init failed: %d\n", ret); hang(); } ret = uclass_get_device(UCLASS_RESET, 0, &dev); if (ret) { - debug("Reset init failed: %d\n", ret); + log_debug("Reset init failed: %d\n", ret); hang(); } ret = uclass_get_device(UCLASS_PINCTRL, 0, &dev); if (ret) { - debug("%s: Cannot find pinctrl device\n", __func__); + log_debug("%s: Cannot find pinctrl device\n", __func__); hang(); } @@ -125,13 +127,13 @@ void board_init_f(ulong dummy) ret = board_early_init_f(); if (ret) { - debug("board_early_init_f() failed: %d\n", ret); + log_debug("board_early_init_f() failed: %d\n", ret); hang(); } ret = uclass_get_device(UCLASS_RAM, 0, &dev); if (ret) { - printf("DRAM init failed: %d\n", ret); + log_err("DRAM init failed: %d\n", ret); hang(); } diff --git a/arch/m68k/lib/traps.c b/arch/m68k/lib/traps.c index c49141f376..0c2c1a9965 100644 --- a/arch/m68k/lib/traps.c +++ b/arch/m68k/lib/traps.c @@ -40,7 +40,7 @@ void exc_handler(struct pt_regs *fp) { for(;;); } -void trap_init(ulong value) { +static void trap_init(ulong value) { unsigned long *vec = (ulong *)value; int i; @@ -59,3 +59,10 @@ void trap_init(ulong value) { setvbr(value); /* set vector base register to new table */ } + +int arch_initr_trap(void) +{ + trap_init(CONFIG_SYS_SDRAM_BASE); + + return 0; +} diff --git a/arch/mips/lib/traps.c b/arch/mips/lib/traps.c index df8b63f383..540ea48e32 100644 --- a/arch/mips/lib/traps.c +++ b/arch/mips/lib/traps.c @@ -99,7 +99,7 @@ static void set_handler(unsigned long offset, void *addr, unsigned long size) flush_cache(ebase + offset, size); } -void trap_init(ulong reloc_addr) +static void trap_init(ulong reloc_addr) { unsigned long ebase = gd->irq_sp; @@ -131,3 +131,10 @@ void trap_restore(void) clear_c0_status(ST0_BEV); execution_hazard_barrier(); } + +int arch_initr_trap(void) +{ + trap_init(CONFIG_SYS_SDRAM_BASE); + + return 0; +} diff --git a/arch/powerpc/cpu/mpc85xx/cpu_init.c b/arch/powerpc/cpu/mpc85xx/cpu_init.c index e0f0f7ecda..e920e01b25 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu_init.c +++ b/arch/powerpc/cpu/mpc85xx/cpu_init.c @@ -1028,7 +1028,7 @@ void arch_preboot_os(void) mtmsr(msr); } -void cpu_secondary_init_r(void) +int cpu_secondary_init_r(void) { #ifdef CONFIG_QE #ifdef CONFIG_U_QE @@ -1040,6 +1040,8 @@ void cpu_secondary_init_r(void) qe_init(qe_base); qe_reset(); #endif + + return 0; } #ifdef CONFIG_BOARD_LATE_INIT diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile index f61809ab05..2782740bf5 100644 --- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile @@ -40,6 +40,7 @@ obj-y += interrupts.o obj-$(CONFIG_CMD_KGDB) += kgdb.o obj-y += stack.o obj-y += time.o +obj-y += traps.o endif # not minimal ifdef CONFIG_SPL_BUILD diff --git a/arch/powerpc/lib/traps.c b/arch/powerpc/lib/traps.c new file mode 100644 index 0000000000..288e377632 --- /dev/null +++ b/arch/powerpc/lib/traps.c @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2003 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + */ + +#include <common.h> +#include <init.h> + +DECLARE_GLOBAL_DATA_PTR; + +void trap_init(unsigned long reloc_addr); + +int arch_initr_trap(void) +{ + trap_init(gd->relocaddr); + + return 0; +} diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 30b05408b1..55eaee2da6 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -152,6 +152,10 @@ config 32BIT config 64BIT bool +config DMA_ADDR_T_64BIT + bool + default y if 64BIT + config SIFIVE_CLINT bool depends on RISCV_MMODE || SPL_RISCV_MMODE diff --git a/arch/riscv/dts/Makefile b/arch/riscv/dts/Makefile index 3a6f96c67d..01331b0aa1 100644 --- a/arch/riscv/dts/Makefile +++ b/arch/riscv/dts/Makefile @@ -3,6 +3,7 @@ dtb-$(CONFIG_TARGET_AX25_AE350) += ae350_32.dtb ae350_64.dtb dtb-$(CONFIG_TARGET_SIFIVE_FU540) += hifive-unleashed-a00.dtb dtb-$(CONFIG_TARGET_SIPEED_MAIX) += k210-maix-bit.dtb +dtb-$(CONFIG_TARGET_MICROCHIP_ICICLE) += microchip-mpfs-icicle-kit.dtb targets += $(dtb-y) diff --git a/arch/riscv/dts/microchip-mpfs-icicle-kit-u-boot.dtsi b/arch/riscv/dts/microchip-mpfs-icicle-kit-u-boot.dtsi new file mode 100644 index 0000000000..f60283fb6b --- /dev/null +++ b/arch/riscv/dts/microchip-mpfs-icicle-kit-u-boot.dtsi @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright (C) 2020 Microchip Technology Inc. + * Padmarao Begari <padmarao.begari@microchip.com> + */ + +/ { + aliases { + cpu1 = &cpu1; + cpu2 = &cpu2; + cpu3 = &cpu3; + cpu4 = &cpu4; + }; +}; diff --git a/arch/riscv/dts/microchip-mpfs-icicle-kit.dts b/arch/riscv/dts/microchip-mpfs-icicle-kit.dts new file mode 100644 index 0000000000..e2b9decc94 --- /dev/null +++ b/arch/riscv/dts/microchip-mpfs-icicle-kit.dts @@ -0,0 +1,421 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* Copyright (c) 2020 Microchip Technology Inc */ + +/dts-v1/; +#include "dt-bindings/clock/microchip-mpfs-clock.h" + +/* Clock frequency (in Hz) of the rtcclk */ +#define RTCCLK_FREQ 1000000 + +/ { + #address-cells = <2>; + #size-cells = <2>; + model = "Microchip MPFS Icicle Kit"; + compatible = "microchip,mpfs-icicle-kit"; + + aliases { + serial0 = &uart0; + ethernet0 = &emac1; + }; + + chosen { + stdout-path = "serial0"; + }; + + cpucomplex: cpus { + #address-cells = <1>; + #size-cells = <0>; + timebase-frequency = <RTCCLK_FREQ>; + cpu0: cpu@0 { + clocks = <&clkcfg CLK_CPU>; + compatible = "sifive,e51", "sifive,rocket0", "riscv"; + device_type = "cpu"; + i-cache-block-size = <64>; + i-cache-sets = <128>; + i-cache-size = <16384>; + reg = <0>; + riscv,isa = "rv64imac"; + status = "disabled"; + operating-points = < + /* kHz uV */ + 600000 1100000 + 300000 950000 + 150000 750000 + >; + cpu0intc: interrupt-controller { + #interrupt-cells = <1>; + compatible = "riscv,cpu-intc"; + interrupt-controller; + }; + }; + cpu1: cpu@1 { + clocks = <&clkcfg CLK_CPU>; + compatible = "sifive,u54-mc", "sifive,rocket0", "riscv"; + d-cache-block-size = <64>; + d-cache-sets = <64>; + d-cache-size = <32768>; + d-tlb-sets = <1>; + d-tlb-size = <32>; + device_type = "cpu"; + i-cache-block-size = <64>; + i-cache-sets = <64>; + i-cache-size = <32768>; + i-tlb-sets = <1>; + i-tlb-size = <32>; + mmu-type = "riscv,sv39"; + reg = <1>; + riscv,isa = "rv64imafdc"; + tlb-split; + status = "okay"; + operating-points = < + /* kHz uV */ + 600000 1100000 + 300000 950000 + 150000 750000 + >; + cpu1intc: interrupt-controller { + #interrupt-cells = <1>; + compatible = "riscv,cpu-intc"; + interrupt-controller; + }; + }; + cpu2: cpu@2 { + clocks = <&clkcfg CLK_CPU>; + compatible = "sifive,u54-mc", "sifive,rocket0", "riscv"; + d-cache-block-size = <64>; + d-cache-sets = <64>; + d-cache-size = <32768>; + d-tlb-sets = <1>; + d-tlb-size = <32>; + device_type = "cpu"; + i-cache-block-size = <64>; + i-cache-sets = <64>; + i-cache-size = <32768>; + i-tlb-sets = <1>; + i-tlb-size = <32>; + mmu-type = "riscv,sv39"; + reg = <2>; + riscv,isa = "rv64imafdc"; + tlb-split; + status = "okay"; + operating-points = < + /* kHz uV */ + 600000 1100000 + 300000 950000 + 150000 750000 + >; + cpu2intc: interrupt-controller { + #interrupt-cells = <1>; + compatible = "riscv,cpu-intc"; + interrupt-controller; + }; + }; + cpu3: cpu@3 { + clocks = <&clkcfg CLK_CPU>; + compatible = "sifive,u54-mc", "sifive,rocket0", "riscv"; + d-cache-block-size = <64>; + d-cache-sets = <64>; + d-cache-size = <32768>; + d-tlb-sets = <1>; + d-tlb-size = <32>; + device_type = "cpu"; + i-cache-block-size = <64>; + i-cache-sets = <64>; + i-cache-size = <32768>; + i-tlb-sets = <1>; + i-tlb-size = <32>; + mmu-type = "riscv,sv39"; + reg = <3>; + riscv,isa = "rv64imafdc"; + tlb-split; + status = "okay"; + operating-points = < + /* kHz uV */ + 600000 1100000 + 300000 950000 + 150000 750000 + >; + cpu3intc: interrupt-controller { + #interrupt-cells = <1>; + compatible = "riscv,cpu-intc"; + interrupt-controller; + }; + }; + cpu4: cpu@4 { + clocks = <&clkcfg CLK_CPU>; + compatible = "sifive,u54-mc", "sifive,rocket0", "riscv"; + d-cache-block-size = <64>; + d-cache-sets = <64>; + d-cache-size = <32768>; + d-tlb-sets = <1>; + d-tlb-size = <32>; + device_type = "cpu"; + i-cache-block-size = <64>; + i-cache-sets = <64>; + i-cache-size = <32768>; + i-tlb-sets = <1>; + i-tlb-size = <32>; + mmu-type = "riscv,sv39"; + reg = <4>; + riscv,isa = "rv64imafdc"; + tlb-split; + status = "okay"; + operating-points = < + /* kHz uV */ + 600000 1100000 + 300000 950000 + 150000 750000 + >; + cpu4intc: interrupt-controller { + #interrupt-cells = <1>; + compatible = "riscv,cpu-intc"; + interrupt-controller; + }; + }; + }; + refclk: refclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <600000000>; + clock-output-names = "msspllclk"; + }; + ddr: memory@80000000 { + device_type = "memory"; + reg = <0x0 0x80000000 0x0 0x40000000>; + clocks = <&clkcfg CLK_DDRC>; + }; + soc: soc { + #address-cells = <2>; + #size-cells = <2>; + compatible = "microchip,mpfs-icicle-kit", "simple-bus"; + ranges; + clint0: clint@2000000 { + compatible = "riscv,clint0"; + interrupts-extended = <&cpu0intc 3 &cpu0intc 7 + &cpu1intc 3 &cpu1intc 7 + &cpu2intc 3 &cpu2intc 7 + &cpu3intc 3 &cpu3intc 7 + &cpu4intc 3 &cpu4intc 7>; + reg = <0x0 0x2000000 0x0 0x10000>; + reg-names = "control"; + clock-frequency = <RTCCLK_FREQ>; + }; + cachecontroller: cache-controller@2010000 { + compatible = "sifive,fu540-c000-ccache", "cache"; + cache-block-size = <64>; + cache-level = <2>; + cache-sets = <1024>; + cache-size = <2097152>; + cache-unified; + interrupt-parent = <&plic>; + interrupts = <1 2 3>; + reg = <0x0 0x2010000 0x0 0x1000>; + }; + plic: interrupt-controller@c000000 { + #interrupt-cells = <1>; + compatible = "sifive,plic-1.0.0"; + reg = <0x0 0xc000000 0x0 0x4000000>; + riscv,max-priority = <7>; + riscv,ndev = <186>; + interrupt-controller; + interrupts-extended = < + &cpu0intc 11 + &cpu1intc 11 &cpu1intc 9 + &cpu2intc 11 &cpu2intc 9 + &cpu3intc 11 &cpu3intc 9 + &cpu4intc 11 &cpu4intc 9>; + }; + uart0: serial@20000000 { + compatible = "ns16550a"; + reg = <0x0 0x20000000 0x0 0x400>; + reg-io-width = <4>; + reg-shift = <2>; + interrupt-parent = <&plic>; + interrupts = <90>; + clock-frequency = <150000000>; + clocks = <&clkcfg CLK_MMUART0>; + status = "okay"; + }; + clkcfg: clkcfg@20002000 { + compatible = "microchip,mpfs-clkcfg"; + reg = <0x0 0x20002000 0x0 0x1000>; + reg-names = "mss_sysreg"; + clocks = <&refclk>; + #clock-cells = <1>; + clock-output-names = "cpu", "axi", "ahb", "envm", + "mac0", "mac1", "mmc", "timer", + "mmuart0", "mmuart1", "mmuart2", + "mmuart3", "mmuart4", "spi0", "spi1", + "i2c0", "i2c1", "can0", "can1", "usb", + "reserved", "rtc", "qspi", "gpio0", + "gpio1", "gpio2", "ddrc", "fic0", + "fic1", "fic2", "fic3", "athena", + "cfm"; + }; + emmc: mmc@20008000 { + compatible = "cdns,sd4hc"; + reg = <0x0 0x20008000 0x0 0x1000>; + interrupt-parent = <&plic>; + interrupts = <88 89>; + pinctrl-names = "default"; + clocks = <&clkcfg CLK_MMC>; + bus-width = <4>; + cap-mmc-highspeed; + mmc-ddr-3_3v; + max-frequency = <200000000>; + non-removable; + no-sd; + no-sdio; + voltage-ranges = <3300 3300>; + status = "okay"; + }; + sdcard: sd@20008000 { + compatible = "cdns,sd4hc"; + reg = <0x0 0x20008000 0x0 0x1000>; + interrupt-parent = <&plic>; + interrupts = <88>; + pinctrl-names = "default"; + clocks = <&clkcfg CLK_MMC>; + bus-width = <4>; + disable-wp; + cap-sd-highspeed; + card-detect-delay = <200>; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + max-frequency = <200000000>; + status = "disabled"; + }; + uart1: serial@20100000 { + compatible = "ns16550a"; + reg = <0x0 0x20100000 0x0 0x400>; + reg-io-width = <4>; + reg-shift = <2>; + interrupt-parent = <&plic>; + interrupts = <91>; + clock-frequency = <150000000>; + clocks = <&clkcfg CLK_MMUART1>; + status = "okay"; + }; + uart2: serial@20102000 { + compatible = "ns16550a"; + reg = <0x0 0x20102000 0x0 0x400>; + reg-io-width = <4>; + reg-shift = <2>; + interrupt-parent = <&plic>; + interrupts = <92>; + clock-frequency = <150000000>; + clocks = <&clkcfg CLK_MMUART2>; + status = "okay"; + }; + uart3: serial@20104000 { + compatible = "ns16550a"; + reg = <0x0 0x20104000 0x0 0x400>; + reg-io-width = <4>; + reg-shift = <2>; + interrupt-parent = <&plic>; + interrupts = <93>; + clock-frequency = <150000000>; + clocks = <&clkcfg CLK_MMUART3>; + status = "okay"; + }; + i2c0: i2c@2010a000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "microchip,mpfs-mss-i2c"; + reg = <0x0 0x2010a000 0x0 0x1000>; + interrupt-parent = <&plic>; + interrupts = <58>; + clocks = <&clkcfg CLK_I2C0>; + status = "disabled"; + }; + i2c1: i2c@2010b000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "microchip,mpfs-mss-i2c"; + reg = <0x0 0x2010b000 0x0 0x1000>; + interrupt-parent = <&plic>; + interrupts = <61>; + clocks = <&clkcfg CLK_I2C1>; + status = "disabled"; + pac193x@10 { + compatible = "microchip,pac1934"; + reg = <0x10>; + samp-rate = <64>; + status = "disabled"; + ch1: channel0 { + uohms-shunt-res = <10000>; + rail-name = "VDD"; + channel_enabled; + }; + ch2: channel1 { + uohms-shunt-res = <10000>; + rail-name = "VDDA25"; + channel_enabled; + }; + ch3: channel2 { + uohms-shunt-res = <10000>; + rail-name = "VDD25"; + channel_enabled; + }; + ch4: channel3 { + uohms-shunt-res = <10000>; + rail-name = "VDDA"; + channel_enabled; + }; + }; + }; + emac0: ethernet@20110000 { + compatible = "microchip,mpfs-mss-gem"; + reg = <0x0 0x20110000 0x0 0x2000>; + interrupt-parent = <&plic>; + interrupts = <64 65 66 67>; + local-mac-address = [56 34 00 FC 00 02]; + phy-mode = "sgmii"; + clocks = <&clkcfg CLK_MAC0>, <&clkcfg CLK_AXI>; + clock-names = "pclk", "hclk"; + status = "disabled"; + + #address-cells = <1>; + #size-cells = <0>; + phy-handle = <&phy0>; + phy0: ethernet-phy@8 { + reg = <8>; + ti,fifo-depth = <0x01>; + }; + }; + emac1: ethernet@20112000 { + compatible = "microchip,mpfs-mss-gem"; + reg = <0x0 0x20112000 0x0 0x2000>; + interrupt-parent = <&plic>; + interrupts = <70 71 72 73>; + local-mac-address = [00 00 00 00 00 00]; + phy-mode = "sgmii"; + clocks = <&clkcfg CLK_MAC1>, <&clkcfg CLK_AHB>; + clock-names = "pclk", "hclk"; + status = "okay"; + + #address-cells = <1>; + #size-cells = <0>; + phy-handle = <&phy1>; + phy1: ethernet-phy@9 { + reg = <9>; + ti,fifo-depth = <0x01>; + }; + }; + gpio: gpio@20122000 { + compatible = "microchip,mpfs-mss-gpio"; + interrupt-parent = <&plic>; + interrupts = <13 14 15 16 17 18 19 20 21 22 23 24 25 26 + 27 28 29 30 31 32 33 34 35 36 37 38 39 + 40 41 42 43 44>; + gpio-controller; + clocks = <&clkcfg CLK_GPIO2>; + reg = <0x00 0x20122000 0x0 0x1000>; + reg-names = "control"; + #gpio-cells = <2>; + status = "disabled"; + }; + }; +}; diff --git a/arch/riscv/include/asm/types.h b/arch/riscv/include/asm/types.h index 403cf9a48f..b800b2d221 100644 --- a/arch/riscv/include/asm/types.h +++ b/arch/riscv/include/asm/types.h @@ -29,7 +29,11 @@ typedef unsigned short umode_t; #include <stddef.h> +#ifdef CONFIG_DMA_ADDR_T_64BIT +typedef u64 dma_addr_t; +#else typedef u32 dma_addr_t; +#endif typedef unsigned long phys_addr_t; typedef unsigned long phys_size_t; diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c index 8322ed7a1f..2d18d9debc 100644 --- a/arch/sandbox/cpu/start.c +++ b/arch/sandbox/cpu/start.c @@ -9,6 +9,7 @@ #include <efi_loader.h> #include <errno.h> #include <init.h> +#include <log.h> #include <os.h> #include <cli.h> #include <sort.h> @@ -486,6 +487,10 @@ int main(int argc, char *argv[]) */ gd->reloc_off = (ulong)gd->arch.text_base; + /* sandbox test: log functions called before log_init in board_init_f */ + log_info("sandbox: starting...\n"); + log_debug("debug: %s\n", __func__); + /* Do pre- and post-relocation init */ board_init_f(0); diff --git a/board/altera/stratix10-socdk/MAINTAINERS b/board/altera/stratix10-socdk/MAINTAINERS index 6192bc9174..6efd0cfc05 100644 --- a/board/altera/stratix10-socdk/MAINTAINERS +++ b/board/altera/stratix10-socdk/MAINTAINERS @@ -4,4 +4,5 @@ M: Dinh Nguyen <dinh.nguyen@intel.com> S: Maintained F: board/altera/stratix10-socdk/ F: include/configs/socfpga_stratix10_socdk.h +F: configs/socfpga_stratix10_atf_defconfig F: configs/socfpga_stratix10_defconfig diff --git a/board/amlogic/beelink-s922x/MAINTAINERS b/board/amlogic/beelink-s922x/MAINTAINERS new file mode 100644 index 0000000000..7f223df4ae --- /dev/null +++ b/board/amlogic/beelink-s922x/MAINTAINERS @@ -0,0 +1,9 @@ +BEELINK-S922X +M: Christian Hewitt <christianshewitt@gmail.com> +S: Maintained +L: u-boot-amlogic@groups.io +F: board/amlogic/beelink-s922x/ +F: configs/beelink-gtking_defconfig +F: configs/beelink-gtkingpro_defconfig +F: doc/board/amlogic/beelink-gtking.rst +F: doc/board/amlogic/beelink-gtkingpro.rst diff --git a/board/amlogic/beelink-s922x/Makefile b/board/amlogic/beelink-s922x/Makefile new file mode 100644 index 0000000000..27b1a74105 --- /dev/null +++ b/board/amlogic/beelink-s922x/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# (C) Copyright 2020 BayLibre, SAS +# Author: Neil Armstrong <narmstrong@baylibre.com> + +obj-y := beelink-s922x.o diff --git a/board/amlogic/beelink-s922x/beelink-s922x.c b/board/amlogic/beelink-s922x/beelink-s922x.c new file mode 100644 index 0000000000..dc0d933a39 --- /dev/null +++ b/board/amlogic/beelink-s922x/beelink-s922x.c @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2020 BayLibre, SAS + * Author: Neil Armstrong <narmstrong@baylibre.com> + */ + +#include <common.h> +#include <dm.h> +#include <env.h> +#include <init.h> +#include <net.h> +#include <asm/io.h> +#include <asm/arch/sm.h> +#include <asm/arch/eth.h> +#include <asm/arch/boot.h> + +#define EFUSE_MAC_OFFSET 20 +#define EFUSE_MAC_SIZE 12 +#define MAC_ADDR_LEN 6 + +int misc_init_r(void) +{ + u8 mac_addr[MAC_ADDR_LEN]; + char efuse_mac_addr[EFUSE_MAC_SIZE], tmp[3]; + ssize_t len; + + if (IS_ENABLED(CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG) && + meson_get_soc_rev(tmp, sizeof(tmp)) > 0) + env_set("soc_rev", tmp); + + meson_eth_init(PHY_INTERFACE_MODE_RGMII, 0); + + if (!eth_env_get_enetaddr("ethaddr", mac_addr)) { + len = meson_sm_read_efuse(EFUSE_MAC_OFFSET, + efuse_mac_addr, EFUSE_MAC_SIZE); + if (len != EFUSE_MAC_SIZE) + return 0; + + /* MAC is stored in ASCII format, 1bytes = 2characters */ + for (int i = 0; i < 6; i++) { + tmp[0] = efuse_mac_addr[i * 2]; + tmp[1] = efuse_mac_addr[i * 2 + 1]; + tmp[2] = '\0'; + mac_addr[i] = simple_strtoul(tmp, NULL, 16); + } + + if (is_valid_ethaddr(mac_addr)) + eth_env_set_enetaddr("ethaddr", mac_addr); + else + meson_generate_serial_ethaddr(); + } + + return 0; +} diff --git a/board/amlogic/odroid-n2/odroid-n2.c b/board/amlogic/odroid-n2/odroid-n2.c index caf7fd6810..d9955433bf 100644 --- a/board/amlogic/odroid-n2/odroid-n2.c +++ b/board/amlogic/odroid-n2/odroid-n2.c @@ -10,19 +10,32 @@ #include <init.h> #include <net.h> #include <asm/io.h> +#include <asm/arch/boot.h> #include <asm/arch/sm.h> #include <asm/arch/eth.h> +#include <asm/arch/boot.h> #define EFUSE_MAC_OFFSET 20 #define EFUSE_MAC_SIZE 12 #define MAC_ADDR_LEN 6 +int mmc_get_env_dev(void) +{ + if (meson_get_boot_device() == BOOT_DEVICE_EMMC) + return 1; + return 0; +} + int misc_init_r(void) { u8 mac_addr[MAC_ADDR_LEN]; char efuse_mac_addr[EFUSE_MAC_SIZE], tmp[3]; ssize_t len; + if (IS_ENABLED(CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG) && + meson_get_soc_rev(tmp, sizeof(tmp)) > 0) + env_set("soc_rev", tmp); + meson_eth_init(PHY_INTERFACE_MODE_RGMII, 0); if (!eth_env_get_enetaddr("ethaddr", mac_addr)) { diff --git a/board/amlogic/p212/MAINTAINERS b/board/amlogic/p212/MAINTAINERS index cae6994393..3d622af29b 100644 --- a/board/amlogic/p212/MAINTAINERS +++ b/board/amlogic/p212/MAINTAINERS @@ -7,6 +7,7 @@ F: include/configs/p212.h F: configs/khadas-vim_defconfig F: configs/libretech-ac_defconfig F: configs/libretech-cc_defconfig +F: configs/libretech-cc_v2_defconfig F: configs/p212_defconfig F: doc/board/amlogic/p212.rst F: doc/board/amlogic/libretech-ac.rst diff --git a/board/amlogic/q200/MAINTAINERS b/board/amlogic/q200/MAINTAINERS index ec05aa6f4c..ba7c12b2c1 100644 --- a/board/amlogic/q200/MAINTAINERS +++ b/board/amlogic/q200/MAINTAINERS @@ -7,4 +7,6 @@ F: include/configs/q200.h F: configs/khadas-vim2_defconfig F: configs/libretech-s905d-pc_defconfig F: configs/libretech-s912-pc_defconfig +F: configs/wetek-core2_defconfig F: doc/board/amlogic/khadas-vim2.rst +F: doc/board/amlogic/wetek-core2.rst diff --git a/board/amlogic/vim3/vim3.c b/board/amlogic/vim3/vim3.c index 09ef39ff30..7145dbe18e 100644 --- a/board/amlogic/vim3/vim3.c +++ b/board/amlogic/vim3/vim3.c @@ -10,10 +10,19 @@ #include <init.h> #include <net.h> #include <asm/io.h> +#include <asm/arch/boot.h> #include <asm/arch/eth.h> +#include <asm/arch/sm.h> #include <i2c.h> #include "khadas-mcu.h" +int mmc_get_env_dev(void) +{ + if (meson_get_boot_device() == BOOT_DEVICE_EMMC) + return 2; + return 1; +} + /* * The VIM3 on-board MCU can mux the PCIe/USB3.0 shared differential * lines using a FUSB340TMX USB 3.1 SuperSpeed Data Switch between @@ -129,9 +138,39 @@ int meson_ft_board_setup(void *blob, struct bd_info *bd) return 0; } +#define EFUSE_MAC_OFFSET 0 +#define EFUSE_MAC_SIZE 12 +#define MAC_ADDR_LEN 6 + int misc_init_r(void) { + u8 mac_addr[MAC_ADDR_LEN]; + char efuse_mac_addr[EFUSE_MAC_SIZE], tmp[3]; + ssize_t len; + meson_eth_init(PHY_INTERFACE_MODE_RGMII, 0); + if (!eth_env_get_enetaddr("ethaddr", mac_addr)) { + len = meson_sm_read_efuse(EFUSE_MAC_OFFSET, + efuse_mac_addr, EFUSE_MAC_SIZE); + if (len != EFUSE_MAC_SIZE) + return 0; + + /* MAC is stored in ASCII format, 1bytes = 2characters */ + for (int i = 0; i < 6; i++) { + tmp[0] = efuse_mac_addr[i * 2]; + tmp[1] = efuse_mac_addr[i * 2 + 1]; + tmp[2] = '\0'; + mac_addr[i] = simple_strtoul(tmp, NULL, 16); + } + + if (is_valid_ethaddr(mac_addr)) + eth_env_set_enetaddr("ethaddr", mac_addr); + else + meson_generate_serial_ethaddr(); + + eth_env_get_enetaddr("ethaddr", mac_addr); + } + return 0; } diff --git a/board/aspeed/evb_ast2600/Kconfig b/board/aspeed/evb_ast2600/Kconfig new file mode 100644 index 0000000000..42008cd033 --- /dev/null +++ b/board/aspeed/evb_ast2600/Kconfig @@ -0,0 +1,12 @@ +if TARGET_EVB_AST2600 + +config SYS_BOARD + default "evb_ast2600" + +config SYS_VENDOR + default "aspeed" + +config SYS_CONFIG_NAME + default "evb_ast2600" + +endif diff --git a/board/aspeed/evb_ast2600/MAINTAINERS b/board/aspeed/evb_ast2600/MAINTAINERS new file mode 100644 index 0000000000..e83aae5d6a --- /dev/null +++ b/board/aspeed/evb_ast2600/MAINTAINERS @@ -0,0 +1,6 @@ +EVB AST2600 BOARD +M: Chia-Wei, Wang <chiawei_wang@aspeedtech.com> +S: Maintained +F: board/aspeed/evb_ast2600/ +F: include/configs/evb_ast2600.h +F: configs/evb-ast2600_defconfig diff --git a/board/aspeed/evb_ast2600/Makefile b/board/aspeed/evb_ast2600/Makefile new file mode 100644 index 0000000000..9291db6ee1 --- /dev/null +++ b/board/aspeed/evb_ast2600/Makefile @@ -0,0 +1 @@ +obj-y += evb_ast2600.o diff --git a/board/aspeed/evb_ast2600/evb_ast2600.c b/board/aspeed/evb_ast2600/evb_ast2600.c new file mode 100644 index 0000000000..e6dc8c7952 --- /dev/null +++ b/board/aspeed/evb_ast2600/evb_ast2600.c @@ -0,0 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) Aspeed Technology Inc. + */ +#include <common.h> diff --git a/board/dhelectronics/dh_stm32mp1/u-boot-dhcom.its b/board/dhelectronics/dh_stm32mp1/u-boot-dhcom.its index ba48786e08..8eed9d0fb2 100644 --- a/board/dhelectronics/dh_stm32mp1/u-boot-dhcom.its +++ b/board/dhelectronics/dh_stm32mp1/u-boot-dhcom.its @@ -47,28 +47,28 @@ config-1 { /* DT+SoM+board model */ description = "dh,stm32mp15xx-dhcom-pdk2_somrev0_boardrev0"; - loadables = "uboot"; + firmware = "uboot"; fdt = "fdt-1"; }; config-2 { /* DT+SoM+board model */ description = "dh,stm32mp15xx-dhcom-pdk2_somrev1_boardrev0"; - loadables = "uboot"; + firmware = "uboot"; fdt = "fdt-1"; }; config-3 { /* DT+SoM+board model */ description = "dh,stm32mp15xx-dhcom-drc02_somrev0_boardrev0"; - loadables = "uboot"; + firmware = "uboot"; fdt = "fdt-2"; }; config-4 { /* DT+SoM+board model */ description = "dh,stm32mp15xx-dhcom-drc02_somrev1_boardrev0"; - loadables = "uboot"; + firmware = "uboot"; fdt = "fdt-2"; }; diff --git a/board/dhelectronics/dh_stm32mp1/u-boot-dhcor.its b/board/dhelectronics/dh_stm32mp1/u-boot-dhcor.its index 7419684f55..0ea10a1497 100644 --- a/board/dhelectronics/dh_stm32mp1/u-boot-dhcor.its +++ b/board/dhelectronics/dh_stm32mp1/u-boot-dhcor.its @@ -31,7 +31,7 @@ config-1 { /* DT+SoM+board model */ description = "arrow,stm32mp15xx-avenger96_somrev0_boardrev1"; - loadables = "uboot"; + firmware = "uboot"; fdt = "fdt-1"; }; diff --git a/board/intel/agilex-socdk/MAINTAINERS b/board/intel/agilex-socdk/MAINTAINERS index b8e28f0b24..18edbdcd2f 100644 --- a/board/intel/agilex-socdk/MAINTAINERS +++ b/board/intel/agilex-socdk/MAINTAINERS @@ -4,4 +4,5 @@ M: Chee Hong Ang <chee.hong.ang@intel.com> S: Maintained F: board/intel/agilex-socdk/ F: include/configs/socfpga_agilex_socdk.h +F: configs/socfpga_agilex_atf_defconfig F: configs/socfpga_agilex_defconfig diff --git a/board/keymile/km_arm/Kconfig b/board/keymile/km_arm/Kconfig index 4b21db8573..6f55cfab86 100644 --- a/board/keymile/km_arm/Kconfig +++ b/board/keymile/km_arm/Kconfig @@ -58,8 +58,12 @@ config BOARD_SPECIFIC_OPTIONS # dummy select DM_SERIAL select DM_SPI select DM_SPI_FLASH + select USB + select USB_EHCI_HCD + select USB_EHCI_MARVELL imply CMD_CRAMFS imply CMD_DIAG imply FS_CRAMFS + imply CMD_USB endif diff --git a/board/mediatek/pumpkin/pumpkin.c b/board/mediatek/pumpkin/pumpkin.c index 666e4d6a26..37daf1c51b 100644 --- a/board/mediatek/pumpkin/pumpkin.c +++ b/board/mediatek/pumpkin/pumpkin.c @@ -4,8 +4,25 @@ */ #include <common.h> +#include <dm.h> int board_init(void) { return 0; } + +int board_late_init(void) +{ + struct udevice *dev; + int ret; + + if (CONFIG_IS_ENABLED(USB_GADGET)) { + ret = uclass_get_device(UCLASS_USB_GADGET_GENERIC, 0, &dev); + if (ret) { + pr_err("%s: Cannot find USB device\n", __func__); + return ret; + } + } + + return 0; +} diff --git a/board/microchip/mpfs_icicle/Kconfig b/board/microchip/mpfs_icicle/Kconfig index bf8e1a13ec..4678462378 100644 --- a/board/microchip/mpfs_icicle/Kconfig +++ b/board/microchip/mpfs_icicle/Kconfig @@ -20,7 +20,30 @@ config BOARD_SPECIFIC_OPTIONS # dummy def_bool y select GENERIC_RISCV select BOARD_EARLY_INIT_F + select BOARD_LATE_INIT imply SMP + imply CLK_CCF + imply CLK_MPFS imply SYS_NS16550 + imply CMD_DHCP + imply CMD_EXT2 + imply CMD_EXT4 + imply CMD_FAT + imply CMD_FS_GENERIC + imply CMD_NET + imply CMD_PING + imply CMD_MMC + imply DOS_PARTITION + imply EFI_PARTITION + imply IP_DYN + imply ISO_PARTITION + imply MACB + imply MII + imply PHY_LIB + imply PHY_VITESSE + imply MMC + imply MMC_WRITE + imply MMC_SDHCI + imply MMC_SDHCI_CADENCE endif diff --git a/board/microchip/mpfs_icicle/mpfs_icicle.c b/board/microchip/mpfs_icicle/mpfs_icicle.c index 8381361ec3..0e34409067 100644 --- a/board/microchip/mpfs_icicle/mpfs_icicle.c +++ b/board/microchip/mpfs_icicle/mpfs_icicle.c @@ -6,10 +6,49 @@ #include <common.h> #include <dm.h> +#include <env.h> #include <init.h> #include <asm/io.h> -#define MPFS_SYSREG_SOFT_RESET ((unsigned int *)0x20002088) +DECLARE_GLOBAL_DATA_PTR; + +#define MPFS_SYSREG_SOFT_RESET ((unsigned int *)0x20002088) +#define MPFS_SYS_SERVICE_CR ((unsigned int *)0x37020050) +#define MPFS_SYS_SERVICE_SR ((unsigned int *)0x37020054) +#define MPFS_SYS_SERVICE_MAILBOX ((unsigned char *)0x37020800) + +#define PERIPH_RESET_VALUE 0x1e8u +#define SERVICE_CR_REQ 0x1u +#define SERVICE_SR_BUSY 0x2u + +static void read_device_serial_number(u8 *response, u8 response_size) +{ + u8 idx; + u8 *response_buf; + unsigned int val; + + response_buf = (u8 *)response; + + writel(SERVICE_CR_REQ, MPFS_SYS_SERVICE_CR); + /* + * REQ bit will remain set till the system controller starts + * processing. + */ + do { + val = readl(MPFS_SYS_SERVICE_CR); + } while (SERVICE_CR_REQ == (val & SERVICE_CR_REQ)); + + /* + * Once system controller starts processing the busy bit will + * go high and service is completed when busy bit is gone low + */ + do { + val = readl(MPFS_SYS_SERVICE_SR); + } while (SERVICE_SR_BUSY == (val & SERVICE_SR_BUSY)); + + for (idx = 0; idx < response_size; idx++) + response_buf[idx] = readb(MPFS_SYS_SERVICE_MAILBOX + idx); +} int board_init(void) { @@ -22,10 +61,64 @@ int board_early_init_f(void) { unsigned int val; - /* Reset uart peripheral */ + /* Reset uart, mmc peripheral */ val = readl(MPFS_SYSREG_SOFT_RESET); - val = (val & ~(1u << 5u)); + val = (val & ~(PERIPH_RESET_VALUE)); writel(val, MPFS_SYSREG_SOFT_RESET); return 0; } + +int board_late_init(void) +{ + u32 ret; + u32 node; + u8 idx; + u8 device_serial_number[16] = { 0 }; + unsigned char mac_addr[6]; + char icicle_mac_addr[20]; + void *blob = (void *)gd->fdt_blob; + + node = fdt_path_offset(blob, "ethernet0"); + if (node < 0) { + printf("No ethernet0 path offset\n"); + return -ENODEV; + } + + ret = fdtdec_get_byte_array(blob, node, "local-mac-address", mac_addr, 6); + if (ret) { + printf("No local-mac-address property\n"); + return -EINVAL; + } + + read_device_serial_number(device_serial_number, 16); + + /* Update MAC address with device serial number */ + mac_addr[0] = 0x00; + mac_addr[1] = 0x04; + mac_addr[2] = 0xA3; + mac_addr[3] = device_serial_number[2]; + mac_addr[4] = device_serial_number[1]; + mac_addr[5] = device_serial_number[0]; + + ret = fdt_setprop(blob, node, "local-mac-address", mac_addr, 6); + if (ret) { + printf("Error setting local-mac-address property\n"); + return -ENODEV; + } + + icicle_mac_addr[0] = '['; + + sprintf(&icicle_mac_addr[1], "%pM", mac_addr); + + icicle_mac_addr[18] = ']'; + icicle_mac_addr[19] = '\0'; + + for (idx = 0; idx < 20; idx++) { + if (icicle_mac_addr[idx] == ':') + icicle_mac_addr[idx] = ' '; + } + env_set("icicle_mac_addr", icicle_mac_addr); + + return 0; +} diff --git a/board/rockchip/evb_rk3328/MAINTAINERS b/board/rockchip/evb_rk3328/MAINTAINERS index e7dd59ff4e..14fda46e8f 100644 --- a/board/rockchip/evb_rk3328/MAINTAINERS +++ b/board/rockchip/evb_rk3328/MAINTAINERS @@ -5,6 +5,13 @@ F: board/rockchip/evb_rk3328 F: include/configs/evb_rk3328.h F: configs/evb-rk3328_defconfig +NANOPI-R2S-RK3328 +M: David Bauer <mail@david-bauer.net> +S: Maintained +F: configs/nanopi-r2s-rk3328_defconfig +F: arch/arm/dts/rk3328-nanopi-r2s-u-boot.dtsi +F: arch/arm/dts/rk3328-nanopi-r2s.dts + ROC-RK3328-CC M: Loic Devulder <ldevulder@suse.com> M: Chen-Yu Tsai <wens@csie.org> diff --git a/board/sipeed/maix/Kconfig b/board/sipeed/maix/Kconfig index 4c42dd2087..2cdea8ea81 100644 --- a/board/sipeed/maix/Kconfig +++ b/board/sipeed/maix/Kconfig @@ -53,4 +53,20 @@ config BOARD_SPECIFIC_OPTIONS imply CMD_GPIO imply LED imply LED_GPIO + imply SPI + imply DESIGNWARE_SPI + imply SPI_FLASH_GIGADEVICE + imply SPI_FLASH_WINBOND + imply DM_MTD + imply SPI_FLASH_MTD + imply CMD_MTD + imply ENV_IS_IN_SPI_FLASH + imply MMC + imply MMC_BROKEN_CD + imply MMC_SPI + imply CMD_MMC + imply DOS_PARTITION + imply EFI_PARTITION + imply CMD_PART + imply CMD_FS_GENERIC endif diff --git a/board/st/common/MAINTAINERS b/board/st/common/MAINTAINERS index 3b02f4ab98..c4e0c5fd94 100644 --- a/board/st/common/MAINTAINERS +++ b/board/st/common/MAINTAINERS @@ -1,5 +1,5 @@ ST BOARDS -M: Patrick Delaunay <patrick.delaunay@st.com> +M: Patrick Delaunay <patrick.delaunay@foss.st.com> L: uboot-stm32@st-md-mailman.stormreply.com (moderated for non-subscribers) T: git https://gitlab.denx.de/u-boot/custodians/u-boot-stm.git S: Maintained diff --git a/board/st/common/stm32mp_dfu.c b/board/st/common/stm32mp_dfu.c index 9c3d115dce..5633a6cb95 100644 --- a/board/st/common/stm32mp_dfu.c +++ b/board/st/common/stm32mp_dfu.c @@ -8,6 +8,7 @@ #include <dm.h> #include <dfu.h> #include <env.h> +#include <log.h> #include <memalign.h> #include <misc.h> #include <mtd.h> @@ -199,7 +200,7 @@ static int dfu_pmic_read(u64 offset, u8 *buffer, long *size) ret = 0; } #else - pr_err("PMIC update not supported"); + log_err("PMIC update not supported"); ret = -EOPNOTSUPP; #endif diff --git a/board/st/common/stm32mp_mtdparts.c b/board/st/common/stm32mp_mtdparts.c index 9f5897f8c8..71a0b449ad 100644 --- a/board/st/common/stm32mp_mtdparts.c +++ b/board/st/common/stm32mp_mtdparts.c @@ -8,6 +8,7 @@ #include <dm.h> #include <env.h> #include <env_internal.h> +#include <log.h> #include <mtd.h> #include <mtd_node.h> #include <tee.h> @@ -117,7 +118,7 @@ void board_mtdparts_default(const char **mtdids, const char **mtdparts) for (uclass_first_device(UCLASS_MTD, &dev); dev; uclass_next_device(&dev)) { - pr_debug("mtd device = %s\n", dev->name); + log_debug("mtd device = %s\n", dev->name); } if (nor || nand) { @@ -163,5 +164,5 @@ void board_mtdparts_default(const char **mtdids, const char **mtdparts) mtd_initialized = true; *mtdids = ids; *mtdparts = parts; - debug("%s:mtdids=%s & mtdparts=%s\n", __func__, ids, parts); + log_debug("mtdids=%s & mtdparts=%s\n", ids, parts); } diff --git a/board/st/common/stpmic1.c b/board/st/common/stpmic1.c index a313b817c5..5fb1be2fd3 100644 --- a/board/st/common/stpmic1.c +++ b/board/st/common/stpmic1.c @@ -3,8 +3,11 @@ * Copyright (C) 2020, STMicroelectronics - All Rights Reserved */ +#define LOG_CATEGORY LOGC_BOARD + #include <common.h> #include <dm.h> +#include <log.h> #include <asm/io.h> #include <asm/arch/ddr.h> #include <linux/bitops.h> @@ -202,7 +205,7 @@ void stpmic1_init(u32 voltage_mv) /* Check if debug is enabled to program PMIC according to the bit */ if (readl(TAMP_BOOT_CONTEXT) & TAMP_BOOT_DEBUG_ON) { - printf("Keep debug unit ON\n"); + log_info("Keep debug unit ON\n"); pmic_clrsetbits(dev, STPMIC1_BUCKS_MRST_CR, STPMIC1_MRST_BUCK_DEBUG, diff --git a/board/st/common/stusb160x.c b/board/st/common/stusb160x.c index e0a2b76353..f0385e5e38 100644 --- a/board/st/common/stusb160x.c +++ b/board/st/common/stusb160x.c @@ -6,6 +6,8 @@ * Copyright (C) 2020, STMicroelectronics - All Rights Reserved */ +#define LOG_CATEGORY UCLASS_I2C_GENERIC + #include <common.h> #include <dm.h> #include <i2c.h> diff --git a/board/st/stih410-b2260/MAINTAINERS b/board/st/stih410-b2260/MAINTAINERS index 4f557ac7d9..6fa625507b 100644 --- a/board/st/stih410-b2260/MAINTAINERS +++ b/board/st/stih410-b2260/MAINTAINERS @@ -1,5 +1,5 @@ STIH410-B2260 BOARD -M: Patrice Chotard <patrice.chotard@st.com> +M: Patrice Chotard <patrice.chotard@foss.st.com> S: Maintained F: board/st/stih410-b2260/ F: include/configs/stih410-b2260.h diff --git a/board/st/stih410-b2260/Makefile b/board/st/stih410-b2260/Makefile index dc3e1d3959..ea573ca145 100644 --- a/board/st/stih410-b2260/Makefile +++ b/board/st/stih410-b2260/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0+ # # Copyright (C) 2017, STMicroelectronics - All Rights Reserved -# Author(s): Patrice CHOTARD, <patrice.chotard@st.com> for STMicroelectronics. +# Author(s): Patrice CHOTARD, <patrice.chotard@foss.st.com> for STMicroelectronics. obj-y = board.o diff --git a/board/st/stm32f429-evaluation/MAINTAINERS b/board/st/stm32f429-evaluation/MAINTAINERS index 8b7b312eee..29d00ef27e 100644 --- a/board/st/stm32f429-evaluation/MAINTAINERS +++ b/board/st/stm32f429-evaluation/MAINTAINERS @@ -1,5 +1,5 @@ STM32F429-EVALUATION BOARD -M: Patrice Chotard <patrice.chotard@st.com> +M: Patrice Chotard <patrice.chotard@foss.st.com> S: Maintained F: board/st/stm32f429-evaluation/ F: include/configs/stm32f429-evaluation.h diff --git a/board/st/stm32f429-evaluation/Makefile b/board/st/stm32f429-evaluation/Makefile index 8bf9e1f6d8..109fba876b 100644 --- a/board/st/stm32f429-evaluation/Makefile +++ b/board/st/stm32f429-evaluation/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0+ # # Copyright (C) 2018, STMicroelectronics - All Rights Reserved -# Author(s): Patrice CHOTARD, <patrice.chotard@st.com> for STMicroelectronics. +# Author(s): Patrice CHOTARD, <patrice.chotard@foss.st.com> for STMicroelectronics. obj-y := stm32f429-evaluation.o diff --git a/board/st/stm32f469-discovery/MAINTAINERS b/board/st/stm32f469-discovery/MAINTAINERS index d3c791a5f5..5a6a78b39e 100644 --- a/board/st/stm32f469-discovery/MAINTAINERS +++ b/board/st/stm32f469-discovery/MAINTAINERS @@ -1,5 +1,5 @@ STM32F469-DISCOVERY BOARD -M: Patrice Chotard <patrice.chotard@st.com> +M: Patrice Chotard <patrice.chotard@foss.st.com> S: Maintained F: board/st/stm32f469-discovery/ F: include/configs/stm32f469-discovery.h diff --git a/board/st/stm32f469-discovery/Makefile b/board/st/stm32f469-discovery/Makefile index 249835b122..45480b72c5 100644 --- a/board/st/stm32f469-discovery/Makefile +++ b/board/st/stm32f469-discovery/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0+ # # Copyright (C) STMicroelectronics SA 2017 -# Author(s): Patrice CHOTARD, <patrice.chotard@st.com> for STMicroelectronics. +# Author(s): Patrice CHOTARD, <patrice.chotard@foss.st.com> for STMicroelectronics. obj-y := stm32f469-discovery.o diff --git a/board/st/stm32h743-disco/MAINTAINERS b/board/st/stm32h743-disco/MAINTAINERS index e5e0b5a6f2..60fbe344f8 100644 --- a/board/st/stm32h743-disco/MAINTAINERS +++ b/board/st/stm32h743-disco/MAINTAINERS @@ -1,5 +1,5 @@ STM32H743 DISCOVERY BOARD -M: Patrice Chotard <patrice.chotard@st.com> +M: Patrice Chotard <patrice.chotard@foss.st.com> S: Maintained F: board/st/stm32h743-disco F: include/configs/stm32h743-disco.h diff --git a/board/st/stm32h743-disco/Makefile b/board/st/stm32h743-disco/Makefile index 8fe7a2d6ff..b6c22be1ea 100644 --- a/board/st/stm32h743-disco/Makefile +++ b/board/st/stm32h743-disco/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0+ # # Copyright (C) 2017, STMicroelectronics - All Rights Reserved -# Author(s): Patrice CHOTARD, <patrice.chotard@st.com> for STMicroelectronics. +# Author(s): Patrice CHOTARD, <patrice.chotard@foss.st.com> for STMicroelectronics. obj-y := stm32h743-disco.o diff --git a/board/st/stm32h743-eval/MAINTAINERS b/board/st/stm32h743-eval/MAINTAINERS index 3029c56023..fda93db777 100644 --- a/board/st/stm32h743-eval/MAINTAINERS +++ b/board/st/stm32h743-eval/MAINTAINERS @@ -1,5 +1,5 @@ STM32H743 EVALUATION BOARD -M: Patrice Chotard <patrice.chotard@st.com> +M: Patrice Chotard <patrice.chotard@foss.st.com> S: Maintained F: board/st/stm32h743-eval F: include/configs/stm32h743-eval.h diff --git a/board/st/stm32h743-eval/Makefile b/board/st/stm32h743-eval/Makefile index 88b59fda0d..86ef19fc36 100644 --- a/board/st/stm32h743-eval/Makefile +++ b/board/st/stm32h743-eval/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0+ # # Copyright (C) 2017, STMicroelectronics - All Rights Reserved -# Author(s): Patrice CHOTARD, <patrice.chotard@st.com> for STMicroelectronics. +# Author(s): Patrice CHOTARD, <patrice.chotard@foss.st.com> for STMicroelectronics. obj-y := stm32h743-eval.o diff --git a/board/st/stm32mp1/MAINTAINERS b/board/st/stm32mp1/MAINTAINERS index 96c4559033..bd5c07da34 100644 --- a/board/st/stm32mp1/MAINTAINERS +++ b/board/st/stm32mp1/MAINTAINERS @@ -1,5 +1,5 @@ STM32MP1 BOARD -M: Patrick Delaunay <patrick.delaunay@st.com> +M: Patrick Delaunay <patrick.delaunay@foss.st.com> L: uboot-stm32@st-md-mailman.stormreply.com (moderated for non-subscribers) T: git https://gitlab.denx.de/u-boot/custodians/u-boot-stm.git S: Maintained diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c index df353cb5ec..78362d24a2 100644 --- a/board/st/stm32mp1/stm32mp1.c +++ b/board/st/stm32mp1/stm32mp1.c @@ -2,6 +2,9 @@ /* * Copyright (C) 2018, STMicroelectronics - All Rights Reserved */ + +#define LOG_CATEGORY LOGC_BOARD + #include <common.h> #include <adc.h> #include <bootm.h> @@ -106,12 +109,11 @@ int checkboard(void) else mode = "basic"; - printf("Board: stm32mp1 in %s mode", mode); fdt_compat = fdt_getprop(gd->fdt_blob, 0, "compatible", &fdt_compat_len); - if (fdt_compat && fdt_compat_len) - printf(" (%s)", fdt_compat); - puts("\n"); + + log_info("Board: stm32mp1 in %s mode (%s)\n", mode, + fdt_compat && fdt_compat_len ? fdt_compat : ""); /* display the STMicroelectronics board identification */ if (CONFIG_IS_ENABLED(CMD_STBOARD)) { @@ -122,12 +124,12 @@ int checkboard(void) ret = misc_read(dev, STM32_BSEC_SHADOW(BSEC_OTP_BOARD), &otp, sizeof(otp)); if (ret > 0 && otp) - printf("Board: MB%04x Var%d.%d Rev.%c-%02d\n", - otp >> 16, - (otp >> 12) & 0xF, - (otp >> 4) & 0xF, - ((otp >> 8) & 0xF) - 1 + 'A', - otp & 0xF); + log_info("Board: MB%04x Var%d.%d Rev.%c-%02d\n", + otp >> 16, + (otp >> 12) & 0xF, + (otp >> 4) & 0xF, + ((otp >> 8) & 0xF) - 1 + 'A', + otp & 0xF); } return 0; @@ -144,17 +146,16 @@ static void board_key_check(void) node = ofnode_path("/config"); if (!ofnode_valid(node)) { - debug("%s: no /config node?\n", __func__); + log_debug("no /config node?\n"); return; } if (IS_ENABLED(CONFIG_FASTBOOT)) { if (gpio_request_by_name_nodev(node, "st,fastboot-gpios", 0, &gpio, GPIOD_IS_IN)) { - debug("%s: could not find a /config/st,fastboot-gpios\n", - __func__); + log_debug("could not find a /config/st,fastboot-gpios\n"); } else { if (dm_gpio_get_value(&gpio)) { - puts("Fastboot key pressed, "); + log_notice("Fastboot key pressed, "); boot_mode = BOOT_FASTBOOT; } @@ -164,18 +165,17 @@ static void board_key_check(void) if (IS_ENABLED(CONFIG_CMD_STM32PROG)) { if (gpio_request_by_name_nodev(node, "st,stm32prog-gpios", 0, &gpio, GPIOD_IS_IN)) { - debug("%s: could not find a /config/st,stm32prog-gpios\n", - __func__); + log_debug("could not find a /config/st,stm32prog-gpios\n"); } else { if (dm_gpio_get_value(&gpio)) { - puts("STM32Programmer key pressed, "); + log_notice("STM32Programmer key pressed, "); boot_mode = BOOT_STM32PROG; } dm_gpio_free(NULL, &gpio); } } if (boot_mode != BOOT_NORMAL) { - puts("entering download mode...\n"); + log_notice("entering download mode...\n"); clrsetbits_le32(TAMP_BOOT_CONTEXT, TAMP_BOOT_FORCED_MASK, boot_mode); @@ -198,8 +198,10 @@ int g_dnl_board_usb_cable_connected(void) ret = uclass_get_device_by_driver(UCLASS_USB_GADGET_GENERIC, DM_DRIVER_GET(dwc2_udc_otg), &dwc2_udc_otg); - if (!ret) - debug("dwc2_udc_otg init failed\n"); + if (ret) { + log_debug("dwc2_udc_otg init failed\n"); + return ret; + } return dwc2_udc_B_session_valid(dwc2_udc_otg); } @@ -231,13 +233,12 @@ static int get_led(struct udevice **dev, char *led_string) led_name = fdtdec_get_config_string(gd->fdt_blob, led_string); if (!led_name) { - pr_debug("%s: could not find %s config string\n", - __func__, led_string); + log_debug("could not find %s config string\n", led_string); return -ENOENT; } ret = led_get_by_label(led_name, dev); if (ret) { - debug("%s: get=%d\n", __func__, ret); + log_debug("get=%d\n", ret); return ret; } @@ -288,49 +289,19 @@ static void __maybe_unused led_error_blink(u32 nb_blink) hang(); } -static int board_check_usb_power(void) +static int adc_measurement(ofnode node, int adc_count, int *min_uV, int *max_uV) { struct ofnode_phandle_args adc_args; struct udevice *adc; - ofnode node; unsigned int raw; - int max_uV = 0; - int min_uV = USB_START_HIGH_THRESHOLD_UV; - int ret, uV, adc_count; - u32 nb_blink; - u8 i; - - if (!IS_ENABLED(CONFIG_ADC)) - return -ENODEV; - - node = ofnode_path("/config"); - if (!ofnode_valid(node)) { - debug("%s: no /config node?\n", __func__); - return -ENOENT; - } - - /* - * Retrieve the ADC channels devices and get measurement - * for each of them - */ - adc_count = ofnode_count_phandle_with_args(node, "st,adc_usb_pd", - "#io-channel-cells", 0); - if (adc_count < 0) { - if (adc_count == -ENOENT) - return 0; - - pr_err("%s: can't find adc channel (%d)\n", __func__, - adc_count); - - return adc_count; - } + int ret, uV; + int i; for (i = 0; i < adc_count; i++) { if (ofnode_parse_phandle_with_args(node, "st,adc_usb_pd", "#io-channel-cells", 0, i, &adc_args)) { - pr_debug("%s: can't find /config/st,adc_usb_pd\n", - __func__); + log_debug("can't find /config/st,adc_usb_pd\n"); return 0; } @@ -338,44 +309,91 @@ static int board_check_usb_power(void) &adc); if (ret) { - pr_err("%s: Can't get adc device(%d)\n", __func__, - ret); + log_err("Can't get adc device(%d)\n", ret); return ret; } ret = adc_channel_single_shot(adc->name, adc_args.args[0], &raw); if (ret) { - pr_err("%s: single shot failed for %s[%d]!\n", - __func__, adc->name, adc_args.args[0]); + log_err("single shot failed for %s[%d]!\n", + adc->name, adc_args.args[0]); return ret; } /* Convert to uV */ if (!adc_raw_to_uV(adc, raw, &uV)) { - if (uV > max_uV) - max_uV = uV; - if (uV < min_uV) - min_uV = uV; - pr_debug("%s: %s[%02d] = %u, %d uV\n", __func__, - adc->name, adc_args.args[0], raw, uV); + if (uV > *max_uV) + *max_uV = uV; + if (uV < *min_uV) + *min_uV = uV; + log_debug("%s[%02d] = %u, %d uV\n", + adc->name, adc_args.args[0], raw, uV); } else { - pr_err("%s: Can't get uV value for %s[%d]\n", - __func__, adc->name, adc_args.args[0]); + log_err("Can't get uV value for %s[%d]\n", + adc->name, adc_args.args[0]); } } + return 0; +} + +static int board_check_usb_power(void) +{ + ofnode node; + int max_uV = 0; + int min_uV = USB_START_HIGH_THRESHOLD_UV; + int adc_count, ret; + u32 nb_blink; + u8 i; + + node = ofnode_path("/config"); + if (!ofnode_valid(node)) { + log_debug("no /config node?\n"); + return -ENOENT; + } + /* - * If highest value is inside 1.23 Volts and 2.10 Volts, that means - * board is plugged on an USB-C 3A power supply and boot process can - * continue. + * Retrieve the ADC channels devices and get measurement + * for each of them */ - if (max_uV > USB_START_LOW_THRESHOLD_UV && - max_uV <= USB_START_HIGH_THRESHOLD_UV && - min_uV <= USB_LOW_THRESHOLD_UV) - return 0; + adc_count = ofnode_count_phandle_with_args(node, "st,adc_usb_pd", + "#io-channel-cells", 0); + if (adc_count < 0) { + if (adc_count == -ENOENT) + return 0; + + log_err("Can't find adc channel (%d)\n", adc_count); + + return adc_count; + } - pr_err("****************************************************\n"); + /* perform maximum of 2 ADC measurements to detect power supply current */ + for (i = 0; i < 2; i++) { + if (IS_ENABLED(CONFIG_ADC)) + ret = adc_measurement(node, adc_count, &min_uV, &max_uV); + else + ret = -ENODEV; + + if (ret) + return ret; + + /* + * If highest value is inside 1.23 Volts and 2.10 Volts, that means + * board is plugged on an USB-C 3A power supply and boot process can + * continue. + */ + if (max_uV > USB_START_LOW_THRESHOLD_UV && + max_uV <= USB_START_HIGH_THRESHOLD_UV && + min_uV <= USB_LOW_THRESHOLD_UV) + return 0; + + if (i == 0) { + log_err("Previous ADC measurements was not the one expected, retry in 20ms\n"); + mdelay(20); /* equal to max tPDDebounce duration (min 10ms - max 20ms) */ + } + } + log_notice("****************************************************\n"); /* * If highest and lowest value are either both below * USB_LOW_THRESHOLD_UV or both above USB_LOW_THRESHOLD_UV, that @@ -386,8 +404,8 @@ static int board_check_usb_power(void) min_uV > USB_LOW_THRESHOLD_UV) || (max_uV <= USB_LOW_THRESHOLD_UV && min_uV <= USB_LOW_THRESHOLD_UV)) { - pr_err("* ERROR USB TYPE-C connection in unattached mode *\n"); - pr_err("* Check that USB TYPE-C cable is correctly plugged *\n"); + log_notice("* ERROR USB TYPE-C connection in unattached mode *\n"); + log_notice("* Check that USB TYPE-C cable is correctly plugged *\n"); /* with 125ms interval, led will blink for 17.02 years ....*/ nb_blink = U32_MAX; } @@ -395,14 +413,14 @@ static int board_check_usb_power(void) if (max_uV > USB_LOW_THRESHOLD_UV && max_uV <= USB_WARNING_LOW_THRESHOLD_UV && min_uV <= USB_LOW_THRESHOLD_UV) { - pr_err("* WARNING 500mA power supply detected *\n"); + log_notice("* WARNING 500mA power supply detected *\n"); nb_blink = 2; } if (max_uV > USB_WARNING_LOW_THRESHOLD_UV && max_uV <= USB_START_LOW_THRESHOLD_UV && min_uV <= USB_LOW_THRESHOLD_UV) { - pr_err("* WARNING 1.5A power supply detected *\n"); + log_notice("* WARNING 1.5A power supply detected *\n"); nb_blink = 3; } @@ -411,14 +429,14 @@ static int board_check_usb_power(void) * supplies more than 3 Amp, this is not compliant with TypeC specification */ if (max_uV > USB_START_HIGH_THRESHOLD_UV) { - pr_err("* USB TYPE-C charger not compliant with *\n"); - pr_err("* specification *\n"); - pr_err("****************************************************\n\n"); + log_notice("* USB TYPE-C charger not compliant with *\n"); + log_notice("* specification *\n"); + log_notice("****************************************************\n\n"); /* with 125ms interval, led will blink for 17.02 years ....*/ nb_blink = U32_MAX; } else { - pr_err("* Current too low, use a 3A power supply! *\n"); - pr_err("****************************************************\n\n"); + log_notice("* Current too low, use a 3A power supply! *\n"); + log_notice("****************************************************\n\n"); } led_error_blink(nb_blink); @@ -471,7 +489,7 @@ static void sysconf_init(void) DM_DRIVER_GET(stm32mp_bsec), &dev); if (ret) { - pr_err("Can't find stm32mp_bsec driver\n"); + log_err("Can't find stm32mp_bsec driver\n"); return; } @@ -494,13 +512,13 @@ static void sysconf_init(void) syscfg + SYSCFG_IOCTRLSETR); if (!otp) - pr_err("product_below_2v5=0: HSLVEN protected by HW\n"); + log_err("product_below_2v5=0: HSLVEN protected by HW\n"); } else { if (otp) - pr_err("product_below_2v5=1: HSLVEN update is destructive, no update as VDD>2.7V\n"); + log_err("product_below_2v5=1: HSLVEN update is destructive, no update as VDD>2.7V\n"); } } else { - debug("VDD unknown"); + log_debug("VDD unknown"); } } @@ -514,7 +532,7 @@ static void sysconf_init(void) val & SYSCFG_CMPCR_READY, 1000000); if (ret) { - pr_err("SYSCFG: I/O compensation failed, timeout.\n"); + log_err("SYSCFG: I/O compensation failed, timeout.\n"); led_error_blink(10); } @@ -533,39 +551,37 @@ static int dk2_i2c1_fix(void) node = ofnode_path("/soc/i2c@40012000/hdmi-transmitter@39"); if (!ofnode_valid(node)) { - pr_debug("%s: no hdmi-transmitter@39 ?\n", __func__); + log_debug("no hdmi-transmitter@39 ?\n"); return -ENOENT; } if (gpio_request_by_name_nodev(node, "reset-gpios", 0, &hdmi, GPIOD_IS_OUT)) { - pr_debug("%s: could not find reset-gpios\n", - __func__); + log_debug("could not find reset-gpios\n"); return -ENOENT; } node = ofnode_path("/soc/i2c@40012000/cs42l51@4a"); if (!ofnode_valid(node)) { - pr_debug("%s: no cs42l51@4a ?\n", __func__); + log_debug("no cs42l51@4a ?\n"); return -ENOENT; } if (gpio_request_by_name_nodev(node, "reset-gpios", 0, &audio, GPIOD_IS_OUT)) { - pr_debug("%s: could not find reset-gpios\n", - __func__); + log_debug("could not find reset-gpios\n"); return -ENOENT; } /* before power up, insure that HDMI and AUDIO IC is under reset */ ret = dm_gpio_set_value(&hdmi, 1); if (ret) { - pr_err("%s: can't set_value for hdmi_nrst gpio", __func__); + log_err("can't set_value for hdmi_nrst gpio"); goto error; } ret = dm_gpio_set_value(&audio, 1); if (ret) { - pr_err("%s: can't set_value for audio_nrst gpio", __func__); + log_err("can't set_value for audio_nrst gpio"); goto error; } @@ -732,7 +748,7 @@ int board_interface_eth_init(struct udevice *dev, case PHY_INTERFACE_MODE_MII: value = SYSCFG_PMCSETR_ETH_SEL_GMII_MII | SYSCFG_PMCSETR_ETH_REF_CLK_SEL; - debug("%s: PHY_INTERFACE_MODE_MII\n", __func__); + log_debug("PHY_INTERFACE_MODE_MII\n"); break; case PHY_INTERFACE_MODE_GMII: if (eth_clk_sel_reg) @@ -740,7 +756,7 @@ int board_interface_eth_init(struct udevice *dev, SYSCFG_PMCSETR_ETH_CLK_SEL; else value = SYSCFG_PMCSETR_ETH_SEL_GMII_MII; - debug("%s: PHY_INTERFACE_MODE_GMII\n", __func__); + log_debug("PHY_INTERFACE_MODE_GMII\n"); break; case PHY_INTERFACE_MODE_RMII: if (eth_ref_clk_sel_reg) @@ -748,7 +764,7 @@ int board_interface_eth_init(struct udevice *dev, SYSCFG_PMCSETR_ETH_REF_CLK_SEL; else value = SYSCFG_PMCSETR_ETH_SEL_RMII; - debug("%s: PHY_INTERFACE_MODE_RMII\n", __func__); + log_debug("PHY_INTERFACE_MODE_RMII\n"); break; case PHY_INTERFACE_MODE_RGMII: case PHY_INTERFACE_MODE_RGMII_ID: @@ -759,11 +775,11 @@ int board_interface_eth_init(struct udevice *dev, SYSCFG_PMCSETR_ETH_CLK_SEL; else value = SYSCFG_PMCSETR_ETH_SEL_RGMII; - debug("%s: PHY_INTERFACE_MODE_RGMII\n", __func__); + log_debug("PHY_INTERFACE_MODE_RGMII\n"); break; default: - debug("%s: Do not manage %d interface\n", - __func__, interface_type); + log_debug("Do not manage %d interface\n", + interface_type); /* Do not manage others interfaces */ return -EINVAL; } @@ -878,14 +894,14 @@ static void board_copro_image_process(ulong fw_image, size_t fw_size) if (!rproc_is_initialized()) if (rproc_init()) { - printf("Remote Processor %d initialization failed\n", - id); + log_err("Remote Processor %d initialization failed\n", + id); return; } ret = rproc_load(id, fw_image, fw_size); - printf("Load Remote Processor %d with data@addr=0x%08lx %u bytes:%s\n", - id, fw_image, fw_size, ret ? " Failed!" : " Success!"); + log_err("Load Remote Processor %d with data@addr=0x%08lx %u bytes:%s\n", + id, fw_image, fw_size, ret ? " Failed!" : " Success!"); if (!ret) rproc_start(id); diff --git a/board/xilinx/common/board.c b/board/xilinx/common/board.c index cdc06a39ce..df19aeadd0 100644 --- a/board/xilinx/common/board.c +++ b/board/xilinx/common/board.c @@ -324,25 +324,30 @@ void *board_fdt_blob_setup(void) { void *fdt_blob; -#if !defined(CONFIG_VERSAL_NO_DDR) && !defined(CONFIG_ZYNQMP_NO_DDR) - fdt_blob = (void *)CONFIG_XILINX_OF_BOARD_DTB_ADDR; + if (!IS_ENABLED(CONFIG_SPL_BUILD) && + !IS_ENABLED(CONFIG_VERSAL_NO_DDR) && + !IS_ENABLED(CONFIG_VERSAL_NO_DDR)) { + fdt_blob = (void *)CONFIG_XILINX_OF_BOARD_DTB_ADDR; - if (fdt_magic(fdt_blob) == FDT_MAGIC) - return fdt_blob; + if (fdt_magic(fdt_blob) == FDT_MAGIC) + return fdt_blob; - debug("DTB is not passed via %p\n", fdt_blob); -#endif + debug("DTB is not passed via %p\n", fdt_blob); + } -#ifdef CONFIG_SPL_BUILD - /* FDT is at end of BSS unless it is in a different memory region */ - if (IS_ENABLED(CONFIG_SPL_SEPARATE_BSS)) - fdt_blob = (ulong *)&_image_binary_end; - else - fdt_blob = (ulong *)&__bss_end; -#else - /* FDT is at end of image */ - fdt_blob = (ulong *)&_end; -#endif + if (IS_ENABLED(CONFIG_SPL_BUILD)) { + /* + * FDT is at end of BSS unless it is in a different memory + * region + */ + if (IS_ENABLED(CONFIG_SPL_SEPARATE_BSS)) + fdt_blob = (ulong *)&_image_binary_end; + else + fdt_blob = (ulong *)&__bss_end; + } else { + /* FDT is at end of image */ + fdt_blob = (ulong *)&_end; + } if (fdt_magic(fdt_blob) == FDT_MAGIC) return fdt_blob; diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c index 047b070485..459d9b1e47 100644 --- a/board/xilinx/zynqmp/zynqmp.c +++ b/board/xilinx/zynqmp/zynqmp.c @@ -648,6 +648,7 @@ int board_late_init(void) if (bootseq >= 0) { bootseq_len = snprintf(NULL, 0, "%i", bootseq); debug("Bootseq len: %x\n", bootseq_len); + env_set_hex("bootseq", bootseq); } /* diff --git a/cmd/Kconfig b/cmd/Kconfig index da86a940ce..0625ee4050 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -122,6 +122,7 @@ config CMD_CONSOLE config CMD_CPU bool "cpu" + depends on CPU help Print information about available CPUs. This normally shows the number of CPUs, type (e.g. manufacturer, architecture, product or @@ -927,6 +928,12 @@ config CMD_GPIO help GPIO support. +config CMD_PWM + bool "pwm" + depends on DM_PWM + help + Control PWM channels, this allows invert/config/enable/disable PWM channels. + config CMD_GPT bool "GPT (GUID Partition Table) command" select EFI_PARTITION @@ -1034,6 +1041,14 @@ config CMD_LSBLK Print list of available block device drivers, and for each, the list of known block devices. +config CMD_MBR + bool "MBR (Master Boot Record) command" + select DOS_PARTITION + select HAVE_BLOCK_DEVICE + help + Enable the 'mbr' command to ready and write MBR (Master Boot Record) + style partition tables. + config CMD_MISC bool "misc" depends on MISC diff --git a/cmd/Makefile b/cmd/Makefile index 5b3400a840..176bf925fd 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -120,6 +120,7 @@ endif obj-$(CONFIG_CMD_PINMUX) += pinmux.o obj-$(CONFIG_CMD_PMC) += pmc.o obj-$(CONFIG_CMD_PSTORE) += pstore.o +obj-$(CONFIG_CMD_PWM) += pwm.o obj-$(CONFIG_CMD_PXE) += pxe.o pxe_utils.o obj-$(CONFIG_CMD_WOL) += wol.o obj-$(CONFIG_CMD_QFW) += qfw.o @@ -178,6 +179,7 @@ obj-$(CONFIG_CMD_ZFS) += zfs.o obj-$(CONFIG_CMD_DFU) += dfu.o obj-$(CONFIG_CMD_GPT) += gpt.o +obj-$(CONFIG_CMD_MBR) += mbr.o obj-$(CONFIG_CMD_ETHSW) += ethsw.o obj-$(CONFIG_CMD_AXI) += axi.o obj-$(CONFIG_CMD_PVBLOCK) += pvblock.o diff --git a/cmd/bootefi.c b/cmd/bootefi.c index fdf909f8da..c8eb5c32b0 100644 --- a/cmd/bootefi.c +++ b/cmd/bootefi.c @@ -29,6 +29,82 @@ DECLARE_GLOBAL_DATA_PTR; static struct efi_device_path *bootefi_image_path; static struct efi_device_path *bootefi_device_path; +static void *image_addr; +static size_t image_size; + +/** + * efi_clear_bootdev() - clear boot device + */ +static void efi_clear_bootdev(void) +{ + efi_free_pool(bootefi_device_path); + efi_free_pool(bootefi_image_path); + bootefi_device_path = NULL; + bootefi_image_path = NULL; + image_addr = NULL; + image_size = 0; +} + +/** + * efi_set_bootdev() - set boot device + * + * This function is called when a file is loaded, e.g. via the 'load' command. + * We use the path to this file to inform the UEFI binary about the boot device. + * + * @dev: device, e.g. "MMC" + * @devnr: number of the device, e.g. "1:2" + * @path: path to file loaded + * @buffer: buffer with file loaded + * @buffer_size: size of file loaded + */ +void efi_set_bootdev(const char *dev, const char *devnr, const char *path, + void *buffer, size_t buffer_size) +{ + struct efi_device_path *device, *image; + efi_status_t ret; + + /* Forget overwritten image */ + if (buffer + buffer_size >= image_addr && + image_addr + image_size >= buffer) + efi_clear_bootdev(); + + /* Remember only PE-COFF and FIT images */ + if (efi_check_pe(buffer, buffer_size, NULL) != EFI_SUCCESS) { +#ifdef CONFIG_FIT + if (!fit_check_format(buffer)) + return; + /* + * FIT images of type EFI_OS are started via command bootm. + * We should not use their boot device with the bootefi command. + */ + buffer = 0; + buffer_size = 0; +#else + return; +#endif + } + + /* efi_set_bootdev() is typically called repeatedly, recover memory */ + efi_clear_bootdev(); + + image_addr = buffer; + image_size = buffer_size; + + ret = efi_dp_from_name(dev, devnr, path, &device, &image); + if (ret == EFI_SUCCESS) { + bootefi_device_path = device; + if (image) { + /* FIXME: image should not contain device */ + struct efi_device_path *image_tmp = image; + + efi_dp_split_file_path(image, &device, &image); + efi_free_pool(image_tmp); + } + bootefi_image_path = image; + } else { + efi_clear_bootdev(); + } +} /** * efi_env_set_load_options() - set load options from environment variable @@ -136,86 +212,6 @@ done: } /** - * efi_reserve_memory() - add reserved memory to memory map - * - * @addr: start address of the reserved memory range - * @size: size of the reserved memory range - * @nomap: indicates that the memory range shall not be accessed by the - * UEFI payload - */ -static void efi_reserve_memory(u64 addr, u64 size, bool nomap) -{ - int type; - efi_uintn_t ret; - - /* Convert from sandbox address space. */ - addr = (uintptr_t)map_sysmem(addr, 0); - - if (nomap) - type = EFI_RESERVED_MEMORY_TYPE; - else - type = EFI_BOOT_SERVICES_DATA; - - ret = efi_add_memory_map(addr, size, type); - if (ret != EFI_SUCCESS) - log_err("Reserved memory mapping failed addr %llx size %llx\n", - addr, size); -} - -/** - * efi_carve_out_dt_rsv() - Carve out DT reserved memory ranges - * - * The mem_rsv entries of the FDT are added to the memory map. Any failures are - * ignored because this is not critical and we would rather continue to try to - * boot. - * - * @fdt: Pointer to device tree - */ -static void efi_carve_out_dt_rsv(void *fdt) -{ - int nr_rsv, i; - u64 addr, size; - int nodeoffset, subnode; - - nr_rsv = fdt_num_mem_rsv(fdt); - - /* Look for an existing entry and add it to the efi mem map. */ - for (i = 0; i < nr_rsv; i++) { - if (fdt_get_mem_rsv(fdt, i, &addr, &size) != 0) - continue; - efi_reserve_memory(addr, size, false); - } - - /* process reserved-memory */ - nodeoffset = fdt_subnode_offset(fdt, 0, "reserved-memory"); - if (nodeoffset >= 0) { - subnode = fdt_first_subnode(fdt, nodeoffset); - while (subnode >= 0) { - fdt_addr_t fdt_addr; - fdt_size_t fdt_size; - - /* check if this subnode has a reg property */ - fdt_addr = fdtdec_get_addr_size_auto_parent( - fdt, nodeoffset, subnode, - "reg", 0, &fdt_size, false); - /* - * The /reserved-memory node may have children with - * a size instead of a reg property. - */ - if (fdt_addr != FDT_ADDR_T_NONE && - fdtdec_get_is_enabled(fdt, subnode)) { - bool nomap; - - nomap = !!fdt_getprop(fdt, subnode, "no-map", - NULL); - efi_reserve_memory(fdt_addr, fdt_size, nomap); - } - subnode = fdt_next_subnode(fdt, subnode); - } - } -} - -/** * get_config_table() - get configuration table * * @guid: GUID of the configuration table @@ -398,43 +394,28 @@ static int do_bootefi_image(const char *image_opt) { void *image_buf; unsigned long addr, size; - const char *size_str; efi_status_t ret; #ifdef CONFIG_CMD_BOOTEFI_HELLO if (!strcmp(image_opt, "hello")) { - char *saddr; - - saddr = env_get("loadaddr"); + image_buf = __efi_helloworld_begin; size = __efi_helloworld_end - __efi_helloworld_begin; - - if (saddr) - addr = simple_strtoul(saddr, NULL, 16); - else - addr = CONFIG_SYS_LOAD_ADDR; - - image_buf = map_sysmem(addr, size); - memcpy(image_buf, __efi_helloworld_begin, size); - - efi_free_pool(bootefi_device_path); - efi_free_pool(bootefi_image_path); - bootefi_device_path = NULL; - bootefi_image_path = NULL; + efi_clear_bootdev(); } else #endif { - size_str = env_get("filesize"); - if (size_str) - size = simple_strtoul(size_str, NULL, 16); - else - size = 0; - - addr = simple_strtoul(image_opt, NULL, 16); + addr = strtoul(image_opt, NULL, 16); /* Check that a numeric value was passed */ - if (!addr && *image_opt != '0') + if (!addr) return CMD_RET_USAGE; - image_buf = map_sysmem(addr, size); + image_buf = map_sysmem(addr, 0); + + if (image_buf != image_addr) { + log_err("No UEFI binary known at %s\n", image_opt); + return CMD_RET_FAILURE; + } + size = image_size; } ret = efi_run_image(image_buf, size); @@ -567,11 +548,8 @@ static efi_status_t bootefi_test_prepare if (ret == EFI_SUCCESS) return ret; - efi_free_pool(bootefi_image_path); - bootefi_image_path = NULL; failure: - efi_free_pool(bootefi_device_path); - bootefi_device_path = NULL; + efi_clear_bootdev(); return ret; } @@ -653,10 +631,12 @@ static int do_bootefi(struct cmd_tbl *cmdtp, int flag, int argc, else if (ret != EFI_SUCCESS) return CMD_RET_FAILURE; - if (!strcmp(argv[1], "bootmgr")) - return do_efibootmgr(); + if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR)) { + if (!strcmp(argv[1], "bootmgr")) + return do_efibootmgr(); + } #ifdef CONFIG_CMD_BOOTEFI_SELFTEST - else if (!strcmp(argv[1], "selftest")) + if (!strcmp(argv[1], "selftest")) return do_efi_selftest(); #endif @@ -679,11 +659,14 @@ static char bootefi_help_text[] = " Use environment variable efi_selftest to select a single test.\n" " Use 'setenv efi_selftest list' to enumerate all tests.\n" #endif +#ifdef CONFIG_CMD_BOOTEFI_BOOTMGR "bootefi bootmgr [fdt address]\n" " - load and boot EFI payload based on BootOrder/BootXXXX variables.\n" "\n" " If specified, the device tree located at <fdt address> gets\n" - " exposed as EFI configuration table.\n"; + " exposed as EFI configuration table.\n" +#endif + ; #endif U_BOOT_CMD( @@ -691,39 +674,3 @@ U_BOOT_CMD( "Boots an EFI payload from memory", bootefi_help_text ); - -/** - * efi_set_bootdev() - set boot device - * - * This function is called when a file is loaded, e.g. via the 'load' command. - * We use the path to this file to inform the UEFI binary about the boot device. - * - * @dev: device, e.g. "MMC" - * @devnr: number of the device, e.g. "1:2" - * @path: path to file loaded - */ -void efi_set_bootdev(const char *dev, const char *devnr, const char *path) -{ - struct efi_device_path *device, *image; - efi_status_t ret; - - /* efi_set_bootdev is typically called repeatedly, recover memory */ - efi_free_pool(bootefi_device_path); - efi_free_pool(bootefi_image_path); - - ret = efi_dp_from_name(dev, devnr, path, &device, &image); - if (ret == EFI_SUCCESS) { - bootefi_device_path = device; - if (image) { - /* FIXME: image should not contain device */ - struct efi_device_path *image_tmp = image; - - efi_dp_split_file_path(image, &device, &image); - efi_free_pool(image_tmp); - } - bootefi_image_path = image; - } else { - bootefi_device_path = NULL; - bootefi_image_path = NULL; - } -} diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c index 1ba7b622e5..409ef9a848 100644 --- a/cmd/bootmenu.c +++ b/cmd/bootmenu.c @@ -45,6 +45,7 @@ enum bootmenu_key { KEY_UP, KEY_DOWN, KEY_SELECT, + KEY_QUIT, }; static char *bootmenu_getoption(unsigned short int n) @@ -109,6 +110,9 @@ static void bootmenu_autoboot_loop(struct bootmenu_data *menu, case '\r': *key = KEY_SELECT; break; + case 0x3: /* ^C */ + *key = KEY_QUIT; + break; default: *key = KEY_NONE; break; @@ -136,13 +140,25 @@ static void bootmenu_loop(struct bootmenu_data *menu, { int c; - while (!tstc()) { - WATCHDOG_RESET(); - mdelay(10); + if (*esc == 1) { + if (tstc()) { + c = getchar(); + } else { + WATCHDOG_RESET(); + mdelay(10); + if (tstc()) + c = getchar(); + else + c = '\e'; + } + } else { + while (!tstc()) { + WATCHDOG_RESET(); + mdelay(10); + } + c = getchar(); } - c = getchar(); - switch (*esc) { case 0: /* First char of ANSI escape sequence '\e' */ @@ -157,7 +173,9 @@ static void bootmenu_loop(struct bootmenu_data *menu, *esc = 2; *key = KEY_NONE; } else { - *esc = 0; + /* Alone ESC key was pressed */ + *key = KEY_QUIT; + *esc = (c == '\e') ? 1 : 0; } break; case 2: @@ -187,6 +205,10 @@ static void bootmenu_loop(struct bootmenu_data *menu, /* enter key was pressed */ if (c == '\r') *key = KEY_SELECT; + + /* ^C was pressed */ + if (c == 0x3) + *key = KEY_QUIT; } static char *bootmenu_choice_entry(void *data) @@ -222,6 +244,12 @@ static char *bootmenu_choice_entry(void *data) for (i = 0; i < menu->active; ++i) iter = iter->next; return iter->key; + case KEY_QUIT: + /* Quit by choosing the last entry - U-Boot console */ + iter = menu->first; + while (iter->next) + iter = iter->next; + return iter->key; default: break; } @@ -389,7 +417,7 @@ static void menu_display_statusline(struct menu *m) printf(ANSI_CURSOR_POSITION, menu->count + 5, 1); puts(ANSI_CLEAR_LINE); printf(ANSI_CURSOR_POSITION, menu->count + 6, 1); - puts(" Press UP/DOWN to move, ENTER to select"); + puts(" Press UP/DOWN to move, ENTER to select, ESC/CTRL+C to quit"); puts(ANSI_CLEAR_LINE_TO_END); printf(ANSI_CURSOR_POSITION, menu->count + 7, 1); puts(ANSI_CLEAR_LINE); diff --git a/cmd/conitrace.c b/cmd/conitrace.c index 811f5c68a9..d50f3bf3cc 100644 --- a/cmd/conitrace.c +++ b/cmd/conitrace.c @@ -30,8 +30,8 @@ static int do_conitrace(struct cmd_tbl *cmdtp, int flag, int argc, printf("%02x ", c); first = false; - /* 1 ms delay - serves to detect separate keystrokes */ - udelay(1000); + /* 10 ms delay - serves to detect separate keystrokes */ + udelay(10000); if (!tstc()) { printf("\n"); first = true; diff --git a/cmd/disk.c b/cmd/disk.c index 8060e753eb..0bc3808dfe 100644 --- a/cmd/disk.c +++ b/cmd/disk.c @@ -120,7 +120,6 @@ int common_diskboot(struct cmd_tbl *cmdtp, const char *intf, int argc, return 1; } bootstage_mark(BOOTSTAGE_ID_IDE_FIT_READ_OK); - fit_print_contents(fit_hdr); } #endif diff --git a/cmd/efidebug.c b/cmd/efidebug.c index 5fb7b1e3c6..9a2d4ddd5e 100644 --- a/cmd/efidebug.c +++ b/cmd/efidebug.c @@ -8,6 +8,7 @@ #include <charset.h> #include <common.h> #include <command.h> +#include <efi_dt_fixup.h> #include <efi_loader.h> #include <efi_rng.h> #include <exports.h> @@ -495,6 +496,10 @@ static const struct { "PXE Base Code", EFI_PXE_BASE_CODE_PROTOCOL_GUID, }, + { + "Device-Tree Fixup", + EFI_DT_FIXUP_PROTOCOL_GUID, + }, /* Configuration table GUIDs */ { "ACPI table", @@ -1362,8 +1367,8 @@ static int do_efi_boot_opt(struct cmd_tbl *cmdtp, int flag, * * efidebug test bootmgr */ -static int do_efi_test_bootmgr(struct cmd_tbl *cmdtp, int flag, - int argc, char * const argv[]) +static __maybe_unused int do_efi_test_bootmgr(struct cmd_tbl *cmdtp, int flag, + int argc, char * const argv[]) { efi_handle_t image; efi_uintn_t exit_data_size = 0; @@ -1387,8 +1392,10 @@ static int do_efi_test_bootmgr(struct cmd_tbl *cmdtp, int flag, } static struct cmd_tbl cmd_efidebug_test_sub[] = { +#ifdef CONFIG_CMD_BOOTEFI_BOOTMGR U_BOOT_CMD_MKENT(bootmgr, CONFIG_SYS_MAXARGS, 1, do_efi_test_bootmgr, "", ""), +#endif }; /** @@ -1576,8 +1583,10 @@ static char efidebug_help_text[] = " - show UEFI memory map\n" "efidebug tables\n" " - show UEFI configuration tables\n" +#ifdef CONFIG_CMD_BOOTEFI_BOOTMGR "efidebug test bootmgr\n" " - run simple bootmgr for test\n" +#endif "efidebug query [-nv][-bs][-rt][-at]\n" " - show size of UEFI variables store\n"; #endif @@ -18,6 +18,7 @@ #include <command.h> #include <part.h> #include <part_efi.h> +#include <part.h> #include <exports.h> #include <uuid.h> #include <linux/ctype.h> @@ -621,6 +622,152 @@ static int gpt_verify(struct blk_desc *blk_dev_desc, const char *str_part) return ret; } +/** + * gpt_enumerate() - Enumerate partition names into environment variable. + * + * Enumerate partition names. Partition names are stored in gpt_partition_list + * environment variable. Each partition name is delimited by space. + * + * @desc: block device descriptor + * + * @Return: '0' on success and -ve error on failure + */ +static int gpt_enumerate(struct blk_desc *desc) +{ + struct part_driver *first_drv, *part_drv; + int str_len = 0, tmp_len; + char part_list[2048]; + int n_drvs; + char *ptr; + + part_list[0] = 0; + n_drvs = part_driver_get_count(); + if (!n_drvs) { + printf("Failed to get partition driver count\n"); + return -ENOENT; + } + + first_drv = part_driver_get_first(); + for (part_drv = first_drv; part_drv != first_drv + n_drvs; part_drv++) { + struct disk_partition pinfo; + int ret; + int i; + + for (i = 1; i < part_drv->max_entries; i++) { + ret = part_drv->get_info(desc, i, &pinfo); + if (ret) { + /* no more entries in table */ + break; + } + + ptr = &part_list[str_len]; + tmp_len = strlen((const char *)pinfo.name); + str_len += tmp_len; + /* +1 for space */ + str_len++; + if (str_len > sizeof(part_list)) { + printf("Error insufficient memory\n"); + return -ENOMEM; + } + strcpy(ptr, (const char *)pinfo.name); + /* One byte for space(" ") delimiter */ + ptr[tmp_len] = ' '; + } + } + if (*part_list) + part_list[strlen(part_list) - 1] = 0; + debug("setenv gpt_partition_list %s\n", part_list); + + return env_set("gpt_partition_list", part_list); +} + +/** + * gpt_setenv_part_variables() - setup partition environmental variables + * + * Setup the gpt_partition_name, gpt_partition_entry, gpt_partition_addr + * and gpt_partition_size environment variables. + * + * @pinfo: pointer to disk partition + * @i: partition entry + * + * @Return: '0' on success and -ENOENT on failure + */ +static int gpt_setenv_part_variables(struct disk_partition *pinfo, int i) +{ + int ret; + + ret = env_set_hex("gpt_partition_addr", pinfo->start); + if (ret) + goto fail; + + ret = env_set_hex("gpt_partition_size", pinfo->size); + if (ret) + goto fail; + + ret = env_set_ulong("gpt_partition_entry", i); + if (ret) + goto fail; + + ret = env_set("gpt_partition_name", (const char *)pinfo->name); + if (ret) + goto fail; + + return 0; + +fail: + return -ENOENT; +} + +/** + * gpt_setenv() - Dynamically setup environment variables. + * + * Dynamically setup environment variables for name, index, offset and size + * for partition in GPT table after running "gpt setenv" for a partition name. + * + * @desc: block device descriptor + * @name: partition name + * + * @Return: '0' on success and -ve err on failure + */ +static int gpt_setenv(struct blk_desc *desc, const char *name) +{ + struct part_driver *first_drv, *part_drv; + int n_drvs; + int ret = -1; + + n_drvs = part_driver_get_count(); + if (!n_drvs) { + printf("Failed to get partition driver count\n"); + goto fail; + } + + first_drv = part_driver_get_first(); + for (part_drv = first_drv; part_drv != first_drv + n_drvs; part_drv++) { + struct disk_partition pinfo; + int i; + + for (i = 1; i < part_drv->max_entries; i++) { + ret = part_drv->get_info(desc, i, &pinfo); + if (ret) { + /* no more entries in table */ + break; + } + + if (!strcmp(name, (const char *)pinfo.name)) { + /* match found, setup environment variables */ + ret = gpt_setenv_part_variables(&pinfo, i); + if (ret) + goto fail; + + return 0; + } + } + } + +fail: + return ret; +} + static int do_disk_guid(struct blk_desc *dev_desc, char * const namestr) { int ret; @@ -827,6 +974,10 @@ static int do_gpt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) } else if ((strcmp(argv[1], "verify") == 0)) { ret = gpt_verify(blk_dev_desc, argv[4]); printf("Verify GPT: "); + } else if ((strcmp(argv[1], "setenv") == 0)) { + ret = gpt_setenv(blk_dev_desc, argv[4]); + } else if ((strcmp(argv[1], "enumerate") == 0)) { + ret = gpt_enumerate(blk_dev_desc); } else if (strcmp(argv[1], "guid") == 0) { ret = do_disk_guid(blk_dev_desc, argv[4]); #ifdef CONFIG_CMD_GPT_RENAME @@ -857,7 +1008,17 @@ U_BOOT_CMD(gpt, CONFIG_SYS_MAXARGS, 1, do_gpt, " to interface\n" " Example usage:\n" " gpt write mmc 0 $partitions\n" + " - write the GPT to device\n" " gpt verify mmc 0 $partitions\n" + " - verify the GPT on device against $partitions\n" + " gpt setenv mmc 0 $name\n" + " - setup environment variables for partition $name:\n" + " gpt_partition_addr, gpt_partition_size,\n" + " gpt_partition_name, gpt_partition_entry\n" + " gpt enumerate mmc 0\n" + " - store list of partitions to gpt_partition_list environment variable\n" + " read <interface> <dev>\n" + " - read GPT into a data structure for manipulation\n" " gpt guid <interface> <dev>\n" " - print disk GUID\n" " gpt guid <interface> <dev> <varname>\n" diff --git a/cmd/mbr.c b/cmd/mbr.c new file mode 100644 index 0000000000..da2e3a4722 --- /dev/null +++ b/cmd/mbr.c @@ -0,0 +1,314 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * cmd_mbr.c -- MBR (Master Boot Record) handling command + * + * Copyright (C) 2020 Samsung Electronics + * author: Marek Szyprowski <m.szyprowski@samsung.com> + * + * based on the gpt command. + */ + +#include <common.h> +#include <blk.h> +#include <command.h> +#include <malloc.h> +#include <part.h> + +/** + * extract_val() - Extract a value from the key=value pair list + * @str: pointer to string with key=values pairs + * @key: pointer to the key to search for + * + * The list of parameters is come separated, only a value for + * the given key is returend. + * + * Function allocates memory for the value, remember to free! + * + * Return: Pointer to allocated string with the value. + */ +static char *extract_val(const char *str, const char *key) +{ + char *v, *k; + char *s, *strcopy; + char *new = NULL; + + strcopy = strdup(str); + if (strcopy == NULL) + return NULL; + + s = strcopy; + while (s) { + v = strsep(&s, ","); + if (!v) + break; + k = strsep(&v, "="); + if (!k) + break; + if (strcmp(k, key) == 0) { + new = strdup(v); + break; + } + } + + free(strcopy); + + return new; +} + +/** + * found_key() - Search for a key without a value in the parameter list + * @str: pointer to string with key + * @key: pointer to the key to search for + * + * The list of parameters is come separated. + * + * Return: True if key has been found. + */ +static bool found_key(const char *str, const char *key) +{ + char *k; + char *s, *strcopy; + bool result = false; + + strcopy = strdup(str); + if (!strcopy) + return NULL; + + s = strcopy; + while (s) { + k = strsep(&s, ","); + if (!k) + break; + if (strcmp(k, key) == 0) { + result = true; + break; + } + } + + free(strcopy); + + return result; +} + +static int str_to_partitions(const char *str_part, int blksz, + unsigned long *disk_uuid, struct disk_partition **partitions, + int *parts_count) +{ + char *tok, *str, *s; + int i; + char *val, *p; + int p_count; + struct disk_partition *parts; + int errno = 0; + uint64_t size_ll, start_ll; + + if (str_part == NULL) + return -1; + + str = strdup(str_part); + if (str == NULL) + return -ENOMEM; + + /* extract disk guid */ + s = str; + val = extract_val(str, "uuid_disk"); + if (val) { + val = strsep(&val, ";"); + p = val; + *disk_uuid = ustrtoull(p, &p, 0); + free(val); + /* Move s to first partition */ + strsep(&s, ";"); + } + if (s == NULL) { + printf("Error: is the partitions string NULL-terminated?\n"); + return -EINVAL; + } + + /* remove the optional semicolon at the end of the string */ + i = strlen(s) - 1; + if (s[i] == ';') + s[i] = '\0'; + + /* calculate expected number of partitions */ + p_count = 1; + p = s; + while (*p) { + if (*p++ == ';') + p_count++; + } + + /* allocate memory for partitions */ + parts = calloc(sizeof(struct disk_partition), p_count); + if (parts == NULL) + return -ENOMEM; + + /* retrieve partitions data from string */ + for (i = 0; i < p_count; i++) { + tok = strsep(&s, ";"); + + if (tok == NULL) + break; + + /* size */ + val = extract_val(tok, "size"); + if (!val) { /* 'size' is mandatory */ + errno = -4; + goto err; + } + p = val; + if ((strcmp(p, "-") == 0)) { + /* auto extend the size */ + parts[i].size = 0; + } else { + size_ll = ustrtoull(p, &p, 0); + parts[i].size = size_ll / blksz; + } + free(val); + + /* start address */ + val = extract_val(tok, "start"); + if (val) { /* start address is optional */ + p = val; + start_ll = ustrtoull(p, &p, 0); + parts[i].start = start_ll / blksz; + free(val); + } + + /* system id */ + val = extract_val(tok, "id"); + if (!val) { /* '' is mandatory */ + errno = -4; + goto err; + } + p = val; + parts[i].sys_ind = ustrtoul(p, &p, 0); + free(val); + + /* bootable */ + if (found_key(tok, "bootable")) + parts[i].bootable = PART_BOOTABLE; + } + + *parts_count = p_count; + *partitions = parts; + free(str); + + return 0; +err: + free(str); + free(parts); + + return errno; +} + +static int do_write_mbr(struct blk_desc *dev, const char *str) +{ + unsigned long disk_uuid = 0; + struct disk_partition *partitions; + int blksz = dev->blksz; + int count; + + if (str_to_partitions(str, blksz, &disk_uuid, &partitions, &count)) { + printf("MBR: failed to setup partitions from \"%s\"\n", str); + return -1; + } + + if (layout_mbr_partitions(partitions, count, dev->lba)) { + printf("MBR: failed to layout partitions on the device\n"); + free(partitions); + return -1; + } + + if (write_mbr_partitions(dev, partitions, count, disk_uuid)) { + printf("MBR: failed to write partitions to the device\n"); + free(partitions); + return -1; + } + + return 0; +} + +static int do_verify_mbr(struct blk_desc *dev, const char *str) +{ + unsigned long disk_uuid = 0; + struct disk_partition *partitions; + int blksz = dev->blksz; + int count, i, ret = 1; + + if (str_to_partitions(str, blksz, &disk_uuid, &partitions, &count)) { + printf("MBR: failed to setup partitions from \"%s\"\n", str); + return -1; + } + + for (i = 0; i < count; i++) { + struct disk_partition p; + + if (part_get_info(dev, i+1, &p)) + goto fail; + + if ((partitions[i].size && p.size < partitions[i].size) || + (partitions[i].start && p.start < partitions[i].start) || + (p.sys_ind != partitions[i].sys_ind)) + goto fail; + } + ret = 0; +fail: + free(partitions); + return ret; +} + +static int do_mbr(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) +{ + const char *parts = NULL; + int ret = CMD_RET_SUCCESS; + int dev = 0; + char *ep; + struct blk_desc *blk_dev_desc = NULL; + + if (argc != 4 && argc != 5) + return CMD_RET_USAGE; + + dev = (int)simple_strtoul(argv[3], &ep, 10); + if (!ep || ep[0] != '\0') { + printf("'%s' is not a number\n", argv[3]); + return CMD_RET_USAGE; + } + blk_dev_desc = blk_get_dev(argv[2], dev); + if (!blk_dev_desc) { + printf("%s: %s dev %d NOT available\n", + __func__, argv[2], dev); + return CMD_RET_FAILURE; + } + + if ((strcmp(argv[1], "write") == 0)) { + parts = (argc == 5) ? argv[4] : env_get("mbr_parts"); + printf("MBR: write "); + ret = do_write_mbr(blk_dev_desc, parts); + } else if ((strcmp(argv[1], "verify") == 0)) { + printf("MBR: verify "); + parts = (argc == 5) ? argv[4] : env_get("mbr_parts"); + ret = do_verify_mbr(blk_dev_desc, parts); + } else { + return CMD_RET_USAGE; + } + + if (ret) { + printf("error!\n"); + return CMD_RET_FAILURE; + } + + printf("success!\n"); + return CMD_RET_SUCCESS; +} + +U_BOOT_CMD(mbr, CONFIG_SYS_MAXARGS, 1, do_mbr, + "MBR (Master Boot Record)", + "<command> <interface> <dev> <partitions_list>\n" + " - MBR partition table restoration utility\n" + " Restore or check partition information on a device connected\n" + " to the given block interface\n" + " Example usage:\n" + " mbr write mmc 0 [\"${mbr_parts}\"]\n" + " mbr verify mmc 0 [\"${partitions}\"]\n" +); diff --git a/cmd/pwm.c b/cmd/pwm.c new file mode 100644 index 0000000000..5849fc57b6 --- /dev/null +++ b/cmd/pwm.c @@ -0,0 +1,117 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Control PWM channels + * + * Copyright (c) 2020 SiFive, Inc + * author: Pragnesh Patel <pragnesh.patel@sifive.com> + */ + +#include <command.h> +#include <dm.h> +#include <pwm.h> + +enum pwm_cmd { + PWM_SET_INVERT, + PWM_SET_CONFIG, + PWM_SET_ENABLE, + PWM_SET_DISABLE, +}; + +static int do_pwm(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + const char *str_cmd, *str_channel = NULL, *str_enable = NULL; + const char *str_pwm = NULL, *str_period = NULL, *str_duty = NULL; + enum pwm_cmd sub_cmd; + struct udevice *dev; + u32 channel, pwm_enable, pwm_dev, period_ns = 0, duty_ns = 0; + int ret; + + if (argc < 4) + return CMD_RET_USAGE; + + str_cmd = argv[1]; + argc -= 2; + argv += 2; + + if (argc > 0) { + str_pwm = *argv; + argc--; + argv++; + } + + if (!str_pwm) + return CMD_RET_USAGE; + + switch (*str_cmd) { + case 'i': + sub_cmd = PWM_SET_INVERT; + break; + case 'c': + sub_cmd = PWM_SET_CONFIG; + break; + case 'e': + sub_cmd = PWM_SET_ENABLE; + break; + case 'd': + sub_cmd = PWM_SET_DISABLE; + break; + default: + return CMD_RET_USAGE; + } + + pwm_dev = simple_strtoul(str_pwm, NULL, 10); + ret = uclass_get_device(UCLASS_PWM, pwm_dev, &dev); + if (ret) { + printf("pwm: '%s' not found\n", str_pwm); + return cmd_process_error(cmdtp, ret); + } + + if (argc > 0) { + str_channel = *argv; + channel = simple_strtoul(str_channel, NULL, 10); + argc--; + argv++; + } else { + return CMD_RET_USAGE; + } + + if (sub_cmd == PWM_SET_INVERT && argc > 0) { + str_enable = *argv; + pwm_enable = simple_strtoul(str_enable, NULL, 10); + ret = pwm_set_invert(dev, channel, pwm_enable); + } else if (sub_cmd == PWM_SET_CONFIG && argc == 2) { + str_period = *argv; + argc--; + argv++; + period_ns = simple_strtoul(str_period, NULL, 10); + + if (argc > 0) { + str_duty = *argv; + duty_ns = simple_strtoul(str_duty, NULL, 10); + } + + ret = pwm_set_config(dev, channel, period_ns, duty_ns); + } else if (sub_cmd == PWM_SET_ENABLE) { + ret = pwm_set_enable(dev, channel, 1); + } else if (sub_cmd == PWM_SET_DISABLE) { + ret = pwm_set_enable(dev, channel, 0); + } else { + printf("PWM arguments missing\n"); + return CMD_RET_FAILURE; + } + + if (ret) { + printf("error(%d)\n", ret); + return CMD_RET_FAILURE; + } + + return CMD_RET_SUCCESS; +} + +U_BOOT_CMD(pwm, 6, 0, do_pwm, + "control pwm channels", + "pwm <invert> <pwm_dev_num> <channel> <polarity>\n" + "pwm <config> <pwm_dev_num> <channel> <period_ns> <duty_ns>\n" + "pwm <enable/disable> <pwm_dev_num> <channel>\n" + "Note: All input values are in decimal"); diff --git a/common/Kconfig b/common/Kconfig index 2bce8c9ba1..d8982ba377 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -17,6 +17,14 @@ config CONSOLE_RECORD To enable console recording, call console_record_reset_enable() from your code. +config CONSOLE_RECORD_INIT_F + bool "Enable console recording during pre-relocation init" + depends on CONSOLE_RECORD && SYS_MALLOC_F + default y + help + This option enables console recording during pre-relocation init. + CONFIG_SYS_MALLOC_F must be enabled to use this feature. + config CONSOLE_RECORD_OUT_SIZE hex "Output buffer size" depends on CONSOLE_RECORD diff --git a/common/Kconfig.boot b/common/Kconfig.boot index 58e98548de..4525a12ab4 100644 --- a/common/Kconfig.boot +++ b/common/Kconfig.boot @@ -819,7 +819,10 @@ config AUTOBOOT_STOP_STR_SHA256 This option adds the feature to only stop the autobooting, and therefore boot into the U-Boot prompt, when the input string / password matches a values that is encypted via - a SHA256 hash and saved in the environment. + a SHA256 hash and saved in the environment variable + "bootstopkeysha256". If the value in that variable + includes a ":", the portion prior to the ":" will be treated + as a salt value. config AUTOBOOT_USE_MENUKEY bool "Allow a specify key to run a menu from the environment" diff --git a/common/Makefile b/common/Makefile index bcf352d016..daeea67cf2 100644 --- a/common/Makefile +++ b/common/Makefile @@ -68,7 +68,6 @@ obj-$(CONFIG_DFU_OVER_USB) += dfu.o endif obj-$(CONFIG_SPL_HASH_SUPPORT) += hash.o obj-$(CONFIG_TPL_HASH_SUPPORT) += hash.o -obj-$(CONFIG_SPL_YMODEM_SUPPORT) += xyzModem.o obj-$(CONFIG_SPL_LOAD_FIT) += common_fit.o obj-$(CONFIG_SPL_NET_SUPPORT) += miiphyutil.o obj-$(CONFIG_$(SPL_TPL_)OF_LIBFDT) += fdt_support.o diff --git a/common/autoboot.c b/common/autoboot.c index e628baffb8..ddb6246be3 100644 --- a/common/autoboot.c +++ b/common/autoboot.c @@ -25,7 +25,7 @@ DECLARE_GLOBAL_DATA_PTR; -#define MAX_DELAY_STOP_STR 32 +#define MAX_DELAY_STOP_STR 64 #ifndef DEBUG_BOOTKEYS #define DEBUG_BOOTKEYS 0 @@ -80,6 +80,7 @@ static int passwd_abort_sha256(uint64_t etime) u8 sha_env[SHA256_SUM_LEN]; u8 *sha; char *presskey; + char *c; const char *algo_name = "sha256"; u_int presskey_len = 0; int abort = 0; @@ -89,6 +90,14 @@ static int passwd_abort_sha256(uint64_t etime) if (sha_env_str == NULL) sha_env_str = AUTOBOOT_STOP_STR_SHA256; + presskey = malloc_cache_aligned(MAX_DELAY_STOP_STR); + c = strstr(sha_env_str, ":"); + if (c && (c - sha_env_str < MAX_DELAY_STOP_STR)) { + /* preload presskey with salt */ + memcpy(presskey, sha_env_str, c - sha_env_str); + presskey_len = c - sha_env_str; + sha_env_str = c + 1; + } /* * Generate the binary value from the environment hash value * so that we can compare this value with the computed hash @@ -100,7 +109,6 @@ static int passwd_abort_sha256(uint64_t etime) return 0; } - presskey = malloc_cache_aligned(MAX_DELAY_STOP_STR); sha = malloc_cache_aligned(SHA256_SUM_LEN); size = SHA256_SUM_LEN; /* diff --git a/common/board_f.c b/common/board_f.c index 9f441c44f1..ae3001bed1 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -503,14 +503,6 @@ static int reserve_board(void) return 0; } -static int setup_machine(void) -{ -#ifdef CONFIG_MACH_TYPE - gd->bd->bi_arch_number = CONFIG_MACH_TYPE; /* board id for Linux */ -#endif - return 0; -} - static int reserve_global_data(void) { gd->start_addr_sp = reserve_stack_aligned(sizeof(gd_t)); @@ -522,21 +514,21 @@ static int reserve_global_data(void) static int reserve_fdt(void) { -#ifndef CONFIG_OF_EMBED - /* - * If the device tree is sitting immediately above our image then we - * must relocate it. If it is embedded in the data section, then it - * will be relocated with other data. - */ - if (gd->fdt_blob) { - gd->fdt_size = ALIGN(fdt_totalsize(gd->fdt_blob), 32); + if (!IS_ENABLED(CONFIG_OF_EMBED)) { + /* + * If the device tree is sitting immediately above our image + * then we must relocate it. If it is embedded in the data + * section, then it will be relocated with other data. + */ + if (gd->fdt_blob) { + gd->fdt_size = ALIGN(fdt_totalsize(gd->fdt_blob), 32); - gd->start_addr_sp = reserve_stack_aligned(gd->fdt_size); - gd->new_fdt = map_sysmem(gd->start_addr_sp, gd->fdt_size); - debug("Reserving %lu Bytes for FDT at: %08lx\n", - gd->fdt_size, gd->start_addr_sp); + gd->start_addr_sp = reserve_stack_aligned(gd->fdt_size); + gd->new_fdt = map_sysmem(gd->start_addr_sp, gd->fdt_size); + debug("Reserving %lu Bytes for FDT at: %08lx\n", + gd->fdt_size, gd->start_addr_sp); + } } -#endif return 0; } @@ -605,6 +597,10 @@ int setup_bdinfo(void) bd->bi_sramsize = CONFIG_SYS_SRAM_SIZE; /* size of SRAM */ } +#ifdef CONFIG_MACH_TYPE + bd->bi_arch_number = CONFIG_MACH_TYPE; /* board id for Linux */ +#endif + return arch_setup_bdinfo(); } @@ -620,14 +616,15 @@ static int init_post(void) static int reloc_fdt(void) { -#ifndef CONFIG_OF_EMBED - if (gd->flags & GD_FLG_SKIP_RELOC) - return 0; - if (gd->new_fdt) { - memcpy(gd->new_fdt, gd->fdt_blob, fdt_totalsize(gd->fdt_blob)); - gd->fdt_blob = gd->new_fdt; + if (!IS_ENABLED(CONFIG_OF_EMBED)) { + if (gd->flags & GD_FLG_SKIP_RELOC) + return 0; + if (gd->new_fdt) { + memcpy(gd->new_fdt, gd->fdt_blob, + fdt_totalsize(gd->fdt_blob)); + gd->fdt_blob = gd->new_fdt; + } } -#endif return 0; } @@ -765,15 +762,6 @@ static int initf_bootstage(void) return 0; } -static int initf_console_record(void) -{ -#if defined(CONFIG_CONSOLE_RECORD) && CONFIG_VAL(SYS_MALLOC_F_LEN) - return console_record_init(); -#else - return 0; -#endif -} - static int initf_dm(void) { #if defined(CONFIG_DM) && CONFIG_VAL(SYS_MALLOC_F_LEN) @@ -784,11 +772,12 @@ static int initf_dm(void) bootstage_accum(BOOTSTAGE_ID_ACCUM_DM_F); if (ret) return ret; -#endif -#ifdef CONFIG_TIMER_EARLY - ret = dm_timer_init(); - if (ret) - return ret; + + if (IS_ENABLED(CONFIG_TIMER_EARLY)) { + ret = dm_timer_init(); + if (ret) + return ret; + } #endif return 0; @@ -830,7 +819,9 @@ static const init_fnc_t init_sequence_f[] = { bloblist_init, #endif setup_spl_handoff, - initf_console_record, +#if defined(CONFIG_CONSOLE_RECORD_INIT_F) + console_record_init, +#endif #if defined(CONFIG_HAVE_FSP) arch_fsp_init, #endif @@ -922,7 +913,6 @@ static const init_fnc_t init_sequence_f[] = { reserve_uboot, reserve_malloc, reserve_board, - setup_machine, reserve_global_data, reserve_fdt, reserve_bootstage, diff --git a/common/board_r.c b/common/board_r.c index 29dd7d26d9..9fa4d4b42e 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -91,21 +91,8 @@ __weak int board_flash_wp_on(void) return 0; } -__weak void cpu_secondary_init_r(void) +__weak int cpu_secondary_init_r(void) { -} - -static int initr_secondary_cpu(void) -{ - /* - * after non-volatile devices & environment is setup and cpu code have - * another round to deal with any initialization that might require - * full access to the environment or loading of some image (firmware) - * from a non-volatile device - */ - /* TODO: maybe define this for all archs? */ - cpu_secondary_init_r(); - return 0; } @@ -195,20 +182,10 @@ static int initr_reloc_global_data(void) return 0; } -#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_MIPS) -static int initr_trap(void) +__weak int arch_initr_trap(void) { - /* - * Setup trap handlers - */ -#if defined(CONFIG_PPC) - trap_init(gd->relocaddr); -#else - trap_init(CONFIG_SYS_SDRAM_BASE); -#endif return 0; } -#endif #ifdef CONFIG_ADDR_MAP static int initr_addr_map(void) @@ -219,14 +196,6 @@ static int initr_addr_map(void) } #endif -#ifdef CONFIG_POST -static int initr_post_backlog(void) -{ - post_output_backlog(); - return 0; -} -#endif - #if defined(CONFIG_SYS_INIT_RAM_LOCK) && defined(CONFIG_E500) static int initr_unlock_ram_in_cache(void) { @@ -235,25 +204,6 @@ static int initr_unlock_ram_in_cache(void) } #endif -#ifdef CONFIG_PCI_ENDPOINT -static int initr_pci_ep(void) -{ - pci_ep_init(); - - return 0; -} -#endif - -#ifdef CONFIG_PCI -static int initr_pci(void) -{ - if (IS_ENABLED(CONFIG_PCI_INIT_R)) - pci_init(); - - return 0; -} -#endif - static int initr_barrier(void) { #ifdef CONFIG_PPC @@ -282,23 +232,6 @@ static int initr_malloc(void) return 0; } -static int initr_console_record(void) -{ -#if defined(CONFIG_CONSOLE_RECORD) - return console_record_init(); -#else - return 0; -#endif -} - -#ifdef CONFIG_SYS_NONCACHED_MEMORY -static int initr_noncached(void) -{ - noncached_init(); - return 0; -} -#endif - static int initr_of_live(void) { if (CONFIG_IS_ENABLED(OF_LIVE)) { @@ -485,14 +418,6 @@ static int initr_mmc(void) } #endif -#ifdef CONFIG_XEN -static int initr_xen(void) -{ - xen_init(); - return 0; -} -#endif - #ifdef CONFIG_PVBLOCK static int initr_pvblock(void) { @@ -555,21 +480,6 @@ static int initr_malloc_bootparams(void) } #endif -static int initr_jumptable(void) -{ - jumptable_init(); - return 0; -} - -#if defined(CONFIG_API) -static int initr_api(void) -{ - /* Initialize API */ - api_init(); - return 0; -} -#endif - #ifdef CONFIG_CMD_NET static int initr_ethaddr(void) { @@ -614,14 +524,6 @@ static int initr_scsi(void) } #endif -#ifdef CONFIG_BITBANGMII -static int initr_bbmii(void) -{ - bb_miiphy_init(); - return 0; -} -#endif - #ifdef CONFIG_CMD_NET static int initr_net(void) { @@ -713,9 +615,11 @@ static init_fnc_t init_sequence_r[] = { initr_malloc, log_init, initr_bootstage, /* Needs malloc() but has its own timer */ - initr_console_record, +#if defined(CONFIG_CONSOLE_RECORD) + console_record_init, +#endif #ifdef CONFIG_SYS_NONCACHED_MEMORY - initr_noncached, + noncached_init, #endif initr_of_live, #ifdef CONFIG_DM @@ -755,9 +659,7 @@ static init_fnc_t init_sequence_r[] = { #ifdef CONFIG_NEEDS_MANUAL_RELOC initr_manual_reloc_cmdtable, #endif -#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_MIPS) - initr_trap, -#endif + arch_initr_trap, #ifdef CONFIG_ADDR_MAP initr_addr_map, #endif @@ -766,15 +668,15 @@ static init_fnc_t init_sequence_r[] = { #endif INIT_FUNC_WATCHDOG_RESET #ifdef CONFIG_POST - initr_post_backlog, + post_output_backlog, #endif INIT_FUNC_WATCHDOG_RESET -#if defined(CONFIG_PCI) && defined(CONFIG_SYS_EARLY_PCI_INIT) +#if defined(CONFIG_PCI_INIT_R) && defined(CONFIG_SYS_EARLY_PCI_INIT) /* * Do early PCI configuration _before_ the flash gets initialised, * because PCU resources are crucial for flash access on some boards. */ - initr_pci, + pci_init, #endif #ifdef CONFIG_ARCH_EARLY_INIT_R arch_early_init_r, @@ -798,7 +700,7 @@ static init_fnc_t init_sequence_r[] = { initr_mmc, #endif #ifdef CONFIG_XEN - initr_xen, + xen_init, #endif #ifdef CONFIG_PVBLOCK initr_pvblock, @@ -808,21 +710,21 @@ static init_fnc_t init_sequence_r[] = { initr_malloc_bootparams, #endif INIT_FUNC_WATCHDOG_RESET - initr_secondary_cpu, + cpu_secondary_init_r, #if defined(CONFIG_ID_EEPROM) || defined(CONFIG_SYS_I2C_MAC_OFFSET) mac_read_from_eeprom, #endif INIT_FUNC_WATCHDOG_RESET -#if defined(CONFIG_PCI) && !defined(CONFIG_SYS_EARLY_PCI_INIT) +#if defined(CONFIG_PCI_INIT_R) && !defined(CONFIG_SYS_EARLY_PCI_INIT) /* * Do pci configuration */ - initr_pci, + pci_init, #endif stdio_add_devices, - initr_jumptable, + jumptable_init, #ifdef CONFIG_API - initr_api, + api_init, #endif console_init_r, /* fully init console as a device */ #ifdef CONFIG_DISPLAY_BOARDINFO_LATE @@ -861,10 +763,10 @@ static init_fnc_t init_sequence_r[] = { initr_scsi, #endif #ifdef CONFIG_BITBANGMII - initr_bbmii, + bb_miiphy_init, #endif #ifdef CONFIG_PCI_ENDPOINT - initr_pci_ep, + pci_ep_init, #endif #ifdef CONFIG_CMD_NET INIT_FUNC_WATCHDOG_RESET diff --git a/common/cli_readline.c b/common/cli_readline.c index 47b876285c..5c158d03b4 100644 --- a/common/cli_readline.c +++ b/common/cli_readline.c @@ -493,8 +493,10 @@ static int cread_line(const char *const prompt, char *buf, unsigned int *len, } #endif default: - cread_add_char(ichar, insert, &num, &eol_num, buf, - *len); + if (ichar >= ' ' && ichar <= '~') { + cread_add_char(ichar, insert, &num, &eol_num, + buf, *len); + } break; } } diff --git a/common/command.c b/common/command.c index 068cb55b4c..3fe6791eda 100644 --- a/common/command.c +++ b/common/command.c @@ -16,6 +16,8 @@ #include <log.h> #include <linux/ctype.h> +DECLARE_GLOBAL_DATA_PTR; + /* * Use puts() instead of printf() to avoid printf buffer overflow * for long help messages @@ -488,9 +490,6 @@ int cmd_get_data_size(char* arg, int default_size) } #endif -#if defined(CONFIG_NEEDS_MANUAL_RELOC) -DECLARE_GLOBAL_DATA_PTR; - void fixup_cmdtable(struct cmd_tbl *cmdtp, int size) { int i; @@ -535,7 +534,6 @@ void fixup_cmdtable(struct cmd_tbl *cmdtp, int size) cmdtp++; } } -#endif int cmd_always_repeatable(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[], int *repeatable) diff --git a/common/console.c b/common/console.c index 3348436da6..f3cc45cab5 100644 --- a/common/console.c +++ b/common/console.c @@ -44,14 +44,15 @@ static int on_console(const char *name, const char *value, enum env_op op, case env_op_create: case env_op_overwrite: -#if CONFIG_IS_ENABLED(CONSOLE_MUX) - if (iomux_doenv(console, value)) - return 1; -#else - /* Try assigning specified device */ - if (console_assign(console, value) < 0) - return 1; -#endif + if (CONFIG_IS_ENABLED(CONSOLE_MUX)) { + if (iomux_doenv(console, value)) + return 1; + } else { + /* Try assigning specified device */ + if (console_assign(console, value) < 0) + return 1; + } + return 0; case env_op_delete: @@ -69,14 +70,13 @@ U_BOOT_ENV_CALLBACK(console, on_console); static int on_silent(const char *name, const char *value, enum env_op op, int flags) { -#if !CONFIG_IS_ENABLED(SILENT_CONSOLE_UPDATE_ON_SET) - if (flags & H_INTERACTIVE) - return 0; -#endif -#if !CONFIG_IS_ENABLED(SILENT_CONSOLE_UPDATE_ON_RELOC) - if ((flags & H_INTERACTIVE) == 0) - return 0; -#endif + if (!CONFIG_IS_ENABLED(SILENT_CONSOLE_UPDATE_ON_SET)) + if (flags & H_INTERACTIVE) + return 0; + + if (!CONFIG_IS_ENABLED(SILENT_CONSOLE_UPDATE_ON_RELOC)) + if ((flags & H_INTERACTIVE) == 0) + return 0; if (value != NULL) gd->flags |= GD_FLG_SILENT; @@ -88,6 +88,64 @@ static int on_silent(const char *name, const char *value, enum env_op op, U_BOOT_ENV_CALLBACK(silent, on_silent); #endif +#ifdef CONFIG_CONSOLE_RECORD +/* helper function: access to gd->console_out and gd->console_in */ +static void console_record_putc(const char c) +{ + if (!(gd->flags & GD_FLG_RECORD)) + return; + if (gd->console_out.start) + membuff_putbyte((struct membuff *)&gd->console_out, c); +} + +static void console_record_puts(const char *s) +{ + if (!(gd->flags & GD_FLG_RECORD)) + return; + if (gd->console_out.start) + membuff_put((struct membuff *)&gd->console_out, s, strlen(s)); +} + +static int console_record_getc(void) +{ + if (!(gd->flags & GD_FLG_RECORD)) + return -1; + if (!gd->console_in.start) + return -1; + + return membuff_getbyte((struct membuff *)&gd->console_in); +} + +static int console_record_tstc(void) +{ + if (!(gd->flags & GD_FLG_RECORD)) + return 0; + if (gd->console_in.start) { + if (membuff_peekbyte((struct membuff *)&gd->console_in) != -1) + return 1; + } + return 0; +} +#else +static void console_record_putc(char c) +{ +} + +static void console_record_puts(const char *s) +{ +} + +static int console_record_getc(void) +{ + return -1; +} + +static int console_record_tstc(void) +{ + return 0; +} +#endif + #if CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV) /* * if overwrite_console returns 1, the stdin, stderr and stdout @@ -114,13 +172,9 @@ static int console_setfile(int file, struct stdio_dev * dev) case stdin: case stdout: case stderr: - /* Start new device */ - if (dev->start) { - error = dev->start(dev); - /* If it's not started dont use it */ - if (error < 0) - break; - } + error = console_start(file, dev); + if (error) + break; /* Assign the new device (leaving the existing one started) */ stdio_devices[file] = dev; @@ -159,14 +213,13 @@ static bool console_dev_is_serial(struct stdio_dev *sdev) { bool is_serial; -#ifdef CONFIG_DM_SERIAL - if (sdev->flags & DEV_FLAGS_DM) { + if (IS_ENABLED(CONFIG_DM_SERIAL) && (sdev->flags & DEV_FLAGS_DM)) { struct udevice *dev = sdev->priv; is_serial = device_get_uclass_id(dev) == UCLASS_SERIAL; - } else -#endif - is_serial = !strcmp(sdev->name, "serial"); + } else { + is_serial = !strcmp(sdev->name, "serial"); + } return is_serial; } @@ -174,10 +227,42 @@ static bool console_dev_is_serial(struct stdio_dev *sdev) #if CONFIG_IS_ENABLED(CONSOLE_MUX) /** Console I/O multiplexing *******************************************/ +/* tstcdev: save the last stdio device with pending characters, with tstc != 0 */ static struct stdio_dev *tstcdev; struct stdio_dev **console_devices[MAX_FILES]; int cd_count[MAX_FILES]; +static void __maybe_unused console_devices_set(int file, struct stdio_dev *dev) +{ + console_devices[file][0] = dev; +} + +/** + * console_needs_start_stop() - check if we need to start or stop the STDIO device + * @file: STDIO file + * @sdev: STDIO device in question + * + * This function checks if we need to start or stop the stdio device used for + * a console. For IOMUX case it simply enforces one time start and one time + * stop of the device independently of how many STDIO files are using it. In + * other words, we start console once before first STDIO device wants it and + * stop after the last is gone. + */ +static bool console_needs_start_stop(int file, struct stdio_dev *sdev) +{ + int i, j; + + for (i = 0; i < ARRAY_SIZE(cd_count); i++) { + if (i == file) + continue; + + for (j = 0; j < cd_count[i]; j++) + if (console_devices[i][j] == sdev) + return false; + } + return true; +} + /* * This depends on tstc() always being called before getchar(). * This is guaranteed to be true because this routine is called @@ -194,6 +279,12 @@ static int console_getc(int file) return ret; } +/* Upper layer may have already called tstc(): check the saved result */ +static bool console_has_tstc(void) +{ + return !!tstcdev; +} + static int console_tstc(int file) { int i, ret; @@ -276,11 +367,26 @@ static inline void console_doenv(int file, struct stdio_dev *dev) } #endif #else + +static void __maybe_unused console_devices_set(int file, struct stdio_dev *dev) +{ +} + +static inline bool console_needs_start_stop(int file, struct stdio_dev *sdev) +{ + return true; +} + static inline int console_getc(int file) { return stdio_devices[file]->getc(stdio_devices[file]); } +static bool console_has_tstc(void) +{ + return false; +} + static inline int console_tstc(int file) { return stdio_devices[file]->tstc(stdio_devices[file]); @@ -310,6 +416,32 @@ static inline void console_doenv(int file, struct stdio_dev *dev) #endif #endif /* CONIFIG_IS_ENABLED(CONSOLE_MUX) */ +int console_start(int file, struct stdio_dev *sdev) +{ + int error; + + if (!console_needs_start_stop(file, sdev)) + return 0; + + /* Start new device */ + if (sdev->start) { + error = sdev->start(sdev); + /* If it's not started don't use it */ + if (error < 0) + return error; + } + return 0; +} + +void console_stop(int file, struct stdio_dev *sdev) +{ + if (!console_needs_start_stop(file, sdev)) + return; + + if (sdev->stop) + sdev->stop(sdev); +} + /** U-Boot INITIAL CONSOLE-NOT COMPATIBLE FUNCTIONS *************************/ int serial_printf(const char *fmt, ...) @@ -338,25 +470,25 @@ int fgetc(int file) */ for (;;) { WATCHDOG_RESET(); -#if CONFIG_IS_ENABLED(CONSOLE_MUX) - /* - * Upper layer may have already called tstc() so - * check for that first. - */ - if (tstcdev != NULL) - return console_getc(file); - console_tstc(file); -#else - if (console_tstc(file)) - return console_getc(file); -#endif -#ifdef CONFIG_WATCHDOG + if (CONFIG_IS_ENABLED(CONSOLE_MUX)) { + /* + * Upper layer may have already called tstc() so + * check for that first. + */ + if (console_has_tstc()) + return console_getc(file); + console_tstc(file); + } else { + if (console_tstc(file)) + return console_getc(file); + } + /* * If the watchdog must be rate-limited then it should * already be handled in board-specific code. */ - udelay(1); -#endif + if (IS_ENABLED(CONFIG_WATCHDOG)) + udelay(1); } } @@ -406,23 +538,18 @@ int fprintf(int file, const char *fmt, ...) int getchar(void) { -#ifdef CONFIG_DISABLE_CONSOLE - if (gd->flags & GD_FLG_DISABLE_CONSOLE) + int ch; + + if (IS_ENABLED(CONFIG_DISABLE_CONSOLE) && (gd->flags & GD_FLG_DISABLE_CONSOLE)) return 0; -#endif if (!gd->have_console) return 0; -#ifdef CONFIG_CONSOLE_RECORD - if (gd->console_in.start) { - int ch; + ch = console_record_getc(); + if (ch != -1) + return ch; - ch = membuff_getbyte((struct membuff *)&gd->console_in); - if (ch != -1) - return 1; - } -#endif if (gd->flags & GD_FLG_DEVINIT) { /* Get from the standard input */ return fgetc(stdin); @@ -434,19 +561,15 @@ int getchar(void) int tstc(void) { -#ifdef CONFIG_DISABLE_CONSOLE - if (gd->flags & GD_FLG_DISABLE_CONSOLE) + if (IS_ENABLED(CONFIG_DISABLE_CONSOLE) && (gd->flags & GD_FLG_DISABLE_CONSOLE)) return 0; -#endif if (!gd->have_console) return 0; -#ifdef CONFIG_CONSOLE_RECORD - if (gd->console_in.start) { - if (membuff_peekbyte((struct membuff *)&gd->console_in) != -1) - return 1; - } -#endif + + if (console_record_tstc()) + return 1; + if (gd->flags & GD_FLG_DEVINIT) { /* Test the standard input */ return ftstc(stdin); @@ -485,10 +608,8 @@ static void print_pre_console_buffer(int flushpoint) char buf_out[CONFIG_PRE_CON_BUF_SZ + 1]; char *buf_in; -#ifdef CONFIG_SILENT_CONSOLE - if (gd->flags & GD_FLG_SILENT) + if (IS_ENABLED(CONFIG_SILENT_CONSOLE) && (gd->flags & GD_FLG_SILENT)) return; -#endif buf_in = map_sysmem(CONFIG_PRE_CON_BUF_ADDR, CONFIG_PRE_CON_BUF_SZ); if (gd->precon_buf_idx > CONFIG_PRE_CON_BUF_SZ) @@ -517,38 +638,31 @@ static inline void print_pre_console_buffer(int flushpoint) {} void putc(const char c) { -#ifdef CONFIG_SANDBOX + if (!gd) + return; + + console_record_putc(c); + /* sandbox can send characters to stdout before it has a console */ - if (!gd || !(gd->flags & GD_FLG_SERIAL_READY)) { + if (IS_ENABLED(CONFIG_SANDBOX) && !(gd->flags & GD_FLG_SERIAL_READY)) { os_putc(c); return; } -#endif -#ifdef CONFIG_DEBUG_UART + /* if we don't have a console yet, use the debug UART */ - if (!gd || !(gd->flags & GD_FLG_SERIAL_READY)) { + if (IS_ENABLED(CONFIG_DEBUG_UART) && !(gd->flags & GD_FLG_SERIAL_READY)) { printch(c); return; } -#endif - if (!gd) - return; -#ifdef CONFIG_CONSOLE_RECORD - if ((gd->flags & GD_FLG_RECORD) && gd->console_out.start) - membuff_putbyte((struct membuff *)&gd->console_out, c); -#endif -#ifdef CONFIG_SILENT_CONSOLE - if (gd->flags & GD_FLG_SILENT) { + + if (IS_ENABLED(CONFIG_SILENT_CONSOLE) && (gd->flags & GD_FLG_SILENT)) { if (!(gd->flags & GD_FLG_DEVINIT)) pre_console_putc(c); return; } -#endif -#ifdef CONFIG_DISABLE_CONSOLE - if (gd->flags & GD_FLG_DISABLE_CONSOLE) + if (IS_ENABLED(CONFIG_DISABLE_CONSOLE) && (gd->flags & GD_FLG_DISABLE_CONSOLE)) return; -#endif if (!gd->have_console) return pre_console_putc(c); @@ -565,15 +679,18 @@ void putc(const char c) void puts(const char *s) { -#ifdef CONFIG_SANDBOX + if (!gd) + return; + + console_record_puts(s); + /* sandbox can send characters to stdout before it has a console */ - if (!gd || !(gd->flags & GD_FLG_SERIAL_READY)) { + if (IS_ENABLED(CONFIG_SANDBOX) && !(gd->flags & GD_FLG_SERIAL_READY)) { os_puts(s); return; } -#endif -#ifdef CONFIG_DEBUG_UART - if (!gd || !(gd->flags & GD_FLG_SERIAL_READY)) { + + if (IS_ENABLED(CONFIG_DEBUG_UART) && !(gd->flags & GD_FLG_SERIAL_READY)) { while (*s) { int ch = *s++; @@ -581,25 +698,15 @@ void puts(const char *s) } return; } -#endif - if (!gd) - return; -#ifdef CONFIG_CONSOLE_RECORD - if ((gd->flags & GD_FLG_RECORD) && gd->console_out.start) - membuff_put((struct membuff *)&gd->console_out, s, strlen(s)); -#endif -#ifdef CONFIG_SILENT_CONSOLE - if (gd->flags & GD_FLG_SILENT) { + + if (IS_ENABLED(CONFIG_SILENT_CONSOLE) && (gd->flags & GD_FLG_SILENT)) { if (!(gd->flags & GD_FLG_DEVINIT)) pre_console_puts(s); return; } -#endif -#ifdef CONFIG_DISABLE_CONSOLE - if (gd->flags & GD_FLG_DISABLE_CONSOLE) + if (IS_ENABLED(CONFIG_DISABLE_CONSOLE) && (gd->flags & GD_FLG_DISABLE_CONSOLE)) return; -#endif if (!gd->have_console) return pre_console_puts(s); @@ -725,7 +832,7 @@ void clear_ctrlc(void) /** U-Boot INIT FUNCTIONS *************************************************/ -struct stdio_dev *search_device(int flags, const char *name) +struct stdio_dev *console_search_dev(int flags, const char *name) { struct stdio_dev *dev; @@ -761,7 +868,7 @@ int console_assign(int file, const char *devname) /* Check for valid device name */ - dev = search_device(flag, devname); + dev = console_search_dev(flag, devname); if (dev) return console_setfile(file, dev); @@ -772,19 +879,19 @@ int console_assign(int file, const char *devname) /* return true if the 'silent' flag is removed */ static bool console_update_silent(void) { -#ifdef CONFIG_SILENT_CONSOLE - if (env_get("silent")) { - gd->flags |= GD_FLG_SILENT; - } else { - unsigned long flags = gd->flags; + unsigned long flags = gd->flags; - gd->flags &= ~GD_FLG_SILENT; + if (!IS_ENABLED(CONFIG_SILENT_CONSOLE)) + return false; - return !!(flags & GD_FLG_SILENT); + if (env_get("silent")) { + gd->flags |= GD_FLG_SILENT; + return false; } -#endif - return false; + gd->flags &= ~GD_FLG_SILENT; + + return !!(flags & GD_FLG_SILENT); } int console_announce_r(void) @@ -843,12 +950,8 @@ int console_init_r(void) { char *stdinname, *stdoutname, *stderrname; struct stdio_dev *inputdev = NULL, *outputdev = NULL, *errdev = NULL; -#ifdef CONFIG_SYS_CONSOLE_ENV_OVERWRITE int i; -#endif /* CONFIG_SYS_CONSOLE_ENV_OVERWRITE */ -#if CONFIG_IS_ENABLED(CONSOLE_MUX) int iomux_err = 0; -#endif int flushpoint; /* update silent for env loaded from flash (initr_env) */ @@ -871,27 +974,27 @@ int console_init_r(void) stderrname = env_get("stderr"); if (OVERWRITE_CONSOLE == 0) { /* if not overwritten by config switch */ - inputdev = search_device(DEV_FLAGS_INPUT, stdinname); - outputdev = search_device(DEV_FLAGS_OUTPUT, stdoutname); - errdev = search_device(DEV_FLAGS_OUTPUT, stderrname); -#if CONFIG_IS_ENABLED(CONSOLE_MUX) - iomux_err = iomux_doenv(stdin, stdinname); - iomux_err += iomux_doenv(stdout, stdoutname); - iomux_err += iomux_doenv(stderr, stderrname); - if (!iomux_err) - /* Successful, so skip all the code below. */ - goto done; -#endif + inputdev = console_search_dev(DEV_FLAGS_INPUT, stdinname); + outputdev = console_search_dev(DEV_FLAGS_OUTPUT, stdoutname); + errdev = console_search_dev(DEV_FLAGS_OUTPUT, stderrname); + if (CONFIG_IS_ENABLED(CONSOLE_MUX)) { + iomux_err = iomux_doenv(stdin, stdinname); + iomux_err += iomux_doenv(stdout, stdoutname); + iomux_err += iomux_doenv(stderr, stderrname); + if (!iomux_err) + /* Successful, so skip all the code below. */ + goto done; + } } /* if the devices are overwritten or not found, use default device */ if (inputdev == NULL) { - inputdev = search_device(DEV_FLAGS_INPUT, "serial"); + inputdev = console_search_dev(DEV_FLAGS_INPUT, "serial"); } if (outputdev == NULL) { - outputdev = search_device(DEV_FLAGS_OUTPUT, "serial"); + outputdev = console_search_dev(DEV_FLAGS_OUTPUT, "serial"); } if (errdev == NULL) { - errdev = search_device(DEV_FLAGS_OUTPUT, "serial"); + errdev = console_search_dev(DEV_FLAGS_OUTPUT, "serial"); } /* Initializes output console first */ if (outputdev != NULL) { @@ -907,33 +1010,25 @@ int console_init_r(void) console_doenv(stdin, inputdev); } -#if CONFIG_IS_ENABLED(CONSOLE_MUX) done: -#endif -#ifndef CONFIG_SYS_CONSOLE_INFO_QUIET - stdio_print_current_devices(); -#endif /* CONFIG_SYS_CONSOLE_INFO_QUIET */ + if (!IS_ENABLED(CONFIG_SYS_CONSOLE_INFO_QUIET)) + stdio_print_current_devices(); + #ifdef CONFIG_VIDCONSOLE_AS_LCD if (strstr(stdoutname, CONFIG_VIDCONSOLE_AS_NAME)) printf("Warning: Please change '%s' to 'vidconsole' in stdout/stderr environment vars\n", CONFIG_VIDCONSOLE_AS_NAME); #endif -#ifdef CONFIG_SYS_CONSOLE_ENV_OVERWRITE - /* set the environment variables (will overwrite previous env settings) */ - for (i = 0; i < MAX_FILES; i++) { - env_set(stdio_names[i], stdio_devices[i]->name); + if (IS_ENABLED(CONFIG_SYS_CONSOLE_ENV_OVERWRITE)) { + /* set the environment variables (will overwrite previous env settings) */ + for (i = 0; i < MAX_FILES; i++) + env_set(stdio_names[i], stdio_devices[i]->name); } -#endif /* CONFIG_SYS_CONSOLE_ENV_OVERWRITE */ gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */ -#if 0 - /* If nothing usable installed, use only the initial console */ - if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL)) - return 0; -#endif print_pre_console_buffer(flushpoint); return 0; } @@ -956,18 +1051,16 @@ int console_init_r(void) else flushpoint = PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL; -#ifdef CONFIG_SPLASH_SCREEN /* * suppress all output if splash screen is enabled and we have * a bmp to display. We redirect the output from frame buffer * console to serial console in this case or suppress it if * "silent" mode was requested. */ - if (env_get("splashimage") != NULL) { + if (IS_ENABLED(CONFIG_SPLASH_SCREEN) && env_get("splashimage")) { if (!(gd->flags & GD_FLG_SILENT)) - outputdev = search_device (DEV_FLAGS_OUTPUT, "serial"); + outputdev = console_search_dev (DEV_FLAGS_OUTPUT, "serial"); } -#endif /* Scan devices looking for input and output devices */ list_for_each(pos, list) { @@ -987,23 +1080,18 @@ int console_init_r(void) if (outputdev != NULL) { console_setfile(stdout, outputdev); console_setfile(stderr, outputdev); -#if CONFIG_IS_ENABLED(CONSOLE_MUX) - console_devices[stdout][0] = outputdev; - console_devices[stderr][0] = outputdev; -#endif + console_devices_set(stdout, outputdev); + console_devices_set(stderr, outputdev); } /* Initializes input console */ if (inputdev != NULL) { console_setfile(stdin, inputdev); -#if CONFIG_IS_ENABLED(CONSOLE_MUX) - console_devices[stdin][0] = inputdev; -#endif + console_devices_set(stdin, inputdev); } -#ifndef CONFIG_SYS_CONSOLE_INFO_QUIET - stdio_print_current_devices(); -#endif /* CONFIG_SYS_CONSOLE_INFO_QUIET */ + if (!IS_ENABLED(CONFIG_SYS_CONSOLE_INFO_QUIET)) + stdio_print_current_devices(); /* Setting environment variables */ for (i = 0; i < MAX_FILES; i++) { @@ -1012,11 +1100,6 @@ int console_init_r(void) gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */ -#if 0 - /* If nothing usable installed, use only the initial console */ - if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL)) - return 0; -#endif print_pre_console_buffer(flushpoint); return 0; } diff --git a/common/exports.c b/common/exports.c index 6253b55694..4578f07021 100644 --- a/common/exports.c +++ b/common/exports.c @@ -25,8 +25,10 @@ unsigned long get_version(void) # define miiphy_set_current_dev dummy #endif -void jumptable_init(void) +int jumptable_init(void) { gd->jt = malloc(sizeof(struct jt_funcs)); #include <_exports.h> + + return 0; } diff --git a/common/image-fit.c b/common/image-fit.c index 6a8787ca0a..21c44bdf69 100644 --- a/common/image-fit.c +++ b/common/image-fit.c @@ -1553,6 +1553,12 @@ int fit_image_check_comp(const void *fit, int noffset, uint8_t comp) */ int fit_check_format(const void *fit) { + /* A FIT image must be a valid FDT */ + if (fdt_check_header(fit)) { + debug("Wrong FIT format: not a flattened device tree\n"); + return 0; + } + /* mandatory / node 'description' property */ if (fdt_getprop(fit, 0, FIT_DESC_PROP, NULL) == NULL) { debug("Wrong FIT format: no description\n"); diff --git a/common/iomux.c b/common/iomux.c index 7cfd9f2e91..15bf533885 100644 --- a/common/iomux.c +++ b/common/iomux.c @@ -27,8 +27,8 @@ int iomux_doenv(const int console, const char *arg) { char *console_args, *temp, **start; int i, j, k, io_flag, cs_idx, repeat; + struct stdio_dev **cons_set, **old_set; struct stdio_dev *dev; - struct stdio_dev **cons_set; console_args = strdup(arg); if (console_args == NULL) @@ -45,15 +45,14 @@ int iomux_doenv(const int console, const char *arg) i = 0; temp = console_args; for (;;) { - temp = strchr(temp, ','); - if (temp != NULL) { - i++; - temp++; - continue; - } /* There's always one entry more than the number of commas. */ i++; - break; + + temp = strchr(temp, ','); + if (temp == NULL) + break; + + temp++; } start = (char **)malloc(i * sizeof(char *)); if (start == NULL) { @@ -95,10 +94,10 @@ int iomux_doenv(const int console, const char *arg) for (j = 0; j < i; j++) { /* * Check whether the device exists and is valid. - * console_assign() also calls search_device(), + * console_assign() also calls console_search_dev(), * but I need the pointer to the device. */ - dev = search_device(io_flag, start[j]); + dev = console_search_dev(io_flag, start[j]); if (dev == NULL) continue; /* @@ -127,21 +126,25 @@ int iomux_doenv(const int console, const char *arg) if (cs_idx == 0) { free(cons_set); return 1; - } else { - /* Works even if console_devices[console] is NULL. */ - console_devices[console] = - (struct stdio_dev **)realloc(console_devices[console], - cs_idx * sizeof(struct stdio_dev *)); - if (console_devices[console] == NULL) { - free(cons_set); - return 1; - } - memcpy(console_devices[console], cons_set, cs_idx * - sizeof(struct stdio_dev *)); + } + + old_set = console_devices[console]; + repeat = cd_count[console]; - cd_count[console] = cs_idx; + console_devices[console] = cons_set; + cd_count[console] = cs_idx; + + /* Stop dropped consoles */ + for (i = 0; i < repeat; i++) { + for (j = 0; j < cs_idx; j++) { + if (old_set[i] == cons_set[j]) + break; + } + if (j == cs_idx) + console_stop(console, old_set[i]); } - free(cons_set); + + free(old_set); return 0; } #endif /* CONSOLE_MUX */ diff --git a/common/log.c b/common/log.c index ce39918e04..767f0febc5 100644 --- a/common/log.c +++ b/common/log.c @@ -198,9 +198,10 @@ static bool log_passes_filters(struct log_device *ldev, struct log_rec *rec) * @rec: log record to dispatch * Return: 0 msg sent, 1 msg not sent while already dispatching another msg */ -static int log_dispatch(struct log_rec *rec) +static int log_dispatch(struct log_rec *rec, const char *fmt, va_list args) { struct log_device *ldev; + char buf[CONFIG_SYS_CBSIZE]; /* * When a log driver writes messages (e.g. via the network stack) this @@ -214,8 +215,13 @@ static int log_dispatch(struct log_rec *rec) gd->processing_msg = true; list_for_each_entry(ldev, &gd->log_head, sibling_node) { if ((ldev->flags & LOGDF_ENABLE) && - log_passes_filters(ldev, rec)) + log_passes_filters(ldev, rec)) { + if (!rec->msg) { + vsnprintf(buf, sizeof(buf), fmt, args); + rec->msg = buf; + } ldev->drv->emit(ldev, rec); + } } gd->processing_msg = false; return 0; @@ -224,10 +230,12 @@ static int log_dispatch(struct log_rec *rec) int _log(enum log_category_t cat, enum log_level_t level, const char *file, int line, const char *func, const char *fmt, ...) { - char buf[CONFIG_SYS_CBSIZE]; struct log_rec rec; va_list args; + if (!gd) + return -ENOSYS; + /* Check for message continuation */ if (cat == LOGC_CONT) cat = gd->logc_prev; @@ -240,19 +248,29 @@ int _log(enum log_category_t cat, enum log_level_t level, const char *file, rec.file = file; rec.line = line; rec.func = func; - va_start(args, fmt); - vsnprintf(buf, sizeof(buf), fmt, args); - va_end(args); - rec.msg = buf; - if (!gd || !(gd->flags & GD_FLG_LOG_READY)) { - if (gd) - gd->log_drop_count++; + rec.msg = NULL; + + if (!(gd->flags & GD_FLG_LOG_READY)) { + gd->log_drop_count++; + + /* display dropped traces with console puts and DEBUG_UART */ + if (rec.level <= CONFIG_LOG_DEFAULT_LEVEL || rec.force_debug) { + char buf[CONFIG_SYS_CBSIZE]; + + va_start(args, fmt); + vsnprintf(buf, sizeof(buf), fmt, args); + puts(buf); + va_end(args); + } + return -ENOSYS; } - if (!log_dispatch(&rec)) { + va_start(args, fmt); + if (!log_dispatch(&rec, fmt, args)) { gd->logc_prev = cat; gd->logl_prev = level; } + va_end(args); return 0; } diff --git a/common/spl/Kconfig b/common/spl/Kconfig index 6b0186763b..7561335bfd 100644 --- a/common/spl/Kconfig +++ b/common/spl/Kconfig @@ -126,7 +126,7 @@ endmenu config HANDOFF bool "Pass hand-off information from SPL to U-Boot proper" - depends on BLOBLIST + depends on SPL && BLOBLIST help It is useful to be able to pass information from SPL to U-Boot proper to preserve state that is known in SPL and is needed in U-Boot. diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c index 795e2922ce..a6ad094e91 100644 --- a/common/spl/spl_fit.c +++ b/common/spl/spl_fit.c @@ -684,8 +684,11 @@ int spl_load_simple_fit(struct spl_image_info *spl_image, ret = spl_load_fit_image(info, sector, fit, base_offset, node, &image_info); - if (ret < 0) - continue; + if (ret < 0) { + printf("%s: can't load image loadables index %d (ret = %d)\n", + __func__, index, ret); + return ret; + } if (!spl_fit_image_get_os(fit, node, &os_type)) debug("Loadable is %s\n", genimg_get_os_name(os_type)); diff --git a/common/stdio.c b/common/stdio.c index a15f30804b..abf9b1e915 100644 --- a/common/stdio.c +++ b/common/stdio.c @@ -181,7 +181,7 @@ struct stdio_dev *stdio_get_by_name(const char *name) * 'stdout', which may include a list of devices separate by * commas. Obviously this is not going to work, so we ignore * that case. The call path in that case is - * console_init_r() -> search_device() -> stdio_get_by_name() + * console_init_r() -> console_search_dev() -> stdio_get_by_name() */ if (!strncmp(name, "vidconsole", 10) && !strchr(name, ',') && !stdio_probe_device(name, UCLASS_VIDEO, &sdev)) @@ -332,7 +332,7 @@ int stdio_add_devices(void) /* * If the console setting is not in environment variables then * console_init_r() will not be calling iomux_doenv() (which - * calls search_device()). So we will not dynamically add + * calls console_search_dev()). So we will not dynamically add * devices by calling stdio_probe_device(). * * So just probe all video devices now so that whichever one is diff --git a/configs/beelink-gtking_defconfig b/configs/beelink-gtking_defconfig new file mode 100644 index 0000000000..ea428874af --- /dev/null +++ b/configs/beelink-gtking_defconfig @@ -0,0 +1,71 @@ +CONFIG_ARM=y +CONFIG_SYS_BOARD="beelink-s922x" +CONFIG_ARCH_MESON=y +CONFIG_SYS_TEXT_BASE=0x01000000 +CONFIG_NR_DRAM_BANKS=1 +CONFIG_ENV_SIZE=0x2000 +CONFIG_DM_GPIO=y +CONFIG_MESON_G12A=y +CONFIG_DEBUG_UART_BASE=0xff803000 +CONFIG_DEBUG_UART_CLOCK=24000000 +CONFIG_IDENT_STRING=" beelink" +CONFIG_DEFAULT_DEVICE_TREE="meson-g12b-gtking" +CONFIG_DEBUG_UART=y +CONFIG_OF_BOARD_SETUP=y +CONFIG_MISC_INIT_R=y +# CONFIG_DISPLAY_CPUINFO is not set +# CONFIG_CMD_BDI is not set +# CONFIG_CMD_IMI is not set +CONFIG_CMD_GPIO=y +# CONFIG_CMD_LOADS is not set +CONFIG_CMD_MMC=y +CONFIG_CMD_SF_TEST=y +CONFIG_CMD_SPI=y +CONFIG_CMD_USB=y +CONFIG_CMD_USB_MASS_STORAGE=y +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_REGULATOR=y +CONFIG_OF_CONTROL=y +CONFIG_SYS_RELOC_GD_ENV_ADDR=y +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_DM_MMC=y +CONFIG_MMC_MESON_GX=y +CONFIG_MTD=y +CONFIG_DM_MTD=y +CONFIG_PHY_REALTEK=y +CONFIG_DM_ETH=y +CONFIG_ETH_DESIGNWARE=y +CONFIG_MESON_G12A_USB_PHY=y +CONFIG_PINCTRL=y +CONFIG_PINCTRL_MESON_G12A=y +CONFIG_POWER_DOMAIN=y +CONFIG_MESON_EE_POWER_DOMAIN=y +CONFIG_DM_REGULATOR=y +CONFIG_DM_REGULATOR_FIXED=y +CONFIG_DM_RESET=y +CONFIG_DEBUG_UART_ANNOUNCE=y +CONFIG_DEBUG_UART_SKIP_INIT=y +CONFIG_MESON_SERIAL=y +CONFIG_USB=y +CONFIG_DM_USB=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_DWC3=y +CONFIG_USB_DWC3=y +# CONFIG_USB_DWC3_GADGET is not set +CONFIG_USB_DWC3_MESON_G12A=y +CONFIG_USB_KEYBOARD=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_VENDOR_NUM=0x1b8e +CONFIG_USB_GADGET_PRODUCT_NUM=0xfada +CONFIG_USB_GADGET_DWC2_OTG=y +CONFIG_USB_GADGET_DWC2_OTG_PHY_BUS_WIDTH_8=y +CONFIG_USB_GADGET_DOWNLOAD=y +CONFIG_DM_VIDEO=y +# CONFIG_VIDEO_BPP8 is not set +# CONFIG_VIDEO_BPP16 is not set +CONFIG_SYS_WHITE_ON_BLACK=y +CONFIG_VIDEO_MESON=y +CONFIG_VIDEO_DT_SIMPLEFB=y +CONFIG_SPLASH_SCREEN=y +CONFIG_SPLASH_SCREEN_ALIGN=y +CONFIG_OF_LIBFDT_OVERLAY=y diff --git a/configs/beelink-gtkingpro_defconfig b/configs/beelink-gtkingpro_defconfig new file mode 100644 index 0000000000..569031600a --- /dev/null +++ b/configs/beelink-gtkingpro_defconfig @@ -0,0 +1,71 @@ +CONFIG_ARM=y +CONFIG_SYS_BOARD="beelink-s922x" +CONFIG_ARCH_MESON=y +CONFIG_SYS_TEXT_BASE=0x01000000 +CONFIG_NR_DRAM_BANKS=1 +CONFIG_ENV_SIZE=0x2000 +CONFIG_DM_GPIO=y +CONFIG_MESON_G12A=y +CONFIG_DEBUG_UART_BASE=0xff803000 +CONFIG_DEBUG_UART_CLOCK=24000000 +CONFIG_IDENT_STRING=" beelink" +CONFIG_DEFAULT_DEVICE_TREE="meson-g12b-gtking-pro" +CONFIG_DEBUG_UART=y +CONFIG_OF_BOARD_SETUP=y +CONFIG_MISC_INIT_R=y +# CONFIG_DISPLAY_CPUINFO is not set +# CONFIG_CMD_BDI is not set +# CONFIG_CMD_IMI is not set +CONFIG_CMD_GPIO=y +# CONFIG_CMD_LOADS is not set +CONFIG_CMD_MMC=y +CONFIG_CMD_SF_TEST=y +CONFIG_CMD_SPI=y +CONFIG_CMD_USB=y +CONFIG_CMD_USB_MASS_STORAGE=y +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_REGULATOR=y +CONFIG_OF_CONTROL=y +CONFIG_SYS_RELOC_GD_ENV_ADDR=y +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_DM_MMC=y +CONFIG_MMC_MESON_GX=y +CONFIG_MTD=y +CONFIG_DM_MTD=y +CONFIG_PHY_REALTEK=y +CONFIG_DM_ETH=y +CONFIG_ETH_DESIGNWARE=y +CONFIG_MESON_G12A_USB_PHY=y +CONFIG_PINCTRL=y +CONFIG_PINCTRL_MESON_G12A=y +CONFIG_POWER_DOMAIN=y +CONFIG_MESON_EE_POWER_DOMAIN=y +CONFIG_DM_REGULATOR=y +CONFIG_DM_REGULATOR_FIXED=y +CONFIG_DM_RESET=y +CONFIG_DEBUG_UART_ANNOUNCE=y +CONFIG_DEBUG_UART_SKIP_INIT=y +CONFIG_MESON_SERIAL=y +CONFIG_USB=y +CONFIG_DM_USB=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_DWC3=y +CONFIG_USB_DWC3=y +# CONFIG_USB_DWC3_GADGET is not set +CONFIG_USB_DWC3_MESON_G12A=y +CONFIG_USB_KEYBOARD=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_VENDOR_NUM=0x1b8e +CONFIG_USB_GADGET_PRODUCT_NUM=0xfada +CONFIG_USB_GADGET_DWC2_OTG=y +CONFIG_USB_GADGET_DWC2_OTG_PHY_BUS_WIDTH_8=y +CONFIG_USB_GADGET_DOWNLOAD=y +CONFIG_DM_VIDEO=y +# CONFIG_VIDEO_BPP8 is not set +# CONFIG_VIDEO_BPP16 is not set +CONFIG_SYS_WHITE_ON_BLACK=y +CONFIG_VIDEO_MESON=y +CONFIG_VIDEO_DT_SIMPLEFB=y +CONFIG_SPLASH_SCREEN=y +CONFIG_SPLASH_SCREEN_ALIGN=y +CONFIG_OF_LIBFDT_OVERLAY=y diff --git a/configs/cortina_presidio-asic-pnand_defconfig b/configs/cortina_presidio-asic-pnand_defconfig new file mode 100644 index 0000000000..e85cdc579e --- /dev/null +++ b/configs/cortina_presidio-asic-pnand_defconfig @@ -0,0 +1,33 @@ +CONFIG_ARM=y +# CONFIG_SYS_ARCH_TIMER is not set +CONFIG_TARGET_PRESIDIO_ASIC=y +CONFIG_SYS_TEXT_BASE=0x04000000 +CONFIG_NR_DRAM_BANKS=1 +CONFIG_ENV_SIZE=0x20000 +CONFIG_DM_GPIO=y +CONFIG_IDENT_STRING="Presidio-SoC" +CONFIG_DEFAULT_DEVICE_TREE="ca-presidio-engboard" +CONFIG_SHOW_BOOT_PROGRESS=y +CONFIG_BOOTDELAY=3 +CONFIG_USE_BOOTARGS=y +CONFIG_BOOTARGS="earlycon=serial,0xf4329148 console=ttyS0,115200 root=/dev/ram0" +CONFIG_BOARD_EARLY_INIT_R=y +CONFIG_SYS_PROMPT="G3#" +CONFIG_CMD_MTD=y +CONFIG_CMD_WDT=y +CONFIG_CMD_CACHE=y +CONFIG_CMD_TIMER=y +CONFIG_CMD_SMC=y +CONFIG_OF_CONTROL=y +CONFIG_OF_LIVE=y +# CONFIG_NET is not set +CONFIG_DM=y +CONFIG_CORTINA_GPIO=y +# CONFIG_MMC is not set +CONFIG_MTD=y +CONFIG_MTD_RAW_NAND=y +CONFIG_CORTINA_NAND=y +CONFIG_DM_SERIAL=y +CONFIG_CORTINA_UART=y +CONFIG_WDT=y +CONFIG_WDT_CORTINA=y diff --git a/configs/evb-ast2600_defconfig b/configs/evb-ast2600_defconfig new file mode 100644 index 0000000000..003fedd02a --- /dev/null +++ b/configs/evb-ast2600_defconfig @@ -0,0 +1,69 @@ +CONFIG_ARM=y +CONFIG_SYS_DCACHE_OFF=y +CONFIG_ARCH_ASPEED=y +CONFIG_SYS_TEXT_BASE=0x10000 +CONFIG_ASPEED_AST2600=y +CONFIG_TARGET_EVB_AST2600=y +CONFIG_SPL_LIBCOMMON_SUPPORT=y +CONFIG_SPL_LIBGENERIC_SUPPORT=y +CONFIG_SYS_MALLOC_F_LEN=0x800 +CONFIG_NR_DRAM_BANKS=1 +CONFIG_ENV_SIZE=0x10000 +CONFIG_SPL_SERIAL_SUPPORT=y +CONFIG_SPL_SIZE_LIMIT=0x10000 +CONFIG_SPL=y +# CONFIG_ARMV7_NONSEC is not set +CONFIG_DEFAULT_DEVICE_TREE="ast2600-evb" +# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set +CONFIG_FIT=y +# CONFIG_LEGACY_IMAGE_FORMAT is not set +CONFIG_USE_BOOTARGS=y +CONFIG_BOOTARGS="console=ttyS4,115200n8 root=/dev/ram rw" +CONFIG_USE_BOOTCOMMAND=y +CONFIG_BOOTCOMMAND="bootm 20100000" +# CONFIG_DISPLAY_CPUINFO is not set +CONFIG_SPL_SIZE_LIMIT_SUBTRACT_GD=y +CONFIG_SPL_SIZE_LIMIT_SUBTRACT_MALLOC=y +# CONFIG_SPL_LEGACY_IMAGE_SUPPORT is not set +CONFIG_SPL_SYS_MALLOC_SIMPLE=y +CONFIG_SPL_DM_RESET=y +CONFIG_SPL_RAM_SUPPORT=y +CONFIG_SPL_RAM_DEVICE=y +CONFIG_HUSH_PARSER=y +CONFIG_CMD_I2C=y +CONFIG_CMD_MMC=y +CONFIG_CMD_DHCP=y +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y +CONFIG_SPL_OF_CONTROL=y +CONFIG_ENV_OVERWRITE=y +CONFIG_SYS_RELOC_GD_ENV_ADDR=y +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_SPL_DM=y +CONFIG_SPL_DM_SEQ_ALIAS=y +CONFIG_REGMAP=y +CONFIG_SPL_OF_TRANSLATE=y +CONFIG_CLK=y +CONFIG_SPL_CLK=y +CONFIG_DM_I2C=y +CONFIG_MISC=y +CONFIG_SPL_MISC=y +CONFIG_DM_MMC=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_ASPEED=y +CONFIG_PHY_REALTEK=y +CONFIG_DM_ETH=y +CONFIG_FTGMAC100=y +CONFIG_PHY=y +CONFIG_PINCTRL=y +CONFIG_RAM=y +CONFIG_SPL_RAM=y +CONFIG_DM_RESET=y +CONFIG_DM_SERIAL=y +CONFIG_SYS_NS16550=y +CONFIG_SYSRESET=y +CONFIG_SPL_SYSRESET=y +CONFIG_WDT=y +CONFIG_HEXDUMP=y +# CONFIG_SPL_HEXDUMP is not set +# CONFIG_EFI_LOADER is not set diff --git a/configs/firefly-rk3399_defconfig b/configs/firefly-rk3399_defconfig index c453b82dc5..cfbaae40aa 100644 --- a/configs/firefly-rk3399_defconfig +++ b/configs/firefly-rk3399_defconfig @@ -35,6 +35,8 @@ CONFIG_MMC_DW=y CONFIG_MMC_DW_ROCKCHIP=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_ROCKCHIP=y +CONFIG_DM_RNG=y +CONFIG_RNG_ROCKCHIP=y CONFIG_SF_DEFAULT_SPEED=20000000 CONFIG_DM_ETH=y CONFIG_ETH_DESIGNWARE=y diff --git a/configs/khadas-vim3_defconfig b/configs/khadas-vim3_defconfig index 9d7ba72d44..5d16652fd6 100644 --- a/configs/khadas-vim3_defconfig +++ b/configs/khadas-vim3_defconfig @@ -29,6 +29,8 @@ CONFIG_CMD_REGULATOR=y CONFIG_OF_CONTROL=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_ADC=y +CONFIG_SARADC_MESON=y CONFIG_DM_I2C=y CONFIG_SYS_I2C_MESON=y CONFIG_DM_MMC=y diff --git a/configs/khadas-vim3l_defconfig b/configs/khadas-vim3l_defconfig index f37993e580..6b13ce045c 100644 --- a/configs/khadas-vim3l_defconfig +++ b/configs/khadas-vim3l_defconfig @@ -29,6 +29,8 @@ CONFIG_CMD_REGULATOR=y CONFIG_OF_CONTROL=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_ADC=y +CONFIG_SARADC_MESON=y CONFIG_DM_I2C=y CONFIG_SYS_I2C_MESON=y CONFIG_DM_MMC=y diff --git a/configs/km_kirkwood_128m16_defconfig b/configs/km_kirkwood_128m16_defconfig index d97e588ede..151425fbe3 100644 --- a/configs/km_kirkwood_128m16_defconfig +++ b/configs/km_kirkwood_128m16_defconfig @@ -8,7 +8,7 @@ CONFIG_ENV_SIZE=0x2000 CONFIG_ENV_OFFSET=0x0 CONFIG_BOOTCOUNT_BOOTLIMIT=3 CONFIG_ENV_OFFSET_REDUND=0x2000 -CONFIG_IDENT_STRING="\nKeymile Kirkwood 128M16" +CONFIG_IDENT_STRING="\nHitachi Power Grids Kirkwood 128M16" CONFIG_DEFAULT_DEVICE_TREE="kirkwood-km_kirkwood" CONFIG_SYS_EXTRA_OPTIONS="KM_KIRKWOOD_128M16" CONFIG_AUTOBOOT_KEYED=y @@ -17,16 +17,18 @@ CONFIG_AUTOBOOT_STOP_STR=" " # CONFIG_DISPLAY_BOARDINFO is not set CONFIG_MISC_INIT_R=y CONFIG_HUSH_PARSER=y +# CONFIG_BOOTM_NETBSD is not set +# CONFIG_BOOTM_PLAN9 is not set +# CONFIG_BOOTM_RTEMS is not set +# CONFIG_BOOTM_VXWORKS is not set CONFIG_CMD_ASKENV=y CONFIG_CMD_GREPENV=y CONFIG_CMD_EEPROM=y # CONFIG_CMD_FLASH is not set CONFIG_CMD_I2C=y CONFIG_CMD_NAND=y -CONFIG_CMD_DHCP=y CONFIG_CMD_MII=y CONFIG_CMD_PING=y -CONFIG_CMD_JFFS2=y CONFIG_CMD_MTDPARTS=y CONFIG_MTDIDS_DEFAULT="nand0=orion_nand" CONFIG_MTDPARTS_DEFAULT="mtdparts=orion_nand:-(ubi0);" diff --git a/configs/km_kirkwood_defconfig b/configs/km_kirkwood_defconfig index 0b364dcd9a..22c2e0509d 100644 --- a/configs/km_kirkwood_defconfig +++ b/configs/km_kirkwood_defconfig @@ -8,7 +8,7 @@ CONFIG_ENV_SIZE=0x2000 CONFIG_ENV_OFFSET=0x0 CONFIG_BOOTCOUNT_BOOTLIMIT=3 CONFIG_ENV_OFFSET_REDUND=0x2000 -CONFIG_IDENT_STRING="\nKeymile Kirkwood" +CONFIG_IDENT_STRING="\nHitachi Power Grids Kirkwood" CONFIG_DEFAULT_DEVICE_TREE="kirkwood-km_kirkwood" CONFIG_SYS_EXTRA_OPTIONS="KM_KIRKWOOD" CONFIG_AUTOBOOT_KEYED=y @@ -17,16 +17,18 @@ CONFIG_AUTOBOOT_STOP_STR=" " # CONFIG_DISPLAY_BOARDINFO is not set CONFIG_MISC_INIT_R=y CONFIG_HUSH_PARSER=y +# CONFIG_BOOTM_NETBSD is not set +# CONFIG_BOOTM_PLAN9 is not set +# CONFIG_BOOTM_RTEMS is not set +# CONFIG_BOOTM_VXWORKS is not set CONFIG_CMD_ASKENV=y CONFIG_CMD_GREPENV=y CONFIG_CMD_EEPROM=y # CONFIG_CMD_FLASH is not set CONFIG_CMD_I2C=y CONFIG_CMD_NAND=y -CONFIG_CMD_DHCP=y CONFIG_CMD_MII=y CONFIG_CMD_PING=y -CONFIG_CMD_JFFS2=y CONFIG_CMD_MTDPARTS=y CONFIG_MTDIDS_DEFAULT="nand0=orion_nand" CONFIG_MTDPARTS_DEFAULT="mtdparts=orion_nand:-(ubi0);" diff --git a/configs/km_kirkwood_pci_defconfig b/configs/km_kirkwood_pci_defconfig index 82d0210574..c091cd6cfe 100644 --- a/configs/km_kirkwood_pci_defconfig +++ b/configs/km_kirkwood_pci_defconfig @@ -9,7 +9,7 @@ CONFIG_ENV_SIZE=0x2000 CONFIG_ENV_OFFSET=0x0 CONFIG_BOOTCOUNT_BOOTLIMIT=3 CONFIG_ENV_OFFSET_REDUND=0x2000 -CONFIG_IDENT_STRING="\nKeymile Kirkwood PCI" +CONFIG_IDENT_STRING="\nHitachi Power Grids Kirkwood PCI" CONFIG_DEFAULT_DEVICE_TREE="kirkwood-km_kirkwood" CONFIG_SYS_EXTRA_OPTIONS="KM_KIRKWOOD_PCI" CONFIG_AUTOBOOT_KEYED=y @@ -18,16 +18,18 @@ CONFIG_AUTOBOOT_STOP_STR=" " # CONFIG_DISPLAY_BOARDINFO is not set CONFIG_MISC_INIT_R=y CONFIG_HUSH_PARSER=y +# CONFIG_BOOTM_NETBSD is not set +# CONFIG_BOOTM_PLAN9 is not set +# CONFIG_BOOTM_RTEMS is not set +# CONFIG_BOOTM_VXWORKS is not set CONFIG_CMD_ASKENV=y CONFIG_CMD_GREPENV=y CONFIG_CMD_EEPROM=y # CONFIG_CMD_FLASH is not set CONFIG_CMD_I2C=y CONFIG_CMD_NAND=y -CONFIG_CMD_DHCP=y CONFIG_CMD_MII=y CONFIG_CMD_PING=y -CONFIG_CMD_JFFS2=y CONFIG_CMD_MTDPARTS=y CONFIG_MTDIDS_DEFAULT="nand0=orion_nand" CONFIG_MTDPARTS_DEFAULT="mtdparts=orion_nand:-(ubi0);" @@ -46,6 +48,7 @@ CONFIG_BOOTCOUNT_RAM=y CONFIG_MTD=y CONFIG_MTD_RAW_NAND=y CONFIG_SF_DEFAULT_SPEED=8100000 +CONFIG_SPI_FLASH_MACRONIX=y CONFIG_SPI_FLASH_STMICRO=y CONFIG_MVGBE=y CONFIG_MII=y diff --git a/configs/kmcoge5un_defconfig b/configs/kmcoge5un_defconfig index b0ae24df03..4d2c17f399 100644 --- a/configs/kmcoge5un_defconfig +++ b/configs/kmcoge5un_defconfig @@ -12,7 +12,7 @@ CONFIG_ENV_OFFSET=0xC0000 CONFIG_ENV_SECT_SIZE=0x10000 CONFIG_BOOTCOUNT_BOOTLIMIT=3 CONFIG_ENV_OFFSET_REDUND=0xD0000 -CONFIG_IDENT_STRING="\nKeymile COGE5UN" +CONFIG_IDENT_STRING="\nHitachi Power Grids COGE5UN" CONFIG_DEFAULT_DEVICE_TREE="kirkwood-km_kirkwood" CONFIG_SYS_EXTRA_OPTIONS="KM_COGE5UN" CONFIG_AUTOBOOT_KEYED=y @@ -21,16 +21,18 @@ CONFIG_AUTOBOOT_STOP_STR=" " # CONFIG_DISPLAY_BOARDINFO is not set CONFIG_MISC_INIT_R=y CONFIG_HUSH_PARSER=y +# CONFIG_BOOTM_NETBSD is not set +# CONFIG_BOOTM_PLAN9 is not set +# CONFIG_BOOTM_RTEMS is not set +# CONFIG_BOOTM_VXWORKS is not set CONFIG_CMD_ASKENV=y CONFIG_CMD_GREPENV=y CONFIG_CMD_EEPROM=y # CONFIG_CMD_FLASH is not set CONFIG_CMD_I2C=y CONFIG_CMD_NAND=y -CONFIG_CMD_DHCP=y CONFIG_CMD_MII=y CONFIG_CMD_PING=y -CONFIG_CMD_JFFS2=y CONFIG_CMD_MTDPARTS=y CONFIG_MTDIDS_DEFAULT="nand0=orion_nand" CONFIG_MTDPARTS_DEFAULT="mtdparts=orion_nand:-(ubi0);" diff --git a/configs/kmnusa_defconfig b/configs/kmnusa_defconfig index 6e6cc5a92e..faaa8d1a5f 100644 --- a/configs/kmnusa_defconfig +++ b/configs/kmnusa_defconfig @@ -12,7 +12,7 @@ CONFIG_ENV_OFFSET=0xC0000 CONFIG_ENV_SECT_SIZE=0x10000 CONFIG_BOOTCOUNT_BOOTLIMIT=3 CONFIG_ENV_OFFSET_REDUND=0xD0000 -CONFIG_IDENT_STRING="\nKeymile NUSA" +CONFIG_IDENT_STRING="\nHitachi Power Grids Kirkwood" CONFIG_DEFAULT_DEVICE_TREE="kirkwood-km_kirkwood" CONFIG_SYS_EXTRA_OPTIONS="KM_NUSA" CONFIG_AUTOBOOT_KEYED=y @@ -21,16 +21,18 @@ CONFIG_AUTOBOOT_STOP_STR=" " # CONFIG_DISPLAY_BOARDINFO is not set CONFIG_MISC_INIT_R=y CONFIG_HUSH_PARSER=y +# CONFIG_BOOTM_NETBSD is not set +# CONFIG_BOOTM_PLAN9 is not set +# CONFIG_BOOTM_RTEMS is not set +# CONFIG_BOOTM_VXWORKS is not set CONFIG_CMD_ASKENV=y CONFIG_CMD_GREPENV=y CONFIG_CMD_EEPROM=y # CONFIG_CMD_FLASH is not set CONFIG_CMD_I2C=y CONFIG_CMD_NAND=y -CONFIG_CMD_DHCP=y CONFIG_CMD_MII=y CONFIG_CMD_PING=y -CONFIG_CMD_JFFS2=y CONFIG_CMD_MTDPARTS=y CONFIG_MTDIDS_DEFAULT="nand0=orion_nand" CONFIG_MTDPARTS_DEFAULT="mtdparts=orion_nand:-(ubi0);" diff --git a/configs/kmsuse2_defconfig b/configs/kmsuse2_defconfig index 0b75b2e80d..d8280f961b 100644 --- a/configs/kmsuse2_defconfig +++ b/configs/kmsuse2_defconfig @@ -13,7 +13,7 @@ CONFIG_ENV_OFFSET=0xC0000 CONFIG_ENV_SECT_SIZE=0x10000 CONFIG_BOOTCOUNT_BOOTLIMIT=3 CONFIG_ENV_OFFSET_REDUND=0xD0000 -CONFIG_IDENT_STRING="\nABB SUSE2" +CONFIG_IDENT_STRING="\nHitachi Power Grids Kirkwood" CONFIG_DEFAULT_DEVICE_TREE="kirkwood-km_kirkwood" CONFIG_SYS_EXTRA_OPTIONS="KM_SUSE2" CONFIG_AUTOBOOT_KEYED=y @@ -22,16 +22,18 @@ CONFIG_AUTOBOOT_STOP_STR=" " # CONFIG_DISPLAY_BOARDINFO is not set CONFIG_MISC_INIT_R=y CONFIG_HUSH_PARSER=y +# CONFIG_BOOTM_NETBSD is not set +# CONFIG_BOOTM_PLAN9 is not set +# CONFIG_BOOTM_RTEMS is not set +# CONFIG_BOOTM_VXWORKS is not set CONFIG_CMD_ASKENV=y CONFIG_CMD_GREPENV=y CONFIG_CMD_EEPROM=y # CONFIG_CMD_FLASH is not set CONFIG_CMD_I2C=y CONFIG_CMD_NAND=y -CONFIG_CMD_DHCP=y CONFIG_CMD_MII=y CONFIG_CMD_PING=y -CONFIG_CMD_JFFS2=y CONFIG_CMD_MTDPARTS=y CONFIG_MTDIDS_DEFAULT="nand0=orion_nand" CONFIG_MTDPARTS_DEFAULT="mtdparts=orion_nand:-(ubi0);" diff --git a/configs/libretech-ac_defconfig b/configs/libretech-ac_defconfig index 171d793ae3..ca61591bd7 100644 --- a/configs/libretech-ac_defconfig +++ b/configs/libretech-ac_defconfig @@ -51,7 +51,7 @@ CONFIG_MESON_GXL_USB_PHY=y CONFIG_PINCTRL=y CONFIG_PINCTRL_MESON_GXL=y CONFIG_POWER_DOMAIN=y -CONFIG_MESON_GX_VPU_POWER_DOMAIN=y +CONFIG_MESON_EE_POWER_DOMAIN=y CONFIG_DM_REGULATOR=y CONFIG_DM_REGULATOR_FIXED=y CONFIG_DM_RESET=y diff --git a/configs/libretech-cc_defconfig b/configs/libretech-cc_defconfig index aaab1a2d08..fb4bf4c929 100644 --- a/configs/libretech-cc_defconfig +++ b/configs/libretech-cc_defconfig @@ -38,7 +38,7 @@ CONFIG_MESON_GXL_USB_PHY=y CONFIG_PINCTRL=y CONFIG_PINCTRL_MESON_GXL=y CONFIG_POWER_DOMAIN=y -CONFIG_MESON_GX_VPU_POWER_DOMAIN=y +CONFIG_MESON_EE_POWER_DOMAIN=y CONFIG_DM_REGULATOR=y CONFIG_DM_REGULATOR_FIXED=y CONFIG_DM_RESET=y diff --git a/configs/libretech-cc_v2_defconfig b/configs/libretech-cc_v2_defconfig new file mode 100644 index 0000000000..e71f88edae --- /dev/null +++ b/configs/libretech-cc_v2_defconfig @@ -0,0 +1,82 @@ +CONFIG_ARM=y +CONFIG_ARCH_MESON=y +CONFIG_SYS_TEXT_BASE=0x01000000 +CONFIG_ENV_SIZE=0x2000 +CONFIG_ENV_OFFSET=0xFFFF0000 +CONFIG_ENV_SECT_SIZE=0x10000 +CONFIG_DM_GPIO=y +CONFIG_MESON_GXL=y +CONFIG_NR_DRAM_BANKS=1 +CONFIG_DEBUG_UART_BASE=0xc81004c0 +CONFIG_DEBUG_UART_CLOCK=24000000 +CONFIG_IDENT_STRING=" libretech-cc-v2" +CONFIG_DEBUG_UART=y +CONFIG_OF_BOARD_SETUP=y +CONFIG_USE_PREBOOT=y +CONFIG_PREBOOT="usb start" +CONFIG_MISC_INIT_R=y +# CONFIG_DISPLAY_CPUINFO is not set +# CONFIG_DISPLAY_BOARDINFO is not set +# CONFIG_CMD_BDI is not set +# CONFIG_CMD_IMI is not set +CONFIG_CMD_ADC=y +CONFIG_CMD_GPIO=y +# CONFIG_CMD_LOADS is not set +CONFIG_CMD_MMC=y +CONFIG_CMD_SPI=y +CONFIG_CMD_USB=y +CONFIG_CMD_USB_MASS_STORAGE=y +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_REGULATOR=y +CONFIG_OF_CONTROL=y +CONFIG_DEFAULT_DEVICE_TREE="meson-gxl-s905x-libretech-cc-v2" +CONFIG_ENV_IS_IN_SPI_FLASH=y +CONFIG_SYS_RELOC_GD_ENV_ADDR=y +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_SARADC_MESON=y +CONFIG_DM_KEYBOARD=y +CONFIG_DM_MMC=y +CONFIG_MMC_MESON_GX=y +CONFIG_MTD=y +CONFIG_DM_MTD=y +CONFIG_DM_SPI_FLASH=y +CONFIG_SPI_FLASH_GIGADEVICE=y +CONFIG_PHY_ADDR_ENABLE=y +CONFIG_PHY_ADDR=8 +CONFIG_PHY_MESON_GXL=y +CONFIG_DM_ETH=y +CONFIG_ETH_DESIGNWARE=y +CONFIG_PHY=y +CONFIG_MESON_GXL_USB_PHY=y +CONFIG_PINCTRL=y +CONFIG_PINCTRL_MESON_GXL=y +CONFIG_POWER_DOMAIN=y +CONFIG_MESON_GX_VPU_POWER_DOMAIN=y +CONFIG_DM_REGULATOR_FIXED=y +CONFIG_DM_RESET=y +CONFIG_DEBUG_UART_ANNOUNCE=y +CONFIG_DEBUG_UART_SKIP_INIT=y +CONFIG_MESON_SERIAL=y +CONFIG_SPI=y +CONFIG_DM_SPI=y +CONFIG_MESON_SPIFC=y +CONFIG_USB=y +CONFIG_DM_USB=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_DWC3=y +CONFIG_USB_XHCI_DWC3_OF_SIMPLE=y +CONFIG_USB_DWC3=y +# CONFIG_USB_DWC3_GADGET is not set +CONFIG_USB_KEYBOARD=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_VENDOR_NUM=0x1b8e +CONFIG_USB_GADGET_PRODUCT_NUM=0xfada +CONFIG_USB_GADGET_DWC2_OTG=y +CONFIG_USB_GADGET_DOWNLOAD=y +CONFIG_DM_VIDEO=y +# CONFIG_VIDEO_BPP8 is not set +# CONFIG_VIDEO_BPP16 is not set +CONFIG_SYS_WHITE_ON_BLACK=y +CONFIG_VIDEO_MESON=y +CONFIG_VIDEO_DT_SIMPLEFB=y +CONFIG_OF_LIBFDT_OVERLAY=y diff --git a/configs/libretech-s905d-pc_defconfig b/configs/libretech-s905d-pc_defconfig index f4e289aca1..9d4c880a3b 100644 --- a/configs/libretech-s905d-pc_defconfig +++ b/configs/libretech-s905d-pc_defconfig @@ -46,7 +46,7 @@ CONFIG_MESON_GXL_USB_PHY=y CONFIG_PINCTRL=y CONFIG_PINCTRL_MESON_GXL=y CONFIG_POWER_DOMAIN=y -CONFIG_MESON_GX_VPU_POWER_DOMAIN=y +CONFIG_MESON_EE_POWER_DOMAIN=y CONFIG_DM_REGULATOR=y CONFIG_DM_REGULATOR_FIXED=y CONFIG_DM_RESET=y diff --git a/configs/libretech-s912-pc_defconfig b/configs/libretech-s912-pc_defconfig index 24e410c5aa..cf600c1cbe 100644 --- a/configs/libretech-s912-pc_defconfig +++ b/configs/libretech-s912-pc_defconfig @@ -45,7 +45,7 @@ CONFIG_MESON_GXL_USB_PHY=y CONFIG_PINCTRL=y CONFIG_PINCTRL_MESON_GXL=y CONFIG_POWER_DOMAIN=y -CONFIG_MESON_GX_VPU_POWER_DOMAIN=y +CONFIG_MESON_EE_POWER_DOMAIN=y CONFIG_DM_REGULATOR=y CONFIG_DM_REGULATOR_FIXED=y CONFIG_DM_RESET=y diff --git a/configs/microchip_mpfs_icicle_defconfig b/configs/microchip_mpfs_icicle_defconfig index 2977966473..9abbc18a89 100644 --- a/configs/microchip_mpfs_icicle_defconfig +++ b/configs/microchip_mpfs_icicle_defconfig @@ -1,12 +1,15 @@ CONFIG_RISCV=y CONFIG_ENV_SIZE=0x2000 CONFIG_TARGET_MICROCHIP_ICICLE=y -CONFIG_NR_CPUS=5 CONFIG_ARCH_RV64I=y +CONFIG_RISCV_SMODE=y +CONFIG_SBI_V01=y +CONFIG_DEFAULT_DEVICE_TREE="microchip-mpfs-icicle-kit" +CONFIG_DISTRO_DEFAULTS=y +CONFIG_DISPLAY_CPUINFO=y +CONFIG_DISPLAY_BOARDINFO=y CONFIG_FIT=y -CONFIG_BOOTDELAY=3 CONFIG_SYS_PROMPT="RISC-V # " -CONFIG_OF_PRIOR_STAGE=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_BOOTP_SEND_HOSTNAME=y CONFIG_DM_MTD=y diff --git a/configs/nanopi-r2s-rk3328_defconfig b/configs/nanopi-r2s-rk3328_defconfig new file mode 100644 index 0000000000..2f67439f78 --- /dev/null +++ b/configs/nanopi-r2s-rk3328_defconfig @@ -0,0 +1,98 @@ +CONFIG_ARM=y +CONFIG_ARCH_ROCKCHIP=y +CONFIG_SYS_TEXT_BASE=0x00200000 +CONFIG_SPL_GPIO_SUPPORT=y +CONFIG_ENV_OFFSET=0x3F8000 +CONFIG_ROCKCHIP_RK3328=y +CONFIG_TPL_ROCKCHIP_COMMON_BOARD=y +CONFIG_TPL_LIBCOMMON_SUPPORT=y +CONFIG_TPL_LIBGENERIC_SUPPORT=y +CONFIG_SPL_DRIVERS_MISC_SUPPORT=y +CONFIG_SPL_STACK_R_ADDR=0x600000 +CONFIG_NR_DRAM_BANKS=1 +CONFIG_DEBUG_UART_BASE=0xFF130000 +CONFIG_DEBUG_UART_CLOCK=24000000 +CONFIG_SYSINFO=y +CONFIG_DEBUG_UART=y +CONFIG_TPL_SYS_MALLOC_F_LEN=0x800 +# CONFIG_ANDROID_BOOT_IMAGE is not set +CONFIG_FIT=y +CONFIG_FIT_VERBOSE=y +CONFIG_SPL_LOAD_FIT=y +CONFIG_DEFAULT_FDT_FILE="rockchip/rk3328-nanopi-r2s.dtb" +CONFIG_MISC_INIT_R=y +# CONFIG_DISPLAY_CPUINFO is not set +CONFIG_DISPLAY_BOARDINFO_LATE=y +# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set +CONFIG_TPL_SYS_MALLOC_SIMPLE=y +CONFIG_SPL_STACK_R=y +CONFIG_SPL_I2C_SUPPORT=y +CONFIG_SPL_POWER_SUPPORT=y +CONFIG_SPL_ATF=y +CONFIG_SPL_ATF_NO_PLATFORM_PARAM=y +CONFIG_CMD_BOOTZ=y +CONFIG_CMD_GPT=y +CONFIG_CMD_MMC=y +CONFIG_CMD_USB=y +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_TIME=y +CONFIG_SPL_OF_CONTROL=y +CONFIG_TPL_OF_CONTROL=y +CONFIG_DEFAULT_DEVICE_TREE="rk3328-nanopi-r2s" +CONFIG_OF_SPL_REMOVE_PROPS="clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents" +CONFIG_TPL_OF_PLATDATA=y +CONFIG_ENV_IS_IN_MMC=y +CONFIG_SYS_RELOC_GD_ENV_ADDR=y +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_TPL_DM=y +CONFIG_REGMAP=y +CONFIG_SPL_REGMAP=y +CONFIG_TPL_REGMAP=y +CONFIG_SYSCON=y +CONFIG_SPL_SYSCON=y +CONFIG_TPL_SYSCON=y +CONFIG_CLK=y +CONFIG_SPL_CLK=y +CONFIG_FASTBOOT_BUF_ADDR=0x800800 +CONFIG_FASTBOOT_CMD_OEM_FORMAT=y +CONFIG_ROCKCHIP_GPIO=y +CONFIG_SYS_I2C_ROCKCHIP=y +CONFIG_MMC_DW=y +CONFIG_MMC_DW_ROCKCHIP=y +CONFIG_SF_DEFAULT_SPEED=20000000 +CONFIG_DM_ETH=y +CONFIG_ETH_DESIGNWARE=y +CONFIG_GMAC_ROCKCHIP=y +CONFIG_PINCTRL=y +CONFIG_SPL_PINCTRL=y +CONFIG_DM_PMIC=y +CONFIG_PMIC_RK8XX=y +CONFIG_SPL_DM_REGULATOR=y +CONFIG_REGULATOR_PWM=y +CONFIG_DM_REGULATOR_FIXED=y +CONFIG_SPL_DM_REGULATOR_FIXED=y +CONFIG_REGULATOR_RK8XX=y +CONFIG_PWM_ROCKCHIP=y +CONFIG_RAM=y +CONFIG_SPL_RAM=y +CONFIG_TPL_RAM=y +CONFIG_DM_RESET=y +CONFIG_BAUDRATE=1500000 +CONFIG_DEBUG_UART_SHIFT=2 +CONFIG_SYSRESET=y +# CONFIG_TPL_SYSRESET is not set +CONFIG_USB=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_DWC3=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_GENERIC=y +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_GENERIC=y +CONFIG_USB_DWC2=y +CONFIG_USB_DWC3=y +# CONFIG_USB_DWC3_GADGET is not set +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_DWC2_OTG=y +CONFIG_SPL_TINY_MEMSET=y +CONFIG_TPL_TINY_MEMSET=y +CONFIG_ERRNO_STR=y diff --git a/configs/odroid-c2_defconfig b/configs/odroid-c2_defconfig index 14e840547f..5c02fa1e62 100644 --- a/configs/odroid-c2_defconfig +++ b/configs/odroid-c2_defconfig @@ -38,7 +38,7 @@ CONFIG_MESON_GXBB_USB_PHY=y CONFIG_PINCTRL=y CONFIG_PINCTRL_MESON_GXBB=y CONFIG_POWER_DOMAIN=y -CONFIG_MESON_GX_VPU_POWER_DOMAIN=y +CONFIG_MESON_EE_POWER_DOMAIN=y CONFIG_DM_REGULATOR=y CONFIG_DM_REGULATOR_FIXED=y CONFIG_DM_REGULATOR_GPIO=y diff --git a/configs/puma-rk3399_defconfig b/configs/puma-rk3399_defconfig index 60178e3754..0f15936c2d 100644 --- a/configs/puma-rk3399_defconfig +++ b/configs/puma-rk3399_defconfig @@ -44,6 +44,7 @@ CONFIG_ENV_OVERWRITE=y CONFIG_ENV_IS_IN_MMC=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_SYS_MMC_ENV_DEV=1 +CONFIG_SPL_DM_SEQ_ALIAS=y CONFIG_ROCKCHIP_GPIO=y CONFIG_SYS_I2C_ROCKCHIP=y CONFIG_MISC=y @@ -53,6 +54,7 @@ CONFIG_MMC_DW_ROCKCHIP=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_SDMA=y CONFIG_MMC_SDHCI_ROCKCHIP=y +CONFIG_SF_DEFAULT_BUS=1 CONFIG_SF_DEFAULT_SPEED=20000000 CONFIG_SPI_FLASH_GIGADEVICE=y CONFIG_SPI_FLASH_WINBOND=y diff --git a/configs/pumpkin_defconfig b/configs/pumpkin_defconfig index ab50124af2..cd77889eea 100644 --- a/configs/pumpkin_defconfig +++ b/configs/pumpkin_defconfig @@ -17,6 +17,7 @@ CONFIG_FIT=y # CONFIG_ARCH_FIXUP_FDT_MEMORY is not set CONFIG_DEFAULT_FDT_FILE="mt8516-pumpkin" # CONFIG_DISPLAY_BOARDINFO is not set +CONFIG_BOARD_LATE_INIT=y CONFIG_HUSH_PARSER=y # CONFIG_CMD_BDI is not set # CONFIG_CMD_CONSOLE is not set @@ -45,8 +46,13 @@ CONFIG_CMD_PART=y # CONFIG_CMD_SLEEP is not set CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y -# CONFIG_NET is not set CONFIG_CLK=y +CONFIG_USB_FUNCTION_FASTBOOT=y +CONFIG_FASTBOOT_BUF_ADDR=0x4d000000 +CONFIG_FASTBOOT_BUF_SIZE=0x4000000 +CONFIG_FASTBOOT_FLASH=y +CONFIG_FASTBOOT_FLASH_MMC_DEV=0 +CONFIG_FASTBOOT_MMC_BOOT1_SUPPORT=y # CONFIG_INPUT is not set CONFIG_DM_MMC=y # CONFIG_MMC_QUIRKS is not set @@ -59,6 +65,13 @@ CONFIG_BAUDRATE=921600 CONFIG_DM_SERIAL=y CONFIG_DEBUG_UART_ANNOUNCE=y CONFIG_MTK_SERIAL=y +CONFIG_USB=y +CONFIG_DM_USB=y +CONFIG_USB_MUSB_GADGET=y +CONFIG_USB_MUSB_MT85XX=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_VENDOR_NUM=0x0e8d +CONFIG_USB_GADGET_PRODUCT_NUM=0x201c CONFIG_WDT=y CONFIG_WDT_MTK=y # CONFIG_EFI_LOADER is not set diff --git a/configs/roc-pc-mezzanine-rk3399_defconfig b/configs/roc-pc-mezzanine-rk3399_defconfig index ae16f3558a..8aa5a15518 100644 --- a/configs/roc-pc-mezzanine-rk3399_defconfig +++ b/configs/roc-pc-mezzanine-rk3399_defconfig @@ -42,6 +42,7 @@ CONFIG_MMC_DW=y CONFIG_MMC_DW_ROCKCHIP=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_ROCKCHIP=y +CONFIG_SF_DEFAULT_BUS=1 CONFIG_SPI_FLASH_WINBOND=y CONFIG_DM_ETH=y CONFIG_ETH_DESIGNWARE=y diff --git a/configs/roc-pc-rk3399_defconfig b/configs/roc-pc-rk3399_defconfig index 774707b115..927b57685d 100644 --- a/configs/roc-pc-rk3399_defconfig +++ b/configs/roc-pc-rk3399_defconfig @@ -41,6 +41,7 @@ CONFIG_MMC_DW=y CONFIG_MMC_DW_ROCKCHIP=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_ROCKCHIP=y +CONFIG_SF_DEFAULT_BUS=1 CONFIG_SPI_FLASH_WINBOND=y CONFIG_DM_ETH=y CONFIG_ETH_DESIGNWARE=y diff --git a/configs/rock960-rk3399_defconfig b/configs/rock960-rk3399_defconfig index 65dce3cd73..aadbc55f57 100644 --- a/configs/rock960-rk3399_defconfig +++ b/configs/rock960-rk3399_defconfig @@ -39,6 +39,8 @@ CONFIG_MMC_DW_ROCKCHIP=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_SDMA=y CONFIG_MMC_SDHCI_ROCKCHIP=y +CONFIG_DM_RNG=y +CONFIG_RNG_ROCKCHIP=y CONFIG_DM_ETH=y CONFIG_NVME=y CONFIG_PCI=y diff --git a/configs/rockpro64-rk3399_defconfig b/configs/rockpro64-rk3399_defconfig index 575b7a20d5..f78dfcc8f7 100644 --- a/configs/rockpro64-rk3399_defconfig +++ b/configs/rockpro64-rk3399_defconfig @@ -42,6 +42,8 @@ CONFIG_MMC_DW=y CONFIG_MMC_DW_ROCKCHIP=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_ROCKCHIP=y +CONFIG_DM_RNG=y +CONFIG_RNG_ROCKCHIP=y CONFIG_SF_DEFAULT_BUS=1 CONFIG_SPI_FLASH_GIGADEVICE=y CONFIG_DM_ETH=y diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 58d4ef18c3..86dc603667 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -58,6 +58,7 @@ CONFIG_CMD_LSBLK=y CONFIG_CMD_MUX=y CONFIG_CMD_OSD=y CONFIG_CMD_PCI=y +CONFIG_CMD_PWM=y CONFIG_CMD_READ=y CONFIG_CMD_REMOTEPROC=y CONFIG_CMD_SPI=y diff --git a/configs/sipeed_maix_bitm_defconfig b/configs/sipeed_maix_bitm_defconfig index 459bf0d530..210848cccf 100644 --- a/configs/sipeed_maix_bitm_defconfig +++ b/configs/sipeed_maix_bitm_defconfig @@ -1,8 +1,19 @@ CONFIG_RISCV=y +CONFIG_ENV_SIZE=0x1000 +CONFIG_ENV_OFFSET=0xfff000 +CONFIG_ENV_SECT_SIZE=0x1000 CONFIG_TARGET_SIPEED_MAIX=y CONFIG_ARCH_RV64I=y CONFIG_STACK_SIZE=0x100000 +CONFIG_USE_BOOTCOMMAND=y +CONFIG_BOOTCOMMAND="run k210_bootcmd" +CONFIG_HUSH_PARSER=y +CONFIG_MTDIDS_DEFAULT="nor0=spi3:0" +CONFIG_MTDPARTS_DEFAULT="nor0:1M(u-boot),0x1000@0xfff000(env)" # CONFIG_NET is not set # CONFIG_INPUT is not set +CONFIG_SF_DEFAULT_BUS=3 # CONFIG_DM_ETH is not set +CONFIG_FS_EXT4=y +CONFIG_FS_FAT=y # CONFIG_EFI_LOADER is not set diff --git a/configs/socfpga_agilex_atf_defconfig b/configs/socfpga_agilex_atf_defconfig new file mode 100644 index 0000000000..ad87a8098f --- /dev/null +++ b/configs/socfpga_agilex_atf_defconfig @@ -0,0 +1,72 @@ +CONFIG_ARM=y +CONFIG_ARM_SMCCC=y +CONFIG_SPL_LDSCRIPT="arch/arm/mach-socfpga/u-boot-spl-soc64.lds" +CONFIG_ARCH_SOCFPGA=y +CONFIG_SYS_TEXT_BASE=0x200000 +CONFIG_SYS_MALLOC_F_LEN=0x2000 +CONFIG_ENV_SIZE=0x1000 +CONFIG_ENV_OFFSET=0x200 +CONFIG_DM_GPIO=y +CONFIG_NR_DRAM_BANKS=2 +CONFIG_TARGET_SOCFPGA_AGILEX_SOCDK=y +CONFIG_IDENT_STRING="socfpga_agilex" +CONFIG_SPL_FS_FAT=y +CONFIG_SPL_TEXT_BASE=0xFFE00000 +CONFIG_FIT=y +CONFIG_SPL_LOAD_FIT=y +CONFIG_SPL_LOAD_FIT_ADDRESS=0x02000000 +# CONFIG_USE_SPL_FIT_GENERATOR is not set +CONFIG_BOOTDELAY=5 +CONFIG_USE_BOOTARGS=y +CONFIG_BOOTARGS="earlycon" +CONFIG_SPL_CACHE=y +CONFIG_SPL_SPI_LOAD=y +CONFIG_SYS_SPI_U_BOOT_OFFS=0x02000000 +CONFIG_SPL_ATF=y +CONFIG_SPL_ATF_NO_PLATFORM_PARAM=y +CONFIG_HUSH_PARSER=y +CONFIG_SYS_PROMPT="SOCFPGA_AGILEX # " +CONFIG_CMD_MEMTEST=y +CONFIG_CMD_GPIO=y +CONFIG_CMD_I2C=y +CONFIG_CMD_MMC=y +CONFIG_CMD_SPI=y +CONFIG_CMD_USB=y +CONFIG_CMD_DHCP=y +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y +CONFIG_CMD_CACHE=y +CONFIG_CMD_EXT4=y +CONFIG_CMD_FAT=y +CONFIG_CMD_FS_GENERIC=y +CONFIG_DEFAULT_DEVICE_TREE="socfpga_agilex_socdk" +CONFIG_ENV_IS_IN_MMC=y +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_SPL_DM_SEQ_ALIAS=y +CONFIG_SPL_ALTERA_SDRAM=y +CONFIG_DWAPB_GPIO=y +CONFIG_DM_I2C=y +CONFIG_SYS_I2C_DW=y +CONFIG_DM_MMC=y +CONFIG_MMC_DW=y +CONFIG_MTD=y +CONFIG_SF_DEFAULT_MODE=0x2003 +CONFIG_SPI_FLASH_SPANSION=y +CONFIG_SPI_FLASH_STMICRO=y +CONFIG_PHY_MICREL=y +CONFIG_PHY_MICREL_KSZ90X1=y +CONFIG_DM_ETH=y +CONFIG_ETH_DESIGNWARE=y +CONFIG_MII=y +CONFIG_DM_RESET=y +CONFIG_SPI=y +CONFIG_CADENCE_QSPI=y +CONFIG_DESIGNWARE_SPI=y +CONFIG_USB=y +CONFIG_DM_USB=y +CONFIG_USB_DWC2=y +CONFIG_USB_STORAGE=y +CONFIG_DESIGNWARE_WATCHDOG=y +CONFIG_WDT=y +# CONFIG_SPL_USE_TINY_PRINTF is not set +CONFIG_PANIC_HANG=y diff --git a/configs/socfpga_stratix10_atf_defconfig b/configs/socfpga_stratix10_atf_defconfig new file mode 100644 index 0000000000..1005ba979e --- /dev/null +++ b/configs/socfpga_stratix10_atf_defconfig @@ -0,0 +1,74 @@ +CONFIG_ARM=y +CONFIG_ARM_SMCCC=y +CONFIG_SPL_LDSCRIPT="arch/arm/mach-socfpga/u-boot-spl-soc64.lds" +CONFIG_ARCH_SOCFPGA=y +CONFIG_SYS_TEXT_BASE=0x200000 +CONFIG_SYS_MALLOC_F_LEN=0x2000 +CONFIG_ENV_SIZE=0x1000 +CONFIG_ENV_OFFSET=0x200 +CONFIG_DM_GPIO=y +CONFIG_NR_DRAM_BANKS=2 +CONFIG_TARGET_SOCFPGA_STRATIX10_SOCDK=y +CONFIG_IDENT_STRING="socfpga_stratix10" +CONFIG_SPL_FS_FAT=y +CONFIG_SPL_TEXT_BASE=0xFFE00000 +CONFIG_FIT=y +CONFIG_SPL_LOAD_FIT=y +CONFIG_SPL_LOAD_FIT_ADDRESS=0x02000000 +# CONFIG_USE_SPL_FIT_GENERATOR is not set +CONFIG_BOOTDELAY=5 +CONFIG_USE_BOOTARGS=y +CONFIG_BOOTARGS="earlycon" +CONFIG_SPL_SPI_LOAD=y +CONFIG_SYS_SPI_U_BOOT_OFFS=0x02000000 +CONFIG_SPL_ATF=y +CONFIG_SPL_ATF_NO_PLATFORM_PARAM=y +CONFIG_HUSH_PARSER=y +CONFIG_SYS_PROMPT="SOCFPGA_STRATIX10 # " +CONFIG_CMD_MEMTEST=y +# CONFIG_CMD_FLASH is not set +CONFIG_CMD_GPIO=y +CONFIG_CMD_I2C=y +CONFIG_CMD_MMC=y +CONFIG_CMD_SPI=y +CONFIG_CMD_USB=y +CONFIG_CMD_DHCP=y +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y +CONFIG_CMD_CACHE=y +CONFIG_CMD_EXT4=y +CONFIG_CMD_FAT=y +CONFIG_CMD_FS_GENERIC=y +CONFIG_DEFAULT_DEVICE_TREE="socfpga_stratix10_socdk" +CONFIG_ENV_IS_IN_MMC=y +CONFIG_SYS_RELOC_GD_ENV_ADDR=y +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_SPL_DM_SEQ_ALIAS=y +CONFIG_SPL_ALTERA_SDRAM=y +CONFIG_FPGA_INTEL_PR=y +CONFIG_DWAPB_GPIO=y +CONFIG_DM_I2C=y +CONFIG_SYS_I2C_DW=y +CONFIG_DM_MMC=y +CONFIG_MMC_DW=y +CONFIG_MTD=y +CONFIG_SF_DEFAULT_MODE=0x2003 +CONFIG_SPI_FLASH_SPANSION=y +CONFIG_SPI_FLASH_STMICRO=y +CONFIG_PHY_MICREL=y +CONFIG_PHY_MICREL_KSZ90X1=y +CONFIG_DM_ETH=y +CONFIG_ETH_DESIGNWARE=y +CONFIG_MII=y +CONFIG_DM_RESET=y +CONFIG_SPI=y +CONFIG_CADENCE_QSPI=y +CONFIG_DESIGNWARE_SPI=y +CONFIG_USB=y +CONFIG_DM_USB=y +CONFIG_USB_DWC2=y +CONFIG_USB_STORAGE=y +CONFIG_DESIGNWARE_WATCHDOG=y +CONFIG_WDT=y +# CONFIG_SPL_USE_TINY_PRINTF is not set +CONFIG_PANIC_HANG=y diff --git a/configs/stm32mp15_basic_defconfig b/configs/stm32mp15_basic_defconfig index 1843bbcc78..d3e5775a5a 100644 --- a/configs/stm32mp15_basic_defconfig +++ b/configs/stm32mp15_basic_defconfig @@ -21,6 +21,7 @@ CONFIG_DEFAULT_DEVICE_TREE="stm32mp157c-ev1" CONFIG_DISTRO_DEFAULTS=y CONFIG_FIT=y CONFIG_BOOTCOMMAND="run bootcmd_stm32mp" +CONFIG_SPL_LOG=y CONFIG_BOARD_EARLY_INIT_F=y CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION=y CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION=3 @@ -54,8 +55,10 @@ CONFIG_CMD_PMIC=y CONFIG_CMD_REGULATOR=y CONFIG_CMD_EXT4_WRITE=y CONFIG_CMD_MTDPARTS=y +CONFIG_CMD_LOG=y CONFIG_CMD_UBI=y # CONFIG_SPL_DOS_PARTITION is not set +CONFIG_OF_LIVE=y CONFIG_OF_SPL_REMOVE_PROPS="interrupts interrupt-names interrupts-extended interrupt-controller \\\#interrupt-cells interrupt-parent dmas dma-names assigned-clocks assigned-clock-rates assigned-clock-parents hwlocks" CONFIG_ENV_IS_NOWHERE=y CONFIG_ENV_IS_IN_MMC=y diff --git a/configs/stm32mp15_trusted_defconfig b/configs/stm32mp15_trusted_defconfig index 964f4c2885..d392b0ff2a 100644 --- a/configs/stm32mp15_trusted_defconfig +++ b/configs/stm32mp15_trusted_defconfig @@ -38,7 +38,9 @@ CONFIG_CMD_PMIC=y CONFIG_CMD_REGULATOR=y CONFIG_CMD_EXT4_WRITE=y CONFIG_CMD_MTDPARTS=y +CONFIG_CMD_LOG=y CONFIG_CMD_UBI=y +CONFIG_OF_LIVE=y CONFIG_ENV_IS_NOWHERE=y CONFIG_ENV_IS_IN_MMC=y CONFIG_ENV_IS_IN_SPI_FLASH=y diff --git a/configs/wetek-core2_defconfig b/configs/wetek-core2_defconfig new file mode 100644 index 0000000000..706abff962 --- /dev/null +++ b/configs/wetek-core2_defconfig @@ -0,0 +1,70 @@ +CONFIG_ARM=y +CONFIG_ARCH_MESON=y +CONFIG_SYS_TEXT_BASE=0x01000000 +CONFIG_NR_DRAM_BANKS=1 +CONFIG_ENV_SIZE=0x2000 +CONFIG_DM_GPIO=y +CONFIG_MESON_GXM=y +CONFIG_DEBUG_UART_BASE=0xc81004c0 +CONFIG_DEBUG_UART_CLOCK=24000000 +CONFIG_IDENT_STRING=" wetek-core2" +CONFIG_DEFAULT_DEVICE_TREE="meson-gxm-wetek-core2" +CONFIG_DEBUG_UART=y +CONFIG_OF_BOARD_SETUP=y +CONFIG_CONSOLE_MUX=y +# CONFIG_DISPLAY_CPUINFO is not set +CONFIG_MISC_INIT_R=y +# CONFIG_CMD_BDI is not set +# CONFIG_CMD_IMI is not set +CONFIG_CMD_ADC=y +CONFIG_CMD_GPIO=y +# CONFIG_CMD_LOADS is not set +CONFIG_CMD_MMC=y +CONFIG_CMD_SF_TEST=y +CONFIG_CMD_USB=y +CONFIG_CMD_USB_MASS_STORAGE=y +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_REGULATOR=y +CONFIG_OF_CONTROL=y +CONFIG_SYS_RELOC_GD_ENV_ADDR=y +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_SARADC_MESON=y +CONFIG_DM_MMC=y +CONFIG_MMC_MESON_GX=y +CONFIG_MTD=y +CONFIG_DM_MTD=y +CONFIG_PHY_REALTEK=y +CONFIG_DM_ETH=y +CONFIG_ETH_DESIGNWARE=y +CONFIG_MESON_GXL_USB_PHY=y +CONFIG_PINCTRL=y +CONFIG_PINCTRL_MESON_GXL=y +CONFIG_DM_REGULATOR=y +CONFIG_POWER_DOMAIN=y +CONFIG_MESON_GX_VPU_POWER_DOMAIN=y +CONFIG_DM_REGULATOR_FIXED=y +CONFIG_DM_RESET=y +CONFIG_DEBUG_UART_ANNOUNCE=y +CONFIG_DEBUG_UART_MESON=y +CONFIG_DEBUG_UART_SKIP_INIT=y +CONFIG_MESON_SERIAL=y +CONFIG_USB=y +CONFIG_DM_USB=y +CONFIG_USB_KEYBOARD=y +CONFIG_DM_VIDEO=y +# CONFIG_VIDEO_BPP8 is not set +# CONFIG_VIDEO_BPP16 is not set +CONFIG_SYS_WHITE_ON_BLACK=y +CONFIG_VIDEO_MESON=y +CONFIG_VIDEO_DT_SIMPLEFB=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_DWC3=y +CONFIG_USB_DWC3=y +# CONFIG_USB_DWC3_GADGET is not set +CONFIG_USB_DWC3_MESON_GXL=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_VENDOR_NUM=0x1b8e +CONFIG_USB_GADGET_PRODUCT_NUM=0xfada +CONFIG_USB_GADGET_DWC2_OTG=y +CONFIG_USB_GADGET_DOWNLOAD=y +CONFIG_OF_LIBFDT_OVERLAY=y diff --git a/configs/xilinx_zynqmp_virt_defconfig b/configs/xilinx_zynqmp_virt_defconfig index e400cd4702..0bf4b7d692 100644 --- a/configs/xilinx_zynqmp_virt_defconfig +++ b/configs/xilinx_zynqmp_virt_defconfig @@ -54,6 +54,7 @@ CONFIG_CMD_SPI=y CONFIG_CMD_USB=y CONFIG_CMD_USB_MASS_STORAGE=y CONFIG_CMD_TFTPPUT=y +CONFIG_CMD_BMP=y CONFIG_CMD_CACHE=y CONFIG_CMD_TIME=y CONFIG_CMD_TIMER=y @@ -155,6 +156,15 @@ CONFIG_USB_ETHER=y CONFIG_USB_ETH_CDC=y CONFIG_USB_HOST_ETHER=y CONFIG_USB_ETHER_ASIX=y +CONFIG_DM_VIDEO=y +CONFIG_VIDEO_COPY=y +CONFIG_DISPLAY=y +CONFIG_VIDEO_SEPS525=y +CONFIG_LCD=y +CONFIG_SPLASH_SCREEN=y +CONFIG_BMP_16BPP=y +CONFIG_BMP_24BPP=y +CONFIG_BMP_32BPP=y CONFIG_WDT=y CONFIG_WDT_CDNS=y CONFIG_PANIC_HANG=y diff --git a/disk/part_dos.c b/disk/part_dos.c index 04f53106f7..f431925745 100644 --- a/disk/part_dos.c +++ b/disk/part_dos.c @@ -18,6 +18,8 @@ #include <command.h> #include <ide.h> #include <memalign.h> +#include <asm/unaligned.h> +#include <linux/compiler.h> #include "part_dos.h" #include <part.h> @@ -29,22 +31,11 @@ * to use large numbers of partitions */ #define MAX_EXT_PARTS 256 -/* Convert char[4] in little endian format to the host format integer - */ -static inline unsigned int le32_to_int(unsigned char *le32) -{ - return ((le32[3] << 24) + - (le32[2] << 16) + - (le32[1] << 8) + - le32[0] - ); -} - static inline int is_extended(int part_type) { - return (part_type == 0x5 || - part_type == 0xf || - part_type == 0x85); + return (part_type == DOS_PART_TYPE_EXTENDED || + part_type == DOS_PART_TYPE_EXTENDED_LBA || + part_type == DOS_PART_TYPE_EXTENDED_LINUX); } static int get_bootable(dos_partition_t *p) @@ -61,8 +52,8 @@ static int get_bootable(dos_partition_t *p) static void print_one_part(dos_partition_t *p, lbaint_t ext_part_sector, int part_num, unsigned int disksig) { - lbaint_t lba_start = ext_part_sector + le32_to_int (p->start4); - lbaint_t lba_size = le32_to_int (p->size4); + lbaint_t lba_start = ext_part_sector + get_unaligned_le32(p->start4); + lbaint_t lba_size = get_unaligned_le32(p->size4); printf("%3d\t%-10" LBAFlength "u\t%-10" LBAFlength "u\t%08x-%02x\t%02x%s%s\n", @@ -171,7 +162,7 @@ static void print_partition_extended(struct blk_desc *dev_desc, } if (!ext_part_sector) - disksig = le32_to_int(&buffer[DOS_PART_DISKSIG_OFFSET]); + disksig = get_unaligned_le32(&buffer[DOS_PART_DISKSIG_OFFSET]); /* Print all primary/logical partitions */ pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET); @@ -198,7 +189,7 @@ static void print_partition_extended(struct blk_desc *dev_desc, for (i = 0; i < 4; i++, pt++) { if (is_extended (pt->sys_ind)) { lbaint_t lba_start - = le32_to_int (pt->start4) + relative; + = get_unaligned_le32 (pt->start4) + relative; print_partition_extended(dev_desc, lba_start, ext_part_sector == 0 ? lba_start : relative, @@ -244,7 +235,7 @@ static int part_get_info_extended(struct blk_desc *dev_desc, #if CONFIG_IS_ENABLED(PARTITION_UUIDS) if (!ext_part_sector) - disksig = le32_to_int(&buffer[DOS_PART_DISKSIG_OFFSET]); + disksig = get_unaligned_le32(&buffer[DOS_PART_DISKSIG_OFFSET]); #endif /* Print all primary/logical partitions */ @@ -260,8 +251,8 @@ static int part_get_info_extended(struct blk_desc *dev_desc, (ext_part_sector == 0 || is_extended(pt->sys_ind) == 0)) { info->blksz = DOS_PART_DEFAULT_SECTOR; info->start = (lbaint_t)(ext_part_sector + - le32_to_int(pt->start4)); - info->size = (lbaint_t)le32_to_int(pt->size4); + get_unaligned_le32(pt->start4)); + info->size = (lbaint_t)get_unaligned_le32(pt->size4); part_set_generic_name(dev_desc, part_num, (char *)info->name); /* sprintf(info->type, "%d, pt->sys_ind); */ @@ -286,7 +277,7 @@ static int part_get_info_extended(struct blk_desc *dev_desc, for (i = 0; i < 4; i++, pt++) { if (is_extended (pt->sys_ind)) { lbaint_t lba_start - = le32_to_int (pt->start4) + relative; + = get_unaligned_le32 (pt->start4) + relative; return part_get_info_extended(dev_desc, lba_start, ext_part_sector == 0 ? lba_start : relative, @@ -312,13 +303,13 @@ static int part_get_info_extended(struct blk_desc *dev_desc, return -1; } -void part_print_dos(struct blk_desc *dev_desc) +static void __maybe_unused part_print_dos(struct blk_desc *dev_desc) { printf("Part\tStart Sector\tNum Sectors\tUUID\t\tType\n"); print_partition_extended(dev_desc, 0, 0, 1, 0); } -int part_get_info_dos(struct blk_desc *dev_desc, int part, +static int __maybe_unused part_get_info_dos(struct blk_desc *dev_desc, int part, struct disk_partition *info) { return part_get_info_extended(dev_desc, 0, 0, 1, part, info, 0); @@ -329,7 +320,174 @@ int is_valid_dos_buf(void *buf) return test_block_type(buf) == DOS_MBR ? 0 : -1; } -int write_mbr_partition(struct blk_desc *dev_desc, void *buf) +#if CONFIG_IS_ENABLED(CMD_MBR) +static void lba_to_chs(lbaint_t lba, unsigned char *rc, unsigned char *rh, + unsigned char *rs) +{ + unsigned int c, h, s; + /* use fixed CHS geometry */ + unsigned int sectpertrack = 63; + unsigned int heads = 255; + + c = (lba + 1) / sectpertrack / heads; + h = (lba + 1) / sectpertrack - c * heads; + s = (lba + 1) - (c * heads + h) * sectpertrack; + + if (c > 1023) { + c = 1023; + h = 254; + s = 63; + } + + *rc = c & 0xff; + *rh = h; + *rs = s + ((c & 0x300) >> 2); +} + +static void mbr_fill_pt_entry(dos_partition_t *pt, lbaint_t start, + lbaint_t relative, lbaint_t size, uchar sys_ind, bool bootable) +{ + pt->boot_ind = bootable ? 0x80 : 0x00; + pt->sys_ind = sys_ind; + lba_to_chs(start, &pt->cyl, &pt->head, &pt->sector); + lba_to_chs(start + size - 1, &pt->end_cyl, &pt->end_head, &pt->end_sector); + put_unaligned_le32(relative, &pt->start4); + put_unaligned_le32(size, &pt->size4); +} + +int write_mbr_partitions(struct blk_desc *dev, + struct disk_partition *p, int count, unsigned int disksig) +{ + ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev->blksz); + lbaint_t ext_part_start = 0, ext_part_size = 0, ext_part_sect = 0; + dos_partition_t *pt; + int i; + + memset(buffer, 0, dev->blksz); + buffer[DOS_PART_MAGIC_OFFSET] = 0x55; + buffer[DOS_PART_MAGIC_OFFSET + 1] = 0xaa; + put_unaligned_le32(disksig, &buffer[DOS_PART_DISKSIG_OFFSET]); + pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET); + + /* create all primary partitions */ + for (i = 0; i < 4 && i < count; i++, pt++) { + mbr_fill_pt_entry(pt, p[i].start, p[i].start, p[i].size, + p[i].sys_ind, p[i].bootable); + if (is_extended(p[i].sys_ind)) { + ext_part_start = p[i].start; + ext_part_size = p[i].size; + ext_part_sect = p[i].start; + } + } + + if (i < count && !ext_part_start) { + printf("%s: extended partition is needed for more than 4 partitions\n", + __func__); + return -1; + } + + /* write MBR */ + if (blk_dwrite(dev, 0, 1, buffer) != 1) { + printf("%s: failed writing 'MBR' (1 blks at 0x0)\n", + __func__); + return -1; + } + + /* create extended volumes */ + for (; i < count; i++) { + lbaint_t next_ebr = 0; + + memset(buffer, 0, dev->blksz); + buffer[DOS_PART_MAGIC_OFFSET] = 0x55; + buffer[DOS_PART_MAGIC_OFFSET + 1] = 0xaa; + pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET); + + mbr_fill_pt_entry(pt, p[i].start, p[i].start - ext_part_sect, + p[i].size, p[i].sys_ind, p[i].bootable); + + if (i + 1 < count) { + pt++; + next_ebr = p[i].start + p[i].size; + mbr_fill_pt_entry(pt, next_ebr, + next_ebr - ext_part_start, + p[i+1].start + p[i+1].size - next_ebr, + DOS_PART_TYPE_EXTENDED, 0); + } + + /* write EBR */ + if (blk_dwrite(dev, ext_part_sect, 1, buffer) != 1) { + printf("%s: failed writing 'EBR' (1 blks at 0x%lx)\n", + __func__, ext_part_sect); + return -1; + } + ext_part_sect = next_ebr; + } + + return 0; +} + +int layout_mbr_partitions(struct disk_partition *p, int count, + lbaint_t total_sectors) +{ + struct disk_partition *ext = NULL; + int i, j; + lbaint_t ext_vol_start; + + /* calculate primary partitions start and size if needed */ + if (!p[0].start) + p[0].start = DOS_PART_DEFAULT_GAP; + for (i = 0; i < 4 && i < count; i++) { + if (!p[i].start) + p[i].start = p[i - 1].start + p[i - 1].size; + if (!p[i].size) { + lbaint_t end = total_sectors; + lbaint_t allocated = 0; + + for (j = i + 1; j < 4 && j < count; j++) { + if (p[j].start) { + end = p[j].start; + break; + } + allocated += p[j].size; + } + p[i].size = end - allocated - p[i].start; + } + if (p[i].sys_ind == 0x05) + ext = &p[i]; + } + + if (i >= 4 && !ext) { + printf("%s: extended partition is needed for more than 4 partitions\n", + __func__); + return -1; + } + + /* calculate extended volumes start and size if needed */ + ext_vol_start = ext->start; + for (i = 4; i < count; i++) { + if (!p[i].start) + p[i].start = ext_vol_start + DOS_PART_DEFAULT_GAP; + if (!p[i].size) { + lbaint_t end = ext->start + ext->size; + lbaint_t allocated = 0; + + for (j = i + 1; j < count; j++) { + if (p[j].start) { + end = p[j].start - DOS_PART_DEFAULT_GAP; + break; + } + allocated += p[j].size + DOS_PART_DEFAULT_GAP; + } + p[i].size = end - allocated - p[i].start; + } + ext_vol_start = p[i].start + p[i].size; + } + + return 0; +} +#endif + +int write_mbr_sector(struct blk_desc *dev_desc, void *buf) { if (is_valid_dos_buf(buf)) return -1; diff --git a/disk/part_dos.h b/disk/part_dos.h index 434b021ae8..5055822422 100644 --- a/disk/part_dos.h +++ b/disk/part_dos.h @@ -15,6 +15,11 @@ #define DOS_PBR_MEDIA_TYPE_OFFSET 0x15 #define DOS_MBR 0 #define DOS_PBR 1 +#define DOS_PART_TYPE_EXTENDED 0x05 +#define DOS_PART_TYPE_EXTENDED_LBA 0x0F +#define DOS_PART_TYPE_EXTENDED_LINUX 0x85 + +#define DOS_PART_DEFAULT_GAP 2048 typedef struct dos_partition { unsigned char boot_ind; /* 0x80 - active */ diff --git a/disk/part_efi.c b/disk/part_efi.c index 60b1c1d761..2f922662e6 100644 --- a/disk/part_efi.c +++ b/disk/part_efi.c @@ -247,10 +247,11 @@ void part_print_efi(struct blk_desc *dev_desc) uuid_bin = (unsigned char *)gpt_pte[i].partition_type_guid.b; uuid_bin_to_str(uuid_bin, uuid, UUID_STR_FORMAT_GUID); printf("\ttype:\t%s\n", uuid); -#ifdef CONFIG_PARTITION_TYPE_GUID - if (!uuid_guid_get_str(uuid_bin, uuid)) - printf("\ttype:\t%s\n", uuid); -#endif + if (CONFIG_IS_ENABLED(PARTITION_TYPE_GUID)) { + const char *type = uuid_guid_get_str(uuid_bin); + if (type) + printf("\ttype:\t%s\n", type); + } uuid_bin = (unsigned char *)gpt_pte[i].unique_partition_guid.b; uuid_bin_to_str(uuid_bin, uuid, UUID_STR_FORMAT_GUID); printf("\tguid:\t%s\n", uuid); diff --git a/doc/README.fdt-overlays b/doc/README.fdt-overlays deleted file mode 100644 index 39139cb850..0000000000 --- a/doc/README.fdt-overlays +++ /dev/null @@ -1,114 +0,0 @@ -U-Boot FDT Overlay usage -============================================= - -Overlays Syntax ---------------- - -Overlays require slightly different syntax compared to traditional overlays. -Please refer to dt-object-internal.txt in the dtc sources for information -regarding the internal format of overlays: -https://git.kernel.org/pub/scm/utils/dtc/dtc.git/tree/Documentation/dt-object-internal.txt - -Building Overlays ------------------ - -In a nutshell overlays provides a means to manipulate a symbol a previous dtb -or overlay has defined. It requires both the base and all the overlays -to be compiled with the -@ command line switch so that symbol information is -included. - -Note support for -@ option can only be found in dtc version 1.4.4 or newer. -Only version 4.14 or higher of the Linux kernel includes a built in version -of dtc that meets this requirement. - -Building an overlay follows the same process as building a traditional dtb. - -For example: - -base.dts --------- - - /dts-v1/; - / { - foo: foonode { - foo-property; - }; - }; - - $ dtc -@ -I dts -O dtb -o base.dtb base.dts - -bar.dts -------- - - /dts-v1/; - /plugin/; - / { - fragment@1 { - target = <&foo>; - __overlay__ { - overlay-1-property; - bar: barnode { - bar-property; - }; - }; - }; - }; - - $ dtc -@ -I dts -O dtb -o bar.dtb bar.dts - -Ways to Utilize Overlays in U-boot ----------------------------------- - -There are two ways to apply overlays in U-boot. -1. Include and define overlays within a FIT image and have overlays - automatically applied. - -2. Manually load and apply overlays - -The remainder of this document will discuss using overlays via the manual -approach. For information on using overlays as part of a FIT image please see: -doc/uImage.FIT/overlay-fdt-boot.txt - -Manually Loading and Applying Overlays --------------------------------------- - -1. Figure out where to place both the base device tree blob and the -overlay. Make sure you have enough space to grow the base tree without -overlapping anything. - -=> setenv fdtaddr 0x87f00000 -=> setenv fdtovaddr 0x87fc0000 - -2. Load the base blob and overlay blobs - -=> load ${devtype} ${bootpart} ${fdtaddr} ${bootdir}/base.dtb -=> load ${devtype} ${bootpart} ${fdtovaddr} ${bootdir}/overlay.dtb - -3. Set it as the working fdt tree. - -=> fdtaddr $fdtaddr - -4. Grow it enough so it can 'fit' all the applied overlays - -=> fdt resize 8192 - -5. You are now ready to apply the overlay. - -=> fdt apply $fdtovaddr - -6. Boot system like you would do with a traditional dtb. - -For bootm: - -=> bootm ${kerneladdr} - ${fdtaddr} - -For bootz: - -=> bootz ${kerneladdr} - ${fdtaddr} - -Please note that in case of an error, both the base and overlays are going -to be invalidated, so keep copies to avoid reloading. - -Pantelis Antoniou -pantelis.antoniou@konsulko.com -11/7/2017 diff --git a/doc/README.gpt b/doc/README.gpt index facd7afc3a..ac975f66b8 100644 --- a/doc/README.gpt +++ b/doc/README.gpt @@ -251,22 +251,24 @@ can specify a other partition type guid: type=0FC63DAF-8483-4772-8E79-3D69D8477DE4;" Some strings can be also used at the place of known GUID : - "system" = PARTITION_SYSTEM_GUID - (C12A7328-F81F-11D2-BA4B-00A0C93EC93B) - "mbr" = LEGACY_MBR_PARTITION_GUID - (024DEE41-33E7-11D3-9D69-0008C781F39F) - "msft" = PARTITION_MSFT_RESERVED_GUID - (E3C9E316-0B5C-4DB8-817D-F92DF00215AE) - "data" = PARTITION_BASIC_DATA_GUID - (EBD0A0A2-B9E5-4433-87C0-68B6B72699C7) - "linux" = PARTITION_LINUX_FILE_SYSTEM_DATA_GUID - (0FC63DAF-8483-4772-8E79-3D69D8477DE4) - "raid" = PARTITION_LINUX_RAID_GUID - (A19D880F-05FC-4D3B-A006-743F0F84911E) - "swap" = PARTITION_LINUX_SWAP_GUID - (0657FD6D-A4AB-43C4-84E5-0933C84B4F4F) - "lvm" = PARTITION_LINUX_LVM_GUID - (E6D6D379-F507-44C2-A23C-238F2A3DF928) + "system" = PARTITION_SYSTEM_GUID + (C12A7328-F81F-11D2-BA4B-00A0C93EC93B) + "mbr" = LEGACY_MBR_PARTITION_GUID + (024DEE41-33E7-11D3-9D69-0008C781F39F) + "msft" = PARTITION_MSFT_RESERVED_GUID + (E3C9E316-0B5C-4DB8-817D-F92DF00215AE) + "data" = PARTITION_BASIC_DATA_GUID + (EBD0A0A2-B9E5-4433-87C0-68B6B72699C7) + "linux" = PARTITION_LINUX_FILE_SYSTEM_DATA_GUID + (0FC63DAF-8483-4772-8E79-3D69D8477DE4) + "raid" = PARTITION_LINUX_RAID_GUID + (A19D880F-05FC-4D3B-A006-743F0F84911E) + "swap" = PARTITION_LINUX_SWAP_GUID + (0657FD6D-A4AB-43C4-84E5-0933C84B4F4F) + "lvm" = PARTITION_LINUX_LVM_GUID + (E6D6D379-F507-44C2-A23C-238F2A3DF928) + "u-boot-env" = PARTITION_U_BOOT_ENVIRONMENT + (3DE21764-95BD-54BD-A5C3-4ABE786F38A8) "uuid_disk=...;name=u-boot,size=60MiB,uuid=...; name=kernel,size=60MiB,uuid=...,type=linux;" diff --git a/doc/board/amlogic/beelink-gtking.rst b/doc/board/amlogic/beelink-gtking.rst new file mode 100644 index 0000000000..56ce2cb273 --- /dev/null +++ b/doc/board/amlogic/beelink-gtking.rst @@ -0,0 +1,115 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +U-Boot for Beelink GT-King +========================== + +The Shenzen AZW (Beelink) GT-King is based on the Amlogic W400 reference +board with an S922X-H chip. + +- 4GB LPDDR4 RAM +- 64GB eMMC storage +- 10/100/1000 Base-T Ethernet +- AP6356S Wireless (802.11 a/b/g/n/ac, BT 4.1) +- HDMI 2.1 video +- S/PDIF optical output +- Analogue audio output +- 1x USB 2.0 port +- 2x USB 3.0 ports +- IR receiver +- 1x micro SD card slot + +Beelink do not provide public schematics, but have been willing +to share them with known distro developers on request. + +U-Boot compilation +------------------ + +.. code-block:: bash + + $ export CROSS_COMPILE=aarch64-none-elf- + $ make beelink-gtking_defconfig + $ make + +Image creation +-------------- + +Amlogic does not provide sources for the firmware and for tools needed +to create the bootloader image. Beelink have provided the Amlogic "SDK" +in their forums, but the u-boot sources included result in 2GB RAM being +detected. The following FIPs were generated with newer private sources +and give correct (4GB) RAM detection: + +https://github.com/LibreELEC/amlogic-boot-fip/tree/master/beelink-s922x + +NB: Beelink use a common board config for GT-King, GT-King Pro and the +GS-King-X model, hence the "beelink-s922x" name. + +.. code-block:: bash + + $ wget https://github.com/LibreELEC/amlogic-boot-fip/archive/master.zip + $ unzip master.zip + $ export FIPDIR=$PWD/amlogic-boot-fip/beelink-s922x + +Go back to the mainline U-Boot source tree then: + +.. code-block:: bash + + $ mkdir fip + $ cp $FIPDIR/* fip/ + $ cp u-boot.bin fip/bl33.bin + + $ sh fip/blx_fix.sh \ + fip/bl30.bin \ + fip/zero_tmp \ + fip/bl30_zero.bin \ + fip/bl301.bin \ + fip/bl301_zero.bin \ + fip/bl30_new.bin \ + bl30 + + $ sh fip/blx_fix.sh \ + fip/bl2.bin \ + fip/zero_tmp \ + fip/bl2_zero.bin \ + fip/acs.bin \ + fip/bl21_zero.bin \ + fip/bl2_new.bin \ + bl2 + + $ fip/aml_encrypt_g12b --bl30sig --input fip/bl30_new.bin \ + --output fip/bl30_new.bin.g12a.enc \ + --level v3 + $ fip/aml_encrypt_g12b --bl3sig --input fip/bl30_new.bin.g12a.enc \ + --output fip/bl30_new.bin.enc \ + --level v3 --type bl30 + $ fip/aml_encrypt_g12b --bl3sig --input fip/bl31.img \ + --output fip/bl31.img.enc \ + --level v3 --type bl31 + $ fip/aml_encrypt_g12b --bl3sig --input fip/bl33.bin --compress lz4 \ + --output fip/bl33.bin.enc \ + --level v3 --type bl33 + $ fip/aml_encrypt_g12b --bl2sig --input fip/bl2_new.bin \ + --output fip/bl2.n.bin.sig + $ fip/aml_encrypt_g12b --bootmk \ + --output fip/u-boot.bin \ + --bl2 fip/bl2.n.bin.sig \ + --bl30 fip/bl30_new.bin.enc \ + --bl31 fip/bl31.img.enc \ + --bl33 fip/bl33.bin.enc \ + --ddrfw1 fip/ddr4_1d.fw \ + --ddrfw2 fip/ddr4_2d.fw \ + --ddrfw3 fip/ddr3_1d.fw \ + --ddrfw4 fip/piei.fw \ + --ddrfw5 fip/lpddr4_1d.fw \ + --ddrfw6 fip/lpddr4_2d.fw \ + --ddrfw7 fip/diag_lpddr4.fw \ + --ddrfw8 fip/aml_ddr.fw \ + --level v3 + +and then write the image to SD with: + +.. code-block:: bash + + $ DEV=/dev/your_sd_device + $ dd if=fip/u-boot.bin.sd.bin of=$DEV conv=fsync,notrunc bs=512 skip=1 seek=1 + $ dd if=fip/u-boot.bin.sd.bin of=$DEV conv=fsync,notrunc bs=1 count=444 diff --git a/doc/board/amlogic/beelink-gtkingpro.rst b/doc/board/amlogic/beelink-gtkingpro.rst new file mode 100644 index 0000000000..d750351361 --- /dev/null +++ b/doc/board/amlogic/beelink-gtkingpro.rst @@ -0,0 +1,116 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +U-Boot for Beelink GT-King Pro +============================== + +The Shenzen AZW (Beelink) GT-King Pro is based on the Amlogic W400 reference +board with an S922X-H chip. + +- 4GB LPDDR4 RAM +- 64GB eMMC storage +- 10/100/1000 Base-T Ethernet +- AP6356S Wireless (802.11 a/b/g/n/ac, BT 4.1) +- HDMI 2.1 video +- Analogue audio output +- 1x RS232 port +- 2x USB 2.0 port +- 2x USB 3.0 ports +- IR receiver +- 1x SD card slot +- 1x Power on/off button + +Beelink do not provide public schematics, but have been willing +to share them with known distro developers on request. + +U-Boot compilation +------------------ + +.. code-block:: bash + + $ export CROSS_COMPILE=aarch64-none-elf- + $ make beelink-gtkingpro_defconfig + $ make + +Image creation +-------------- + +Amlogic does not provide sources for the firmware and for tools needed +to create the bootloader image. Beelink have provided the Amlogic "SDK" +in their forums, but the u-boot sources included result in 2GB RAM being +detected. The following FIPs were generated with newer private sources +and give correct (4GB) RAM detection: + +https://github.com/LibreELEC/amlogic-boot-fip/tree/master/beelink-s922x + +NB: Beelink use a common board config for GT-King, GT-King Pro and the +GS-King-X model, hence the "beelink-s922x" name. + +.. code-block:: bash + + $ wget https://github.com/LibreELEC/amlogic-boot-fip/archive/master.zip + $ unzip master.zip + $ export FIPDIR=$PWD/amlogic-boot-fip/beelink-s922x + +Go back to the mainline U-Boot source tree then: + +.. code-block:: bash + + $ mkdir fip + $ cp $FIPDIR/* fip/ + $ cp u-boot.bin fip/bl33.bin + + $ sh fip/blx_fix.sh \ + fip/bl30.bin \ + fip/zero_tmp \ + fip/bl30_zero.bin \ + fip/bl301.bin \ + fip/bl301_zero.bin \ + fip/bl30_new.bin \ + bl30 + + $ sh fip/blx_fix.sh \ + fip/bl2.bin \ + fip/zero_tmp \ + fip/bl2_zero.bin \ + fip/acs.bin \ + fip/bl21_zero.bin \ + fip/bl2_new.bin \ + bl2 + + $ fip/aml_encrypt_g12b --bl30sig --input fip/bl30_new.bin \ + --output fip/bl30_new.bin.g12a.enc \ + --level v3 + $ fip/aml_encrypt_g12b --bl3sig --input fip/bl30_new.bin.g12a.enc \ + --output fip/bl30_new.bin.enc \ + --level v3 --type bl30 + $ fip/aml_encrypt_g12b --bl3sig --input fip/bl31.img \ + --output fip/bl31.img.enc \ + --level v3 --type bl31 + $ fip/aml_encrypt_g12b --bl3sig --input fip/bl33.bin --compress lz4 \ + --output fip/bl33.bin.enc \ + --level v3 --type bl33 + $ fip/aml_encrypt_g12b --bl2sig --input fip/bl2_new.bin \ + --output fip/bl2.n.bin.sig + $ fip/aml_encrypt_g12b --bootmk \ + --output fip/u-boot.bin \ + --bl2 fip/bl2.n.bin.sig \ + --bl30 fip/bl30_new.bin.enc \ + --bl31 fip/bl31.img.enc \ + --bl33 fip/bl33.bin.enc \ + --ddrfw1 fip/ddr4_1d.fw \ + --ddrfw2 fip/ddr4_2d.fw \ + --ddrfw3 fip/ddr3_1d.fw \ + --ddrfw4 fip/piei.fw \ + --ddrfw5 fip/lpddr4_1d.fw \ + --ddrfw6 fip/lpddr4_2d.fw \ + --ddrfw7 fip/diag_lpddr4.fw \ + --ddrfw8 fip/aml_ddr.fw \ + --level v3 + +and then write the image to SD with: + +.. code-block:: bash + + $ DEV=/dev/your_sd_device + $ dd if=fip/u-boot.bin.sd.bin of=$DEV conv=fsync,notrunc bs=512 skip=1 seek=1 + $ dd if=fip/u-boot.bin.sd.bin of=$DEV conv=fsync,notrunc bs=1 count=444 diff --git a/doc/board/amlogic/index.rst b/doc/board/amlogic/index.rst index 9e780ba47c..275c3664b7 100644 --- a/doc/board/amlogic/index.rst +++ b/doc/board/amlogic/index.rst @@ -10,66 +10,66 @@ An up-do-date matrix is also available on: http://linux-meson.com This matrix concerns the actual source code version. -+-------------------------------+-----------+--------------+--------------+------------+------------+-------------+--------------+ -| | S905 | S905X | S912 | A113X | S905X2 | S922X | S905X3 | -| | | S805X | S905D | | S905D2 | A311D | S905D3 | -| | | | | | S905Y2 | | | -+===============================+===========+==============+==============+============+============+=============+==============+ -| Boards | Odroid-C2 | P212 | Khadas VIM2 | S400 | U200 | Odroid-N2 | SEI610 | -| | Nanopi-K2 | Khadas-VIM | Libretech-PC | | SEI510 | Khadas-VIM3 | Khadas-VIM3L | -| | P200 | LibreTech-CC | | | | | Odroid-C4 | -| | P201 | LibreTech-AC | | | | | | -+-------------------------------+-----------+--------------+--------------+------------+------------+-------------+--------------+ -| UART | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | -+-------------------------------+-----------+--------------+--------------+------------+------------+-------------+--------------+ -| Pinctrl/GPIO | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | -+-------------------------------+-----------+--------------+--------------+------------+------------+-------------+--------------+ -| Clock Control | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | -+-------------------------------+-----------+--------------+--------------+------------+------------+-------------+--------------+ -| PWM | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | -+-------------------------------+-----------+--------------+--------------+------------+------------+-------------+--------------+ -| Reset Control | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | -+-------------------------------+-----------+--------------+--------------+------------+------------+-------------+--------------+ -| Infrared Decoder | No | No | No | No | No | No | No | -+-------------------------------+-----------+--------------+--------------+------------+------------+-------------+--------------+ -| Ethernet | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | -+-------------------------------+-----------+--------------+--------------+------------+------------+-------------+--------------+ -| Multi-core | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | -+-------------------------------+-----------+--------------+--------------+------------+------------+-------------+--------------+ -| Fuse access | **Yes** | **Yes** |**Yes** |**Yes** |**Yes** |**Yes** | **Yes** | -+-------------------------------+-----------+--------------+--------------+------------+------------+-------------+--------------+ -| SPI (FC) | **Yes** | **Yes** | **Yes** | **Yes** |**Yes** | **Yes** | No | -+-------------------------------+-----------+--------------+--------------+------------+------------+-------------+--------------+ -| SPI (CC) | No | No | No | No | No | No | No | -+-------------------------------+-----------+--------------+--------------+------------+------------+-------------+--------------+ -| I2C | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | -+-------------------------------+-----------+--------------+--------------+------------+------------+-------------+--------------+ -| USB | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | -+-------------------------------+-----------+--------------+--------------+------------+------------+-------------+--------------+ -| USB OTG | No | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | -+-------------------------------+-----------+--------------+--------------+------------+------------+-------------+--------------+ -| eMMC | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | -+-------------------------------+-----------+--------------+--------------+------------+------------+-------------+--------------+ -| SDCard | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | -+-------------------------------+-----------+--------------+--------------+------------+------------+-------------+--------------+ -| NAND | No | No | No | No | No | No | No | -+-------------------------------+-----------+--------------+--------------+------------+------------+-------------+--------------+ -| ADC | **Yes** | **Yes** | **Yes** | No | No | No | No | -+-------------------------------+-----------+--------------+--------------+------------+------------+-------------+--------------+ -| CVBS Output | **Yes** | **Yes** | **Yes** | *N/A* | **Yes** | **Yes** | **Yes** | -+-------------------------------+-----------+--------------+--------------+------------+------------+-------------+--------------+ -| HDMI Output | **Yes** | **Yes** | **Yes** | *N/A* | **Yes** | **Yes** | **Yes** | -+-------------------------------+-----------+--------------+--------------+------------+------------+-------------+--------------+ -| CEC | No | No | No | *N/A* | No | No | No | -+-------------------------------+-----------+--------------+--------------+------------+------------+-------------+--------------+ -| Thermal Sensor | No | No | No | No | No | No | No | -+-------------------------------+-----------+--------------+--------------+------------+------------+-------------+--------------+ -| LCD/LVDS Output | No | *N/A* | No | No | No | No | No | -+-------------------------------+-----------+--------------+--------------+------------+------------+-------------+--------------+ -| MIPI DSI Output | *N/A* | *N/A* | *N/A* | No | No | No | No | -+-------------------------------+-----------+--------------+--------------+------------+------------+-------------+--------------+ -| SoC (version) information | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | -+-------------------------------+-----------+--------------+--------------+------------+------------+-------------+--------------+ ++-------------------------------+-----------+-----------------+--------------+------------+------------+-------------+--------------+ +| | S905 | S905X | S912 | A113X | S905X2 | S922X | S905X3 | +| | | S805X | S905D | | S905D2 | A311D | S905D3 | +| | | | | | S905Y2 | | | ++===============================+===========+=================+==============+============+============+=============+==============+ +| Boards | Odroid-C2 | P212 | Khadas VIM2 | S400 | U200 | Odroid-N2 | SEI610 | +| | Nanopi-K2 | Khadas-VIM | Libretech-PC | | SEI510 | Khadas-VIM3 | Khadas-VIM3L | +| | P200 | LibreTech-CC v1 | WeTek Core2 | | | GT-King/Pro | Odroid-C4 | +| | P201 | LibreTech-AC v2 | | | | | | ++-------------------------------+-----------+-----------------+--------------+------------+------------+-------------+--------------+ +| UART | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | ++-------------------------------+-----------+-----------------+--------------+------------+------------+-------------+--------------+ +| Pinctrl/GPIO | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | ++-------------------------------+-----------+-----------------+--------------+------------+------------+-------------+--------------+ +| Clock Control | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | ++-------------------------------+-----------+-----------------+--------------+------------+------------+-------------+--------------+ +| PWM | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | ++-------------------------------+-----------+-----------------+--------------+------------+------------+-------------+--------------+ +| Reset Control | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | ++-------------------------------+-----------+-----------------+--------------+------------+------------+-------------+--------------+ +| Infrared Decoder | No | No | No | No | No | No | No | ++-------------------------------+-----------+-----------------+--------------+------------+------------+-------------+--------------+ +| Ethernet | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | ++-------------------------------+-----------+-----------------+--------------+------------+------------+-------------+--------------+ +| Multi-core | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | ++-------------------------------+-----------+-----------------+--------------+------------+------------+-------------+--------------+ +| Fuse access | **Yes** | **Yes** |**Yes** |**Yes** |**Yes** |**Yes** | **Yes** | ++-------------------------------+-----------+-----------------+--------------+------------+------------+-------------+--------------+ +| SPI (FC) | **Yes** | **Yes** | **Yes** | **Yes** |**Yes** | **Yes** | No | ++-------------------------------+-----------+-----------------+--------------+------------+------------+-------------+--------------+ +| SPI (CC) | No | No | No | No | No | No | No | ++-------------------------------+-----------+-----------------+--------------+------------+------------+-------------+--------------+ +| I2C | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | ++-------------------------------+-----------+-----------------+--------------+------------+------------+-------------+--------------+ +| USB | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | ++-------------------------------+-----------+-----------------+--------------+------------+------------+-------------+--------------+ +| USB OTG | No | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | ++-------------------------------+-----------+-----------------+--------------+------------+------------+-------------+--------------+ +| eMMC | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | ++-------------------------------+-----------+-----------------+--------------+------------+------------+-------------+--------------+ +| SDCard | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | ++-------------------------------+-----------+-----------------+--------------+------------+------------+-------------+--------------+ +| NAND | No | No | No | No | No | No | No | ++-------------------------------+-----------+-----------------+--------------+------------+------------+-------------+--------------+ +| ADC | **Yes** | **Yes** | **Yes** | No | No | No | No | ++-------------------------------+-----------+-----------------+--------------+------------+------------+-------------+--------------+ +| CVBS Output | **Yes** | **Yes** | **Yes** | *N/A* | **Yes** | **Yes** | **Yes** | ++-------------------------------+-----------+-----------------+--------------+------------+------------+-------------+--------------+ +| HDMI Output | **Yes** | **Yes** | **Yes** | *N/A* | **Yes** | **Yes** | **Yes** | ++-------------------------------+-----------+-----------------+--------------+------------+------------+-------------+--------------+ +| CEC | No | No | No | *N/A* | No | No | No | ++-------------------------------+-----------+-----------------+--------------+------------+------------+-------------+--------------+ +| Thermal Sensor | No | No | No | No | No | No | No | ++-------------------------------+-----------+-----------------+--------------+------------+------------+-------------+--------------+ +| LCD/LVDS Output | No | *N/A* | No | No | No | No | No | ++-------------------------------+-----------+-----------------+--------------+------------+------------+-------------+--------------+ +| MIPI DSI Output | *N/A* | *N/A* | *N/A* | No | No | No | No | ++-------------------------------+-----------+-----------------+--------------+------------+------------+-------------+--------------+ +| SoC (version) information | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | ++-------------------------------+-----------+-----------------+--------------+------------+------------+-------------+--------------+ Board Documentation ------------------- @@ -77,6 +77,8 @@ Board Documentation .. toctree:: :maxdepth: 1 + beelink-gtking + beelink-gtkingpro khadas-vim2 khadas-vim3l khadas-vim3 @@ -95,4 +97,5 @@ Board Documentation sei510 sei610 u200 + wetek-core2 w400 diff --git a/doc/board/amlogic/libretech-cc.rst b/doc/board/amlogic/libretech-cc.rst index f2e26cabf9..94c74c5a8b 100644 --- a/doc/board/amlogic/libretech-cc.rst +++ b/doc/board/amlogic/libretech-cc.rst @@ -1,11 +1,13 @@ .. SPDX-License-Identifier: GPL-2.0+ -U-Boot for LibreTech CC -======================= +U-Boot for LibreTech CCs +======================== LibreTech CC is a single board computer manufactured by Libre Technology with the following specifications: +V1: + - Amlogic S905X ARM Cortex-A53 quad-core SoC @ 1.5GHz - ARM Mali 450 GPU - 2GB DDR3 SDRAM @@ -15,6 +17,12 @@ with the following specifications: - 4 x USB 2.0 Host - eMMC, microSD - Infrared receiver + - Jack for CVBS and Audio + +V2: + + - Added SPI NOR + - Removed Jack Schematics are available on the manufacturer website. @@ -27,6 +35,8 @@ U-Boot compilation $ make libretech-cc_defconfig $ make +Use libretech-cc_v2_defconfig for v2. + Image creation -------------- @@ -41,7 +51,8 @@ bootloaders: * acs.bin: built from vendor u-boot source These binaries and the tools required below have been collected and prebuilt -for convenience at <https://github.com/BayLibre/u-boot/releases/> +for convenience at <https://github.com/BayLibre/u-boot/releases/>. These +apply to both v1 and v2. Download and extract the libretech-cc release from there, and set FIPDIR to point to the `fip` subdirectory. diff --git a/doc/board/amlogic/wetek-core2.rst b/doc/board/amlogic/wetek-core2.rst new file mode 100644 index 0000000000..1012079ded --- /dev/null +++ b/doc/board/amlogic/wetek-core2.rst @@ -0,0 +1,96 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +U-Boot for WeTek Core2 +====================== + +WeTek Core2 is an Android STB based on the Q200 reference design with +the following specifications: + + - Amlogic S912 ARM Cortex-A53 octo-core SoC @ 1.5GHz + - ARM Mali T820 GPU + - 3GB DDR4 SDRAM + - 10/100 Realtek RTL8152 Ethernet (internal USB) + - HDMI 2.0 4K/60Hz display + - 2x USB 2.0 Host, 1x USB 2.0 OTG (internal) + - 32GB eMMC + - microSD + - SDIO Wifi Module, Bluetooth + - Two channel IR receiver + +U-Boot compilation +------------------ + +.. code-block:: bash + + $ export CROSS_COMPILE=aarch64-none-elf- + $ make wetek-core2_defconfig + $ make + +Image creation +-------------- + +Amlogic does not provide sources for the firmware or the tools needed +to create the bootloader image, and WeTek has not publicly shared the +precompiled FIP binaries. However the public Khadas VIM2 sources also +work with the Core2 box so we can use the Khadas git tree: + +.. code-block:: bash + + $ wget https://releases.linaro.org/archive/13.11/components/toolchain/binaries/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux.tar.xz + $ wget https://releases.linaro.org/archive/13.11/components/toolchain/binaries/gcc-linaro-arm-none-eabi-4.8-2013.11_linux.tar.xz + $ tar xvfJ gcc-linaro-aarch64-none-elf-4.8-2013.11_linux.tar.xz + $ tar xvfJ gcc-linaro-arm-none-eabi-4.8-2013.11_linux.tar.xz + $ export PATH=$PWD/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin:$PWD/gcc-linaro-arm-none-eabi-4.8-2013.11_linux/bin:$PATH + $ git clone https://github.com/khadas/u-boot -b khadas-vim-v2015.01 vim-u-boot + $ cd vim-u-boot + $ make kvim2_defconfig + $ make + $ export FIPDIR=$PWD/fip + +Go back to mainline U-Boot source tree then: + +.. code-block:: bash + + $ mkdir fip + $ cp $FIPDIR/gxl/bl2.bin fip/ + $ cp $FIPDIR/gxl/acs.bin fip/ + $ cp $FIPDIR/gxl/bl21.bin fip/ + $ cp $FIPDIR/gxl/bl30.bin fip/ + $ cp $FIPDIR/gxl/bl301.bin fip/ + $ cp $FIPDIR/gxl/bl31.img fip/ + $ cp u-boot.bin fip/bl33.bin + $ $FIPDIR/blx_fix.sh \ + fip/bl30.bin \ + fip/zero_tmp \ + fip/bl30_zero.bin \ + fip/bl301.bin \ + fip/bl301_zero.bin \ + fip/bl30_new.bin \ + bl30 + $ python $FIPDIR/acs_tool.pyc fip/bl2.bin fip/bl2_acs.bin fip/acs.bin 0 + $ $FIPDIR/blx_fix.sh \ + fip/bl2_acs.bin \ + fip/zero_tmp \ + fip/bl2_zero.bin \ + fip/bl21.bin \ + fip/bl21_zero.bin \ + fip/bl2_new.bin \ + bl2 + $ $FIPDIR/gxl/aml_encrypt_gxl --bl3enc --input fip/bl30_new.bin + $ $FIPDIR/gxl/aml_encrypt_gxl --bl3enc --input fip/bl31.img + $ $FIPDIR/gxl/aml_encrypt_gxl --bl3enc --input fip/bl33.bin + $ $FIPDIR/gxl/aml_encrypt_gxl --bl2sig --input fip/bl2_new.bin --output fip/bl2.n.bin.sig + $ $FIPDIR/gxl/aml_encrypt_gxl --bootmk \ + --output fip/u-boot.bin \ + --bl2 fip/bl2.n.bin.sig \ + --bl30 fip/bl30_new.bin.enc \ + --bl31 fip/bl31.img.enc \ + --bl33 fip/bl33.bin.enc + +then write the image to SD with: + +.. code-block:: bash + + $ DEV=/dev/your_sd_device + $ dd if=fip/u-boot.bin.sd.bin of=$DEV conv=fsync,notrunc bs=512 skip=1 seek=1 + $ dd if=fip/u-boot.bin.sd.bin of=$DEV conv=fsync,notrunc bs=1 count=444 diff --git a/doc/board/emulation/qemu-riscv.rst b/doc/board/emulation/qemu-riscv.rst index 3acd40630e..4b8e104a21 100644 --- a/doc/board/emulation/qemu-riscv.rst +++ b/doc/board/emulation/qemu-riscv.rst @@ -73,7 +73,7 @@ supported by U-Boot. Clone the OpenSBI repository and run the following command. git clone https://github.com/riscv/opensbi.git cd opensbi - make PLATFORM=qemu/virt + make PLATFORM=generic See the OpenSBI documentation for full details: https://github.com/riscv/opensbi/blob/master/docs/platform/qemu_virt.md diff --git a/doc/board/freescale/b4860qds.rst b/doc/board/freescale/b4860qds.rst index 37d7d08b09..de14d857b9 100644 --- a/doc/board/freescale/b4860qds.rst +++ b/doc/board/freescale/b4860qds.rst @@ -134,7 +134,7 @@ B4860QDS Default Settings ------------------------- Switch Settings ---------------- +^^^^^^^^^^^^^^^ .. code-block:: none @@ -167,7 +167,7 @@ B4420QDS Default Settings ------------------------- Switch Settings ---------------- +^^^^^^^^^^^^^^^ .. code-block:: none diff --git a/doc/board/freescale/imx8mm_evk.rst b/doc/board/freescale/imx8mm_evk.rst index f75190227c..a9ccdb7850 100644 --- a/doc/board/freescale/imx8mm_evk.rst +++ b/doc/board/freescale/imx8mm_evk.rst @@ -18,7 +18,7 @@ Get and Build the ARM Trusted firmware Note: builddir is U-Boot build directory (source directory for in-tree builds) Get ATF from: https://source.codeaurora.org/external/imx/imx-atf -branch: imx_4.19.35_1.0.0 +branch: imx_5.4.47_2.2.0 .. code-block:: bash @@ -30,10 +30,10 @@ Get the ddr firmware .. code-block:: bash - $ wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-8.0.bin - $ chmod +x firmware-imx-8.0.bin - $ ./firmware-imx-8.0 - $ cp firmware-imx-8.0/firmware/ddr/synopsys/lpddr4*.bin $(builddir) + $ wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-8.9.bin + $ chmod +x firmware-imx-8.9.bin + $ ./firmware-imx-8.9 + $ cp firmware-imx-8.9/firmware/ddr/synopsys/lpddr4*.bin $(builddir) Build U-Boot ------------ diff --git a/doc/board/freescale/imx8mn_evk.rst b/doc/board/freescale/imx8mn_evk.rst index c3e92cecee..375e0bb761 100644 --- a/doc/board/freescale/imx8mn_evk.rst +++ b/doc/board/freescale/imx8mn_evk.rst @@ -18,7 +18,7 @@ Get and Build the ARM Trusted firmware Note: srctree is U-Boot source directory Get ATF from: https://source.codeaurora.org/external/imx/imx-atf -branch: imx_4.19.35_1.1.0 +branch: imx_5.4.47_2.2.0 .. code-block:: bash @@ -30,10 +30,10 @@ Get the ddr firmware .. code-block:: bash - $ wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-8.5.bin - $ chmod +x firmware-imx-8.5.bin - $ ./firmware-imx-8.5 - $ cp firmware-imx-8.5/firmware/ddr/synopsys/ddr4*.bin $(srctree) + $ wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-8.9.bin + $ chmod +x firmware-imx-8.9.bin + $ ./firmware-imx-8.9 + $ cp firmware-imx-8.9/firmware/ddr/synopsys/ddr4*.bin $(srctree) Build U-Boot ------------ diff --git a/doc/board/freescale/imx8mp_evk.rst b/doc/board/freescale/imx8mp_evk.rst index 96df6d470f..ccffcf7257 100644 --- a/doc/board/freescale/imx8mp_evk.rst +++ b/doc/board/freescale/imx8mp_evk.rst @@ -18,7 +18,7 @@ Get and Build the ARM Trusted firmware Note: $(srctree) is the U-Boot source directory Get ATF from: https://source.codeaurora.org/external/imx/imx-atf -branch: imx_5.4.3_2.0.0 +branch: imx_5.4.47_2.2.0 .. code-block:: bash @@ -30,13 +30,13 @@ Get the ddr firmware .. code-block:: bash - $ wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-8.7.bin - $ chmod +x firmware-imx-8.7.bin - $ ./firmware-imx-8.7.bin - $ cp firmware-imx-8.7/firmware/ddr/synopsys/lpddr4_pmu_train_1d_dmem_201904.bin $(srctree)/lpddr4_pmu_train_1d_dmem.bin - $ cp firmware-imx-8.7/firmware/ddr/synopsys/lpddr4_pmu_train_1d_imem_201904.bin $(srctree)/lpddr4_pmu_train_1d_imem.bin - $ cp firmware-imx-8.7/firmware/ddr/synopsys/lpddr4_pmu_train_2d_dmem_201904.bin $(srctree)/lpddr4_pmu_train_2d_dmem.bin - $ cp firmware-imx-8.7/firmware/ddr/synopsys/lpddr4_pmu_train_2d_imem_201904.bin $(srctree)/lpddr4_pmu_train_2d_imem.bin + $ wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-8.9.bin + $ chmod +x firmware-imx-8.9.bin + $ ./firmware-imx-8.9.bin + $ cp firmware-imx-8.9/firmware/ddr/synopsys/lpddr4_pmu_train_1d_dmem_201904.bin $(srctree)/lpddr4_pmu_train_1d_dmem.bin + $ cp firmware-imx-8.9/firmware/ddr/synopsys/lpddr4_pmu_train_1d_imem_201904.bin $(srctree)/lpddr4_pmu_train_1d_imem.bin + $ cp firmware-imx-8.9/firmware/ddr/synopsys/lpddr4_pmu_train_2d_dmem_201904.bin $(srctree)/lpddr4_pmu_train_2d_dmem.bin + $ cp firmware-imx-8.9/firmware/ddr/synopsys/lpddr4_pmu_train_2d_imem_201904.bin $(srctree)/lpddr4_pmu_train_2d_imem.bin Build U-Boot ------------ diff --git a/doc/board/freescale/imx8mq_evk.rst b/doc/board/freescale/imx8mq_evk.rst index 0a64ecc5ba..c269fdebe3 100644 --- a/doc/board/freescale/imx8mq_evk.rst +++ b/doc/board/freescale/imx8mq_evk.rst @@ -18,7 +18,7 @@ Get and Build the ARM Trusted firmware Note: srctree is U-Boot source directory Get ATF from: https://source.codeaurora.org/external/imx/imx-atf -branch: imx_4.19.35_1.0.0 +branch: imx_5.4.47_2.2.0 .. code-block:: bash @@ -30,11 +30,11 @@ Get the ddr and hdmi firmware .. code-block:: bash - $ wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-7.9.bin - $ chmod +x firmware-imx-7.9.bin - $ ./firmware-imx-7.9.bin - $ cp firmware-imx-7.9/firmware/hdmi/cadence/signed_hdmi_imx8m.bin $(builddir) - $ cp firmware-imx-7.9/firmware/ddr/synopsys/lpddr4*.bin $(builddir) + $ wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-8.9.bin + $ chmod +x firmware-imx-8.9.bin + $ ./firmware-imx-8.9.bin + $ cp firmware-imx-8.9/firmware/hdmi/cadence/signed_hdmi_imx8m.bin $(builddir) + $ cp firmware-imx-8.9/firmware/ddr/synopsys/lpddr4*.bin $(builddir) Build U-Boot ------------ diff --git a/doc/board/index.rst b/doc/board/index.rst index 915f1be8a5..08c167b6b5 100644 --- a/doc/board/index.rst +++ b/doc/board/index.rst @@ -17,6 +17,7 @@ Board-specific doc google/index intel/index kontron/index + microchip/index renesas/index rockchip/index sifive/index diff --git a/doc/board/microchip/index.rst b/doc/board/microchip/index.rst new file mode 100644 index 0000000000..affc5a9e01 --- /dev/null +++ b/doc/board/microchip/index.rst @@ -0,0 +1,9 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +Microchip +========= + +.. toctree:: + :maxdepth: 2 + + mpfs_icicle diff --git a/doc/board/microchip/mpfs_icicle.rst b/doc/board/microchip/mpfs_icicle.rst new file mode 100644 index 0000000000..7489761501 --- /dev/null +++ b/doc/board/microchip/mpfs_icicle.rst @@ -0,0 +1,810 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +Microchip PolarFire SoC Icicle Kit +================================== + +RISC-V PolarFire SoC +-------------------- +The PolarFire SoC is the 4+1 64-bit RISC-V SoC from Microchip. + +The Icicle Kit development platform is based on PolarFire SoC and capable +of running Linux. + +Mainline support +---------------- +The support for following drivers are already enabled: + +1. NS16550 UART Driver. +2. Microchip Clock Driver. +3. Cadence MACB ethernet driver for networking support. +4. Cadence MMC Driver for eMMC/SD support. + +Booting from eMMC using HSS +--------------------------- + +Building U-Boot +--------------- + +1. Add the RISC-V toolchain to your PATH. +2. Setup ARCH & cross compilation environment variable: + +.. code-block:: none + + export CROSS_COMPILE=<riscv64 toolchain prefix> + +3. make microchip_mpfs_icicle_defconfig +4. make + +Flashing +-------- + +The current U-Boot port is supported in S-mode only and loaded from DRAM. + +A prior stage M-mode firmware/bootloader (e.g HSS with OpenSBI) is required to +boot the u-boot.bin in S-mode. + +Currently, the u-boot.bin is used as a payload of the HSS firmware (Microchip +boot-flow) and OpenSBI generic platform fw_payload.bin (with u-boot.bin embedded) +as HSS payload (Custom boot-flow) + +Microchip boot-flow +------------------- +HSS with OpenSBI (M-Mode) -> U-Boot (S-Mode) -> Linux (S-Mode) + +Build the HSS (Hart Software Services) - Microchip boot-flow +------------------------------------------------------------ +(Note: HSS git repo is at https://github.com/polarfire-soc/hart-software-services) + +1. Configure + +.. code-block:: none + + make BOARD=icicle-kit-es config + +Alternatively, copy the default config for Microchip boot-flow. + +.. code-block:: none + + cp boards/icicle-kit-es/def_config .config + +2. make BOARD=icicle-kit-es +3. In the Default subdirectory, the standard build will create hss.elf and + various binary formats (hss.hex and hss.bin). + +The FPGA design will use the hss.hex or hss.bin. + +FPGA design with HSS programming file +------------------------------------- +https://github.com/polarfire-soc/polarfire-soc-documentation/blob/master/boards/mpfs-icicle-kit-es/updating-icicle-kit/updating-icicle-kit-design-and-linux.md + +The HSS firmware runs from the PolarFire SoC eNVM on reset. + +Creating the HSS payload - Microchip boot-flow +---------------------------------------------- +1. You will be creating a payload from `u-boot-dtb.bin`. + Copy this file to the HSS/tools/hss-payload-generator/test directory. +2. Go to hss-payload-generator source directory. + +.. code-block:: none + + cd hart-software-services/tools/hss-payload-generator + +3. Edit test/uboot.yaml file for hart entry points and correct name of the binary file. + + hart-entry-points: {u54_1: '0x80200000', u54_2: '0x80200000', u54_3: '0x80200000', u54_4: '0x80200000'} + + payloads: + test/u-boot-dtb.bin: {exec-addr: '0x80200000', owner-hart: u54_1, secondary-hart: u54_2, secondary-hart: u54_3, secondary-hart: u54_4, priv-mode: prv_s} + +4. Generate payload + +.. code-block:: none + + ./hss-payload-generator -c test/uboot.yaml payload.bin + +Once the payload binary is generated, it should be copied to the eMMC. + +Please refer to HSS documenation to build the HSS firmware for payload. +(Note: HSS git repo is at https://github.com/polarfire-soc/hart-software-services/blob/master/tools/hss-payload-generator/README.md) + +Custom boot-flow +---------------- +HSS without OpenSBI (M-Mode) -> OpenSBI (M-Mode) -> U-Boot (S-Mode) -> Linux (S-Mode) + +Build OpenSBI +------------- + +1. Get the OpenSBI source + +.. code-block:: none + + git clone https://github.com/riscv/opensbi.git + cd opensbi + +2. Build + +.. code-block:: none + + make PLATFORM=generic FW_PAYLOAD_PATH=<u-boot-directory>/u-boot.bin + FW_FDT_PATH=<u-boot-directory>/arch/riscv/dts/microchip-mpfs-icicle-kit-.dtb + +3. Output "fw_payload.bin" file available at + "<opensbi-directory>/build/platform/generic/firmware/fw_payload.bin" + +Build the HSS (Hart Software Services)- Custom boot-flow +-------------------------------------------------------- +(Note: HSS git repo is at https://github.com/polarfire-soc/hart-software-services) + +1. Configure + +.. code-block:: none + + make BOARD=icicle-kit-es config + +Alternatively, copy the default custom config for Custom boot-flow. + +.. code-block:: none + + cp boards/icicle-kit-es/def_config_custom .config + +2. make BOARD=icicle-kit-es +3. In the Default subdirectory, the standard build will create hss.elf and + various binary formats (hss.hex and hss.bin). + +The FPGA design will use the hss.hex or hss.bin. + +Creating the HSS payload - Custom boot-flow +------------------------------------------- +1. You will be creating a payload from `fw_payload.bin`. + Copy this file to the HSS/tools/hss-payload-generator/test directory. +2. Go to hss-payload-generator source directory. + +.. code-block:: none + + cd hart-software-services/tools/hss-payload-generator + +3. Edit test/uboot.yaml file for hart entry points and correct name of the binary file. + + hart-entry-points: {u54_1: '0x80000000', u54_2: '0x80000000', u54_3: '0x80000000', u54_4: '0x80000000'} + + payloads: + test/fw_payload.bin: {exec-addr: '0x80000000', owner-hart: u54_1, secondary-hart: u54_2, secondary-hart: u54_3, secondary-hart: u54_4, priv-mode: prv_m} + +4. Generate payload + +.. code-block:: none + + ./hss-payload-generator -c test/uboot.yaml payload.bin + +Once the payload binary is generated, it should be copied to the eMMC. + +Please refer to HSS documenation to build the HSS firmware for payload. +(Note: HSS git repo is at https://github.com/polarfire-soc/hart-software-services/blob/master/tools/hss-payload-generator/README.md +and also refer the HSS payload generator at https://github.com/polarfire-soc/polarfire-soc-documentation/blob/master/software-development/hss-payloads.md) + +eMMC +---- +Program eMMC with payload binary is explained in the PolarFire SoC documentation. +(Note: PolarFire SoC Documentation git repo is at https://github.com/polarfire-soc/polarfire-soc-documentation/blob/master/boards/mpfs-icicle-kit-es/updating-icicle-kit/updating-icicle-kit-design-and-linux.md#eMMC) + +Once the payload image is copied to the eMMC, press CTRL+C in the HSS command +line interface, then type 'boot' and enter to boot the newly copied image. + +.. code-block:: none + + sudo dd if=<payload_binary> of=/dev/sdX bs=512 + +GUID type +--------- +The HSS always picks up HSS payload from a GPT partition with +GIUD type "21686148-6449-6E6F-744E-656564454649" or sector '0' of the eMMC if no +GPT partition. + +Booting +------- +You should see the U-Boot prompt on UART0. + +Sample boot log from MPFS Icicle Kit +------------------------------------ + +.. code-block:: none + + U-Boot 2021.01-00314-g7303332537-dirty (Jan 14 2021 - 10:09:43 +0530) + + CPU: rv64imafdc + Model: Microchip MPFS Icicle Kit + DRAM: 1 GiB + MMC: sdhc@20008000: 0 + In: serial@20100000 + Out: serial@20100000 + Err: serial@20100000 + Net: eth0: ethernet@20112000 + Hit any key to stop autoboot: 0 + +Now you can configure your networking, tftp server and use tftp boot method to +load uImage (with initramfs). + +.. code-block:: none + + RISC-V # setenv kernel_addr_r 0x80200000 + RISC-V # setenv fdt_addr_r 0x82200000 + + RISC-V # setenv ipaddr 192.168.1.5 + RISC-V # setenv netmask 255.255.255.0 + RISC-V # setenv serverip 192.168.1.3 + RISC-V # setenv gateway 192.168.1.1 + + RISC-V # tftpboot ${kernel_addr_r} uImage + ethernet@20112000: PHY present at 9 + ethernet@20112000: Starting autonegotiation... + ethernet@20112000: Autonegotiation complete + ethernet@20112000: link up, 1000Mbps full-duplex (lpa: 0x7800) + Using ethernet@20112000 device + TFTP from server 192.168.1.3; our IP address is 192.168.1.5 + Filename 'uImage'. + Load address: 0x80200000 + Loading: ################################################################# + ################################################################# + ################################################################# + ################################################################# + ################################################################# + ################################################################# + ################################################################# + ################################################################# + ################################################################# + ################################################################# + ################################################################# + ################################################################# + ################################################################# + ################################################################# + ################################################################# + ############ + 6.4 MiB/s + done + Bytes transferred = 14482480 (dcfc30 hex) + + RISC-V # tftpboot ${fdt_addr_r} microchip-mpfs-icicle-kit.dtb + ethernet@20112000: PHY present at 9 + ethernet@20112000: Starting autonegotiation... + ethernet@20112000: Autonegotiation complete + ethernet@20112000: link up, 1000Mbps full-duplex (lpa: 0x7800) + Using ethernet@20112000 device + TFTP from server 192.168.1.3; our IP address is 192.168.1.5 + Filename 'microchip-mpfs-icicle-kit.dtb'. + Load address: 0x82200000 + Loading: # + 2.5 MiB/s + done + Bytes transferred = 10282 (282a hex) + + RISC-V # bootm ${kernel_addr_r} - ${fdt_addr_r} + ## Booting kernel from Legacy Image at 80200000 ... + Image Name: Linux + Image Type: RISC-V Linux Kernel Image (uncompressed) + Data Size: 14482416 Bytes = 13.8 MiB + Load Address: 80200000 + Entry Point: 80200000 + Verifying Checksum ... OK + ## Flattened Device Tree blob at 82200000 + Booting using the fdt blob at 0x82200000 + Loading Kernel Image + Using Device Tree in place at 000000008fffa000, end 000000008ffff829 ... OK + + Starting kernel ... + + [ 0.000000] OF: fdt: Ignoring memory range 0x80000000 - 0x80200000 + [ 0.000000] Linux version 5.6.17 (padmarao@padmarao-VirtualBox) (gcc version 7.2.0 (GCC)) #2 SMP Tue Jun 16 21:27:50 IST 2020 + [ 0.000000] initrd not found or empty - disabling initrd + [ 0.000000] Zone ranges: + [ 0.000000] DMA32 [mem 0x0000000080200000-0x00000000bfffffff] + [ 0.000000] Normal empty + [ 0.000000] Movable zone start for each node + [ 0.000000] Early memory node ranges + [ 0.000000] node 0: [mem 0x0000000080200000-0x00000000bfffffff] + [ 0.000000] Initmem setup node 0 [mem 0x0000000080200000-0x00000000bfffffff] + [ 0.000000] software IO TLB: mapped [mem 0xbb1f5000-0xbf1f5000] (64MB) + [ 0.000000] elf_hwcap is 0x112d + [ 0.000000] percpu: Embedded 14 pages/cpu s24856 r0 d32488 u57344 + [ 0.000000] Built 1 zonelists, mobility grouping on. Total pages: 258055 + [ 0.000000] Kernel command line: console=ttyS0,115200n8 + [ 0.000000] Dentry cache hash table entries: 131072 (order: 8, 1048576 bytes, linear) + [ 0.000000] Inode-cache hash table entries: 65536 (order: 7, 524288 bytes, linear) + [ 0.000000] Sorting __ex_table... + [ 0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off + [ 0.000000] Memory: 950308K/1046528K available (3289K kernel code, 212K rwdata, 900K rodata, 9476K init, 250K bss, 96220K reserved, 0K cma-reserved) + [ 0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1 + [ 0.000000] rcu: Hierarchical RCU implementation. + [ 0.000000] rcu: RCU event tracing is enabled. + [ 0.000000] rcu: RCU restricting CPUs from NR_CPUS=8 to nr_cpu_ids=4. + [ 0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 10 jiffies. + [ 0.000000] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=4 + [ 0.000000] NR_IRQS: 0, nr_irqs: 0, preallocated irqs: 0 + [ 0.000000] plic: mapped 186 interrupts with 4 handlers for 9 contexts. + [ 0.000000] riscv_timer_init_dt: Registering clocksource cpuid [0] hartid [1] + [ 0.000000] clocksource: riscv_clocksource: mask: 0xffffffffffffffff max_cycles: 0x1d854df40, max_idle_ns: 3526361616960 ns + [ 0.000015] sched_clock: 64 bits at 1000kHz, resolution 1000ns, wraps every 2199023255500ns + [ 0.000311] Calibrating delay loop (skipped), value calculated using timer frequency.. 2.00 BogoMIPS (lpj=10000) + [ 0.000349] pid_max: default: 32768 minimum: 301 + [ 0.000846] Mount-cache hash table entries: 2048 (order: 2, 16384 bytes, linear) + [ 0.000964] Mountpoint-cache hash table entries: 2048 (order: 2, 16384 bytes, linear) + [ 0.005630] rcu: Hierarchical SRCU implementation. + [ 0.006901] smp: Bringing up secondary CPUs ... + [ 0.012545] smp: Brought up 1 node, 4 CPUs + [ 0.014431] devtmpfs: initialized + [ 0.020526] random: get_random_bytes called from setup_net+0x36/0x192 with crng_init=0 + [ 0.020928] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns + [ 0.020999] futex hash table entries: 1024 (order: 4, 65536 bytes, linear) + [ 0.022768] NET: Registered protocol family 16 + [ 0.035478] microchip-pfsoc-clkcfg 20002000.clkcfg: Registered PFSOC core clocks + [ 0.048429] SCSI subsystem initialized + [ 0.049694] pps_core: LinuxPPS API ver. 1 registered + [ 0.049719] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it> + [ 0.049780] PTP clock support registered + [ 0.051781] clocksource: Switched to clocksource riscv_clocksource + [ 0.055326] NET: Registered protocol family 2 + [ 0.056922] tcp_listen_portaddr_hash hash table entries: 512 (order: 1, 8192 bytes, linear) + [ 0.057053] TCP established hash table entries: 8192 (order: 4, 65536 bytes, linear) + [ 0.057648] TCP bind hash table entries: 8192 (order: 5, 131072 bytes, linear) + [ 0.058579] TCP: Hash tables configured (established 8192 bind 8192) + [ 0.059648] UDP hash table entries: 512 (order: 2, 16384 bytes, linear) + [ 0.059837] UDP-Lite hash table entries: 512 (order: 2, 16384 bytes, linear) + [ 0.060707] NET: Registered protocol family 1 + [ 0.266229] workingset: timestamp_bits=62 max_order=18 bucket_order=0 + [ 0.287107] io scheduler mq-deadline registered + [ 0.287140] io scheduler kyber registered + [ 0.429601] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled + [ 0.433979] printk: console [ttyS0] disabled + [ 0.434154] 20000000.serial: ttyS0 at MMIO 0x20000000 (irq = 18, base_baud = 9375000) is a 16550A + [ 0.928039] printk: console [ttyS0] enabled + [ 0.939804] libphy: Fixed MDIO Bus: probed + [ 0.948702] libphy: MACB_mii_bus: probed + [ 0.993698] macb 20112000.ethernet eth0: Cadence GEM rev 0x0107010c at 0x20112000 irq 21 (56:34:12:00:fc:00) + [ 1.006751] mousedev: PS/2 mouse device common for all mice + [ 1.013803] i2c /dev entries driver + [ 1.019451] sdhci: Secure Digital Host Controller Interface driver + [ 1.027242] sdhci: Copyright(c) Pierre Ossman + [ 1.032731] sdhci-pltfm: SDHCI platform and OF driver helper + [ 1.091826] mmc0: SDHCI controller on 20008000.sdhc [20008000.sdhc] using ADMA 64-bit + [ 1.102738] NET: Registered protocol family 17 + [ 1.170326] Freeing unused kernel memory: 9476K + [ 1.176067] This architecture does not have kernel memory protection. + [ 1.184157] Run /init as init process + Starting logging: OK + Starting mdev... + /etc/init.d/S10mdev: line 21: can't create /proc/sys/kernel/hotplug: nonexiste[ 1.331981] mmc0: mmc_select_hs200 failed, error -74 + nt directory + [ 1.355011] mmc0: new MMC card at address 0001 + [ 1.363981] mmcblk0: mmc0:0001 DG4008 7.28 GiB + [ 1.372248] mmcblk0boot0: mmc0:0001 DG4008 partition 1 4.00 MiB + [ 1.382292] mmcblk0boot1: mmc0:0001 DG4008 partition 2 4.00 MiB + [ 1.390265] mmcblk0rpmb: mmc0:0001 DG4008 partition 3 4.00 MiB, chardev (251:0) + [ 1.425234] GPT:Primary header thinks Alt. header is not at the end of the disk. + [ 1.434656] GPT:2255809 != 15273599 + [ 1.439038] GPT:Alternate GPT header not at the end of the disk. + [ 1.446671] GPT:2255809 != 15273599 + [ 1.451048] GPT: Use GNU Parted to correct GPT errors. + [ 1.457755] mmcblk0: p1 p2 p3 + sort: /sys/devices/platform/Fixed: No such file or directory + modprobe: can't change directory to '/lib/modules': No such file or directory + Initializing random number generator... [ 2.830198] random: dd: uninitialized urandom read (512 bytes read) + done. + Starting network... + [ 3.061867] macb 20112000.ethernet eth0: PHY [20112000.ethernet-ffffffff:09] driver [Vitesse VSC8662] (irq=POLL) + [ 3.074674] macb 20112000.ethernet eth0: configuring for phy/sgmii link mode + [ 3.084263] pps pps0: new PPS source ptp0 + [ 3.089710] macb 20112000.ethernet: gem-ptp-timer ptp clock registered. + udhcpc (v1.24.2) started + Sending discover... + Sending discover... + [ 6.380169] macb 20112000.ethernet eth0: Link is Up - 1Gbps/Full - flow control tx + Sending discover... + Sending select for 192.168.1.2... + Lease of 192.168.1.2 obtained, lease time 86400 + deleting routers + adding dns 192.168.1.1 + Starting dropbear sshd: [ 11.385619] random: dropbear: uninitialized urandom read (32 bytes read) + OK + + Welcome to Buildroot + buildroot login: root + Password: + # + +Booting U-Boot and Linux from eMMC +---------------------------------- + +FPGA design with HSS programming file and Linux Image +----------------------------------------------------- +https://github.com/polarfire-soc/polarfire-soc-documentation/blob/master/boards/mpfs-icicle-kit-es/updating-icicle-kit/updating-icicle-kit-design-and-linux.md + +The HSS firmware runs from the PolarFire SoC eNVM on reset. + +eMMC +---- +Program eMMC with payload binary and Linux image is explained in the +PolarFire SoC documentation. +The payload binary should be copied to partition 2 of the eMMC. + +(Note: PolarFire SoC Documentation git repo is at https://github.com/polarfire-soc/polarfire-soc-documentation/blob/master/boards/mpfs-icicle-kit-es/updating-icicle-kit/updating-icicle-kit-design-and-linux.md#eMMC) + +Once the Linux image and payload binary is copied to the eMMC, press CTRL+C +in the HSS command line interface, then type 'boot' and enter to boot the newly +copied payload and Linux image. + +.. code-block:: none + + zcat <linux-image>.wic.gz | sudo dd of=/dev/sdX bs=4096 iflag=fullblock oflag=direct conv=fsync status=progress + + sudo dd if=<payload_binary> of=/dev/sdX2 bs=512 + +You should see the U-Boot prompt on UART0. + +GUID type +--------- +The HSS always picks up the HSS payload from a GPT partition with +GIUD type "21686148-6449-6E6F-744E-656564454649" or sector '0' of the eMMC if no +GPT partition. + +Sample boot log from MPFS Icicle Kit +------------------------------------ + +.. code-block:: none + + U-Boot 2021.01-00314-g7303332537-dirty (Jan 14 2021 - 10:09:43 +0530) + + CPU: rv64imafdc + Model: Microchip MPFS Icicle Kit + DRAM: 1 GiB + MMC: sdhc@20008000: 0 + In: serial@20100000 + Out: serial@20100000 + Err: serial@20100000 + Net: eth0: ethernet@20112000 + Hit any key to stop autoboot: 0 + + RISC-V # mmc info + Device: sdhc@20008000 + Manufacturer ID: 45 + OEM: 100 + Name: DG400 + Bus Speed: 52000000 + Mode: MMC High Speed (52MHz) + Rd Block Len: 512 + MMC version 5.1 + High Capacity: Yes + Capacity: 7.3 GiB + Bus Width: 4-bit + Erase Group Size: 512 KiB + HC WP Group Size: 8 MiB + User Capacity: 7.3 GiB WRREL + Boot Capacity: 4 MiB ENH + RPMB Capacity: 4 MiB ENH + + RISC-V # mmc part + Partition Map for MMC device 0 -- Partition Type: EFI + + Part Start LBA End LBA Name + Attributes + Type GUID + Partition GUID + 1 0x00002000 0x0000b031 "boot" + attrs: 0x0000000000000004 + type: ebd0a0a2-b9e5-4433-87c0-68b6b72699c7 + guid: 99ff6a94-f2e7-44dd-a7df-f3a2da106ef9 + 2 0x0000b032 0x0000f031 "primary" + attrs: 0x0000000000000000 + type: 21686148-6449-6e6f-744e-656564454649 + guid: 12006052-e64b-4423-beb0-b956ea00f1ba + 3 0x00010000 0x00226b9f "root" + attrs: 0x0000000000000000 + type: 0fc63daf-8483-4772-8e79-3d69d8477de4 + guid: dd2c5619-2272-4c3c-8dc2-e21942e17ce6 + + RISC-V # load mmc 0 ${ramdisk_addr_r} fitimage + RISC-V # bootm ${ramdisk_addr_r} + ## Loading kernel from FIT Image at 88300000 ... + Using 'conf@microchip_icicle-kit-es-a000-microchip.dtb' configuration + Trying 'kernel@1' kernel subimage + Description: Linux kernel + Type: Kernel Image + Compression: gzip compressed + Data Start: 0x883000fc + Data Size: 3574555 Bytes = 3.4 MiB + Architecture: RISC-V + OS: Linux + Load Address: 0x80200000 + Entry Point: 0x80200000 + Hash algo: sha256 + Hash value: 21f18d72cf2f0a7192220abb577ad25c77c26960052d779aa02bf55dbf0a6403 + Verifying Hash Integrity ... sha256+ OK + ## Loading fdt from FIT Image at 88300000 ... + Using 'conf@microchip_icicle-kit-es-a000-microchip.dtb' configuration + Trying 'fdt@microchip_icicle-kit-es-a000-microchip.dtb' fdt subimage + Description: Flattened Device Tree blob + Type: Flat Device Tree + Compression: uncompressed + Data Start: 0x88668d44 + Data Size: 9760 Bytes = 9.5 KiB + Architecture: RISC-V + Load Address: 0x82200000 + Hash algo: sha256 + Hash value: 5c3a9f30d41b6b8e53b47916e1f339b3a4d454006554d1f7e1f552ed62409f4b + Verifying Hash Integrity ... sha256+ OK + Loading fdt from 0x88668d48 to 0x82200000 + Booting using the fdt blob at 0x82200000 + Uncompressing Kernel Image + Loading Device Tree to 000000008fffa000, end 000000008ffff61f ... OK + + Starting kernel ... + + [ 0.000000] OF: fdt: Ignoring memory range 0x80000000 - 0x80200000 + [ 0.000000] Linux version 5.6.16 (oe-user@oe-host) (gcc version 9.3.0 (GCC)) #1 SMP Fri Oct 9 11:49:47 UTC 2020 + [ 0.000000] earlycon: sbi0 at I/O port 0x0 (options '') + [ 0.000000] printk: bootconsole [sbi0] enabled + [ 0.000000] Zone ranges: + [ 0.000000] DMA32 [mem 0x0000000080200000-0x00000000bfffffff] + [ 0.000000] Normal empty + [ 0.000000] Movable zone start for each node + [ 0.000000] Early memory node ranges + [ 0.000000] node 0: [mem 0x0000000080200000-0x00000000bfffffff] + [ 0.000000] Zeroed struct page in unavailable ranges: 512 pages + [ 0.000000] Initmem setup node 0 [mem 0x0000000080200000-0x00000000bfffffff] + [ 0.000000] software IO TLB: mapped [mem 0xb9e00000-0xbde00000] (64MB) + [ 0.000000] CPU with hartid=0 is not available + [ 0.000000] CPU with hartid=0 is not available + [ 0.000000] elf_hwcap is 0x112d + [ 0.000000] percpu: Embedded 17 pages/cpu s29784 r8192 d31656 u69632 + [ 0.000000] Built 1 zonelists, mobility grouping on. Total pages: 258055 + [ 0.000000] Kernel command line: earlycon=sbi root=/dev/mmcblk0p3 rootwait console=ttyS0,115200n8 uio_pdrv_genirq.of_id=generic-uio + [ 0.000000] Dentry cache hash table entries: 131072 (order: 8, 1048576 bytes, linear) + [ 0.000000] Inode-cache hash table entries: 65536 (order: 7, 524288 bytes, linear) + [ 0.000000] Sorting __ex_table... + [ 0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off + [ 0.000000] Memory: 941440K/1046528K available (4118K kernel code, 280K rwdata, 1687K rodata, 169K init, 273K bss, 105088K reserved, 0K cma-reserved) + [ 0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1 + [ 0.000000] rcu: Hierarchical RCU implementation. + [ 0.000000] rcu: RCU event tracing is enabled. + [ 0.000000] rcu: RCU restricting CPUs from NR_CPUS=5 to nr_cpu_ids=4. + [ 0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 10 jiffies. + [ 0.000000] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=4 + [ 0.000000] NR_IRQS: 0, nr_irqs: 0, preallocated irqs: 0 + [ 0.000000] plic: mapped 53 interrupts with 4 handlers for 9 contexts. + [ 0.000000] riscv_timer_init_dt: Registering clocksource cpuid [0] hartid [1] + [ 0.000000] clocksource: riscv_clocksource: mask: 0xffffffffffffffff max_cycles: 0x1d854df40, max_idle_ns: 3526361616960 ns + [ 0.000015] sched_clock: 64 bits at 1000kHz, resolution 1000ns, wraps every 2199023255500ns + [ 0.008679] Console: colour dummy device 80x25 + [ 0.013112] Calibrating delay loop (skipped), value calculated using timer frequency.. 2.00 BogoMIPS (lpj=10000) + [ 0.023368] pid_max: default: 32768 minimum: 301 + [ 0.028314] Mount-cache hash table entries: 2048 (order: 2, 16384 bytes, linear) + [ 0.035766] Mountpoint-cache hash table entries: 2048 (order: 2, 16384 bytes, linear) + [ 0.047099] rcu: Hierarchical SRCU implementation. + [ 0.052813] smp: Bringing up secondary CPUs ... + [ 0.061581] smp: Brought up 1 node, 4 CPUs + [ 0.067069] devtmpfs: initialized + [ 0.073621] random: get_random_u32 called from bucket_table_alloc.isra.0+0x4e/0x150 with crng_init=0 + [ 0.074409] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns + [ 0.093399] futex hash table entries: 1024 (order: 4, 65536 bytes, linear) + [ 0.101879] NET: Registered protocol family 16 + [ 0.110336] microchip-pfsoc-clkcfg 20002000.clkcfg: Registered PFSOC core clocks + [ 0.132717] usbcore: registered new interface driver usbfs + [ 0.138225] usbcore: registered new interface driver hub + [ 0.143813] usbcore: registered new device driver usb + [ 0.148939] pps_core: LinuxPPS API ver. 1 registered + [ 0.153929] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it> + [ 0.163071] PTP clock support registered + [ 0.168521] clocksource: Switched to clocksource riscv_clocksource + [ 0.174927] VFS: Disk quotas dquot_6.6.0 + [ 0.179016] VFS: Dquot-cache hash table entries: 512 (order 0, 4096 bytes) + [ 0.205536] NET: Registered protocol family 2 + [ 0.210944] tcp_listen_portaddr_hash hash table entries: 512 (order: 1, 8192 bytes, linear) + [ 0.219393] TCP established hash table entries: 8192 (order: 4, 65536 bytes, linear) + [ 0.227497] TCP bind hash table entries: 8192 (order: 5, 131072 bytes, linear) + [ 0.235440] TCP: Hash tables configured (established 8192 bind 8192) + [ 0.242537] UDP hash table entries: 512 (order: 2, 16384 bytes, linear) + [ 0.249285] UDP-Lite hash table entries: 512 (order: 2, 16384 bytes, linear) + [ 0.256690] NET: Registered protocol family 1 + [ 0.262585] workingset: timestamp_bits=62 max_order=18 bucket_order=0 + [ 0.281036] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 249) + [ 0.288481] io scheduler mq-deadline registered + [ 0.292983] io scheduler kyber registered + [ 0.298895] microsemi,mss-gpio 20122000.gpio: Microsemi MSS GPIO registered 32 GPIOs + [ 0.453723] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled + [ 0.462911] printk: console [ttyS0] disabled + [ 0.467216] 20100000.serial: ttyS0 at MMIO 0x20100000 (irq = 12, base_baud = 9375000) is a 16550A + [ 0.476201] printk: console [ttyS0] enabled + [ 0.476201] printk: console [ttyS0] enabled + [ 0.484576] printk: bootconsole [sbi0] disabled + [ 0.484576] printk: bootconsole [sbi0] disabled + [ 0.494920] 20102000.serial: ttyS1 at MMIO 0x20102000 (irq = 13, base_baud = 9375000) is a 16550A + [ 0.505068] 20104000.serial: ttyS2 at MMIO 0x20104000 (irq = 14, base_baud = 9375000) is a 16550A + [ 0.533336] loop: module loaded + [ 0.572284] Rounding down aligned max_sectors from 4294967295 to 4294967288 + [ 0.580000] db_root: cannot open: /etc/target + [ 0.585413] libphy: Fixed MDIO Bus: probed + [ 0.591526] libphy: MACB_mii_bus: probed + [ 0.598060] macb 20112000.ethernet eth0: Cadence GEM rev 0x0107010c at 0x20112000 irq 17 (56:34:12:00:fc:00) + [ 0.608352] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver + [ 0.615001] ehci-platform: EHCI generic platform driver + [ 0.620446] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver + [ 0.626632] ohci-platform: OHCI generic platform driver + [ 0.632326] usbcore: registered new interface driver cdc_acm + [ 0.637996] cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters + [ 0.646459] i2c /dev entries driver + [ 0.650852] microsemi-mss-i2c 2010b000.i2c: Microsemi I2C Probe Complete + [ 0.658010] sdhci: Secure Digital Host Controller Interface driver + [ 0.664326] sdhci: Copyright(c) Pierre Ossman + [ 0.668754] sdhci-pltfm: SDHCI platform and OF driver helper + [ 0.706845] mmc0: SDHCI controller on 20008000.sdhc [20008000.sdhc] using ADMA 64-bit + [ 0.715052] usbcore: registered new interface driver usbhid + [ 0.720722] usbhid: USB HID core driver + [ 0.725174] pac193x 0-0010: Chip revision: 0x03 + [ 0.733339] pac193x 0-0010: :pac193x_prep_iio_channels: Channel 0 active + [ 0.740127] pac193x 0-0010: :pac193x_prep_iio_channels: Channel 1 active + [ 0.746881] pac193x 0-0010: :pac193x_prep_iio_channels: Channel 2 active + [ 0.753686] pac193x 0-0010: :pac193x_prep_iio_channels: Channel 3 active + [ 0.760495] pac193x 0-0010: :pac193x_prep_iio_channels: Active chip channels: 25 + [ 0.778006] NET: Registered protocol family 10 + [ 0.784929] Segment Routing with IPv6 + [ 0.788875] sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver + [ 0.795743] NET: Registered protocol family 17 + [ 0.801191] hctosys: unable to open rtc device (rtc0) + [ 0.807774] Waiting for root device /dev/mmcblk0p3... + [ 0.858506] mmc0: mmc_select_hs200 failed, error -74 + [ 0.865764] mmc0: new MMC card at address 0001 + [ 0.872564] mmcblk0: mmc0:0001 DG4008 7.28 GiB + [ 0.878777] mmcblk0boot0: mmc0:0001 DG4008 partition 1 4.00 MiB + [ 0.886182] mmcblk0boot1: mmc0:0001 DG4008 partition 2 4.00 MiB + [ 0.892633] mmcblk0rpmb: mmc0:0001 DG4008 partition 3 4.00 MiB, chardev (247:0) + [ 0.919029] GPT:Primary header thinks Alt. header is not at the end of the disk. + [ 0.926448] GPT:2255841 != 15273599 + [ 0.930019] GPT:Alternate GPT header not at the end of the disk. + [ 0.936029] GPT:2255841 != 15273599 + [ 0.939583] GPT: Use GNU Parted to correct GPT errors. + [ 0.944800] mmcblk0: p1 p2 p3 + [ 0.966696] EXT4-fs (mmcblk0p3): INFO: recovery required on readonly filesystem + [ 0.974105] EXT4-fs (mmcblk0p3): write access will be enabled during recovery + [ 1.052362] random: fast init done + [ 1.057961] EXT4-fs (mmcblk0p3): recovery complete + [ 1.065734] EXT4-fs (mmcblk0p3): mounted filesystem with ordered data mode. Opts: (null) + [ 1.074002] VFS: Mounted root (ext4 filesystem) readonly on device 179:3. + [ 1.081654] Freeing unused kernel memory: 168K + [ 1.086108] This architecture does not have kernel memory protection. + [ 1.092629] Run /sbin/init as init process + [ 1.702217] systemd[1]: System time before build time, advancing clock. + [ 1.754192] systemd[1]: systemd 244.3+ running in system mode. (+PAM -AUDIT -SELINUX +IMA -APPARMOR -SMACK +SYSVINIT +UTMP -LIBCRYPTSETUP -GCRYPT -GNUTLS +ACL +XZ -LZ4 -SECCOMP +BLKID -ELFUTILS +KMOD -IDN2 -IDN -PCRE2 default-hierarchy=hybrid) + [ 1.776361] systemd[1]: Detected architecture riscv64. + + Welcome to OpenEmbedded nodistro.0! + + [ 1.829651] systemd[1]: Set hostname to <icicle-kit-es>. + [ 2.648597] random: systemd: uninitialized urandom read (16 bytes read) + [ 2.657485] systemd[1]: Created slice system-getty.slice. + [ OK ] Created slice system-getty.slice. + [ 2.698779] random: systemd: uninitialized urandom read (16 bytes read) + [ 2.706317] systemd[1]: Created slice system-serial\x2dgetty.slice. + [ OK ] Created slice system-serial\x2dgetty.slice. + [ 2.748716] random: systemd: uninitialized urandom read (16 bytes read) + [ 2.756098] systemd[1]: Created slice User and Session Slice. + [ OK ] Created slice User and Session Slice. + [ 2.789065] systemd[1]: Started Dispatch Password Requests to Console Directory Watch. + [ OK ] Started Dispatch Password …ts to Console Directory Watch. + [ 2.828974] systemd[1]: Started Forward Password Requests to Wall Directory Watch. + [ OK ] Started Forward Password R…uests to Wall Directory Watch. + [ 2.869009] systemd[1]: Reached target Paths. + [ OK ] Reached target Paths. + [ 2.898808] systemd[1]: Reached target Remote File Systems. + [ OK ] Reached target Remote File Systems. + [ 2.938771] systemd[1]: Reached target Slices. + [ OK ] Reached target Slices. + [ 2.968754] systemd[1]: Reached target Swap. + [ OK ] Reached target Swap. + [ 2.999283] systemd[1]: Listening on initctl Compatibility Named Pipe. + [ OK ] Listening on initctl Compatibility Named Pipe. + [ 3.060458] systemd[1]: Condition check resulted in Journal Audit Socket being skipped. + [ 3.069826] systemd[1]: Listening on Journal Socket (/dev/log). + [ OK ] Listening on Journal Socket (/dev/log). + [ 3.109601] systemd[1]: Listening on Journal Socket. + [ OK ] Listening on Journal Socket. + [ 3.149868] systemd[1]: Listening on Network Service Netlink Socket. + [ OK ] Listening on Network Service Netlink Socket. + [ 3.189419] systemd[1]: Listening on udev Control Socket. + [ OK ] Listening on udev Control Socket. + [ 3.229179] systemd[1]: Listening on udev Kernel Socket. + [ OK ] Listening on udev Kernel Socket. + [ 3.269520] systemd[1]: Condition check resulted in Huge Pages File System being skipped. + [ 3.278477] systemd[1]: Condition check resulted in POSIX Message Queue File System being skipped. + [ 3.288200] systemd[1]: Condition check resulted in Kernel Debug File System being skipped. + [ 3.302570] systemd[1]: Mounting Temporary Directory (/tmp)... + Mounting Temporary Directory (/tmp)... + [ 3.339226] systemd[1]: Condition check resulted in Create list of static device nodes for the current kernel being skipped. + [ 3.355883] systemd[1]: Starting File System Check on Root Device... + Starting File System Check on Root Device... + [ 3.407220] systemd[1]: Starting Journal Service... + Starting Journal Service... + [ 3.422441] systemd[1]: Condition check resulted in Load Kernel Modules being skipped. + [ 3.431770] systemd[1]: Condition check resulted in FUSE Control File System being skipped. + [ 3.446415] systemd[1]: Mounting Kernel Configuration File System... + Mounting Kernel Configuration File System... + [ 3.458983] systemd[1]: Starting Apply Kernel Variables... + Starting Apply Kernel Variables... + [ 3.471368] systemd[1]: Starting udev Coldplug all Devices... + Starting udev Coldplug all Devices... + [ 3.491071] systemd[1]: Mounted Temporary Directory (/tmp). + [ OK 3.498114] systemd[1]: Mounted Kernel Configuration File System. + 0m] Mounted Temporary Directory (/tmp). + [ OK ] Mounted Kernel Configuration File System. + [ 3.550853] systemd[1]: Started Apply Kernel Variables. + [ OK 3.557535] systemd[1]: Started Journal Service. + 0m] Started Apply Kernel Variables. + [ OK ] Started Journal Service. + [ OK ] Started udev Coldplug all Devices. + [ OK ] Started File System Check on Root Device. + Starting Remount Root and Kernel File Systems... + [ 8.133469] EXT4-fs (mmcblk0p3): re-mounted. Opts: (null) + [ OK ] Started Remount Root and Kernel File Systems. + Starting Flush Journal to Persistent Storage... + [ 8.215327] systemd-journald[77]: Received client request to flush runtime journal. + Starting Create Static Device Nodes in /dev... + [ OK ] Started Flush Journal to Persistent Storage. + [ OK ] Started Create Static Device Nodes in /dev. + [ OK ] Reached target Local File Systems (Pre). + Mounting /var/volatile... + Starting udev Kernel Device Manager... + [ OK ] Mounted /var/volatile. + Starting Load/Save Random Seed... + [ OK ] Reached target Local File Systems. + Starting Create Volatile Files and Directories... + [ OK ] Started udev Kernel Device Manager. + [ OK ] Started Create Volatile Files and Directories. + Starting Network Time Synchronization... + Starting Update UTMP about System Boot/Shutdown... + [ OK ] Started Update UTMP about System Boot/Shutdown. + [ OK ] Started Network Time Synchronization. + [ 11.618575] random: crng init done + [ 11.622007] random: 7 urandom warning(s) missed due to ratelimiting + [ OK ] Started Load/Save Random Seed. + [ OK ] Reached target System Initialization. + [ OK ] Started Daily Cleanup of Temporary Directories. + [ OK ] Reached target System Time Set. + [ OK ] Reached target System Time Synchronized. + [ OK ] Reached target Timers. + [ OK ] Listening on D-Bus System Message Bus Socket. + [ OK ] Listening on dropbear.socket. + [ OK ] Reached target Sockets. + [ OK ] Reached target Basic System. + [ OK ] Started D-Bus System Message Bus. + Starting IPv6 Packet Filtering Framework... + Starting IPv4 Packet Filtering Framework... + Starting Login Service... + [ OK ] Started IPv6 Packet Filtering Framework. + [ OK ] Started IPv4 Packet Filtering Framework. + [ OK ] Reached target Network (Pre). + Starting Network Service... + [ OK ] Started Login Service. + [ 12.602455] macb 20112000.ethernet eth0: PHY [20112000.ethernet-ffffffff:09] driver [Vitesse VSC8662] (irq=POLL) + [ 12.612795] macb 20112000.ethernet eth0: configuring for phy/sgmii link mode + [ 12.622153] pps pps0: new PPS source ptp0 + [ OK 12.626725] macb 20112000.ethernet: gem-ptp-timer ptp clock registered. + 0m] Started Network Service. + Starting Network Name Resolution... + [ OK ] Started Network Name Resolution. + [ OK ] Reached target Network. + [ OK ] Reached target Host and Network Name Lookups. + [ OK ] Started Collectd. + [ OK ] Started Collectd. + Starting Permit User Sessions... + [ OK ] Started Permit User Sessions. + [ OK ] Started Getty on tty1. + [ OK ] Started Serial Getty on ttyS0. + [ OK ] Reached target Login Prompts. + [ OK ] Reached target Multi-User System. + Starting Update UTMP about System Runlevel Changes... + [ OK ] Started Update UTMP about System Runlevel Changes. + + OpenEmbedded nodistro.0 icicle-kit-es ttyS0 + + icicle-kit-es login: [ 15.795564] macb 20112000.ethernet eth0: Link is Up - 1Gbps/Full - flow control tx + [ 15.803306] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready + + icicle-kit-es login: root + root@icicle-kit-es:~# diff --git a/doc/board/sifive/fu540.rst b/doc/board/sifive/fu540.rst index 1ce9ab14f5..4e4c852ff3 100644 --- a/doc/board/sifive/fu540.rst +++ b/doc/board/sifive/fu540.rst @@ -12,6 +12,7 @@ of running Linux. Mainline support ---------------- + The support for following drivers are already enabled: 1. SiFive UART Driver. @@ -24,7 +25,7 @@ Booting from MMC using FSBL --------------------------- Building --------- +~~~~~~~~ 1. Add the RISC-V toolchain to your PATH. 2. Setup ARCH & cross compilation environment variable: @@ -37,7 +38,7 @@ Building 4. make Flashing --------- +~~~~~~~~ The current U-Boot port is supported in S-mode only and loaded from DRAM. @@ -63,11 +64,12 @@ copied to the first partition of the sdcard. sudo dd if=<prior_stage_firmware_binary> of=/dev/disk2s1 bs=1024 Booting -------- +~~~~~~~ + Once you plugin the sdcard and power up, you should see the U-Boot prompt. Sample boot log from HiFive Unleashed board -------------------------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. code-block:: none @@ -417,7 +419,7 @@ Booting from MMC using U-Boot SPL --------------------------------- Building --------- +~~~~~~~~ Before building U-Boot SPL, OpenSBI must be built first. OpenSBI can be cloned and built for FU540 as below: @@ -441,7 +443,7 @@ This will generate spl/u-boot-spl.bin and FIT image (u-boot.itb) Flashing --------- +~~~~~~~~ ZSBL loads the U-Boot SPL (u-boot-spl.bin) from a partition with GUID type 5B193300-FC78-40CD-8002-E86C45580B47 @@ -471,11 +473,12 @@ Program the SD card sudo dd if=u-boot.itb of=/dev/sda seek=2082 Booting -------- +~~~~~~~ + Once you plugin the sdcard and power up, you should see the U-Boot prompt. Sample boot log from HiFive Unleashed board -------------------------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. code-block:: none diff --git a/doc/board/sipeed/maix.rst b/doc/board/sipeed/maix.rst index 92f2d112a9..bf945b3458 100644 --- a/doc/board/sipeed/maix.rst +++ b/doc/board/sipeed/maix.rst @@ -70,6 +70,7 @@ console shall be opened immediately. Boot output should look like the following: U-Boot 2020.04-rc2-00087-g2221cc09c1-dirty (Feb 28 2020 - 13:53:09 -0500) DRAM: 8 MiB + MMC: spi@53000000:slot@0: 0 In: serial@38000000 Out: serial@38000000 Err: serial@38000000 @@ -118,14 +119,115 @@ The value of FW_PAYLOAD_OFFSET must match CONFIG_SYS_TEXT_BASE - 0x80000000. The file to flash is build/platform/kendryte/k210/firmware/fw_payload.bin. +Booting +^^^^^^^ + +The default boot process is to load and boot the files ``/uImage`` and +``/k210.dtb`` off of the first partition of the MMC. For Linux, this will result +in an output like + +.. code-block:: none + + U-Boot 2020.10-00691-gd1d651d988-dirty (Oct 16 2020 - 17:05:24 -0400) + + DRAM: 8 MiB + MMC: spi@53000000:slot@0: 0 + Loading Environment from SPIFlash... SF: Detected w25q128fw with page size 256 Bytes, erase size 4 KiB, total 16 MiB + OK + In: serial@38000000 + Out: serial@38000000 + Err: serial@38000000 + Hit any key to stop autoboot: 0 + 1827380 bytes read in 1044 ms (1.7 MiB/s) + 13428 bytes read in 10 ms (1.3 MiB/s) + ## Booting kernel from Legacy Image at 80060000 ... + Image Name: linux + Image Type: RISC-V Linux Kernel Image (uncompressed) + Data Size: 1827316 Bytes = 1.7 MiB + Load Address: 80000000 + Entry Point: 80000000 + Verifying Checksum ... OK + ## Flattened Device Tree blob at 80400000 + Booting using the fdt blob at 0x80400000 + Loading Kernel Image + Loading Device Tree to 00000000803f9000, end 00000000803ff473 ... OK + + Starting kernel ... + + [ 0.000000] Linux version 5.9.0-00021-g6dcc2f0814c6-dirty (sean@godwin) (riscv64-linux-gnu-gcc (GCC) 10.2.0, GNU ld (GNU Binutils) 2.35) #34 SMP Fri Oct 16 14:40:57 EDT 2020 + [ 0.000000] earlycon: sifive0 at MMIO 0x0000000038000000 (options '115200n8') + [ 0.000000] printk: bootconsole [sifive0] enabled + [ 0.000000] Zone ranges: + [ 0.000000] DMA32 [mem 0x0000000080000000-0x00000000807fffff] + [ 0.000000] Normal empty + [ 0.000000] Movable zone start for each node + [ 0.000000] Early memory node ranges + [ 0.000000] node 0: [mem 0x0000000080000000-0x00000000807fffff] + [ 0.000000] Initmem setup node 0 [mem 0x0000000080000000-0x00000000807fffff] + [ 0.000000] riscv: ISA extensions acdfgim + [ 0.000000] riscv: ELF capabilities acdfim + [ 0.000000] percpu: max_distance=0x18000 too large for vmalloc space 0x0 + [ 0.000000] percpu: Embedded 12 pages/cpu s18848 r0 d30304 u49152 + [ 0.000000] Built 1 zonelists, mobility grouping off. Total pages: 2020 + [ 0.000000] Kernel command line: earlycon console=ttySIF0 + [ 0.000000] Dentry cache hash table entries: 1024 (order: 1, 8192 bytes, linear) + [ 0.000000] Inode-cache hash table entries: 512 (order: 0, 4096 bytes, linear) + [ 0.000000] Sorting __ex_table... + [ 0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off + [ 0.000000] Memory: 6004K/8192K available (1139K kernel code, 126K rwdata, 198K rodata, 90K init, 81K bss, 2188K reserved, 0K cma-reserved) + [ 0.000000] rcu: Hierarchical RCU implementation. + [ 0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies. + [ 0.000000] NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0 + [ 0.000000] riscv-intc: 64 local interrupts mapped + [ 0.000000] plic: interrupt-controller@C000000: mapped 65 interrupts with 2 handlers for 2 contexts. + [ 0.000000] random: get_random_bytes called from 0x00000000800019a8 with crng_init=0 + [ 0.000000] k210-clk: clock-controller + [ 0.000000] k210-clk: clock-controller: fixed-rate 26 MHz osc base clock + [ 0.000000] clint: clint@2000000: timer running at 7800000 Hz + [ 0.000000] clocksource: clint_clocksource: mask: 0xffffffffffffffff max_cycles: 0x3990be68b, max_idle_ns: 881590404272 ns + [ 0.000014] sched_clock: 64 bits at 7MHz, resolution 128ns, wraps every 4398046511054ns + [ 0.008450] Console: colour dummy device 80x25 + [ 0.012494] Calibrating delay loop (skipped), value calculated using timer frequency.. 15.60 BogoMIPS (lpj=31200) + [ 0.022693] pid_max: default: 4096 minimum: 301 + [ 0.027352] Mount-cache hash table entries: 512 (order: 0, 4096 bytes, linear) + [ 0.034428] Mountpoint-cache hash table entries: 512 (order: 0, 4096 bytes, linear) + [ 0.045099] rcu: Hierarchical SRCU implementation. + [ 0.050048] smp: Bringing up secondary CPUs ... + [ 0.055417] smp: Brought up 1 node, 2 CPUs + [ 0.059602] devtmpfs: initialized + [ 0.082796] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns + [ 0.091820] futex hash table entries: 16 (order: -2, 1024 bytes, linear) + [ 0.098507] pinctrl core: initialized pinctrl subsystem + [ 0.140938] clocksource: Switched to clocksource clint_clocksource + [ 0.247216] workingset: timestamp_bits=62 max_order=11 bucket_order=0 + [ 0.277392] k210-fpioa 502b0000.pinmux: K210 FPIOA pin controller + [ 0.291724] k210-sysctl 50440000.syscon: K210 system controller + [ 0.305317] k210-rst 50440000.syscon:reset-controller: K210 reset controller + [ 0.313808] 38000000.serial: ttySIF0 at MMIO 0x38000000 (irq = 1, base_baud = 115200) is a SiFive UART v0 + [ 0.322712] printk: console [ttySIF0] enabled + [ 0.322712] printk: console [ttySIF0] enabled + [ 0.331328] printk: bootconsole [sifive0] disabled + [ 0.331328] printk: bootconsole [sifive0] disabled + [ 0.353347] Freeing unused kernel memory: 88K + [ 0.357004] This architecture does not have kernel memory protection. + [ 0.363397] Run /init as init process + +Loading, Booting, and Storing Images +------------------------------------ + +.. _loading: + Loading Images ^^^^^^^^^^^^^^ -To load a kernel, transfer it over serial. +Serial +"""""" + +Use the ``loady`` command to load images over serial. .. code-block:: none - => loady 80000000 1500000 + => loady $loadaddr 1500000 ## Switch baudrate to 1500000 bps and press ENTER ... *** baud: 1500000 @@ -150,6 +252,61 @@ To load a kernel, transfer it over serial. *** baud: 115200 *** => +This command does not set ``$filesize``, so it may need to be set manually. + +SPI Flash +""""""""" + +To load an image off of SPI flash, first set up a partition as described in +:ref:`partitions`. Then, use ``mtd`` to load that partition + +.. code-block:: none + + => sf probe + SF: Detected w25q128fw with page size 256 Bytes, erase size 4 KiB, total 16 MiB + => mtd read linux $loadaddr + Reading 2097152 byte(s) at offset 0x00000000 + +This command does not set ``$filesize``, so it may need to be set manually. + +MMC +""" + +The MMC device number is 0. To list partitions on the device, use ``part``: + +.. code-block:: none + + => part list mmc 0 + + Partition Map for MMC device 0 -- Partition Type: EFI + + Part Start LBA End LBA Name + Attributes + Type GUID + Partition GUID + 1 0x00000800 0x039effde "boot" + attrs: 0x0000000000000000 + type: c12a7328-f81f-11d2-ba4b-00a0c93ec93b + guid: 96161f7d-7113-4cc7-9a24-08ab7fc5cb72 + +To list files, use ``ls``: + +.. code-block:: none + + => ls mmc 0:1 + <DIR> 4096 . + <DIR> 4096 .. + <DIR> 16384 lost+found + 13428 k210.dtb + 1827380 uImage + +To load a file, use ``load``: + +.. code-block:: none + + => load mmc 0:1 $loadaddr uImage + 1827380 bytes read in 1049 ms (1.7 MiB/s) + Running Programs ^^^^^^^^^^^^^^^^ @@ -160,20 +317,6 @@ To run a bare binary, use the ``go`` command: .. code-block:: none - => loady - ## Ready for binary (ymodem) download to 0x80000000 at 115200 bps... - C - *** file: ./examples/standalone/hello_world.bin - $ sz -vv ./examples/standalone/hello_world.bin - Sending: hello_world.bin - Bytes Sent: 4864 BPS:649 - Sending: - Ymodem sectors/kbytes sent: 0/ 0k - Transfer complete - - *** exit status: 0 *** - (CAN) packets, 5 retries - ## Total Size = 0x000012f8 = 4856 Bytes => go 80000000 ## Starting application at 0x80000000 ... Example expects ABI version 9 @@ -184,51 +327,127 @@ To run a bare binary, use the ``go`` command: argv[1] = "<NULL>" Hit any key to exit ... +Note that this will only start a program on one hart. As-of this writing it is +only possible to start a program on multiple harts using the ``bootm`` command. + Legacy Images """"""""""""" -To run legacy images, use the ``bootm`` command: +To create a legacy image, use ``tools/mkimage``: .. code-block:: none - $ tools/mkimage -A riscv -O u-boot -T standalone -C none -a 80000000 -e 80000000 -d examples/standalone/hello_world.bin hello_world.img - Image Name: - Created: Thu Mar 5 12:04:10 2020 - Image Type: RISC-V U-Boot Standalone Program (uncompressed) - Data Size: 4856 Bytes = 4.74 KiB = 0.00 MiB + $ tools/mkimage -A riscv -O linux -T kernel -C none -a 0x80000000 -e 0x80000000 -n linux -d ../linux-git/arch/riscv/boot/Image uImage + Image Name: linux + Created: Fri Oct 16 17:36:32 2020 + Image Type: RISC-V Linux Kernel Image (uncompressed) + Data Size: 1827316 Bytes = 1784.49 KiB = 1.74 MiB Load Address: 80000000 Entry Point: 80000000 - $ picocom -b 115200 /dev/ttyUSB0 - => loady - ## Ready for binary (ymodem) download to 0x80000000 at 115200 bps... - C - *** file: hello_world.img - $ sz -vv hello_world.img - Sending: hello_world.img - Bytes Sent: 4992 BPS:665 - Sending: - Ymodem sectors/kbytes sent: 0/ 0k - Transfer complete +The ``bootm`` command also requires an FDT, even if the image doesn't require +one. After loading the image to ``$loadaddr`` and the FDT to ``$fdt_addr_r``, +boot with: - *** exit status: 0 *** - CAN) packets, 3 retries - ## Total Size = 0x00001338 = 4920 Bytes - => bootm - ## Booting kernel from Legacy Image at 80000000 ... - Image Name: - Image Type: RISC-V U-Boot Standalone Program (uncompressed) - Data Size: 4856 Bytes = 4.7 KiB +.. code-block:: none + + => bootm $loadaddr - $fdt_addr_r + ## Booting kernel from Legacy Image at 80060000 ... + Image Name: linux + Image Type: RISC-V Linux Kernel Image (uncompressed) + Data Size: 1827316 Bytes = 1.7 MiB Load Address: 80000000 Entry Point: 80000000 Verifying Checksum ... OK - Loading Standalone Program - Example expects ABI version 9 - Actual U-Boot ABI version 9 - Hello World - argc = 0 - argv[0] = "<NULL>" - Hit any key to exit ... + ## Flattened Device Tree blob at 80400000 + Booting using the fdt blob at 0x80400000 + Loading Kernel Image + Loading Device Tree to 00000000803f9000, end 00000000803ff473 ... OK + + Starting kernel ... + +The FDT is verified after the kernel is relocated, so it must be loaded high +enough so that it won't be overwritten. The default values for ``$loadaddr`` +and ``$fdt_addr_r`` should provide ample headroom for most use-cases. + +Flashing Images +^^^^^^^^^^^^^^^ + +SPI Flash +""""""""" + +To flash data to SPI flash, first load it using one of the methods in +:ref:`loading`. Addiotionally, create some partitions as described in +:ref:`partitions`. Then use the ``mtd`` command: + +.. code-block:: none + + => sf probe + SF: Detected w25q128fw with page size 256 Bytes, erase size 4 KiB, total 16 MiB + => mtd write linux $loadaddr 0 $filesize + Writing 2478162 byte(s) at offset 0x00000000 + +Note that in order to write a bootable image, a header and tailer must be added. + +MMC +""" + +MMC writes are unsupported for now. + +SPI Flash +^^^^^^^^^ + +Sipeed MAIX boards typically provide around 16 MiB of SPI NOR flash. U-Boot is +stored in the first 1 MiB or so of this flash. U-Boot's environment is stored at +the end of flash. + +.. _partitions: + +Partitions +"""""""""" + +There is no set data layout. The default partition layout only allocates +partitions for U-Boot and its default environment + +.. code-block:: none + + => mtd list + List of MTD devices: + * nor0 + - type: NOR flash + - block size: 0x1000 bytes + - min I/O: 0x1 bytes + - 0x000000000000-0x000001000000 : "nor0" + - 0x000000000000-0x000000100000 : "u-boot" + - 0x000000fff000-0x000001000000 : "env" + +As an example, to allocate 2MiB for Linux and (almost) 13 MiB for other data, +set the ``mtdparts`` like: + +.. code-block:: none + + => env set mtdparts nor0:1M(u-boot),2M(linux),0xcff000(data),0x1000@0xfff000(env) + => mtd list + List of MTD devices: + * nor0 + - type: NOR flash + - block size: 0x1000 bytes + - min I/O: 0x1 bytes + - 0x000000000000-0x000001000000 : "nor0" + - 0x000000000000-0x000000100000 : "u-boot" + - 0x000000100000-0x000000300000 : "linux" + - 0x000000300000-0x000000fff000 : "data" + - 0x000000fff000-0x000001000000 : "env" + +To make these changes permanent, save the environment: + +.. code-block:: none + + => env save + Saving Environment to SPIFlash... Erasing SPI flash...Writing to SPI flash...done + OK + +U-Boot will always load the environment from the last 4 KiB of flash. Pin Assignment -------------- diff --git a/doc/board/st/stm32mp1.rst b/doc/board/st/stm32mp1.rst index e74f7afdae..20f5c9e301 100644 --- a/doc/board/st/stm32mp1.rst +++ b/doc/board/st/stm32mp1.rst @@ -1,5 +1,5 @@ .. SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause -.. sectionauthor:: Patrick Delaunay <patrick.delaunay@st.com> +.. sectionauthor:: Patrick Delaunay <patrick.delaunay@foss.st.com> STM32MP15x boards ================= diff --git a/doc/driver-model/bind.rst b/doc/driver-model/bind.rst index e3e9cb4d3c..b19661b5fe 100644 --- a/doc/driver-model/bind.rst +++ b/doc/driver-model/bind.rst @@ -1,5 +1,5 @@ .. SPDX-License-Identifier: GPL-2.0+ -.. sectionauthor:: Patrice Chotard <patrice.chotard@st.com> +.. sectionauthor:: Patrice Chotard <patrice.chotard@foss.st.com> Binding/unbinding a driver ========================== diff --git a/doc/uefi/uefi.rst b/doc/uefi/uefi.rst index dc930d9240..5a67737c15 100644 --- a/doc/uefi/uefi.rst +++ b/doc/uefi/uefi.rst @@ -59,13 +59,10 @@ Below you find the output of an example session starting GRUB:: 120832 bytes read in 7 ms (16.5 MiB/s) => bootefi ${kernel_addr_r} ${fdt_addr_r} -The bootefi command uses the device, the file name, and the file size -(environment variable 'filesize') of the most recently loaded file when setting -up the binary for execution. So the UEFI binary should be loaded last. - -The environment variable 'bootargs' is passed as load options in the UEFI system -table. The Linux kernel EFI stub uses the load options as command line -arguments. +When booting from a memory location it is unknown from which file it was loaded. +Therefore the bootefi command uses the device path of the block device partition +or the network adapter and the file name of the most recently loaded PE-COFF +file when setting up the loaded image protocol. Launching a UEFI binary from a FIT image ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/usage/base.rst b/doc/usage/base.rst new file mode 100644 index 0000000000..db9cd4d978 --- /dev/null +++ b/doc/usage/base.rst @@ -0,0 +1,23 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +base command +============ + +Synopsis +-------- + +:: + + base [address] + +Description +----------- + +The *base* command sets or displays the address offset used by the memory +commands *cmp, cp, md, mdc, mm, ms, mw, mwc*. + +All other commands ignore the address defined by *base*. + +address + new base address as hexadecimal number. If no value is provided, the current + value is displayed. diff --git a/doc/usage/fdt_overlays.rst b/doc/usage/fdt_overlays.rst new file mode 100644 index 0000000000..ea39713434 --- /dev/null +++ b/doc/usage/fdt_overlays.rst @@ -0,0 +1,134 @@ +.. SPDX-License-Identifier: GPL-2.0+ +.. Copyright (c) 2017, Pantelis Antoniou <pantelis.antoniou@konsulko.com> + +Device Tree Overlays +==================== + +Overlay Syntax +-------------- + +Device-tree overlays require a slightly different syntax compared to traditional +device-trees. Please refer to dt-object-internal.txt in the device-tree compiler +sources for information regarding the internal format of overlays: +https://git.kernel.org/pub/scm/utils/dtc/dtc.git/tree/Documentation/dt-object-internal.txt + +Building Overlays +----------------- + +In a nutshell overlays provides a means to manipulate a symbol a previous +device-tree or device-tree overlay has defined. It requires both the base +device-tree and all the overlays to be compiled with the *-@* command line +switch of the device-tree compiler so that symbol information is included. + +Note + Support for *-@* option can only be found in dtc version 1.4.4 or newer. + Only version 4.14 or higher of the Linux kernel includes a built in version + of dtc that meets this requirement. + +Building a binary device-tree overlay follows the same process as building a +traditional binary device-tree. For example: + +**base.dts** + +:: + + /dts-v1/; + / { + foo: foonode { + foo-property; + }; + }; + +.. code-block:: console + + $ dtc -@ -I dts -O dtb -o base.dtb base.dts + +**overlay.dts** + +:: + + /dts-v1/; + /plugin/; + / { + fragment@1 { + target = <&foo>; + __overlay__ { + overlay-1-property; + bar: barnode { + bar-property; + }; + }; + }; + }; + +.. code-block:: console + + $ dtc -@ -I dts -O dtb -o overlay.dtbo overlay.dts + +Ways to Utilize Overlays in U-Boot +---------------------------------- + +There are two ways to apply overlays in U-Boot. + +* Include and define overlays within a FIT image and have overlays + automatically applied. + +* Manually load and apply overlays + +The remainder of this document will discuss using overlays via the manual +approach. For information on using overlays as part of a FIT image please see: +doc/uImage.FIT/overlay-fdt-boot.txt + +Manually Loading and Applying Overlays +-------------------------------------- + +1. Figure out where to place both the base device tree blob and the + overlay. Make sure you have enough space to grow the base tree without + overlapping anything. + +:: + + => setenv fdtaddr 0x87f00000 + => setenv fdtovaddr 0x87fc0000 + +2. Load the base binary device-tree and the binary device-tree overlay. + +:: + + => load ${devtype} ${bootpart} ${fdtaddr} ${bootdir}/base.dtb + => load ${devtype} ${bootpart} ${fdtovaddr} ${bootdir}/overlay.dtbo + +3. Set the base binary device-tree as the working fdt tree. + +:: + + => fdtaddr $fdtaddr + +4. Grow it enough so it can encompass all applied overlays + +:: + + => fdt resize 8192 + +5. You are now ready to apply the overlay. + +:: + + => fdt apply $fdtovaddr + +6. Boot system like you would do with a traditional dtb. + +For bootm: + +:: + + => bootm ${kerneladdr} - ${fdtaddr} + +For bootz: + +:: + + => bootz ${kerneladdr} - ${fdtaddr} + +Please note that in case of an error, both the base and overlays are going +to be invalidated, so keep copies to avoid reloading. diff --git a/doc/usage/index.rst b/doc/usage/index.rst index fbb2c0481c..6def250766 100644 --- a/doc/usage/index.rst +++ b/doc/usage/index.rst @@ -2,7 +2,9 @@ Use U-Boot ========== .. toctree:: + :maxdepth: 1 + fdt_overlays netconsole Shell commands @@ -11,7 +13,9 @@ Shell commands .. toctree:: :maxdepth: 1 + base bootefi bootmenu button + mbr pstore diff --git a/doc/usage/mbr.rst b/doc/usage/mbr.rst new file mode 100644 index 0000000000..bddf2f612a --- /dev/null +++ b/doc/usage/mbr.rst @@ -0,0 +1,94 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +mbr command +=========== + +Synopsis +-------- + +:: + + mbr verify [interface] [device no] [partition list] + mbr write [interface] [device no] [partition list] + +Description +----------- + +The mbr command lets users create or verify the MBR (Master Boot Record) +partition layout based on the provided text description. The partition +layout is alternatively read from the 'mbr_parts' environment variable. +This can be used in scripts to help system image flashing tools to ensure +proper partition layout. + +The syntax of the text description of the partition list is similar to +the one used by the 'gpt' command. + +Supported partition parameters are: + +* name (currently ignored) +* start (partition start offset in bytes) +* size (in bytes or '-' to expand it to the whole free area) +* bootable (boolean flag) +* id (MBR partition type) + +If one wants to create more than 4 partitions, an 'Extended' primary +partition (with 0x05 ID) has to be explicitly provided as a one of the +first 4 entries. + +Here is an example how to create a 6 partitions (3 on the 'extended +volume'), some of the predefined sizes: + +:: + + => setenv mbr_parts 'name=boot,start=4M,size=128M,bootable,id=0x0e; + name=rootfs,size=3072M,id=0x83; + name=system-data,size=512M,id=0x83; + name=[ext],size=-,id=0x05; + name=user,size=-,id=0x83; + name=modules,size=100M,id=0x83; + name=ramdisk,size=8M,id=0x83' + => mbr write mmc 0 + +To check if the layout on the MMC #0 storage device matches the provided +text description one has to issue following command (assuming that +mbr_parts environment variable is set): + +:: + + => mbr verify mmc 0 + +The verify sub-command is especially useful in the system update scripts: + +:: + + => if mbr verify mmc 0; then + echo MBR layout needs to be updated + ... + fi + +The 'mbr write' command returns 0 on success write or 1 on failure. + +The 'mbr verify' returns 0 if the layout matches the one on the storage +device or 1 if not. + +Configuration +------------- + +To use the mbr command you must specify CONFIG_CMD_MBR=y. + +Return value +------------ + +The variable *$?* takes the following values + ++---+------------------------------+ +| 0 | mbr write was succesful | ++---+------------------------------+ +| 1 | mbr write failed | ++---+------------------------------+ +| 0 | mbr verify was succesful | ++---+------------------------------+ +| 1 | mbr verify was not succesful | ++---+------------------------------+ +|-1 | invalid arguments | ++---+------------------------------+ diff --git a/doc/usage/pstore.rst b/doc/usage/pstore.rst index 8c4e5274aa..1c8374513a 100644 --- a/doc/usage/pstore.rst +++ b/doc/usage/pstore.rst @@ -1,8 +1,17 @@ .. SPDX-License-Identifier: GPL-2.0+ -PStore command +pstore command ============== +Synopsis +-------- + +:: + + pstore set <addr> <len> [record-size] [console-size] [ftrace-size] [pmsg_size] [ecc-size] + pstore display [record-type] [nb] + pstore save <interface> <dev[:part]> <directory-path> + Design ------ diff --git a/drivers/adc/meson-saradc.c b/drivers/adc/meson-saradc.c index 13a8f49dc5..21db55831d 100644 --- a/drivers/adc/meson-saradc.c +++ b/drivers/adc/meson-saradc.c @@ -282,7 +282,7 @@ static int meson_saradc_read_raw_sample(struct meson_saradc_priv *priv, regmap_read(priv->regmap, MESON_SAR_ADC_FIFO_RD, ®val); 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", + printf("ADC FIFO entry belongs to channel %u instead of %u\n", fifo_chan, channel); return -EINVAL; } @@ -512,8 +512,11 @@ static int meson_saradc_init(struct meson_saradc_priv *priv) * reading the temperature sensor. */ regmap_read(priv->regmap, MESON_SAR_ADC_REG3, ®val); - if (regval & MESON_SAR_ADC_REG3_BL30_INITIALIZED) - return 0; + if (regval & MESON_SAR_ADC_REG3_BL30_INITIALIZED) { + regmap_read(priv->regmap, MESON_SAR_ADC_REG3, ®val); + if (regval & MESON_SAR_ADC_REG3_ADC_EN) + return 0; + } meson_saradc_stop_sample_engine(priv); @@ -711,6 +714,8 @@ static const struct udevice_id meson_saradc_ids[] = { .data = (ulong)&gxl_saradc_data }, { .compatible = "amlogic,meson-gxm-saradc", .data = (ulong)&gxl_saradc_data }, + { .compatible = "amlogic,meson-g12a-saradc", + .data = (ulong)&gxl_saradc_data }, { } }; diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index db06f276ec..4aeaa0cd58 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -165,6 +165,7 @@ source "drivers/clk/exynos/Kconfig" source "drivers/clk/imx/Kconfig" source "drivers/clk/kendryte/Kconfig" source "drivers/clk/meson/Kconfig" +source "drivers/clk/microchip/Kconfig" source "drivers/clk/mvebu/Kconfig" source "drivers/clk/owl/Kconfig" source "drivers/clk/renesas/Kconfig" diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index f8383e523d..645709b855 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -30,6 +30,7 @@ obj-$(CONFIG_$(SPL_TPL_)CLK_INTEL) += intel/ obj-$(CONFIG_CLK_HSDK) += clk-hsdk-cgu.o obj-$(CONFIG_CLK_K210) += kendryte/ obj-$(CONFIG_CLK_MPC83XX) += mpc83xx_clk.o +obj-$(CONFIG_CLK_MPFS) += microchip/ obj-$(CONFIG_CLK_OCTEON) += clk_octeon.o obj-$(CONFIG_CLK_OWL) += owl/ obj-$(CONFIG_CLK_RENESAS) += renesas/ diff --git a/drivers/clk/aspeed/Makefile b/drivers/clk/aspeed/Makefile index 81764b4391..84776e5265 100644 --- a/drivers/clk/aspeed/Makefile +++ b/drivers/clk/aspeed/Makefile @@ -4,3 +4,4 @@ # obj-$(CONFIG_ASPEED_AST2500) += clk_ast2500.o +obj-$(CONFIG_ASPEED_AST2600) += clk_ast2600.o diff --git a/drivers/clk/aspeed/clk_ast2600.c b/drivers/clk/aspeed/clk_ast2600.c new file mode 100644 index 0000000000..f72d384047 --- /dev/null +++ b/drivers/clk/aspeed/clk_ast2600.c @@ -0,0 +1,1173 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) ASPEED Technology Inc. + */ + +#include <common.h> +#include <clk-uclass.h> +#include <dm.h> +#include <asm/io.h> +#include <dm/lists.h> +#include <linux/delay.h> +#include <asm/arch/scu_ast2600.h> +#include <dt-bindings/clock/ast2600-clock.h> +#include <dt-bindings/reset/ast2600-reset.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define CLKIN_25M 25000000UL + +/* MAC Clock Delay settings */ +#define MAC12_DEF_DELAY_1G 0x0041b75d +#define MAC12_DEF_DELAY_100M 0x00417410 +#define MAC12_DEF_DELAY_10M 0x00417410 +#define MAC34_DEF_DELAY_1G 0x0010438a +#define MAC34_DEF_DELAY_100M 0x00104208 +#define MAC34_DEF_DELAY_10M 0x00104208 + +/* + * 3-bit encode of CPU freqeucy + * Some code is duplicated + */ +enum ast2600_cpu_freq { + CPU_FREQ_1200M_1, + CPU_FREQ_1600M_1, + CPU_FREQ_1200M_2, + CPU_FREQ_1600M_2, + CPU_FREQ_800M_1, + CPU_FREQ_800M_2, + CPU_FREQ_800M_3, + CPU_FREQ_800M_4, +}; + +struct ast2600_clk_priv { + struct ast2600_scu *scu; +}; + +/* + * Clock divider/multiplier configuration struct. + * For H-PLL and M-PLL the formula is + * (Output Frequency) = CLKIN * ((M + 1) / (N + 1)) / (P + 1) + * M - Numerator + * N - Denumerator + * P - Post Divider + * They have the same layout in their control register. + * + * D-PLL and D2-PLL have extra divider (OD + 1), which is not + * yet needed and ignored by clock configurations. + */ +union ast2600_pll_reg { + uint32_t w; + struct { + unsigned int m : 13; + unsigned int n : 6; + unsigned int p : 4; + unsigned int off : 1; + unsigned int bypass : 1; + unsigned int reset : 1; + unsigned int reserved : 6; + } b; +}; + +struct ast2600_pll_cfg { + union ast2600_pll_reg reg; + unsigned int ext_reg; +}; + +struct ast2600_pll_desc { + uint32_t in; + uint32_t out; + struct ast2600_pll_cfg cfg; +}; + +static const struct ast2600_pll_desc ast2600_pll_lookup[] = { + { + .in = CLKIN_25M, + .out = 400000000, + .cfg.reg.b.m = 95, + .cfg.reg.b.n = 2, + .cfg.reg.b.p = 1, + .cfg.ext_reg = 0x31, + }, + { + .in = CLKIN_25M, + .out = 200000000, + .cfg.reg.b.m = 127, + .cfg.reg.b.n = 0, + .cfg.reg.b.p = 15, + .cfg.ext_reg = 0x3f, + }, + { + .in = CLKIN_25M, + .out = 334000000, + .cfg.reg.b.m = 667, + .cfg.reg.b.n = 4, + .cfg.reg.b.p = 9, + .cfg.ext_reg = 0x14d, + }, + { + .in = CLKIN_25M, + .out = 1000000000, + .cfg.reg.b.m = 119, + .cfg.reg.b.n = 2, + .cfg.reg.b.p = 0, + .cfg.ext_reg = 0x3d, + }, + { + .in = CLKIN_25M, + .out = 50000000, + .cfg.reg.b.m = 95, + .cfg.reg.b.n = 2, + .cfg.reg.b.p = 15, + .cfg.ext_reg = 0x31, + }, +}; + +/* divisor tables */ +static uint32_t axi_ahb_div0_table[] = { + 3, 2, 3, 4, +}; + +static uint32_t axi_ahb_div1_table[] = { + 3, 4, 6, 8, +}; + +static uint32_t axi_ahb_default_table[] = { + 3, 4, 3, 4, 2, 2, 2, 2, +}; + +extern uint32_t ast2600_get_pll_rate(struct ast2600_scu *scu, int pll_idx) +{ + union ast2600_pll_reg pll_reg; + uint32_t hwstrap1; + uint32_t cpu_freq; + uint32_t mul = 1, div = 1; + + switch (pll_idx) { + case ASPEED_CLK_APLL: + pll_reg.w = readl(&scu->apll); + break; + case ASPEED_CLK_DPLL: + pll_reg.w = readl(&scu->dpll); + break; + case ASPEED_CLK_EPLL: + pll_reg.w = readl(&scu->epll); + break; + case ASPEED_CLK_HPLL: + pll_reg.w = readl(&scu->hpll); + break; + case ASPEED_CLK_MPLL: + pll_reg.w = readl(&scu->mpll); + break; + } + + if (!pll_reg.b.bypass) { + /* F = 25Mhz * [(M + 2) / (n + 1)] / (p + 1) + * HPLL Numerator (M) = fix 0x5F when SCU500[10]=1 + * Fixed 0xBF when SCU500[10]=0 and SCU500[8]=1 + * SCU200[12:0] (default 0x8F) when SCU510[10]=0 and SCU510[8]=0 + * HPLL Denumerator (N) = SCU200[18:13] (default 0x2) + * HPLL Divider (P) = SCU200[22:19] (default 0x0) + * HPLL Bandwidth Adj (NB) = fix 0x2F when SCU500[10]=1 + * Fixed 0x5F when SCU500[10]=0 and SCU500[8]=1 + * SCU204[11:0] (default 0x31) when SCU500[10]=0 and SCU500[8]=0 + */ + if (pll_idx == ASPEED_CLK_HPLL) { + hwstrap1 = readl(&scu->hwstrap1); + cpu_freq = (hwstrap1 & SCU_HWSTRAP1_CPU_FREQ_MASK) >> + SCU_HWSTRAP1_CPU_FREQ_SHIFT; + + switch (cpu_freq) { + case CPU_FREQ_800M_1: + case CPU_FREQ_800M_2: + case CPU_FREQ_800M_3: + case CPU_FREQ_800M_4: + pll_reg.b.m = 0x5f; + break; + case CPU_FREQ_1600M_1: + case CPU_FREQ_1600M_2: + pll_reg.b.m = 0xbf; + break; + default: + pll_reg.b.m = 0x8f; + break; + } + } + + mul = (pll_reg.b.m + 1) / (pll_reg.b.n + 1); + div = (pll_reg.b.p + 1); + } + + return ((CLKIN_25M * mul) / div); +} + +static uint32_t ast2600_get_hclk_rate(struct ast2600_scu *scu) +{ + uint32_t rate = ast2600_get_pll_rate(scu, ASPEED_CLK_HPLL); + uint32_t axi_div, ahb_div; + uint32_t hwstrap1 = readl(&scu->hwstrap1); + uint32_t cpu_freq = (hwstrap1 & SCU_HWSTRAP1_CPU_FREQ_MASK) >> + SCU_HWSTRAP1_CPU_FREQ_SHIFT; + uint32_t axi_ahb_ratio = (hwstrap1 & SCU_HWSTRAP1_AXI_AHB_CLK_RATIO_MASK) >> + SCU_HWSTRAP1_AXI_AHB_CLK_RATIO_SHIFT; + + if (hwstrap1 & SCU_HWSTRAP1_CPU_AXI_CLK_RATIO) { + axi_ahb_div1_table[0] = axi_ahb_default_table[cpu_freq] * 2; + axi_div = 1; + ahb_div = axi_ahb_div1_table[axi_ahb_ratio]; + } else { + axi_ahb_div0_table[0] = axi_ahb_default_table[cpu_freq]; + axi_div = 2; + ahb_div = axi_ahb_div0_table[axi_ahb_ratio]; + } + + return (rate / axi_div / ahb_div); +} + +static uint32_t ast2600_get_bclk_rate(struct ast2600_scu *scu) +{ + uint32_t rate = ast2600_get_pll_rate(scu, ASPEED_CLK_HPLL); + uint32_t clksrc1 = readl(&scu->clksrc1); + uint32_t bclk_div = (clksrc1 & SCU_CLKSRC1_BCLK_DIV_MASK) >> + SCU_CLKSRC1_BCLK_DIV_SHIFT; + + return (rate / ((bclk_div + 1) * 4)); +} + +static uint32_t ast2600_get_pclk1_rate(struct ast2600_scu *scu) +{ + uint32_t rate = ast2600_get_pll_rate(scu, ASPEED_CLK_HPLL); + uint32_t clksrc1 = readl(&scu->clksrc1); + uint32_t pclk_div = (clksrc1 & SCU_CLKSRC1_PCLK_DIV_MASK) >> + SCU_CLKSRC1_PCLK_DIV_SHIFT; + + return (rate / ((pclk_div + 1) * 4)); +} + +static uint32_t ast2600_get_pclk2_rate(struct ast2600_scu *scu) +{ + uint32_t rate = ast2600_get_hclk_rate(scu); + uint32_t clksrc4 = readl(&scu->clksrc4); + uint32_t pclk_div = (clksrc4 & SCU_CLKSRC4_PCLK_DIV_MASK) >> + SCU_CLKSRC4_PCLK_DIV_SHIFT; + + return (rate / ((pclk_div + 1) * 2)); +} + +static uint32_t ast2600_get_uxclk_in_rate(struct ast2600_scu *scu) +{ + uint32_t rate = 0; + uint32_t clksrc5 = readl(&scu->clksrc5); + uint32_t uxclk = (clksrc5 & SCU_CLKSRC5_UXCLK_MASK) >> + SCU_CLKSRC5_UXCLK_SHIFT; + + switch (uxclk) { + case 0: + rate = ast2600_get_pll_rate(scu, ASPEED_CLK_APLL) / 4; + break; + case 1: + rate = ast2600_get_pll_rate(scu, ASPEED_CLK_APLL) / 2; + break; + case 2: + rate = ast2600_get_pll_rate(scu, ASPEED_CLK_APLL); + break; + case 3: + rate = ast2600_get_hclk_rate(scu); + break; + } + + return rate; +} + +static uint32_t ast2600_get_huxclk_in_rate(struct ast2600_scu *scu) +{ + uint32_t rate = 0; + uint32_t clksrc5 = readl(&scu->clksrc5); + uint32_t huxclk = (clksrc5 & SCU_CLKSRC5_HUXCLK_MASK) >> + SCU_CLKSRC5_HUXCLK_SHIFT; + + switch (huxclk) { + case 0: + rate = ast2600_get_pll_rate(scu, ASPEED_CLK_APLL) / 4; + break; + case 1: + rate = ast2600_get_pll_rate(scu, ASPEED_CLK_APLL) / 2; + break; + case 2: + rate = ast2600_get_pll_rate(scu, ASPEED_CLK_APLL); + break; + case 3: + rate = ast2600_get_hclk_rate(scu); + break; + } + + return rate; +} + +static uint32_t ast2600_get_uart_uxclk_rate(struct ast2600_scu *scu) +{ + uint32_t rate = ast2600_get_uxclk_in_rate(scu); + uint32_t uart_clkgen = readl(&scu->uart_clkgen); + uint32_t n = (uart_clkgen & SCU_UART_CLKGEN_N_MASK) >> + SCU_UART_CLKGEN_N_SHIFT; + uint32_t r = (uart_clkgen & SCU_UART_CLKGEN_R_MASK) >> + SCU_UART_CLKGEN_R_SHIFT; + + return ((rate * r) / (n * 2)); +} + +static uint32_t ast2600_get_uart_huxclk_rate(struct ast2600_scu *scu) +{ + uint32_t rate = ast2600_get_huxclk_in_rate(scu); + uint32_t huart_clkgen = readl(&scu->huart_clkgen); + uint32_t n = (huart_clkgen & SCU_HUART_CLKGEN_N_MASK) >> + SCU_HUART_CLKGEN_N_SHIFT; + uint32_t r = (huart_clkgen & SCU_HUART_CLKGEN_R_MASK) >> + SCU_HUART_CLKGEN_R_SHIFT; + + return ((rate * r) / (n * 2)); +} + +static uint32_t ast2600_get_sdio_clk_rate(struct ast2600_scu *scu) +{ + uint32_t rate = 0; + uint32_t clksrc4 = readl(&scu->clksrc4); + uint32_t sdio_div = (clksrc4 & SCU_CLKSRC4_SDIO_DIV_MASK) >> + SCU_CLKSRC4_SDIO_DIV_SHIFT; + + if (clksrc4 & SCU_CLKSRC4_SDIO) + rate = ast2600_get_pll_rate(scu, ASPEED_CLK_APLL); + else + rate = ast2600_get_hclk_rate(scu); + + return (rate / ((sdio_div + 1) * 2)); +} + +static uint32_t ast2600_get_emmc_clk_rate(struct ast2600_scu *scu) +{ + uint32_t rate = ast2600_get_pll_rate(scu, ASPEED_CLK_HPLL); + uint32_t clksrc1 = readl(&scu->clksrc1); + uint32_t emmc_div = (clksrc1 & SCU_CLKSRC1_EMMC_DIV_MASK) >> + SCU_CLKSRC1_EMMC_DIV_SHIFT; + + return (rate / ((emmc_div + 1) * 4)); +} + +static uint32_t ast2600_get_uart_clk_rate(struct ast2600_scu *scu, int uart_idx) +{ + uint32_t rate = 0; + uint32_t uart5_clk = 0; + uint32_t clksrc2 = readl(&scu->clksrc2); + uint32_t clksrc4 = readl(&scu->clksrc4); + uint32_t clksrc5 = readl(&scu->clksrc5); + uint32_t misc_ctrl1 = readl(&scu->misc_ctrl1); + + switch (uart_idx) { + case 1: + case 2: + case 3: + case 4: + case 6: + if (clksrc4 & BIT(uart_idx - 1)) + rate = ast2600_get_uart_huxclk_rate(scu); + else + rate = ast2600_get_uart_uxclk_rate(scu); + break; + case 5: + /* + * SCU0C[12] and SCU304[14] together decide + * the UART5 clock generation + */ + if (misc_ctrl1 & SCU_MISC_CTRL1_UART5_DIV) + uart5_clk = 0x1 << 1; + + if (clksrc2 & SCU_CLKSRC2_UART5) + uart5_clk |= 0x1; + + switch (uart5_clk) { + case 0: + rate = 24000000; + break; + case 1: + rate = 192000000; + break; + case 2: + rate = 24000000 / 13; + break; + case 3: + rate = 192000000 / 13; + break; + } + + break; + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + if (clksrc5 & BIT(uart_idx - 1)) + rate = ast2600_get_uart_huxclk_rate(scu); + else + rate = ast2600_get_uart_uxclk_rate(scu); + break; + } + + return rate; +} + +static ulong ast2600_clk_get_rate(struct clk *clk) +{ + struct ast2600_clk_priv *priv = dev_get_priv(clk->dev); + ulong rate = 0; + + switch (clk->id) { + case ASPEED_CLK_HPLL: + case ASPEED_CLK_EPLL: + case ASPEED_CLK_DPLL: + case ASPEED_CLK_MPLL: + case ASPEED_CLK_APLL: + rate = ast2600_get_pll_rate(priv->scu, clk->id); + break; + case ASPEED_CLK_AHB: + rate = ast2600_get_hclk_rate(priv->scu); + break; + case ASPEED_CLK_APB1: + rate = ast2600_get_pclk1_rate(priv->scu); + break; + case ASPEED_CLK_APB2: + rate = ast2600_get_pclk2_rate(priv->scu); + break; + case ASPEED_CLK_GATE_UART1CLK: + rate = ast2600_get_uart_clk_rate(priv->scu, 1); + break; + case ASPEED_CLK_GATE_UART2CLK: + rate = ast2600_get_uart_clk_rate(priv->scu, 2); + break; + case ASPEED_CLK_GATE_UART3CLK: + rate = ast2600_get_uart_clk_rate(priv->scu, 3); + break; + case ASPEED_CLK_GATE_UART4CLK: + rate = ast2600_get_uart_clk_rate(priv->scu, 4); + break; + case ASPEED_CLK_GATE_UART5CLK: + rate = ast2600_get_uart_clk_rate(priv->scu, 5); + break; + case ASPEED_CLK_BCLK: + rate = ast2600_get_bclk_rate(priv->scu); + break; + case ASPEED_CLK_SDIO: + rate = ast2600_get_sdio_clk_rate(priv->scu); + break; + case ASPEED_CLK_EMMC: + rate = ast2600_get_emmc_clk_rate(priv->scu); + break; + case ASPEED_CLK_UARTX: + rate = ast2600_get_uart_uxclk_rate(priv->scu); + break; + case ASPEED_CLK_HUARTX: + rate = ast2600_get_uart_huxclk_rate(priv->scu); + break; + default: + debug("can't get clk rate\n"); + return -ENOENT; + } + + return rate; +} + +/** + * @brief lookup PLL divider config by input/output rate + * @param[in] *pll - PLL descriptor + * @return true - if PLL divider config is found, false - else + * The function caller shall fill "pll->in" and "pll->out", + * then this function will search the lookup table + * to find a valid PLL divider configuration. + */ +static bool ast2600_search_clock_config(struct ast2600_pll_desc *pll) +{ + uint32_t i; + const struct ast2600_pll_desc *def_desc; + bool is_found = false; + + for (i = 0; i < ARRAY_SIZE(ast2600_pll_lookup); i++) { + def_desc = &ast2600_pll_lookup[i]; + + if (def_desc->in == pll->in && def_desc->out == pll->out) { + is_found = true; + pll->cfg.reg.w = def_desc->cfg.reg.w; + pll->cfg.ext_reg = def_desc->cfg.ext_reg; + break; + } + } + return is_found; +} + +static uint32_t ast2600_configure_pll(struct ast2600_scu *scu, + struct ast2600_pll_cfg *p_cfg, int pll_idx) +{ + uint32_t addr, addr_ext; + uint32_t reg; + + switch (pll_idx) { + case ASPEED_CLK_HPLL: + addr = (uint32_t)(&scu->hpll); + addr_ext = (uint32_t)(&scu->hpll_ext); + break; + case ASPEED_CLK_MPLL: + addr = (uint32_t)(&scu->mpll); + addr_ext = (uint32_t)(&scu->mpll_ext); + break; + case ASPEED_CLK_DPLL: + addr = (uint32_t)(&scu->dpll); + addr_ext = (uint32_t)(&scu->dpll_ext); + break; + case ASPEED_CLK_EPLL: + addr = (uint32_t)(&scu->epll); + addr_ext = (uint32_t)(&scu->epll_ext); + break; + case ASPEED_CLK_APLL: + addr = (uint32_t)(&scu->apll); + addr_ext = (uint32_t)(&scu->apll_ext); + break; + default: + debug("unknown PLL index\n"); + return 1; + } + + p_cfg->reg.b.bypass = 0; + p_cfg->reg.b.off = 1; + p_cfg->reg.b.reset = 1; + + reg = readl(addr); + reg &= ~GENMASK(25, 0); + reg |= p_cfg->reg.w; + writel(reg, addr); + + /* write extend parameter */ + writel(p_cfg->ext_reg, addr_ext); + udelay(100); + p_cfg->reg.b.off = 0; + p_cfg->reg.b.reset = 0; + reg &= ~GENMASK(25, 0); + reg |= p_cfg->reg.w; + writel(reg, addr); + while (!(readl(addr_ext) & BIT(31))) + ; + + return 0; +} + +static uint32_t ast2600_configure_ddr(struct ast2600_scu *scu, ulong rate) +{ + struct ast2600_pll_desc mpll; + + mpll.in = CLKIN_25M; + mpll.out = rate; + if (ast2600_search_clock_config(&mpll) == false) { + printf("error!! unable to find valid DDR clock setting\n"); + return 0; + } + ast2600_configure_pll(scu, &mpll.cfg, ASPEED_CLK_MPLL); + + return ast2600_get_pll_rate(scu, ASPEED_CLK_MPLL); +} + +static ulong ast2600_clk_set_rate(struct clk *clk, ulong rate) +{ + struct ast2600_clk_priv *priv = dev_get_priv(clk->dev); + ulong new_rate; + + switch (clk->id) { + case ASPEED_CLK_MPLL: + new_rate = ast2600_configure_ddr(priv->scu, rate); + break; + default: + return -ENOENT; + } + + return new_rate; +} + +static uint32_t ast2600_configure_mac12_clk(struct ast2600_scu *scu) +{ + /* scu340[25:0]: 1G default delay */ + clrsetbits_le32(&scu->mac12_clk_delay, GENMASK(25, 0), + MAC12_DEF_DELAY_1G); + + /* set 100M/10M default delay */ + writel(MAC12_DEF_DELAY_100M, &scu->mac12_clk_delay_100M); + writel(MAC12_DEF_DELAY_10M, &scu->mac12_clk_delay_10M); + + /* MAC AHB = HPLL / 6 */ + clrsetbits_le32(&scu->clksrc1, SCU_CLKSRC1_MAC_DIV_MASK, + (0x2 << SCU_CLKSRC1_MAC_DIV_SHIFT)); + + return 0; +} + +static uint32_t ast2600_configure_mac34_clk(struct ast2600_scu *scu) +{ + /* + * scu350[31] RGMII 125M source: 0 = from IO pin + * scu350[25:0] MAC 1G delay + */ + clrsetbits_le32(&scu->mac34_clk_delay, (BIT(31) | GENMASK(25, 0)), + MAC34_DEF_DELAY_1G); + writel(MAC34_DEF_DELAY_100M, &scu->mac34_clk_delay_100M); + writel(MAC34_DEF_DELAY_10M, &scu->mac34_clk_delay_10M); + + /* + * clock source seletion and divider + * scu310[26:24] : MAC AHB bus clock = HCLK / 2 + * scu310[18:16] : RMII 50M = HCLK_200M / 4 + */ + clrsetbits_le32(&scu->clksrc4, + (SCU_CLKSRC4_MAC_DIV_MASK | SCU_CLKSRC4_RMII34_DIV_MASK), + ((0x0 << SCU_CLKSRC4_MAC_DIV_SHIFT) + | (0x3 << SCU_CLKSRC4_RMII34_DIV_SHIFT))); + + /* + * set driving strength + * scu458[3:2] : MAC4 driving strength + * scu458[1:0] : MAC3 driving strength + */ + clrsetbits_le32(&scu->pinmux16, + SCU_PINCTRL16_MAC4_DRIVING_MASK | SCU_PINCTRL16_MAC3_DRIVING_MASK, + (0x3 << SCU_PINCTRL16_MAC4_DRIVING_SHIFT) + | (0x3 << SCU_PINCTRL16_MAC3_DRIVING_SHIFT)); + + return 0; +} + +/** + * ast2600 RGMII clock source tree + * 125M from external PAD -------->|\ + * HPLL -->|\ | |---->RGMII 125M for MAC#1 & MAC#2 + * | |---->| divider |---->|/ + + * EPLL -->|/ | + * | + * +---------<-----------|RGMIICK PAD output enable|<-------------+ + * | + * +--------------------------->|\ + * | |----> RGMII 125M for MAC#3 & MAC#4 + * HCLK 200M ---->|divider|---->|/ + * To simplify the control flow: + * 1. RGMII 1/2 always use EPLL as the internal clock source + * 2. RGMII 3/4 always use RGMIICK pad as the RGMII 125M source + * 125M from external PAD -------->|\ + * | |---->RGMII 125M for MAC#1 & MAC#2 + * EPLL---->| divider |--->|/ + + * | + * +<--------------------|RGMIICK PAD output enable|<-------------+ + * | + * +--------------------------->RGMII 125M for MAC#3 & MAC#4 + */ +#define RGMIICK_SRC_PAD 0 +#define RGMIICK_SRC_EPLL 1 /* recommended */ +#define RGMIICK_SRC_HPLL 2 + +#define RGMIICK_DIV2 1 +#define RGMIICK_DIV3 2 +#define RGMIICK_DIV4 3 +#define RGMIICK_DIV5 4 +#define RGMIICK_DIV6 5 +#define RGMIICK_DIV7 6 +#define RGMIICK_DIV8 7 /* recommended */ + +#define RMIICK_DIV4 0 +#define RMIICK_DIV8 1 +#define RMIICK_DIV12 2 +#define RMIICK_DIV16 3 +#define RMIICK_DIV20 4 /* recommended */ +#define RMIICK_DIV24 5 +#define RMIICK_DIV28 6 +#define RMIICK_DIV32 7 + +struct ast2600_mac_clk_div { + uint32_t src; /* 0=external PAD, 1=internal PLL */ + uint32_t fin; /* divider input speed */ + uint32_t n; /* 0=div2, 1=div2, 2=div3, 3=div4,...,7=div8 */ + uint32_t fout; /* fout = fin / n */ +}; + +struct ast2600_mac_clk_div rgmii_clk_defconfig = { + .src = ASPEED_CLK_EPLL, + .fin = 1000000000, + .n = RGMIICK_DIV8, + .fout = 125000000, +}; + +struct ast2600_mac_clk_div rmii_clk_defconfig = { + .src = ASPEED_CLK_EPLL, + .fin = 1000000000, + .n = RMIICK_DIV20, + .fout = 50000000, +}; + +static void ast2600_init_mac_pll(struct ast2600_scu *p_scu, + struct ast2600_mac_clk_div *p_cfg) +{ + struct ast2600_pll_desc pll; + + pll.in = CLKIN_25M; + pll.out = p_cfg->fin; + if (ast2600_search_clock_config(&pll) == false) { + pr_err("unable to find valid ETHNET MAC clock setting\n"); + return; + } + ast2600_configure_pll(p_scu, &pll.cfg, p_cfg->src); +} + +static void ast2600_init_rgmii_clk(struct ast2600_scu *p_scu, + struct ast2600_mac_clk_div *p_cfg) +{ + uint32_t reg_304 = readl(&p_scu->clksrc2); + uint32_t reg_340 = readl(&p_scu->mac12_clk_delay); + uint32_t reg_350 = readl(&p_scu->mac34_clk_delay); + + reg_340 &= ~GENMASK(31, 29); + /* scu340[28]: RGMIICK PAD output enable (to MAC 3/4) */ + reg_340 |= BIT(28); + if (p_cfg->src == ASPEED_CLK_EPLL || p_cfg->src == ASPEED_CLK_HPLL) { + /* + * re-init PLL if the current PLL output frequency doesn't match + * the divider setting + */ + if (p_cfg->fin != ast2600_get_pll_rate(p_scu, p_cfg->src)) + ast2600_init_mac_pll(p_scu, p_cfg); + /* scu340[31]: select RGMII 125M from internal source */ + reg_340 |= BIT(31); + } + + reg_304 &= ~GENMASK(23, 20); + + /* set clock divider */ + reg_304 |= (p_cfg->n & 0x7) << 20; + + /* select internal clock source */ + if (p_cfg->src == ASPEED_CLK_HPLL) + reg_304 |= BIT(23); + + /* RGMII 3/4 clock source select */ + reg_350 &= ~BIT(31); + + writel(reg_304, &p_scu->clksrc2); + writel(reg_340, &p_scu->mac12_clk_delay); + writel(reg_350, &p_scu->mac34_clk_delay); +} + +/** + * ast2600 RMII/NCSI clock source tree + * HPLL -->|\ + * | |---->| divider |----> RMII 50M for MAC#1 & MAC#2 + * EPLL -->|/ + * HCLK(SCLICLK)---->| divider |----> RMII 50M for MAC#3 & MAC#4 + */ +static void ast2600_init_rmii_clk(struct ast2600_scu *p_scu, + struct ast2600_mac_clk_div *p_cfg) +{ + uint32_t clksrc2 = readl(&p_scu->clksrc2); + uint32_t clksrc4 = readl(&p_scu->clksrc4); + + if (p_cfg->src == ASPEED_CLK_EPLL || p_cfg->src == ASPEED_CLK_HPLL) { + /* + * re-init PLL if the current PLL output frequency doesn't match + * the divider setting + */ + if (p_cfg->fin != ast2600_get_pll_rate(p_scu, p_cfg->src)) + ast2600_init_mac_pll(p_scu, p_cfg); + } + + clksrc2 &= ~(SCU_CLKSRC2_RMII12 | SCU_CLKSRC2_RMII12_DIV_MASK); + + /* set RMII 1/2 clock divider */ + clksrc2 |= (p_cfg->n & 0x7) << 16; + + /* RMII clock source selection */ + if (p_cfg->src == ASPEED_CLK_HPLL) + clksrc2 |= SCU_CLKSRC2_RMII12; + + /* set RMII 3/4 clock divider */ + clksrc4 &= ~SCU_CLKSRC4_RMII34_DIV_MASK; + clksrc4 |= (0x3 << SCU_CLKSRC4_RMII34_DIV_SHIFT); + + writel(clksrc2, &p_scu->clksrc2); + writel(clksrc4, &p_scu->clksrc4); +} + +static uint32_t ast2600_configure_mac(struct ast2600_scu *scu, int index) +{ + uint32_t reset_bit; + uint32_t clkgate_bit; + + switch (index) { + case 1: + reset_bit = BIT(ASPEED_RESET_MAC1); + clkgate_bit = SCU_CLKGATE1_MAC1; + writel(reset_bit, &scu->modrst_ctrl1); + udelay(100); + writel(clkgate_bit, &scu->clkgate_clr1); + mdelay(10); + writel(reset_bit, &scu->modrst_clr1); + break; + case 2: + reset_bit = BIT(ASPEED_RESET_MAC2); + clkgate_bit = SCU_CLKGATE1_MAC2; + writel(reset_bit, &scu->modrst_ctrl1); + udelay(100); + writel(clkgate_bit, &scu->clkgate_clr1); + mdelay(10); + writel(reset_bit, &scu->modrst_clr1); + break; + case 3: + reset_bit = BIT(ASPEED_RESET_MAC3 - 32); + clkgate_bit = SCU_CLKGATE2_MAC3; + writel(reset_bit, &scu->modrst_ctrl2); + udelay(100); + writel(clkgate_bit, &scu->clkgate_clr2); + mdelay(10); + writel(reset_bit, &scu->modrst_clr2); + break; + case 4: + reset_bit = BIT(ASPEED_RESET_MAC4 - 32); + clkgate_bit = SCU_CLKGATE2_MAC4; + writel(reset_bit, &scu->modrst_ctrl2); + udelay(100); + writel(clkgate_bit, &scu->clkgate_clr2); + mdelay(10); + writel(reset_bit, &scu->modrst_clr2); + break; + default: + return -EINVAL; + } + + return 0; +} + +static void ast2600_configure_rsa_ecc_clk(struct ast2600_scu *scu) +{ + uint32_t clksrc1 = readl(&scu->clksrc1); + + /* Configure RSA clock = HPLL/3 */ + clksrc1 |= SCU_CLKSRC1_ECC_RSA; + clksrc1 &= ~SCU_CLKSRC1_ECC_RSA_DIV_MASK; + clksrc1 |= (2 << SCU_CLKSRC1_ECC_RSA_DIV_SHIFT); + + writel(clksrc1, &scu->clksrc1); +} + +static ulong ast2600_enable_sdclk(struct ast2600_scu *scu) +{ + uint32_t reset_bit; + uint32_t clkgate_bit; + + reset_bit = BIT(ASPEED_RESET_SD - 32); + clkgate_bit = SCU_CLKGATE2_SDIO; + + writel(reset_bit, &scu->modrst_ctrl2); + udelay(100); + writel(clkgate_bit, &scu->clkgate_clr2); + mdelay(10); + writel(reset_bit, &scu->modrst_clr2); + + return 0; +} + +static ulong ast2600_enable_extsdclk(struct ast2600_scu *scu) +{ + int i = 0; + uint32_t div = 0; + uint32_t rate = 0; + uint32_t clksrc4 = readl(&scu->clksrc4); + + /* + * ast2600 SD controller max clk is 200Mhz + * use apll for clock source 800/4 = 200 + * controller max is 200mhz + */ + rate = ast2600_get_pll_rate(scu, ASPEED_CLK_APLL); + for (i = 0; i < 8; i++) { + div = (i + 1) * 2; + if ((rate / div) <= 200000000) + break; + } + clksrc4 &= ~SCU_CLKSRC4_SDIO_DIV_MASK; + clksrc4 |= (i << SCU_CLKSRC4_SDIO_DIV_SHIFT); + clksrc4 |= SCU_CLKSRC4_SDIO; + writel(clksrc4, &scu->clksrc4); + + setbits_le32(&scu->clksrc4, SCU_CLKSRC4_SDIO_EN); + + return 0; +} + +static ulong ast2600_enable_emmcclk(struct ast2600_scu *scu) +{ + uint32_t reset_bit; + uint32_t clkgate_bit; + + reset_bit = BIT(ASPEED_RESET_EMMC); + clkgate_bit = SCU_CLKGATE1_EMMC; + + writel(reset_bit, &scu->modrst_ctrl1); + udelay(100); + writel(clkgate_bit, &scu->clkgate_clr1); + mdelay(10); + writel(reset_bit, &scu->modrst_clr1); + + return 0; +} + +static ulong ast2600_enable_extemmcclk(struct ast2600_scu *scu) +{ + int i = 0; + uint32_t div = 0; + uint32_t rate = 0; + uint32_t clksrc1 = readl(&scu->clksrc1); + + /* + * ast2600 eMMC controller max clk is 200Mhz + * HPll->1/2->|\ + * |->SCU300[11]->SCU300[14:12][1/N] + + * MPLL------>|/ | + * +----------------------------------------------+ + * | + * +---------> EMMC12C[15:8][1/N]-> eMMC clk + */ + rate = ast2600_get_pll_rate(scu, ASPEED_CLK_MPLL); + for (i = 0; i < 8; i++) { + div = (i + 1) * 2; + if ((rate / div) <= 200000000) + break; + } + + clksrc1 &= ~SCU_CLKSRC1_EMMC_DIV_MASK; + clksrc1 |= (i << SCU_CLKSRC1_EMMC_DIV_SHIFT); + clksrc1 |= SCU_CLKSRC1_EMMC; + writel(clksrc1, &scu->clksrc1); + + setbits_le32(&scu->clksrc1, SCU_CLKSRC1_EMMC_EN); + + return 0; +} + +static ulong ast2600_enable_fsiclk(struct ast2600_scu *scu) +{ + uint32_t reset_bit; + uint32_t clkgate_bit; + + reset_bit = BIT(ASPEED_RESET_FSI % 32); + clkgate_bit = SCU_CLKGATE2_FSI; + + /* The FSI clock is shared between masters. If it's already on + * don't touch it, as that will reset the existing master. + */ + if (!(readl(&scu->clkgate_ctrl2) & clkgate_bit)) { + debug("%s: already running, not touching it\n", __func__); + return 0; + } + + writel(reset_bit, &scu->modrst_ctrl2); + udelay(100); + writel(clkgate_bit, &scu->clkgate_clr2); + mdelay(10); + writel(reset_bit, &scu->modrst_clr2); + + return 0; +} + +static ulong ast2600_enable_usbahclk(struct ast2600_scu *scu) +{ + uint32_t reset_bit; + uint32_t clkgate_bit; + + reset_bit = BIT(ASPEED_RESET_EHCI_P1); + clkgate_bit = SCU_CLKGATE1_USB_HUB; + + writel(reset_bit, &scu->modrst_ctrl1); + udelay(100); + writel(clkgate_bit, &scu->clkgate_ctrl1); + mdelay(20); + writel(reset_bit, &scu->modrst_clr1); + + return 0; +} + +static ulong ast2600_enable_usbbhclk(struct ast2600_scu *scu) +{ + uint32_t reset_bit; + uint32_t clkgate_bit; + + reset_bit = BIT(ASPEED_RESET_EHCI_P2); + clkgate_bit = SCU_CLKGATE1_USB_HOST2; + + writel(reset_bit, &scu->modrst_ctrl1); + udelay(100); + writel(clkgate_bit, &scu->clkgate_clr1); + mdelay(20); + writel(reset_bit, &scu->modrst_clr1); + + return 0; +} + +static int ast2600_clk_enable(struct clk *clk) +{ + struct ast2600_clk_priv *priv = dev_get_priv(clk->dev); + + switch (clk->id) { + case ASPEED_CLK_GATE_MAC1CLK: + ast2600_configure_mac(priv->scu, 1); + break; + case ASPEED_CLK_GATE_MAC2CLK: + ast2600_configure_mac(priv->scu, 2); + break; + case ASPEED_CLK_GATE_MAC3CLK: + ast2600_configure_mac(priv->scu, 3); + break; + case ASPEED_CLK_GATE_MAC4CLK: + ast2600_configure_mac(priv->scu, 4); + break; + case ASPEED_CLK_GATE_SDCLK: + ast2600_enable_sdclk(priv->scu); + break; + case ASPEED_CLK_GATE_SDEXTCLK: + ast2600_enable_extsdclk(priv->scu); + break; + case ASPEED_CLK_GATE_EMMCCLK: + ast2600_enable_emmcclk(priv->scu); + break; + case ASPEED_CLK_GATE_EMMCEXTCLK: + ast2600_enable_extemmcclk(priv->scu); + break; + case ASPEED_CLK_GATE_FSICLK: + ast2600_enable_fsiclk(priv->scu); + break; + case ASPEED_CLK_GATE_USBPORT1CLK: + ast2600_enable_usbahclk(priv->scu); + break; + case ASPEED_CLK_GATE_USBPORT2CLK: + ast2600_enable_usbbhclk(priv->scu); + break; + default: + pr_err("can't enable clk\n"); + return -ENOENT; + } + + return 0; +} + +struct clk_ops ast2600_clk_ops = { + .get_rate = ast2600_clk_get_rate, + .set_rate = ast2600_clk_set_rate, + .enable = ast2600_clk_enable, +}; + +static int ast2600_clk_probe(struct udevice *dev) +{ + struct ast2600_clk_priv *priv = dev_get_priv(dev); + + priv->scu = devfdt_get_addr_ptr(dev); + if (IS_ERR(priv->scu)) + return PTR_ERR(priv->scu); + + ast2600_init_rgmii_clk(priv->scu, &rgmii_clk_defconfig); + ast2600_init_rmii_clk(priv->scu, &rmii_clk_defconfig); + ast2600_configure_mac12_clk(priv->scu); + ast2600_configure_mac34_clk(priv->scu); + ast2600_configure_rsa_ecc_clk(priv->scu); + + return 0; +} + +static int ast2600_clk_bind(struct udevice *dev) +{ + int ret; + + /* The reset driver does not have a device node, so bind it here */ + ret = device_bind_driver(gd->dm_root, "ast_sysreset", "reset", &dev); + if (ret) + debug("Warning: No reset driver: ret=%d\n", ret); + + return 0; +} + +struct aspeed_clks { + ulong id; + const char *name; +}; + +static struct aspeed_clks aspeed_clk_names[] = { + { ASPEED_CLK_HPLL, "hpll" }, + { ASPEED_CLK_MPLL, "mpll" }, + { ASPEED_CLK_APLL, "apll" }, + { ASPEED_CLK_EPLL, "epll" }, + { ASPEED_CLK_DPLL, "dpll" }, + { ASPEED_CLK_AHB, "hclk" }, + { ASPEED_CLK_APB1, "pclk1" }, + { ASPEED_CLK_APB2, "pclk2" }, + { ASPEED_CLK_BCLK, "bclk" }, + { ASPEED_CLK_UARTX, "uxclk" }, + { ASPEED_CLK_HUARTX, "huxclk" }, +}; + +int soc_clk_dump(void) +{ + struct udevice *dev; + struct clk clk; + unsigned long rate; + int i, ret; + + ret = uclass_get_device_by_driver(UCLASS_CLK, DM_DRIVER_GET(aspeed_scu), + &dev); + if (ret) + return ret; + + printf("Clk\t\tHz\n"); + + for (i = 0; i < ARRAY_SIZE(aspeed_clk_names); i++) { + clk.id = aspeed_clk_names[i].id; + ret = clk_request(dev, &clk); + if (ret < 0) { + debug("%s clk_request() failed: %d\n", __func__, ret); + continue; + } + + ret = clk_get_rate(&clk); + rate = ret; + + clk_free(&clk); + + if (ret == -ENOTSUPP) { + printf("clk ID %lu not supported yet\n", + aspeed_clk_names[i].id); + continue; + } + if (ret < 0) { + printf("%s %lu: get_rate err: %d\n", __func__, + aspeed_clk_names[i].id, ret); + continue; + } + + printf("%s(%3lu):\t%lu\n", aspeed_clk_names[i].name, + aspeed_clk_names[i].id, rate); + } + + return 0; +} + +static const struct udevice_id ast2600_clk_ids[] = { + { .compatible = "aspeed,ast2600-scu", }, + { }, +}; + +U_BOOT_DRIVER(aspeed_ast2600_scu) = { + .name = "aspeed_ast2600_scu", + .id = UCLASS_CLK, + .of_match = ast2600_clk_ids, + .priv_auto = sizeof(struct ast2600_clk_priv), + .ops = &ast2600_clk_ops, + .bind = ast2600_clk_bind, + .probe = ast2600_clk_probe, +}; diff --git a/drivers/clk/clk_stm32f.c b/drivers/clk/clk_stm32f.c index 7e67895ab7..e7c26db51c 100644 --- a/drivers/clk/clk_stm32f.c +++ b/drivers/clk/clk_stm32f.c @@ -4,18 +4,19 @@ * Author(s): Vikas Manocha, <vikas.manocha@st.com> for STMicroelectronics. */ +#define LOG_CATEGORY UCLASS_CLK + #include <common.h> #include <clk-uclass.h> #include <dm.h> #include <log.h> #include <stm32_rcc.h> -#include <linux/bitops.h> - #include <asm/io.h> #include <asm/arch/stm32.h> #include <asm/arch/stm32_pwr.h> - +#include <dm/device_compat.h> #include <dt-bindings/mfd/stm32f7-rcc.h> +#include <linux/bitops.h> #define RCC_CR_HSION BIT(0) #define RCC_CR_HSEON BIT(16) @@ -309,7 +310,7 @@ static unsigned long stm32_clk_get_pllsai_rate(struct stm32_clk *priv, >> RCC_PLLSAICFGR_PLLSAIR_SHIFT; break; default: - pr_err("incorrect PLLSAI output %d\n", output); + log_err("incorrect PLLSAI output %d\n", output); return -EINVAL; } @@ -490,7 +491,7 @@ static ulong stm32_clk_get_rate(struct clk *clk) return (sysclk >> stm32_get_apb_shift(regs, APB2)); default: - pr_err("clock index %ld out of range\n", clk->id); + dev_err(clk->dev, "clock index %ld out of range\n", clk->id); return -EINVAL; } } @@ -509,8 +510,9 @@ static ulong stm32_set_rate(struct clk *clk, ulong rate) /* Only set_rate for LTDC clock is implemented */ if (clk->id != STM32F7_APB2_CLOCK(LTDC)) { - pr_err("set_rate not implemented for clock index %ld\n", - clk->id); + dev_err(clk->dev, + "set_rate not implemented for clock index %ld\n", + clk->id); return 0; } @@ -604,8 +606,8 @@ static int stm32_clk_enable(struct clk *clk) u32 offset = clk->id / 32; u32 bit_index = clk->id % 32; - debug("%s: clkid = %ld, offset from AHB1ENR is %d, bit_index = %d\n", - __func__, clk->id, offset, bit_index); + dev_dbg(clk->dev, "clkid = %ld, offset from AHB1ENR is %d, bit_index = %d\n", + clk->id, offset, bit_index); setbits_le32(®s->ahb1enr + offset, BIT(bit_index)); return 0; @@ -618,7 +620,7 @@ static int stm32_clk_probe(struct udevice *dev) struct clk clk; int err; - debug("%s\n", __func__); + dev_dbg(dev, "%s\n", __func__); struct stm32_clk *priv = dev_get_priv(dev); fdt_addr_t addr; @@ -652,14 +654,14 @@ static int stm32_clk_probe(struct udevice *dev) &fixed_clock_dev); if (err) { - pr_err("Can't find fixed clock (%d)", err); + dev_err(dev, "Can't find fixed clock (%d)", err); return err; } err = clk_request(fixed_clock_dev, &clk); if (err) { - pr_err("Can't request %s clk (%d)", fixed_clock_dev->name, - err); + dev_err(dev, "Can't request %s clk (%d)", + fixed_clock_dev->name, err); return err; } @@ -673,8 +675,8 @@ static int stm32_clk_probe(struct udevice *dev) priv->hse_rate = clk_get_rate(&clk); if (priv->hse_rate < 1000000) { - pr_err("%s: unexpected HSE clock rate = %ld \"n", __func__, - priv->hse_rate); + dev_err(dev, "unexpected HSE clock rate = %ld \"n", + priv->hse_rate); return -EINVAL; } @@ -684,8 +686,7 @@ static int stm32_clk_probe(struct udevice *dev) err = dev_read_phandle_with_args(dev, "st,syscfg", NULL, 0, 0, &args); if (err) { - debug("%s: can't find syscon device (%d)\n", __func__, - err); + dev_err(dev, "can't find syscon device (%d)\n", err); return err; } @@ -699,10 +700,10 @@ static int stm32_clk_probe(struct udevice *dev) static int stm32_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args) { - debug("%s(clk=%p)\n", __func__, clk); + dev_dbg(clk->dev, "clk=%p\n", clk); if (args->args_count != 2) { - debug("Invaild args_count: %d\n", args->args_count); + dev_dbg(clk->dev, "Invaild args_count: %d\n", args->args_count); return -EINVAL; } diff --git a/drivers/clk/clk_stm32h7.c b/drivers/clk/clk_stm32h7.c index 0171fe8c11..20b3647099 100644 --- a/drivers/clk/clk_stm32h7.c +++ b/drivers/clk/clk_stm32h7.c @@ -4,6 +4,8 @@ * Author(s): Patrice Chotard, <patrice.chotard@foss.st.com> for STMicroelectronics. */ +#define LOG_CATEGORY UCLASS_CLK + #include <common.h> #include <clk-uclass.h> #include <dm.h> @@ -11,6 +13,7 @@ #include <regmap.h> #include <syscon.h> #include <asm/io.h> +#include <dm/device_compat.h> #include <dm/root.h> #include <linux/bitops.h> @@ -465,18 +468,18 @@ static ulong stm32_get_rate(struct stm32_rcc_regs *regs, enum pllsrc pllsrc) int ret; const char *name = pllsrc_name[pllsrc]; - debug("%s name %s\n", __func__, name); + log_debug("pllsrc name %s\n", name); clk.id = 0; ret = uclass_get_device_by_name(UCLASS_CLK, name, &fixed_clock_dev); if (ret) { - pr_err("Can't find clk %s (%d)", name, ret); + log_err("Can't find clk %s (%d)", name, ret); return 0; } ret = clk_request(fixed_clock_dev, &clk); if (ret) { - pr_err("Can't request %s clk (%d)", name, ret); + log_err("Can't request %s clk (%d)", name, ret); return 0; } @@ -484,8 +487,7 @@ static ulong stm32_get_rate(struct stm32_rcc_regs *regs, enum pllsrc pllsrc) if (pllsrc == HSI) divider = stm32_get_HSI_divider(regs); - debug("%s divider %d rate %ld\n", __func__, - divider, clk_get_rate(&clk)); + log_debug("divider %d rate %ld\n", divider, clk_get_rate(&clk)); return clk_get_rate(&clk) >> divider; }; @@ -516,7 +518,7 @@ static u32 stm32_get_PLL1_rate(struct stm32_rcc_regs *regs, break; case RCC_PLLCKSELR_PLLSRC_NO_CLK: /* shouldn't happen */ - pr_err("wrong value for RCC_PLLCKSELR register\n"); + log_err("wrong value for RCC_PLLCKSELR register\n"); pllsrc = 0; break; } @@ -546,10 +548,10 @@ static u32 stm32_get_PLL1_rate(struct stm32_rcc_regs *regs, vco = (pllsrc / divm1) * divn1; rate = (pllsrc * fracn1) / (divm1 * 8192); - debug("%s divm1 = %d divn1 = %d divp1 = %d divq1 = %d divr1 = %d\n", - __func__, divm1, divn1, divp1, divq1, divr1); - debug("%s fracn1 = %d vco = %ld rate = %ld\n", - __func__, fracn1, vco, rate); + log_debug("divm1 = %d divn1 = %d divp1 = %d divq1 = %d divr1 = %d\n", + divm1, divn1, divp1, divq1, divr1); + log_debug("fracn1 = %d vco = %ld rate = %ld\n", + fracn1, vco, rate); switch (output) { case PLL1_P_CK: @@ -610,7 +612,7 @@ u32 psc = stm32_get_apb_psc(regs, apb); case 16: return sysclk / 4; default: - pr_err("unexpected prescaler value (%d)\n", psc); + log_err("unexpected prescaler value (%d)\n", psc); return 0; } else @@ -623,7 +625,7 @@ u32 psc = stm32_get_apb_psc(regs, apb); case 16: return sysclk / psc; default: - pr_err("unexpected prescaler value (%d)\n", psc); + log_err("unexpected prescaler value (%d)\n", psc); return 0; } }; @@ -665,8 +667,8 @@ static ulong stm32_clk_get_rate(struct clk *clk) if (!sysclk) return sysclk; - debug("%s system clock: source = %d freq = %ld\n", - __func__, source, sysclk); + dev_dbg(clk->dev, "system clock: source = %d freq = %ld\n", + source, sysclk); d1cfgr = readl(®s->d1cfgr); @@ -685,8 +687,8 @@ static ulong stm32_clk_get_rate(struct clk *clk) gate_offset = clk_map[clk->id].gate_offset; - debug("%s clk->id=%ld gate_offset=0x%x sysclk=%ld\n", - __func__, clk->id, gate_offset, sysclk); + dev_dbg(clk->dev, "clk->id=%ld gate_offset=0x%x sysclk=%ld\n", + clk->id, gate_offset, sysclk); switch (gate_offset) { case RCC_AHB3ENR: @@ -704,8 +706,8 @@ static ulong stm32_clk_get_rate(struct clk *clk) sysclk = sysclk / prescaler_table[idx]; } - debug("%s system clock: freq after APB3 prescaler = %ld\n", - __func__, sysclk); + dev_dbg(clk->dev, "system clock: freq after APB3 prescaler = %ld\n", + sysclk); return sysclk; break; @@ -719,8 +721,9 @@ static ulong stm32_clk_get_rate(struct clk *clk) sysclk = sysclk / prescaler_table[idx]; } - debug("%s system clock: freq after APB4 prescaler = %ld\n", - __func__, sysclk); + dev_dbg(clk->dev, + "system clock: freq after APB4 prescaler = %ld\n", + sysclk); return sysclk; break; @@ -741,8 +744,9 @@ static ulong stm32_clk_get_rate(struct clk *clk) return stm32_get_timer_rate(priv, sysclk, APB1); } - debug("%s system clock: freq after APB1 prescaler = %ld\n", - __func__, sysclk); + dev_dbg(clk->dev, + "system clock: freq after APB1 prescaler = %ld\n", + sysclk); return (sysclk / stm32_get_apb_psc(regs, APB1)); break; @@ -758,15 +762,17 @@ static ulong stm32_clk_get_rate(struct clk *clk) return stm32_get_timer_rate(priv, sysclk, APB2); } - debug("%s system clock: freq after APB2 prescaler = %ld\n", - __func__, sysclk); + dev_dbg(clk->dev, + "system clock: freq after APB2 prescaler = %ld\n", + sysclk); return (sysclk / stm32_get_apb_psc(regs, APB2)); break; default: - pr_err("unexpected gate_offset value (0x%x)\n", gate_offset); + dev_err(clk->dev, "unexpected gate_offset value (0x%x)\n", + gate_offset); return -EINVAL; break; } @@ -783,9 +789,9 @@ static int stm32_clk_enable(struct clk *clk) gate_offset = clk_map[clk_id].gate_offset; gate_bit_index = clk_map[clk_id].gate_bit_idx; - debug("%s: clkid=%ld gate offset=0x%x bit_index=%d name=%s\n", - __func__, clk->id, gate_offset, gate_bit_index, - clk_map[clk_id].name); + dev_dbg(clk->dev, "clkid=%ld gate offset=0x%x bit_index=%d name=%s\n", + clk->id, gate_offset, gate_bit_index, + clk_map[clk_id].name); setbits_le32(®s->cr + (gate_offset / 4), BIT(gate_bit_index)); @@ -810,13 +816,13 @@ static int stm32_clk_probe(struct udevice *dev) "st,syscfg", &syscon); if (err) { - pr_err("unable to find syscon device\n"); + dev_err(dev, "unable to find syscon device\n"); return err; } priv->pwr_regmap = syscon_get_regmap(syscon); if (!priv->pwr_regmap) { - pr_err("unable to find regmap\n"); + dev_err(dev, "unable to find regmap\n"); return -ENODEV; } @@ -829,7 +835,7 @@ static int stm32_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args) { if (args->args_count != 1) { - debug("Invaild args_count: %d\n", args->args_count); + dev_dbg(clk->dev, "Invaild args_count: %d\n", args->args_count); return -EINVAL; } @@ -852,7 +858,7 @@ static int stm32_clk_of_xlate(struct clk *clk, clk->id = 0; } - debug("%s clk->id %ld\n", __func__, clk->id); + dev_dbg(clk->dev, "clk->id %ld\n", clk->id); return 0; } diff --git a/drivers/clk/clk_stm32mp1.c b/drivers/clk/clk_stm32mp1.c index 5bea2b60b9..d4f1048591 100644 --- a/drivers/clk/clk_stm32mp1.c +++ b/drivers/clk/clk_stm32mp1.c @@ -3,6 +3,8 @@ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved */ +#define LOG_CATEGORY UCLASS_CLK + #include <common.h> #include <clk-uclass.h> #include <div64.h> @@ -14,12 +16,13 @@ #include <syscon.h> #include <time.h> #include <vsprintf.h> -#include <linux/bitops.h> -#include <linux/io.h> -#include <linux/iopoll.h> #include <asm/arch/sys_proto.h> +#include <dm/device_compat.h> #include <dt-bindings/clock/stm32mp1-clks.h> #include <dt-bindings/clock/stm32mp1-clksrc.h> +#include <linux/bitops.h> +#include <linux/io.h> +#include <linux/iopoll.h> DECLARE_GLOBAL_DATA_PTR; @@ -781,7 +784,7 @@ static const struct stm32mp1_clk_data stm32mp1_data = { static ulong stm32mp1_clk_get_fixed(struct stm32mp1_clk_priv *priv, int idx) { if (idx >= NB_OSC) { - debug("%s: clk id %d not found\n", __func__, idx); + log_debug("clk id %d not found\n", idx); return 0; } @@ -799,7 +802,7 @@ static int stm32mp1_clk_get_id(struct stm32mp1_clk_priv *priv, unsigned long id) } if (i == nb_clks) { - printf("%s: clk id %d not found\n", __func__, (u32)id); + log_err("clk id %d not found\n", (u32)id); return -EINVAL; } @@ -812,8 +815,7 @@ static int stm32mp1_clk_get_sel(struct stm32mp1_clk_priv *priv, const struct stm32mp1_clk_gate *gate = priv->data->gate; if (gate[i].sel > _PARENT_SEL_NB) { - printf("%s: parents for clk id %d not found\n", - __func__, i); + log_err("parents for clk id %d not found\n", i); return -EINVAL; } @@ -858,17 +860,14 @@ static int stm32mp1_clk_get_parent(struct stm32mp1_clk_priv *priv, p = (readl(priv->base + sel[s].offset) >> sel[s].src) & sel[s].msk; if (p < sel[s].nb_parent) { -#ifdef DEBUG - debug("%s: %s clock is the parent %s of clk id %d\n", __func__, - stm32mp1_clk_parent_name[sel[s].parent[p]], - stm32mp1_clk_parent_sel_name[s], - (u32)id); -#endif + log_content("%s clock is the parent %s of clk id %d\n", + stm32mp1_clk_parent_name[sel[s].parent[p]], + stm32mp1_clk_parent_sel_name[s], + (u32)id); return sel[s].parent[p]; } - pr_err("%s: no parents defined for clk id %d\n", - __func__, (u32)id); + log_err("no parents defined for clk id %d\n", (u32)id); return -EINVAL; } @@ -1124,7 +1123,7 @@ static ulong stm32mp1_clk_get(struct stm32mp1_clk_priv *priv, int p) if (!uclass_get_device_by_name(UCLASS_CLK, "ck_dsi_phy", &dev)) { if (clk_request(dev, &clk)) { - pr_err("ck_dsi_phy request"); + log_err("ck_dsi_phy request"); } else { clk.id = 0; clock = clk_get_rate(&clk); @@ -1136,8 +1135,7 @@ static ulong stm32mp1_clk_get(struct stm32mp1_clk_priv *priv, int p) break; } - debug("%s(%d) clock = %lx : %ld kHz\n", - __func__, p, clock, clock / 1000); + log_debug("id=%d clock = %lx : %ld kHz\n", p, clock, clock / 1000); return clock; } @@ -1156,7 +1154,7 @@ static int stm32mp1_clk_enable(struct clk *clk) else setbits_le32(priv->base + gate[i].offset, BIT(gate[i].bit)); - debug("%s: id clock %d has been enabled\n", __func__, (u32)clk->id); + dev_dbg(clk->dev, "%s: id clock %d has been enabled\n", __func__, (u32)clk->id); return 0; } @@ -1177,7 +1175,7 @@ static int stm32mp1_clk_disable(struct clk *clk) else clrbits_le32(priv->base + gate[i].offset, BIT(gate[i].bit)); - debug("%s: id clock %d has been disabled\n", __func__, (u32)clk->id); + dev_dbg(clk->dev, "%s: id clock %d has been disabled\n", __func__, (u32)clk->id); return 0; } @@ -1193,10 +1191,9 @@ static ulong stm32mp1_clk_get_rate(struct clk *clk) rate = stm32mp1_clk_get(priv, p); -#ifdef DEBUG - debug("%s: computed rate for id clock %d is %d (parent is %s)\n", - __func__, (u32)clk->id, (u32)rate, stm32mp1_clk_parent_name[p]); -#endif + dev_vdbg(clk->dev, "computed rate for id clock %d is %d (parent is %s)\n", + (u32)clk->id, (u32)rate, stm32mp1_clk_parent_name[p]); + return rate; } @@ -1335,7 +1332,7 @@ static int stm32mp1_pll1_opp(struct stm32mp1_clk_priv *priv, int clksrc, ret = stm32mp1_get_max_opp_freq(priv, &output_freq); if (ret) { - debug("PLL1 OPP configuration not found (%d).\n", ret); + log_debug("PLL1 OPP configuration not found (%d).\n", ret); return ret; } @@ -1440,8 +1437,8 @@ static int stm32mp1_osc_wait(int enable, fdt_addr_t rcc, u32 offset, TIMEOUT_1S); if (ret) - pr_err("OSC %x @ %x timeout for enable=%d : 0x%x\n", - mask_rdy, address, enable, readl(address)); + log_err("OSC %x @ %x timeout for enable=%d : 0x%x\n", + mask_rdy, address, enable, readl(address)); return ret; } @@ -1529,8 +1526,8 @@ static int stm32mp1_set_hsidiv(fdt_addr_t rcc, u8 hsidiv) val & RCC_OCRDYR_HSIDIVRDY, TIMEOUT_200MS); if (ret) - pr_err("HSIDIV failed @ 0x%x: 0x%x\n", - address, readl(address)); + log_err("HSIDIV failed @ 0x%x: 0x%x\n", + address, readl(address)); return ret; } @@ -1546,7 +1543,7 @@ static int stm32mp1_hsidiv(fdt_addr_t rcc, ulong hsifreq) break; if (hsidiv == 4) { - pr_err("clk-hsi frequency invalid"); + log_err("clk-hsi frequency invalid"); return -1; } @@ -1577,8 +1574,8 @@ static int pll_output(struct stm32mp1_clk_priv *priv, int pll_id, int output) TIMEOUT_200MS); if (ret) { - pr_err("PLL%d start failed @ 0x%x: 0x%x\n", - pll_id, pllxcr, readl(pllxcr)); + log_err("PLL%d start failed @ 0x%x: 0x%x\n", + pll_id, pllxcr, readl(pllxcr)); return ret; } @@ -1640,7 +1637,7 @@ static int pll_config(struct stm32mp1_clk_priv *priv, int pll_id, if (refclk < (stm32mp1_pll[type].refclk_min * 1000000) || refclk > (stm32mp1_pll[type].refclk_max * 1000000)) { - debug("invalid refclk = %x\n", (u32)refclk); + log_err("invalid refclk = %x\n", (u32)refclk); return -EINVAL; } if (type == PLL_800 && refclk >= 8000000) @@ -1736,7 +1733,7 @@ static __maybe_unused int pll_set_rate(struct udevice *dev, divn = (value >> 13) - 1; if (divn < DIVN_MIN || divn > stm32mp1_pll[type].divn_max) { - pr_err("divn invalid = %d", divn); + dev_err(dev, "divn invalid = %d", divn); return -EINVAL; } fracv = value - ((divn + 1) << 13); @@ -1761,8 +1758,8 @@ static int set_clksrc(struct stm32mp1_clk_priv *priv, unsigned int clksrc) ret = readl_poll_timeout(address, val, val & RCC_SELR_SRCRDY, TIMEOUT_200MS); if (ret) - pr_err("CLKSRC %x start failed @ 0x%x: 0x%x\n", - clksrc, address, readl(address)); + log_err("CLKSRC %x start failed @ 0x%x: 0x%x\n", + clksrc, address, readl(address)); return ret; } @@ -1781,7 +1778,7 @@ static void stgen_config(struct stm32mp1_clk_priv *priv) if (cntfid0 != rate) { u64 counter; - pr_debug("System Generic Counter (STGEN) update\n"); + log_debug("System Generic Counter (STGEN) update\n"); clrbits_le32(stgenc + STGENC_CNTCR, STGENC_CNTCR_EN); counter = (u64)readl(stgenc + STGENC_CNTCVL); counter |= ((u64)(readl(stgenc + STGENC_CNTCVU))) << 32; @@ -1807,8 +1804,8 @@ static int set_clkdiv(unsigned int clkdiv, u32 address) ret = readl_poll_timeout(address, val, val & RCC_DIVR_DIVRDY, TIMEOUT_200MS); if (ret) - pr_err("CLKDIV %x start failed @ 0x%x: 0x%x\n", - clkdiv, address, readl(address)); + log_err("CLKDIV %x start failed @ 0x%x: 0x%x\n", + clkdiv, address, readl(address)); return ret; } @@ -1891,13 +1888,13 @@ static int stm32mp1_clktree(struct udevice *dev) /* check mandatory field */ ret = dev_read_u32_array(dev, "st,clksrc", clksrc, CLKSRC_NB); if (ret < 0) { - debug("field st,clksrc invalid: error %d\n", ret); + dev_dbg(dev, "field st,clksrc invalid: error %d\n", ret); return -FDT_ERR_NOTFOUND; } ret = dev_read_u32_array(dev, "st,clkdiv", clkdiv, CLKDIV_NB); if (ret < 0) { - debug("field st,clkdiv invalid: error %d\n", ret); + dev_dbg(dev, "field st,clkdiv invalid: error %d\n", ret); return -FDT_ERR_NOTFOUND; } @@ -1911,11 +1908,11 @@ static int stm32mp1_clktree(struct udevice *dev) pllcfg_valid[i] = ofnode_valid(node); pllcsg_set[i] = false; if (pllcfg_valid[i]) { - debug("DT for PLL %d @ %s\n", i, name); + dev_dbg(dev, "DT for PLL %d @ %s\n", i, name); ret = ofnode_read_u32_array(node, "cfg", pllcfg[i], PLLCFG_NB); if (ret < 0) { - debug("field cfg invalid: error %d\n", ret); + dev_dbg(dev, "field cfg invalid: error %d\n", ret); return -FDT_ERR_NOTFOUND; } pllfracv[i] = ofnode_read_u32_default(node, "frac", 0); @@ -1925,30 +1922,30 @@ static int stm32mp1_clktree(struct udevice *dev) if (!ret) { pllcsg_set[i] = true; } else if (ret != -FDT_ERR_NOTFOUND) { - debug("invalid csg node for pll@%d res=%d\n", - i, ret); + dev_dbg(dev, "invalid csg node for pll@%d res=%d\n", + i, ret); return ret; } } else if (i == _PLL1) { /* use OPP for PLL1 for A7 CPU */ - debug("DT for PLL %d with OPP\n", i); + dev_dbg(dev, "DT for PLL %d with OPP\n", i); ret = stm32mp1_pll1_opp(priv, clksrc[CLKSRC_PLL12], pllcfg[i], &pllfracv[i]); if (ret) { - debug("PLL %d with OPP error = %d\n", i, ret); + dev_dbg(dev, "PLL %d with OPP error = %d\n", i, ret); return ret; } pllcfg_valid[i] = true; } } - debug("configuration MCO\n"); + dev_dbg(dev, "configuration MCO\n"); stm32mp1_mco_csg(priv, clksrc[CLKSRC_MCO1], clkdiv[CLKDIV_MCO1]); stm32mp1_mco_csg(priv, clksrc[CLKSRC_MCO2], clkdiv[CLKDIV_MCO2]); - debug("switch ON osillator\n"); + dev_dbg(dev, "switch ON osillator\n"); /* * switch ON oscillator found in device-tree, * HSI already ON after bootrom @@ -1986,24 +1983,24 @@ static int stm32mp1_clktree(struct udevice *dev) stm32mp1_csi_set(rcc, 1); /* come back to HSI */ - debug("come back to HSI\n"); + dev_dbg(dev, "come back to HSI\n"); set_clksrc(priv, CLK_MPU_HSI); set_clksrc(priv, CLK_AXI_HSI); set_clksrc(priv, CLK_MCU_HSI); - debug("pll stop\n"); + dev_dbg(dev, "pll stop\n"); for (i = 0; i < _PLL_NB; i++) pll_stop(priv, i); /* configure HSIDIV */ - debug("configure HSIDIV\n"); + dev_dbg(dev, "configure HSIDIV\n"); if (priv->osc[_HSI]) { stm32mp1_hsidiv(rcc, priv->osc[_HSI]); stgen_config(priv); } /* select DIV */ - debug("select DIV\n"); + dev_dbg(dev, "select DIV\n"); /* no ready bit when MPUSRC != CLK_MPU_PLL1P_DIV, MPUDIV is disabled */ writel(clkdiv[CLKDIV_MPU] & RCC_DIVR_DIV_MASK, rcc + RCC_MPCKDIVR); set_clkdiv(clkdiv[CLKDIV_AXI], rcc + RCC_AXIDIVR); @@ -2018,17 +2015,17 @@ static int stm32mp1_clktree(struct udevice *dev) writel(clkdiv[CLKDIV_RTC] & RCC_DIVR_DIV_MASK, rcc + RCC_RTCDIVR); /* configure PLLs source */ - debug("configure PLLs source\n"); + dev_dbg(dev, "configure PLLs source\n"); set_clksrc(priv, clksrc[CLKSRC_PLL12]); set_clksrc(priv, clksrc[CLKSRC_PLL3]); set_clksrc(priv, clksrc[CLKSRC_PLL4]); /* configure and start PLLs */ - debug("configure PLLs\n"); + dev_dbg(dev, "configure PLLs\n"); for (i = 0; i < _PLL_NB; i++) { if (!pllcfg_valid[i]) continue; - debug("configure PLL %d\n", i); + dev_dbg(dev, "configure PLL %d\n", i); pll_config(priv, i, pllcfg[i], pllfracv[i]); if (pllcsg_set[i]) pll_csg(priv, i, pllcsg[i]); @@ -2039,7 +2036,7 @@ static int stm32mp1_clktree(struct udevice *dev) for (i = 0; i < _PLL_NB; i++) { if (!pllcfg_valid[i]) continue; - debug("output PLL %d\n", i); + dev_dbg(dev, "output PLL %d\n", i); pll_output(priv, i, pllcfg[i][PLLCFG_O]); } @@ -2048,14 +2045,14 @@ static int stm32mp1_clktree(struct udevice *dev) stm32mp1_lse_wait(rcc); /* configure with expected clock source */ - debug("CLKSRC\n"); + dev_dbg(dev, "CLKSRC\n"); set_clksrc(priv, clksrc[CLKSRC_MPU]); set_clksrc(priv, clksrc[CLKSRC_AXI]); set_clksrc(priv, clksrc[CLKSRC_MCU]); set_rtcsrc(priv, clksrc[CLKSRC_RTC], lse_css); /* configure PKCK */ - debug("PKCK\n"); + dev_dbg(dev, "PKCK\n"); pkcs_cell = dev_read_prop(dev, "st,pkcs", &len); if (pkcs_cell) { bool ckper_disabled = false; @@ -2081,7 +2078,7 @@ static int stm32mp1_clktree(struct udevice *dev) /* STGEN clock source can change with CLK_STGEN_XXX */ stgen_config(priv); - debug("oscillator off\n"); + dev_dbg(dev, "oscillator off\n"); /* switch OFF HSI if not found in device-tree */ if (!priv->osc[_HSI]) stm32mp1_hsi_set(rcc, 0); @@ -2147,14 +2144,12 @@ static ulong stm32mp1_clk_set_rate(struct clk *clk, unsigned long clk_rate) case DSI_PX: break; default: - pr_err("not supported"); + dev_err(clk->dev, "Set of clk %ld not supported", clk->id); return -EINVAL; } p = stm32mp1_clk_get_parent(priv, clk->id); -#ifdef DEBUG - debug("%s: parent = %d:%s\n", __func__, p, stm32mp1_clk_parent_name[p]); -#endif + dev_vdbg(clk->dev, "parent = %d:%s\n", p, stm32mp1_clk_parent_name[p]); if (p < 0) return -EINVAL; @@ -2192,7 +2187,7 @@ static void stm32mp1_osc_clk_init(const char *name, clk.id = 0; if (!uclass_get_device_by_name(UCLASS_CLK, name, &dev)) { if (clk_request(dev, &clk)) - pr_err("%s request", name); + log_err("%s request", name); else priv->osc[index] = clk_get_rate(&clk); } @@ -2214,7 +2209,7 @@ static void stm32mp1_osc_init(struct udevice *dev) for (i = 0; i < NB_OSC; i++) { stm32mp1_osc_clk_init(name[i], priv, i); - debug("%d: %s => %x\n", i, name[i], (u32)priv->osc[i]); + dev_dbg(dev, "%d: %s => %x\n", i, name[i], (u32)priv->osc[i]); } } @@ -2288,11 +2283,11 @@ static int stm32mp1_clk_probe(struct udevice *dev) if (!(gd->flags & GD_FLG_RELOC)) result = stm32mp1_clktree(dev); if (result) - printf("clock tree initialization failed (%d)\n", result); + dev_err(dev, "clock tree initialization failed (%d)\n", result); #endif #ifndef CONFIG_SPL_BUILD -#if defined(DEBUG) +#if defined(VERBOSE_DEBUG) /* display debug information for probe after relocation */ if (gd->flags & GD_FLG_RELOC) stm32mp1_clk_dump(priv); @@ -2306,14 +2301,14 @@ static int stm32mp1_clk_probe(struct udevice *dev) if (gd->flags & GD_FLG_RELOC) { char buf[32]; - printf("Clocks:\n"); - printf("- MPU : %s MHz\n", strmhz(buf, gd->cpu_clk)); - printf("- MCU : %s MHz\n", - strmhz(buf, stm32mp1_clk_get(priv, _CK_MCU))); - printf("- AXI : %s MHz\n", strmhz(buf, gd->bus_clk)); - printf("- PER : %s MHz\n", - strmhz(buf, stm32mp1_clk_get(priv, _CK_PER))); - printf("- DDR : %s MHz\n", strmhz(buf, gd->mem_clk)); + log_info("Clocks:\n"); + log_info("- MPU : %s MHz\n", strmhz(buf, gd->cpu_clk)); + log_info("- MCU : %s MHz\n", + strmhz(buf, stm32mp1_clk_get(priv, _CK_MCU))); + log_info("- AXI : %s MHz\n", strmhz(buf, gd->bus_clk)); + log_info("- PER : %s MHz\n", + strmhz(buf, stm32mp1_clk_get(priv, _CK_PER))); + log_info("- DDR : %s MHz\n", strmhz(buf, gd->mem_clk)); } #endif /* CONFIG_DISPLAY_CPUINFO */ #endif diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile index 237fd17f16..522e724221 100644 --- a/drivers/clk/mediatek/Makefile +++ b/drivers/clk/mediatek/Makefile @@ -7,5 +7,6 @@ obj-$(CONFIG_MT8512) += clk-mt8512.o obj-$(CONFIG_TARGET_MT7623) += clk-mt7623.o obj-$(CONFIG_TARGET_MT7622) += clk-mt7622.o obj-$(CONFIG_TARGET_MT7629) += clk-mt7629.o +obj-$(CONFIG_TARGET_MT8183) += clk-mt8183.o obj-$(CONFIG_TARGET_MT8516) += clk-mt8516.o obj-$(CONFIG_TARGET_MT8518) += clk-mt8518.o diff --git a/drivers/clk/mediatek/clk-mt8183.c b/drivers/clk/mediatek/clk-mt8183.c new file mode 100644 index 0000000000..17e653a1f0 --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8183.c @@ -0,0 +1,823 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * MediaTek clock driver for MT8183 SoC + * + * Copyright (C) 2020 BayLibre, SAS + * Copyright (c) 2020 MediaTek Inc. + * Author: Fabien Parent <fparent@baylibre.com> + * Author: Weiyi Lu <weiyi.lu@mediatek.com> + */ + +#include <common.h> +#include <dm.h> +#include <asm/io.h> +#include <dt-bindings/clock/mt8183-clk.h> + +#include "clk-mtk.h" + +#define MT8183_PLL_FMAX (3800UL * MHZ) +#define MT8183_PLL_FMIN (1500UL * MHZ) + +/* apmixedsys */ +#define PLL(_id, _reg, _pwr_reg, _en_mask, _flags, _rst_bar_mask, _pcwbits, \ + _pcwibits, _pd_reg, _pd_shift, _pcw_reg, _pcw_shift) { \ + .id = _id, \ + .reg = _reg, \ + .pwr_reg = _pwr_reg, \ + .en_mask = _en_mask, \ + .rst_bar_mask = _rst_bar_mask, \ + .fmax = MT8183_PLL_FMAX, \ + .fmin = MT8183_PLL_FMIN, \ + .flags = _flags, \ + .pcwbits = _pcwbits, \ + .pcwibits = _pcwibits, \ + .pd_reg = _pd_reg, \ + .pd_shift = _pd_shift, \ + .pcw_reg = _pcw_reg, \ + .pcw_shift = _pcw_shift, \ + } + +static const struct mtk_pll_data apmixed_plls[] = { + PLL(CLK_APMIXED_ARMPLL_LL, 0x0200, 0x020C, 0x00000001, + HAVE_RST_BAR, BIT(24), 22, 8, 0x0204, 24, + 0x0204, 0), + PLL(CLK_APMIXED_ARMPLL_L, 0x0210, 0x021C, 0x00000001, + HAVE_RST_BAR, BIT(24), 22, 8, 0x0214, 24, + 0x0214, 0), + PLL(CLK_APMIXED_CCIPLL, 0x0290, 0x029C, 0x00000001, + HAVE_RST_BAR, BIT(24), 22, 8, 0x0294, 24, + 0x0294, 0), + PLL(CLK_APMIXED_MAINPLL, 0x0220, 0x022C, 0x00000001, + HAVE_RST_BAR, BIT(24), 22, 8, 0x0224, 24, + 0x0224, 0), + PLL(CLK_APMIXED_UNIV2PLL, 0x0230, 0x023C, 0x00000001, + HAVE_RST_BAR, BIT(24), 22, 8, 0x0234, 24, + 0x0234, 0), + PLL(CLK_APMIXED_MSDCPLL, 0x0250, 0x025C, 0x00000001, + 0, 0, 22, 8, 0x0254, 24, 0x0254, 0), + PLL(CLK_APMIXED_MMPLL, 0x0270, 0x027C, 0x00000001, + HAVE_RST_BAR, BIT(23), 22, 8, 0x0274, 24, + 0x0274, 0), + PLL(CLK_APMIXED_MFGPLL, 0x0240, 0x024C, 0x00000001, + 0, 0, 22, 8, 0x0244, 24, 0x0244, 0), + PLL(CLK_APMIXED_TVDPLL, 0x0260, 0x026C, 0x00000001, + 0, 0, 22, 8, 0x0264, 24, 0x0264, 0), + PLL(CLK_APMIXED_APLL1, 0x02A0, 0x02B0, 0x00000001, + 0, 0, 32, 8, 0x02A0, 1, 0x02A4, 0), + PLL(CLK_APMIXED_APLL2, 0x02b4, 0x02c4, 0x00000001, + 0, 0, 32, 8, 0x02B4, 1, 0x02B8, 0), +}; + +static const struct mtk_fixed_clk top_fixed_clks[] = { + FIXED_CLK(CLK_TOP_CLK26M, CLK_XTAL, 26000000), + FIXED_CLK(CLK_TOP_ULPOSC, CLK_XTAL, 250000), + FIXED_CLK(CLK_TOP_UNIVP_192M, CLK_TOP_UNIVPLL, 192000000), +}; + +static const struct mtk_fixed_factor top_fixed_divs[] = { + FACTOR(CLK_TOP_CLK13M, CLK_TOP_CLK26M, 1, 2, CLK_PARENT_TOPCKGEN), + FACTOR(CLK_TOP_F26M_CK_D2, CLK_TOP_CLK26M, 1, 2, CLK_PARENT_TOPCKGEN), + FACTOR(CLK_TOP_SYSPLL_CK, CLK_APMIXED_MAINPLL, 1, + 1, CLK_PARENT_APMIXED), + FACTOR(CLK_TOP_SYSPLL_D2, CLK_TOP_SYSPLL_CK, 1, + 2, CLK_PARENT_TOPCKGEN), + FACTOR(CLK_TOP_SYSPLL_D3, CLK_APMIXED_MAINPLL, 1, + 3, CLK_PARENT_APMIXED), + FACTOR(CLK_TOP_SYSPLL_D5, CLK_APMIXED_MAINPLL, 1, + 5, CLK_PARENT_APMIXED), + FACTOR(CLK_TOP_SYSPLL_D7, CLK_APMIXED_MAINPLL, 1, + 7, CLK_PARENT_APMIXED), + FACTOR(CLK_TOP_SYSPLL_D2_D2, CLK_TOP_SYSPLL_D2, 1, + 2, CLK_PARENT_TOPCKGEN), + FACTOR(CLK_TOP_SYSPLL_D2_D4, CLK_TOP_SYSPLL_D2, 1, + 4, CLK_PARENT_TOPCKGEN), + FACTOR(CLK_TOP_SYSPLL_D2_D8, CLK_TOP_SYSPLL_D2, 1, + 8, CLK_PARENT_TOPCKGEN), + FACTOR(CLK_TOP_SYSPLL_D2_D16, CLK_TOP_SYSPLL_D2, 1, + 16, CLK_PARENT_TOPCKGEN), + FACTOR(CLK_TOP_SYSPLL_D3_D2, CLK_TOP_SYSPLL_D3, 1, + 2, CLK_PARENT_TOPCKGEN), + FACTOR(CLK_TOP_SYSPLL_D3_D4, CLK_TOP_SYSPLL_D3, 1, + 4, CLK_PARENT_TOPCKGEN), + FACTOR(CLK_TOP_SYSPLL_D3_D8, CLK_TOP_SYSPLL_D3, 1, + 8, CLK_PARENT_TOPCKGEN), + FACTOR(CLK_TOP_SYSPLL_D5_D2, CLK_TOP_SYSPLL_D5, 1, + 2, CLK_PARENT_TOPCKGEN), + FACTOR(CLK_TOP_SYSPLL_D5_D4, CLK_TOP_SYSPLL_D5, 1, + 4, CLK_PARENT_TOPCKGEN), + FACTOR(CLK_TOP_SYSPLL_D7_D2, CLK_TOP_SYSPLL_D7, 1, + 2, CLK_PARENT_TOPCKGEN), + FACTOR(CLK_TOP_SYSPLL_D7_D4, CLK_TOP_SYSPLL_D7, 1, + 4, CLK_PARENT_TOPCKGEN), + FACTOR(CLK_TOP_UNIVPLL_CK, CLK_TOP_UNIVPLL, 1, 1, CLK_PARENT_TOPCKGEN), + FACTOR(CLK_TOP_UNIVPLL_D2, CLK_TOP_UNIVPLL_CK, 1, + 2, CLK_PARENT_TOPCKGEN), + FACTOR(CLK_TOP_UNIVPLL_D3, CLK_TOP_UNIVPLL, 1, 3, CLK_PARENT_TOPCKGEN), + FACTOR(CLK_TOP_UNIVPLL_D5, CLK_TOP_UNIVPLL, 1, 5, CLK_PARENT_TOPCKGEN), + FACTOR(CLK_TOP_UNIVPLL_D7, CLK_TOP_UNIVPLL, 1, 7, CLK_PARENT_TOPCKGEN), + FACTOR(CLK_TOP_UNIVPLL_D2_D2, CLK_TOP_UNIVPLL_D2, 1, + 2, CLK_PARENT_TOPCKGEN), + FACTOR(CLK_TOP_UNIVPLL_D2_D4, CLK_TOP_UNIVPLL_D2, 1, + 4, CLK_PARENT_TOPCKGEN), + FACTOR(CLK_TOP_UNIVPLL_D2_D8, CLK_TOP_UNIVPLL_D2, 1, + 8, CLK_PARENT_TOPCKGEN), + FACTOR(CLK_TOP_UNIVPLL_D3_D2, CLK_TOP_UNIVPLL_D3, 1, + 2, CLK_PARENT_TOPCKGEN), + FACTOR(CLK_TOP_UNIVPLL_D3_D4, CLK_TOP_UNIVPLL_D3, 1, + 4, CLK_PARENT_TOPCKGEN), + FACTOR(CLK_TOP_UNIVPLL_D3_D8, CLK_TOP_UNIVPLL_D3, 1, + 8, CLK_PARENT_TOPCKGEN), + FACTOR(CLK_TOP_UNIVPLL_D5_D2, CLK_TOP_UNIVPLL_D5, 1, + 2, CLK_PARENT_TOPCKGEN), + FACTOR(CLK_TOP_UNIVPLL_D5_D4, CLK_TOP_UNIVPLL_D5, 1, + 4, CLK_PARENT_TOPCKGEN), + FACTOR(CLK_TOP_UNIVPLL_D5_D8, CLK_TOP_UNIVPLL_D5, 1, + 8, CLK_PARENT_TOPCKGEN), + FACTOR(CLK_TOP_UNIVP_192M_CK, CLK_TOP_UNIVP_192M, 1, 1, + CLK_PARENT_TOPCKGEN), + FACTOR(CLK_TOP_UNIVP_192M_D2, CLK_TOP_UNIVP_192M_CK, 1, + 2, CLK_PARENT_TOPCKGEN), + FACTOR(CLK_TOP_UNIVP_192M_D4, CLK_TOP_UNIVP_192M_CK, 1, + 4, CLK_PARENT_TOPCKGEN), + FACTOR(CLK_TOP_UNIVP_192M_D8, CLK_TOP_UNIVP_192M_CK, 1, + 8, CLK_PARENT_TOPCKGEN), + FACTOR(CLK_TOP_UNIVP_192M_D16, CLK_TOP_UNIVP_192M_CK, 1, + 16, CLK_PARENT_TOPCKGEN), + FACTOR(CLK_TOP_UNIVP_192M_D32, CLK_TOP_UNIVP_192M_CK, 1, + 32, CLK_PARENT_TOPCKGEN), + FACTOR(CLK_TOP_APLL1_CK, CLK_APMIXED_APLL1, 1, 1, CLK_PARENT_APMIXED), + FACTOR(CLK_TOP_APLL1_D2, CLK_APMIXED_APLL1, 1, 2, CLK_PARENT_APMIXED), + FACTOR(CLK_TOP_APLL1_D4, CLK_APMIXED_APLL1, 1, 4, CLK_PARENT_APMIXED), + FACTOR(CLK_TOP_APLL1_D8, CLK_APMIXED_APLL1, 1, 8, CLK_PARENT_APMIXED), + FACTOR(CLK_TOP_APLL2_CK, CLK_APMIXED_APLL2, 1, 1, CLK_PARENT_APMIXED), + FACTOR(CLK_TOP_APLL2_D2, CLK_APMIXED_APLL2, 1, 2, CLK_PARENT_APMIXED), + FACTOR(CLK_TOP_APLL2_D4, CLK_APMIXED_APLL2, 1, 4, CLK_PARENT_APMIXED), + FACTOR(CLK_TOP_APLL2_D8, CLK_APMIXED_APLL2, 1, 8, CLK_PARENT_APMIXED), + FACTOR(CLK_TOP_TVDPLL_CK, CLK_APMIXED_TVDPLL, 1, 1, CLK_PARENT_APMIXED), + FACTOR(CLK_TOP_TVDPLL_D2, CLK_TOP_TVDPLL_CK, 1, 2, CLK_PARENT_TOPCKGEN), + FACTOR(CLK_TOP_TVDPLL_D4, CLK_APMIXED_TVDPLL, 1, 4, CLK_PARENT_APMIXED), + FACTOR(CLK_TOP_TVDPLL_D8, CLK_APMIXED_TVDPLL, 1, 8, CLK_PARENT_APMIXED), + FACTOR(CLK_TOP_TVDPLL_D16, CLK_APMIXED_TVDPLL, 1, + 16, CLK_PARENT_APMIXED), + FACTOR(CLK_TOP_MMPLL_CK, CLK_APMIXED_MMPLL, 1, 1, CLK_PARENT_APMIXED), + FACTOR(CLK_TOP_MMPLL_D4, CLK_APMIXED_MMPLL, 1, 4, CLK_PARENT_APMIXED), + FACTOR(CLK_TOP_MMPLL_D4_D2, CLK_TOP_MMPLL_D4, 1, + 2, CLK_PARENT_TOPCKGEN), + FACTOR(CLK_TOP_MMPLL_D4_D4, CLK_TOP_MMPLL_D4, 1, 4, CLK_PARENT_TOPCKGEN), + FACTOR(CLK_TOP_MMPLL_D5, CLK_APMIXED_MMPLL, 1, 5, CLK_PARENT_APMIXED), + FACTOR(CLK_TOP_MMPLL_D5_D2, CLK_TOP_MMPLL_D5, 1, + 2, CLK_PARENT_TOPCKGEN), + FACTOR(CLK_TOP_MMPLL_D5_D4, CLK_TOP_MMPLL_D5, 1, + 4, CLK_PARENT_TOPCKGEN), + FACTOR(CLK_TOP_MMPLL_D6, CLK_APMIXED_MMPLL, 1, 6, CLK_PARENT_APMIXED), + FACTOR(CLK_TOP_MMPLL_D7, CLK_APMIXED_MMPLL, 1, 7, CLK_PARENT_APMIXED), + FACTOR(CLK_TOP_MFGPLL_CK, CLK_APMIXED_MFGPLL, 1, 1, CLK_PARENT_APMIXED), + FACTOR(CLK_TOP_MSDCPLL_CK, CLK_APMIXED_MSDCPLL, 1, + 1, CLK_PARENT_APMIXED), + FACTOR(CLK_TOP_MSDCPLL_D2, CLK_APMIXED_MSDCPLL, 1, + 2, CLK_PARENT_APMIXED), + FACTOR(CLK_TOP_MSDCPLL_D4, CLK_APMIXED_MSDCPLL, 1, + 4, CLK_PARENT_APMIXED), + FACTOR(CLK_TOP_MSDCPLL_D8, CLK_APMIXED_MSDCPLL, 1, + 8, CLK_PARENT_APMIXED), + FACTOR(CLK_TOP_MSDCPLL_D16, CLK_APMIXED_MSDCPLL, 1, + 16, CLK_PARENT_APMIXED), + FACTOR(CLK_TOP_AD_OSC_CK, CLK_TOP_ULPOSC, 1, 1, CLK_PARENT_TOPCKGEN), + FACTOR(CLK_TOP_OSC_D2, CLK_TOP_ULPOSC, 1, 2, CLK_PARENT_TOPCKGEN), + FACTOR(CLK_TOP_OSC_D4, CLK_TOP_ULPOSC, 1, 4, CLK_PARENT_TOPCKGEN), + FACTOR(CLK_TOP_OSC_D8, CLK_TOP_ULPOSC, 1, 8, CLK_PARENT_TOPCKGEN), + FACTOR(CLK_TOP_OSC_D16, CLK_TOP_ULPOSC, 1, 16, CLK_PARENT_TOPCKGEN), + FACTOR(CLK_TOP_UNIVPLL, CLK_APMIXED_UNIV2PLL, 1, 2, CLK_PARENT_APMIXED), + FACTOR(CLK_TOP_UNIVPLL_D3_D16, CLK_TOP_UNIVPLL_D3, 1, + 16, CLK_PARENT_TOPCKGEN), +}; + +static const int axi_parents[] = { + CLK_TOP_CLK26M, + CLK_TOP_SYSPLL_D2_D4, + CLK_TOP_SYSPLL_D7, + CLK_TOP_OSC_D4 +}; + +static const int mm_parents[] = { + CLK_TOP_CLK26M, + CLK_TOP_MMPLL_D7, + CLK_TOP_SYSPLL_D3, + CLK_TOP_UNIVPLL_D2_D2, + CLK_TOP_SYSPLL_D2_D2, + CLK_TOP_SYSPLL_D3_D2 +}; + +static const int img_parents[] = { + CLK_TOP_CLK26M, + CLK_TOP_MMPLL_D6, + CLK_TOP_UNIVPLL_D3, + CLK_TOP_SYSPLL_D3, + CLK_TOP_UNIVPLL_D2_D2, + CLK_TOP_SYSPLL_D2_D2, + CLK_TOP_UNIVPLL_D3_D2, + CLK_TOP_SYSPLL_D3_D2 +}; + +static const int cam_parents[] = { + CLK_TOP_CLK26M, + CLK_TOP_SYSPLL_D2, + CLK_TOP_MMPLL_D6, + CLK_TOP_SYSPLL_D3, + CLK_TOP_MMPLL_D7, + CLK_TOP_UNIVPLL_D3, + CLK_TOP_UNIVPLL_D2_D2, + CLK_TOP_SYSPLL_D2_D2, + CLK_TOP_SYSPLL_D3_D2, + CLK_TOP_UNIVPLL_D3_D2 +}; + +static const int dsp_parents[] = { + CLK_TOP_CLK26M, + CLK_TOP_MMPLL_D6, + CLK_TOP_MMPLL_D7, + CLK_TOP_UNIVPLL_D3, + CLK_TOP_SYSPLL_D3, + CLK_TOP_UNIVPLL_D2_D2, + CLK_TOP_SYSPLL_D2_D2, + CLK_TOP_UNIVPLL_D3_D2, + CLK_TOP_SYSPLL_D3_D2 +}; + +static const int dsp1_parents[] = { + CLK_TOP_CLK26M, + CLK_TOP_MMPLL_D6, + CLK_TOP_MMPLL_D7, + CLK_TOP_UNIVPLL_D3, + CLK_TOP_SYSPLL_D3, + CLK_TOP_UNIVPLL_D2_D2, + CLK_TOP_SYSPLL_D2_D2, + CLK_TOP_UNIVPLL_D3_D2, + CLK_TOP_SYSPLL_D3_D2 +}; + +static const int dsp2_parents[] = { + CLK_TOP_CLK26M, + CLK_TOP_MMPLL_D6, + CLK_TOP_MMPLL_D7, + CLK_TOP_UNIVPLL_D3, + CLK_TOP_SYSPLL_D3, + CLK_TOP_UNIVPLL_D2_D2, + CLK_TOP_SYSPLL_D2_D2, + CLK_TOP_UNIVPLL_D3_D2, + CLK_TOP_SYSPLL_D3_D2 +}; + +static const int ipu_if_parents[] = { + CLK_TOP_CLK26M, + CLK_TOP_MMPLL_D6, + CLK_TOP_MMPLL_D7, + CLK_TOP_UNIVPLL_D3, + CLK_TOP_SYSPLL_D3, + CLK_TOP_UNIVPLL_D2_D2, + CLK_TOP_SYSPLL_D2_D2, + CLK_TOP_UNIVPLL_D3_D2, + CLK_TOP_SYSPLL_D3_D2 +}; + +static const int mfg_parents[] = { + CLK_TOP_CLK26M, + CLK_TOP_MFGPLL_CK, + CLK_TOP_UNIVPLL_D3, + CLK_TOP_SYSPLL_D3 +}; + +static const int f52m_mfg_parents[] = { + CLK_TOP_CLK26M, + CLK_TOP_UNIVPLL_D3_D2, + CLK_TOP_UNIVPLL_D3_D4, + CLK_TOP_UNIVPLL_D3_D8 +}; + +static const int camtg_parents[] = { + CLK_TOP_CLK26M, + CLK_TOP_UNIVP_192M_D8, + CLK_TOP_UNIVPLL_D3_D8, + CLK_TOP_UNIVP_192M_D4, + CLK_TOP_UNIVPLL_D3_D16, + CLK_TOP_F26M_CK_D2, + CLK_TOP_UNIVP_192M_D16, + CLK_TOP_UNIVP_192M_D32 +}; + +static const int camtg2_parents[] = { + CLK_TOP_CLK26M, + CLK_TOP_UNIVP_192M_D8, + CLK_TOP_UNIVPLL_D3_D8, + CLK_TOP_UNIVP_192M_D4, + CLK_TOP_UNIVPLL_D3_D16, + CLK_TOP_F26M_CK_D2, + CLK_TOP_UNIVP_192M_D16, + CLK_TOP_UNIVP_192M_D32 +}; + +static const int camtg3_parents[] = { + CLK_TOP_CLK26M, + CLK_TOP_UNIVP_192M_D8, + CLK_TOP_UNIVPLL_D3_D8, + CLK_TOP_UNIVP_192M_D4, + CLK_TOP_UNIVPLL_D3_D16, + CLK_TOP_F26M_CK_D2, + CLK_TOP_UNIVP_192M_D16, + CLK_TOP_UNIVP_192M_D32 +}; + +static const int camtg4_parents[] = { + CLK_TOP_CLK26M, + CLK_TOP_UNIVP_192M_D8, + CLK_TOP_UNIVPLL_D3_D8, + CLK_TOP_UNIVP_192M_D4, + CLK_TOP_UNIVPLL_D3_D16, + CLK_TOP_F26M_CK_D2, + CLK_TOP_UNIVP_192M_D16, + CLK_TOP_UNIVP_192M_D32 +}; + +static const int uart_parents[] = { + CLK_TOP_CLK26M, + CLK_TOP_UNIVPLL_D3_D8 +}; + +static const int spi_parents[] = { + CLK_TOP_CLK26M, + CLK_TOP_SYSPLL_D5_D2, + CLK_TOP_SYSPLL_D3_D4, + CLK_TOP_MSDCPLL_D4 +}; + +static const int msdc50_hclk_parents[] = { + CLK_TOP_CLK26M, + CLK_TOP_SYSPLL_D2_D2, + CLK_TOP_SYSPLL_D3_D2 +}; + +static const int msdc50_0_parents[] = { + CLK_TOP_CLK26M, + CLK_TOP_MSDCPLL_CK, + CLK_TOP_MSDCPLL_D2, + CLK_TOP_UNIVPLL_D2_D4, + CLK_TOP_SYSPLL_D3_D2, + CLK_TOP_UNIVPLL_D2_D2 +}; + +static const int msdc30_1_parents[] = { + CLK_TOP_CLK26M, + CLK_TOP_UNIVPLL_D3_D2, + CLK_TOP_SYSPLL_D3_D2, + CLK_TOP_SYSPLL_D7, + CLK_TOP_MSDCPLL_D2 +}; + +static const int msdc30_2_parents[] = { + CLK_TOP_CLK26M, + CLK_TOP_UNIVPLL_D3_D2, + CLK_TOP_SYSPLL_D3_D2, + CLK_TOP_SYSPLL_D7, + CLK_TOP_MSDCPLL_D2 +}; + +static const int audio_parents[] = { + CLK_TOP_CLK26M, + CLK_TOP_SYSPLL_D5_D4, + CLK_TOP_SYSPLL_D7_D4, + CLK_TOP_SYSPLL_D2_D16 +}; + +static const int aud_intbus_parents[] = { + CLK_TOP_CLK26M, + CLK_TOP_SYSPLL_D2_D4, + CLK_TOP_SYSPLL_D7_D2 +}; + +static const int pmicspi_parents[] = { + CLK_TOP_CLK26M, + CLK_TOP_SYSPLL_D2_D8, + CLK_TOP_OSC_D8 +}; + +static const int fpwrap_ulposc_parents[] = { + CLK_TOP_CLK26M, + CLK_TOP_OSC_D16, + CLK_TOP_OSC_D4, + CLK_TOP_OSC_D8 +}; + +static const int atb_parents[] = { + CLK_TOP_CLK26M, + CLK_TOP_SYSPLL_D2_D2, + CLK_TOP_SYSPLL_D5 +}; + +static const int sspm_parents[] = { + CLK_TOP_CLK26M, + CLK_TOP_UNIVPLL_D2_D4, + CLK_TOP_SYSPLL_D2_D2, + CLK_TOP_UNIVPLL_D2_D2, + CLK_TOP_SYSPLL_D3 +}; + +static const int dpi0_parents[] = { + CLK_TOP_CLK26M, + CLK_TOP_TVDPLL_D2, + CLK_TOP_TVDPLL_D4, + CLK_TOP_TVDPLL_D8, + CLK_TOP_TVDPLL_D16, + CLK_TOP_UNIVPLL_D5_D2, + CLK_TOP_UNIVPLL_D3_D4, + CLK_TOP_SYSPLL_D3_D4, + CLK_TOP_UNIVPLL_D3_D8 +}; + +static const int scam_parents[] = { + CLK_TOP_CLK26M, + CLK_TOP_SYSPLL_D5_D2 +}; + +static const int disppwm_parents[] = { + CLK_TOP_CLK26M, + CLK_TOP_UNIVPLL_D3_D4, + CLK_TOP_OSC_D2, + CLK_TOP_OSC_D4, + CLK_TOP_OSC_D16 +}; + +static const int usb_top_parents[] = { + CLK_TOP_CLK26M, + CLK_TOP_UNIVPLL_D5_D4, + CLK_TOP_UNIVPLL_D3_D4, + CLK_TOP_UNIVPLL_D5_D2 +}; + +static const int ssusb_top_xhci_parents[] = { + CLK_TOP_CLK26M, + CLK_TOP_UNIVPLL_D5_D4, + CLK_TOP_UNIVPLL_D3_D4, + CLK_TOP_UNIVPLL_D5_D2 +}; + +static const int spm_parents[] = { + CLK_TOP_CLK26M, + CLK_TOP_SYSPLL_D2_D8 +}; + +static const int i2c_parents[] = { + CLK_TOP_CLK26M, + CLK_TOP_SYSPLL_D2_D8, + CLK_TOP_UNIVPLL_D5_D2 +}; + +static const int scp_parents[] = { + CLK_TOP_CLK26M, + CLK_TOP_UNIVPLL_D2_D8, + CLK_TOP_SYSPLL_D5, + CLK_TOP_SYSPLL_D2_D2, + CLK_TOP_UNIVPLL_D2_D2, + CLK_TOP_SYSPLL_D3, + CLK_TOP_UNIVPLL_D3 +}; + +static const int seninf_parents[] = { + CLK_TOP_CLK26M, + CLK_TOP_UNIVPLL_D2_D2, + CLK_TOP_UNIVPLL_D3_D2, + CLK_TOP_UNIVPLL_D2_D4 +}; + +static const int dxcc_parents[] = { + CLK_TOP_CLK26M, + CLK_TOP_SYSPLL_D2_D2, + CLK_TOP_SYSPLL_D2_D4, + CLK_TOP_SYSPLL_D2_D8 +}; + +static const int aud_engen1_parents[] = { + CLK_TOP_CLK26M, + CLK_TOP_APLL1_D2, + CLK_TOP_APLL1_D4, + CLK_TOP_APLL1_D8 +}; + +static const int aud_engen2_parents[] = { + CLK_TOP_CLK26M, + CLK_TOP_APLL2_D2, + CLK_TOP_APLL2_D4, + CLK_TOP_APLL2_D8 +}; + +static const int faes_ufsfde_parents[] = { + CLK_TOP_CLK26M, + CLK_TOP_SYSPLL_D2, + CLK_TOP_SYSPLL_D2_D2, + CLK_TOP_SYSPLL_D3, + CLK_TOP_SYSPLL_D2_D4, + CLK_TOP_UNIVPLL_D3 +}; + +static const int fufs_parents[] = { + CLK_TOP_CLK26M, + CLK_TOP_SYSPLL_D2_D4, + CLK_TOP_SYSPLL_D2_D8, + CLK_TOP_SYSPLL_D2_D16 +}; + +static const int aud_1_parents[] = { + CLK_TOP_CLK26M, + CLK_TOP_APLL1_CK +}; + +static const int aud_2_parents[] = { + CLK_TOP_CLK26M, + CLK_TOP_APLL2_CK +}; + +static const struct mtk_composite top_muxes[] = { + /* CLK_CFG_0 */ + MUX(CLK_TOP_MUX_AXI, axi_parents, 0x40, 0, 2), + MUX(CLK_TOP_MUX_MM, mm_parents, 0x40, 8, 3), + MUX(CLK_TOP_MUX_IMG, img_parents, 0x40, 16, 3), + MUX(CLK_TOP_MUX_CAM, cam_parents, 0x40, 24, 4), + /* CLK_CFG_1 */ + MUX(CLK_TOP_MUX_DSP, dsp_parents, 0x50, 0, 4), + MUX(CLK_TOP_MUX_DSP1, dsp1_parents, 0x50, 8, 4), + MUX(CLK_TOP_MUX_DSP2, dsp2_parents, 0x50, 16, 4), + MUX(CLK_TOP_MUX_IPU_IF, ipu_if_parents, 0x50, 24, 4), + /* CLK_CFG_2 */ + MUX(CLK_TOP_MUX_MFG, mfg_parents, 0x60, 0, 2), + MUX(CLK_TOP_MUX_F52M_MFG, f52m_mfg_parents, 0x60, 8, 2), + MUX(CLK_TOP_MUX_CAMTG, camtg_parents, 0x60, 16, 3), + MUX(CLK_TOP_MUX_CAMTG2, camtg2_parents, 0x60, 24, 3), + /* CLK_CFG_3 */ + MUX(CLK_TOP_MUX_CAMTG3, camtg3_parents, 0x70, 0, 3), + MUX(CLK_TOP_MUX_CAMTG4, camtg4_parents, 0x70, 8, 3), + MUX(CLK_TOP_MUX_UART, uart_parents, 0x70, 16, 1), + MUX(CLK_TOP_MUX_SPI, spi_parents, 0x70, 24, 2), + /* CLK_CFG_4 */ + MUX(CLK_TOP_MUX_MSDC50_0_HCLK, msdc50_hclk_parents, 0x80, 0, 2), + MUX(CLK_TOP_MUX_MSDC50_0, msdc50_0_parents, 0x80, 8, 3), + MUX(CLK_TOP_MUX_MSDC30_1, msdc30_1_parents, 0x80, 16, 3), + MUX(CLK_TOP_MUX_MSDC30_2, msdc30_2_parents, 0x80, 24, 3), + /* CLK_CFG_5 */ + MUX(CLK_TOP_MUX_AUDIO, audio_parents, 0x90, 0, 2), + MUX(CLK_TOP_MUX_AUD_INTBUS, aud_intbus_parents, 0x90, 8, 2), + MUX(CLK_TOP_MUX_PMICSPI, pmicspi_parents, 0x90, 16, 2), + MUX(CLK_TOP_MUX_FPWRAP_ULPOSC, fpwrap_ulposc_parents, 0x90, 24, 2), + /* CLK_CFG_6 */ + MUX(CLK_TOP_MUX_ATB, atb_parents, 0xa0, 0, 2), + MUX(CLK_TOP_MUX_SSPM, sspm_parents, 0xa0, 8, 3), + MUX(CLK_TOP_MUX_DPI0, dpi0_parents, 0xa0, 16, 4), + MUX(CLK_TOP_MUX_SCAM, scam_parents, 0xa0, 24, 1), + /* CLK_CFG_7 */ + MUX(CLK_TOP_MUX_DISP_PWM, disppwm_parents, 0xb0, 0, 3), + MUX(CLK_TOP_MUX_USB_TOP, usb_top_parents, 0xb0, 8, 2), + MUX(CLK_TOP_MUX_SSUSB_TOP_XHCI, ssusb_top_xhci_parents, 0xb0, 16, 2), + MUX(CLK_TOP_MUX_SPM, spm_parents, 0xb0, 24, 1), + /* CLK_CFG_8 */ + MUX(CLK_TOP_MUX_I2C, i2c_parents, 0xc0, 0, 2), + MUX(CLK_TOP_MUX_SCP, scp_parents, 0xc0, 8, 3), + MUX(CLK_TOP_MUX_SENINF, seninf_parents, 0xc0, 16, 2), + MUX(CLK_TOP_MUX_DXCC, dxcc_parents, 0xc0, 24, 2), + /* CLK_CFG_9 */ + MUX(CLK_TOP_MUX_AUD_ENG1, aud_engen1_parents, 0xd0, 0, 2), + MUX(CLK_TOP_MUX_AUD_ENG2, aud_engen2_parents, 0xd0, 8, 2), + MUX(CLK_TOP_MUX_FAES_UFSFDE, faes_ufsfde_parents, 0xd0, 16, 3), + MUX(CLK_TOP_MUX_FUFS, fufs_parents, 0xd0, 24, 2), + /* CLK_CFG_10 */ + MUX(CLK_TOP_MUX_AUD_1, aud_1_parents, 0xe0, 0, 1), + MUX(CLK_TOP_MUX_AUD_2, aud_2_parents, 0xe0, 8, 1), +}; + +static const struct mtk_clk_tree mt8183_clk_tree = { + .xtal_rate = 26 * MHZ, + .xtal2_rate = 26 * MHZ, + .fdivs_offs = CLK_TOP_CLK13M, + .muxes_offs = CLK_TOP_MUX_AXI, + .plls = apmixed_plls, + .fclks = top_fixed_clks, + .fdivs = top_fixed_divs, + .muxes = top_muxes, +}; + +static const struct mtk_gate_regs infra0_cg_regs = { + .set_ofs = 0x80, + .clr_ofs = 0x84, + .sta_ofs = 0x90, +}; + +static const struct mtk_gate_regs infra1_cg_regs = { + .set_ofs = 0x88, + .clr_ofs = 0x8c, + .sta_ofs = 0x94, +}; + +static const struct mtk_gate_regs infra2_cg_regs = { + .set_ofs = 0xa4, + .clr_ofs = 0xa8, + .sta_ofs = 0xac, +}; + +static const struct mtk_gate_regs infra3_cg_regs = { + .set_ofs = 0xc0, + .clr_ofs = 0xc4, + .sta_ofs = 0xc8, +}; + +#define GATE_INFRA0(_id, _parent, _shift) { \ + .id = _id, \ + .parent = _parent, \ + .regs = &infra0_cg_regs, \ + .shift = _shift, \ + .flags = CLK_GATE_SETCLR | CLK_PARENT_TOPCKGEN, \ + } + +#define GATE_INFRA1(_id, _parent, _shift) { \ + .id = _id, \ + .parent = _parent, \ + .regs = &infra1_cg_regs, \ + .shift = _shift, \ + .flags = CLK_GATE_SETCLR | CLK_PARENT_TOPCKGEN, \ + } + +#define GATE_INFRA2(_id, _parent, _shift) { \ + .id = _id, \ + .parent = _parent, \ + .regs = &infra2_cg_regs, \ + .shift = _shift, \ + .flags = CLK_GATE_SETCLR | CLK_PARENT_TOPCKGEN, \ + } + +#define GATE_INFRA3(_id, _parent, _shift) { \ + .id = _id, \ + .parent = _parent, \ + .regs = &infra3_cg_regs, \ + .shift = _shift, \ + .flags = CLK_GATE_SETCLR | CLK_PARENT_TOPCKGEN, \ + } + +static const struct mtk_gate infra_clks[] = { + /* INFRA0 */ + GATE_INFRA0(CLK_INFRA_PMIC_TMR, CLK_TOP_MUX_AXI, 0), + GATE_INFRA0(CLK_INFRA_PMIC_AP, CLK_TOP_MUX_AXI, 1), + GATE_INFRA0(CLK_INFRA_PMIC_MD, CLK_TOP_MUX_AXI, 2), + GATE_INFRA0(CLK_INFRA_PMIC_CONN, CLK_TOP_MUX_AXI, 3), + GATE_INFRA0(CLK_INFRA_SCPSYS, CLK_TOP_MUX_SCP, 4), + GATE_INFRA0(CLK_INFRA_SEJ, CLK_TOP_CLK26M, 5), + GATE_INFRA0(CLK_INFRA_APXGPT, CLK_TOP_MUX_AXI, 6), + GATE_INFRA0(CLK_INFRA_ICUSB, CLK_TOP_MUX_AXI, 8), + GATE_INFRA0(CLK_INFRA_GCE, CLK_TOP_MUX_AXI, 9), + GATE_INFRA0(CLK_INFRA_THERM, CLK_TOP_MUX_AXI, 10), + GATE_INFRA0(CLK_INFRA_I2C0, CLK_TOP_MUX_I2C, 11), + GATE_INFRA0(CLK_INFRA_I2C1, CLK_TOP_MUX_I2C, 12), + GATE_INFRA0(CLK_INFRA_I2C2, CLK_TOP_MUX_I2C, 13), + GATE_INFRA0(CLK_INFRA_I2C3, CLK_TOP_MUX_I2C, 14), + GATE_INFRA0(CLK_INFRA_PWM_HCLK, CLK_TOP_MUX_AXI, 15), + GATE_INFRA0(CLK_INFRA_PWM1, CLK_TOP_MUX_I2C, 16), + GATE_INFRA0(CLK_INFRA_PWM2, CLK_TOP_MUX_I2C, 17), + GATE_INFRA0(CLK_INFRA_PWM3, CLK_TOP_MUX_I2C, 18), + GATE_INFRA0(CLK_INFRA_PWM4, CLK_TOP_MUX_I2C, 19), + GATE_INFRA0(CLK_INFRA_PWM, CLK_TOP_MUX_I2C, 21), + GATE_INFRA0(CLK_INFRA_UART0, CLK_TOP_MUX_UART, 22), + GATE_INFRA0(CLK_INFRA_UART1, CLK_TOP_MUX_UART, 23), + GATE_INFRA0(CLK_INFRA_UART2, CLK_TOP_MUX_UART, 24), + GATE_INFRA0(CLK_INFRA_UART3, CLK_TOP_MUX_UART, 25), + GATE_INFRA0(CLK_INFRA_GCE_26M, CLK_TOP_MUX_AXI, 27), + GATE_INFRA0(CLK_INFRA_CQ_DMA_FPC, CLK_TOP_MUX_AXI, 28), + GATE_INFRA0(CLK_INFRA_BTIF, CLK_TOP_MUX_AXI, 31), + /* INFRA1 */ + GATE_INFRA1(CLK_INFRA_SPI0, CLK_TOP_MUX_SPI, 1), + GATE_INFRA1(CLK_INFRA_MSDC0, CLK_TOP_MUX_MSDC50_0_HCLK, 2), + GATE_INFRA1(CLK_INFRA_MSDC1, CLK_TOP_MUX_AXI, 4), + GATE_INFRA1(CLK_INFRA_MSDC2, CLK_TOP_MUX_AXI, 5), + GATE_INFRA1(CLK_INFRA_MSDC0_SCK, CLK_TOP_MUX_MSDC50_0, 6), + GATE_INFRA1(CLK_INFRA_DVFSRC, CLK_TOP_CLK26M, 7), + GATE_INFRA1(CLK_INFRA_GCPU, CLK_TOP_MUX_AXI, 8), + GATE_INFRA1(CLK_INFRA_TRNG, CLK_TOP_MUX_AXI, 9), + GATE_INFRA1(CLK_INFRA_AUXADC, CLK_TOP_CLK26M, 10), + GATE_INFRA1(CLK_INFRA_CPUM, CLK_TOP_MUX_AXI, 11), + GATE_INFRA1(CLK_INFRA_CCIF1_AP, CLK_TOP_MUX_AXI, 12), + GATE_INFRA1(CLK_INFRA_CCIF1_MD, CLK_TOP_MUX_AXI, 13), + GATE_INFRA1(CLK_INFRA_AUXADC_MD, CLK_TOP_CLK26M, 14), + GATE_INFRA1(CLK_INFRA_MSDC1_SCK, CLK_TOP_MUX_MSDC30_1, 16), + GATE_INFRA1(CLK_INFRA_MSDC2_SCK, CLK_TOP_MUX_MSDC30_2, 17), + GATE_INFRA1(CLK_INFRA_AP_DMA, CLK_TOP_MUX_AXI, 18), + GATE_INFRA1(CLK_INFRA_XIU, CLK_TOP_MUX_AXI, 19), + GATE_INFRA1(CLK_INFRA_DEVICE_APC, CLK_TOP_MUX_AXI, 20), + GATE_INFRA1(CLK_INFRA_CCIF_AP, CLK_TOP_MUX_AXI, 23), + GATE_INFRA1(CLK_INFRA_DEBUGSYS, CLK_TOP_MUX_AXI, 24), + GATE_INFRA1(CLK_INFRA_AUDIO, CLK_TOP_MUX_AXI, 25), + GATE_INFRA1(CLK_INFRA_CCIF_MD, CLK_TOP_MUX_AXI, 26), + GATE_INFRA1(CLK_INFRA_DXCC_SEC_CORE, CLK_TOP_MUX_DXCC, 27), + GATE_INFRA1(CLK_INFRA_DXCC_AO, CLK_TOP_MUX_DXCC, 28), + GATE_INFRA1(CLK_INFRA_DEVMPU_BCLK, CLK_TOP_MUX_AXI, 30), + GATE_INFRA1(CLK_INFRA_DRAMC_F26M, CLK_TOP_CLK26M, 31), + /* INFRA2 */ + GATE_INFRA2(CLK_INFRA_IRTX, CLK_TOP_CLK26M, 0), + GATE_INFRA2(CLK_INFRA_USB, CLK_TOP_MUX_USB_TOP, 1), + GATE_INFRA2(CLK_INFRA_DISP_PWM, CLK_TOP_MUX_AXI, 2), + GATE_INFRA2(CLK_INFRA_CLDMA_BCLK, CLK_TOP_MUX_AXI, 3), + GATE_INFRA2(CLK_INFRA_AUDIO_26M_BCLK, CLK_TOP_CLK26M, 4), + GATE_INFRA2(CLK_INFRA_SPI1, CLK_TOP_MUX_SPI, 6), + GATE_INFRA2(CLK_INFRA_I2C4, CLK_TOP_MUX_I2C, 7), + GATE_INFRA2(CLK_INFRA_MODEM_TEMP_SHARE, CLK_TOP_CLK26M, 8), + GATE_INFRA2(CLK_INFRA_SPI2, CLK_TOP_MUX_SPI, 9), + GATE_INFRA2(CLK_INFRA_SPI3, CLK_TOP_MUX_SPI, 10), + GATE_INFRA2(CLK_INFRA_UNIPRO_SCK, CLK_TOP_MUX_SSUSB_TOP_XHCI, 11), + GATE_INFRA2(CLK_INFRA_UNIPRO_TICK, CLK_TOP_MUX_FUFS, 12), + GATE_INFRA2(CLK_INFRA_UFS_MP_SAP_BCLK, CLK_TOP_MUX_FUFS, 13), + GATE_INFRA2(CLK_INFRA_MD32_BCLK, CLK_TOP_MUX_AXI, 14), + GATE_INFRA2(CLK_INFRA_UNIPRO_MBIST, CLK_TOP_MUX_AXI, 16), + GATE_INFRA2(CLK_INFRA_I2C5, CLK_TOP_MUX_I2C, 18), + GATE_INFRA2(CLK_INFRA_I2C5_ARBITER, CLK_TOP_MUX_I2C, 19), + GATE_INFRA2(CLK_INFRA_I2C5_IMM, CLK_TOP_MUX_I2C, 20), + GATE_INFRA2(CLK_INFRA_I2C1_ARBITER, CLK_TOP_MUX_I2C, 21), + GATE_INFRA2(CLK_INFRA_I2C1_IMM, CLK_TOP_MUX_I2C, 22), + GATE_INFRA2(CLK_INFRA_I2C2_ARBITER, CLK_TOP_MUX_I2C, 23), + GATE_INFRA2(CLK_INFRA_I2C2_IMM, CLK_TOP_MUX_I2C, 24), + GATE_INFRA2(CLK_INFRA_SPI4, CLK_TOP_MUX_SPI, 25), + GATE_INFRA2(CLK_INFRA_SPI5, CLK_TOP_MUX_SPI, 26), + GATE_INFRA2(CLK_INFRA_CQ_DMA, CLK_TOP_MUX_AXI, 27), + GATE_INFRA2(CLK_INFRA_UFS, CLK_TOP_MUX_FUFS, 28), + GATE_INFRA2(CLK_INFRA_AES_UFSFDE, CLK_TOP_MUX_FAES_UFSFDE, 29), + GATE_INFRA2(CLK_INFRA_UFS_TICK, CLK_TOP_MUX_FUFS, 30), + /* INFRA3 */ + GATE_INFRA3(CLK_INFRA_MSDC0_SELF, CLK_TOP_MUX_MSDC50_0, 0), + GATE_INFRA3(CLK_INFRA_MSDC1_SELF, CLK_TOP_MUX_MSDC50_0, 1), + GATE_INFRA3(CLK_INFRA_MSDC2_SELF, CLK_TOP_MUX_MSDC50_0, 2), + GATE_INFRA3(CLK_INFRA_UFS_AXI, CLK_TOP_MUX_AXI, 5), + GATE_INFRA3(CLK_INFRA_I2C6, CLK_TOP_MUX_I2C, 6), + GATE_INFRA3(CLK_INFRA_AP_MSDC0, CLK_TOP_MUX_MSDC50_0_HCLK, 7), + GATE_INFRA3(CLK_INFRA_MD_MSDC0, CLK_TOP_MUX_MSDC50_0_HCLK, 8), + GATE_INFRA3(CLK_INFRA_CCIF2_AP, CLK_TOP_MUX_AXI, 16), + GATE_INFRA3(CLK_INFRA_CCIF2_MD, CLK_TOP_MUX_AXI, 17), + GATE_INFRA3(CLK_INFRA_CCIF3_AP, CLK_TOP_MUX_AXI, 18), + GATE_INFRA3(CLK_INFRA_CCIF3_MD, CLK_TOP_MUX_AXI, 19), + GATE_INFRA3(CLK_INFRA_SEJ_F13M, CLK_TOP_CLK26M, 20), + GATE_INFRA3(CLK_INFRA_AES_BCLK, CLK_TOP_MUX_AXI, 21), + GATE_INFRA3(CLK_INFRA_I2C7, CLK_TOP_MUX_I2C, 22), + GATE_INFRA3(CLK_INFRA_I2C8, CLK_TOP_MUX_I2C, 23), + GATE_INFRA3(CLK_INFRA_FBIST2FPC, CLK_TOP_MUX_MSDC50_0, 24), +}; + +static int mt8183_apmixedsys_probe(struct udevice *dev) +{ + return mtk_common_clk_init(dev, &mt8183_clk_tree); +} + +static int mt8183_topckgen_probe(struct udevice *dev) +{ + return mtk_common_clk_init(dev, &mt8183_clk_tree); +} + +static int mt8183_infracfg_probe(struct udevice *dev) +{ + return mtk_common_clk_gate_init(dev, &mt8183_clk_tree, infra_clks); +} + +static const struct udevice_id mt8183_apmixed_compat[] = { + { .compatible = "mediatek,mt8183-apmixedsys", }, + { } +}; + +static const struct udevice_id mt8183_topckgen_compat[] = { + { .compatible = "mediatek,mt8183-topckgen", }, + { } +}; + +static const struct udevice_id mt8183_infracfg_compat[] = { + { .compatible = "mediatek,mt8183-infracfg", }, + { } +}; + +U_BOOT_DRIVER(mtk_clk_apmixedsys) = { + .name = "mt8183-apmixedsys", + .id = UCLASS_CLK, + .of_match = mt8183_apmixed_compat, + .probe = mt8183_apmixedsys_probe, + .priv_auto = sizeof(struct mtk_clk_priv), + .ops = &mtk_clk_apmixedsys_ops, + .flags = DM_FLAG_PRE_RELOC, +}; + +U_BOOT_DRIVER(mtk_clk_topckgen) = { + .name = "mt8183-topckgen", + .id = UCLASS_CLK, + .of_match = mt8183_topckgen_compat, + .probe = mt8183_topckgen_probe, + .priv_auto = sizeof(struct mtk_clk_priv), + .ops = &mtk_clk_topckgen_ops, + .flags = DM_FLAG_PRE_RELOC, +}; + +U_BOOT_DRIVER(mtk_clk_infracfg) = { + .name = "mt8183-infracfg", + .id = UCLASS_CLK, + .of_match = mt8183_infracfg_compat, + .probe = mt8183_infracfg_probe, + .priv_auto = sizeof(struct mtk_clk_priv), + .ops = &mtk_clk_gate_ops, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile index c873d6976f..7204383e17 100644 --- a/drivers/clk/meson/Makefile +++ b/drivers/clk/meson/Makefile @@ -6,4 +6,5 @@ obj-$(CONFIG_CLK_MESON_GX) += gxbb.o obj-$(CONFIG_CLK_MESON_AXG) += axg.o obj-$(CONFIG_CLK_MESON_G12A) += g12a.o +obj-$(CONFIG_CLK_MESON_G12A) += g12a-ao.o diff --git a/drivers/clk/meson/g12a-ao.c b/drivers/clk/meson/g12a-ao.c new file mode 100644 index 0000000000..0148529e04 --- /dev/null +++ b/drivers/clk/meson/g12a-ao.c @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include <common.h> +#include <log.h> +#include <asm/io.h> +#include <clk-uclass.h> +#include <dm.h> +#include <regmap.h> +#include <syscon.h> +#include <dt-bindings/clock/g12a-aoclkc.h> + +#include "clk_meson.h" + +struct meson_clk { + struct regmap *map; +}; + +#define AO_CLK_GATE0 0x4c +#define AO_SAR_CLK 0x90 + +static struct meson_gate gates[] = { + MESON_GATE(CLKID_AO_SAR_ADC, AO_CLK_GATE0, 8), + MESON_GATE(CLKID_AO_SAR_ADC_CLK, AO_SAR_CLK, 8), +}; + +static int meson_set_gate(struct clk *clk, bool on) +{ + struct meson_clk *priv = dev_get_priv(clk->dev); + struct meson_gate *gate; + + if (clk->id >= ARRAY_SIZE(gates)) + return -ENOENT; + + gate = &gates[clk->id]; + + if (gate->reg == 0) + return 0; + + regmap_update_bits(priv->map, gate->reg, + BIT(gate->bit), on ? BIT(gate->bit) : 0); + + return 0; +} + +static int meson_clk_enable(struct clk *clk) +{ + return meson_set_gate(clk, true); +} + +static int meson_clk_disable(struct clk *clk) +{ + return meson_set_gate(clk, false); +} + +static int meson_clk_probe(struct udevice *dev) +{ + struct meson_clk *priv = dev_get_priv(dev); + + priv->map = syscon_node_to_regmap(dev_ofnode(dev_get_parent(dev))); + if (IS_ERR(priv->map)) + return PTR_ERR(priv->map); + + return 0; +} + +static struct clk_ops meson_clk_ops = { + .disable = meson_clk_disable, + .enable = meson_clk_enable, +}; + +static const struct udevice_id meson_clk_ids[] = { + { .compatible = "amlogic,meson-g12a-aoclkc" }, + { } +}; + +U_BOOT_DRIVER(meson_clk_axg) = { + .name = "meson_clk_g12a_ao", + .id = UCLASS_CLK, + .of_match = meson_clk_ids, + .priv_auto = sizeof(struct meson_clk), + .ops = &meson_clk_ops, + .probe = meson_clk_probe, +}; diff --git a/drivers/clk/microchip/Kconfig b/drivers/clk/microchip/Kconfig new file mode 100644 index 0000000000..b70241559d --- /dev/null +++ b/drivers/clk/microchip/Kconfig @@ -0,0 +1,5 @@ +config CLK_MPFS + bool "Clock support for Microchip PolarFire SoC" + depends on CLK && CLK_CCF + help + This enables support clock driver for Microchip PolarFire SoC platform. diff --git a/drivers/clk/microchip/Makefile b/drivers/clk/microchip/Makefile new file mode 100644 index 0000000000..904b345d75 --- /dev/null +++ b/drivers/clk/microchip/Makefile @@ -0,0 +1 @@ +obj-y += mpfs_clk.o mpfs_clk_cfg.o mpfs_clk_periph.o diff --git a/drivers/clk/microchip/mpfs_clk.c b/drivers/clk/microchip/mpfs_clk.c new file mode 100644 index 0000000000..722c79b7c0 --- /dev/null +++ b/drivers/clk/microchip/mpfs_clk.c @@ -0,0 +1,123 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2020 Microchip Technology Inc. + * Padmarao Begari <padmarao.begari@microchip.com> + */ +#include <common.h> +#include <clk.h> +#include <clk-uclass.h> +#include <dm.h> +#include <log.h> +#include <dm/device.h> +#include <dm/devres.h> +#include <dm/uclass.h> +#include <linux/err.h> + +#include "mpfs_clk.h" + +/* All methods are delegated to CCF clocks */ + +static ulong mpfs_clk_get_rate(struct clk *clk) +{ + struct clk *c; + int err = clk_get_by_id(clk->id, &c); + + if (err) + return err; + return clk_get_rate(c); +} + +static ulong mpfs_clk_set_rate(struct clk *clk, unsigned long rate) +{ + struct clk *c; + int err = clk_get_by_id(clk->id, &c); + + if (err) + return err; + return clk_set_rate(c, rate); +} + +static int mpfs_clk_set_parent(struct clk *clk, struct clk *parent) +{ + struct clk *c, *p; + int err = clk_get_by_id(clk->id, &c); + + if (err) + return err; + + err = clk_get_by_id(parent->id, &p); + if (err) + return err; + + return clk_set_parent(c, p); +} + +static int mpfs_clk_endisable(struct clk *clk, bool enable) +{ + struct clk *c; + int err = clk_get_by_id(clk->id, &c); + + if (err) + return err; + return enable ? clk_enable(c) : clk_disable(c); +} + +static int mpfs_clk_enable(struct clk *clk) +{ + return mpfs_clk_endisable(clk, true); +} + +static int mpfs_clk_disable(struct clk *clk) +{ + return mpfs_clk_endisable(clk, false); +} + +static int mpfs_clk_probe(struct udevice *dev) +{ + int ret; + void __iomem *base; + u32 clk_rate; + const char *parent_clk_name; + struct clk *clk = dev_get_priv(dev); + + base = dev_read_addr_ptr(dev); + if (!base) + return -EINVAL; + + ret = clk_get_by_index(dev, 0, clk); + if (ret) + return ret; + + dev_read_u32(clk->dev, "clock-frequency", &clk_rate); + parent_clk_name = clk->dev->name; + + ret = mpfs_clk_register_cfgs(base, clk_rate, parent_clk_name); + if (ret) + return ret; + + ret = mpfs_clk_register_periphs(base, clk_rate, "clk_ahb"); + + return ret; +} + +static const struct clk_ops mpfs_clk_ops = { + .set_rate = mpfs_clk_set_rate, + .get_rate = mpfs_clk_get_rate, + .set_parent = mpfs_clk_set_parent, + .enable = mpfs_clk_enable, + .disable = mpfs_clk_disable, +}; + +static const struct udevice_id mpfs_of_match[] = { + { .compatible = "microchip,mpfs-clkcfg" }, + { } +}; + +U_BOOT_DRIVER(mpfs_clk) = { + .name = "mpfs_clk", + .id = UCLASS_CLK, + .of_match = mpfs_of_match, + .ops = &mpfs_clk_ops, + .probe = mpfs_clk_probe, + .priv_auto = sizeof(struct clk), +}; diff --git a/drivers/clk/microchip/mpfs_clk.h b/drivers/clk/microchip/mpfs_clk.h new file mode 100644 index 0000000000..8e3fc55ae3 --- /dev/null +++ b/drivers/clk/microchip/mpfs_clk.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2020 Microchip Technology Inc. + * Padmarao Begari <padmarao.begari@microchip.com> + */ +#ifndef __MICROCHIP_MPFS_CLK_H +#define __MICROCHIP_MPFS_CLK_H + +#include <linux/clk-provider.h> +/** + * mpfs_clk_register_cfgs() - register configuration clocks + * + * @base: base address of the mpfs system register. + * @clk_rate: the mpfs pll clock rate. + * @parent_name: a pointer to parent clock name. + * @return zero on success, or a negative error code. + */ +int mpfs_clk_register_cfgs(void __iomem *base, u32 clk_rate, + const char *parent_name); +/** + * mpfs_clk_register_periphs() - register peripheral clocks + * + * @base: base address of the mpfs system register. + * @clk_rate: the mpfs pll clock rate. + * @parent_name: a pointer to parent clock name. + * @return zero on success, or a negative error code. + */ +int mpfs_clk_register_periphs(void __iomem *base, u32 clk_rate, + const char *parent_name); +/** + * divider_get_val() - get the clock divider value + * + * @rate: requested clock rate. + * @parent_rate: parent clock rate. + * @table: a pointer to clock divider table. + * @width: width of the divider bit field. + * @flags: common clock framework flags. + * @return divider value on success, or a negative error code. + */ +int divider_get_val(unsigned long rate, unsigned long parent_rate, + const struct clk_div_table *table, + u8 width, unsigned long flags); + +#endif /* __MICROCHIP_MPFS_CLK_H */ diff --git a/drivers/clk/microchip/mpfs_clk_cfg.c b/drivers/clk/microchip/mpfs_clk_cfg.c new file mode 100644 index 0000000000..fefddd1413 --- /dev/null +++ b/drivers/clk/microchip/mpfs_clk_cfg.c @@ -0,0 +1,152 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2020 Microchip Technology Inc. + * Padmarao Begari <padmarao.begari@microchip.com> + */ +#include <common.h> +#include <clk.h> +#include <clk-uclass.h> +#include <asm/io.h> +#include <dm/device.h> +#include <dm/devres.h> +#include <dm/uclass.h> +#include <dt-bindings/clock/microchip-mpfs-clock.h> +#include <linux/err.h> + +#include "mpfs_clk.h" + +#define MPFS_CFG_CLOCK "mpfs_cfg_clock" + +#define REG_CLOCK_CONFIG_CR 0x08 + +/* CPU and AXI clock divisors */ +static const struct clk_div_table mpfs_div_cpu_axi_table[] = { + { 0, 1 }, { 1, 2 }, { 2, 4 }, { 3, 8 }, + { 0, 0 } +}; + +/* AHB clock divisors */ +static const struct clk_div_table mpfs_div_ahb_table[] = { + { 1, 2 }, { 2, 4}, { 3, 8 }, + { 0, 0 } +}; + +/** + * struct mpfs_cfg_clock - per instance of configuration clock + * @id: index of a configuration clock + * @name: name of a configuration clock + * @shift: shift to the divider bit field of a configuration clock + * @width: width of the divider bit field of a configation clock + * @table: clock divider table instance + * @flags: common clock framework flags + */ +struct mpfs_cfg_clock { + unsigned int id; + const char *name; + u8 shift; + u8 width; + const struct clk_div_table *table; + unsigned long flags; +}; + +/** + * struct mpfs_cfg_hw_clock - hardware configuration clock (cpu, axi, ahb) + * @cfg: configuration clock instance + * @sys_base: base address of the mpfs system register + * @prate: the pll clock rate + * @hw: clock instance + */ +struct mpfs_cfg_hw_clock { + struct mpfs_cfg_clock cfg; + void __iomem *sys_base; + u32 prate; + struct clk hw; +}; + +#define to_mpfs_cfg_clk(_hw) container_of(_hw, struct mpfs_cfg_hw_clock, hw) + +static ulong mpfs_cfg_clk_recalc_rate(struct clk *hw) +{ + struct mpfs_cfg_hw_clock *cfg_hw = to_mpfs_cfg_clk(hw); + struct mpfs_cfg_clock *cfg = &cfg_hw->cfg; + void __iomem *base_addr = cfg_hw->sys_base; + unsigned long rate; + u32 val; + + val = readl(base_addr + REG_CLOCK_CONFIG_CR) >> cfg->shift; + val &= clk_div_mask(cfg->width); + rate = cfg_hw->prate / (1u << val); + hw->rate = rate; + + return rate; +} + +static ulong mpfs_cfg_clk_set_rate(struct clk *hw, ulong rate) +{ + struct mpfs_cfg_hw_clock *cfg_hw = to_mpfs_cfg_clk(hw); + struct mpfs_cfg_clock *cfg = &cfg_hw->cfg; + void __iomem *base_addr = cfg_hw->sys_base; + u32 val; + int divider_setting; + + divider_setting = divider_get_val(rate, cfg_hw->prate, cfg->table, cfg->width, cfg->flags); + + if (divider_setting < 0) + return divider_setting; + + val = readl(base_addr + REG_CLOCK_CONFIG_CR); + val &= ~(clk_div_mask(cfg->width) << cfg_hw->cfg.shift); + val |= divider_setting << cfg->shift; + writel(val, base_addr + REG_CLOCK_CONFIG_CR); + + return clk_get_rate(hw); +} + +#define CLK_CFG(_id, _name, _shift, _width, _table, _flags) { \ + .cfg.id = _id, \ + .cfg.name = _name, \ + .cfg.shift = _shift, \ + .cfg.width = _width, \ + .cfg.table = _table, \ + .cfg.flags = _flags, \ + } + +static struct mpfs_cfg_hw_clock mpfs_cfg_clks[] = { + CLK_CFG(CLK_CPU, "clk_cpu", 0, 2, mpfs_div_cpu_axi_table, 0), + CLK_CFG(CLK_AXI, "clk_axi", 2, 2, mpfs_div_cpu_axi_table, 0), + CLK_CFG(CLK_AHB, "clk_ahb", 4, 2, mpfs_div_ahb_table, 0), +}; + +int mpfs_clk_register_cfgs(void __iomem *base, u32 clk_rate, + const char *parent_name) +{ + int ret; + int i, id, num_clks; + const char *name; + struct clk *hw; + + num_clks = ARRAY_SIZE(mpfs_cfg_clks); + for (i = 0; i < num_clks; i++) { + hw = &mpfs_cfg_clks[i].hw; + mpfs_cfg_clks[i].sys_base = base; + mpfs_cfg_clks[i].prate = clk_rate; + name = mpfs_cfg_clks[i].cfg.name; + ret = clk_register(hw, MPFS_CFG_CLOCK, name, parent_name); + if (ret) + ERR_PTR(ret); + id = mpfs_cfg_clks[i].cfg.id; + clk_dm(id, hw); + } + return 0; +} + +const struct clk_ops mpfs_cfg_clk_ops = { + .set_rate = mpfs_cfg_clk_set_rate, + .get_rate = mpfs_cfg_clk_recalc_rate, +}; + +U_BOOT_DRIVER(mpfs_cfg_clock) = { + .name = MPFS_CFG_CLOCK, + .id = UCLASS_CLK, + .ops = &mpfs_cfg_clk_ops, +}; diff --git a/drivers/clk/microchip/mpfs_clk_periph.c b/drivers/clk/microchip/mpfs_clk_periph.c new file mode 100644 index 0000000000..61d90eb4a8 --- /dev/null +++ b/drivers/clk/microchip/mpfs_clk_periph.c @@ -0,0 +1,187 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2020 Microchip Technology Inc. + * Padmarao Begari <padmarao.begari@microchip.com> + */ +#include <common.h> +#include <clk.h> +#include <clk-uclass.h> +#include <asm/io.h> +#include <dm/device.h> +#include <dm/devres.h> +#include <dm/uclass.h> +#include <dt-bindings/clock/microchip-mpfs-clock.h> +#include <linux/err.h> + +#include "mpfs_clk.h" + +#define MPFS_PERIPH_CLOCK "mpfs_periph_clock" + +#define REG_CLOCK_CONFIG_CR 0x08 +#define REG_SUBBLK_CLOCK_CR 0x84 +#define REG_SUBBLK_RESET_CR 0x88 + +#define CFG_CPU_SHIFT 0x0 +#define CFG_AXI_SHIFT 0x2 +#define CFG_AHB_SHIFT 0x4 +#define CFG_WIDTH 0x2 + +/** + * struct mpfs_periph_clock - per instance of peripheral clock + * @id: index of a peripheral clock + * @name: name of a peripheral clock + * @shift: shift to a peripheral clock bit field + * @flags: common clock framework flags + */ +struct mpfs_periph_clock { + unsigned int id; + const char *name; + u8 shift; + unsigned long flags; +}; + +/** + * struct mpfs_periph_hw_clock - hardware peripheral clock + * @periph: peripheral clock instance + * @sys_base: base address of the mpfs system register + * @prate: the pll clock rate + * @hw: clock instance + */ +struct mpfs_periph_hw_clock { + struct mpfs_periph_clock periph; + void __iomem *sys_base; + u32 prate; + struct clk hw; +}; + +#define to_mpfs_periph_clk(_hw) container_of(_hw, struct mpfs_periph_hw_clock, hw) + +static int mpfs_periph_clk_enable(struct clk *hw) +{ + struct mpfs_periph_hw_clock *periph_hw = to_mpfs_periph_clk(hw); + struct mpfs_periph_clock *periph = &periph_hw->periph; + void __iomem *base_addr = periph_hw->sys_base; + u32 reg, val; + + if (periph->flags != CLK_IS_CRITICAL) { + reg = readl(base_addr + REG_SUBBLK_RESET_CR); + val = reg & ~(1u << periph->shift); + writel(val, base_addr + REG_SUBBLK_RESET_CR); + + reg = readl(base_addr + REG_SUBBLK_CLOCK_CR); + val = reg | (1u << periph->shift); + writel(val, base_addr + REG_SUBBLK_CLOCK_CR); + } + + return 0; +} + +static int mpfs_periph_clk_disable(struct clk *hw) +{ + struct mpfs_periph_hw_clock *periph_hw = to_mpfs_periph_clk(hw); + struct mpfs_periph_clock *periph = &periph_hw->periph; + void __iomem *base_addr = periph_hw->sys_base; + u32 reg, val; + + if (periph->flags != CLK_IS_CRITICAL) { + reg = readl(base_addr + REG_SUBBLK_RESET_CR); + val = reg | (1u << periph->shift); + writel(val, base_addr + REG_SUBBLK_RESET_CR); + + reg = readl(base_addr + REG_SUBBLK_CLOCK_CR); + val = reg & ~(1u << periph->shift); + writel(val, base_addr + REG_SUBBLK_CLOCK_CR); + } + + return 0; +} + +static ulong mpfs_periph_clk_recalc_rate(struct clk *hw) +{ + struct mpfs_periph_hw_clock *periph_hw = to_mpfs_periph_clk(hw); + void __iomem *base_addr = periph_hw->sys_base; + unsigned long rate; + u32 val; + + val = readl(base_addr + REG_CLOCK_CONFIG_CR) >> CFG_AHB_SHIFT; + val &= clk_div_mask(CFG_WIDTH); + rate = periph_hw->prate / (1u << val); + hw->rate = rate; + + return rate; +} + +#define CLK_PERIPH(_id, _name, _shift, _flags) { \ + .periph.id = _id, \ + .periph.name = _name, \ + .periph.shift = _shift, \ + .periph.flags = _flags, \ + } + +static struct mpfs_periph_hw_clock mpfs_periph_clks[] = { + CLK_PERIPH(CLK_ENVM, "clk_periph_envm", 0, CLK_IS_CRITICAL), + CLK_PERIPH(CLK_MAC0, "clk_periph_mac0", 1, 0), + CLK_PERIPH(CLK_MAC1, "clk_periph_mac1", 2, 0), + CLK_PERIPH(CLK_MMC, "clk_periph_mmc", 3, 0), + CLK_PERIPH(CLK_TIMER, "clk_periph_timer", 4, 0), + CLK_PERIPH(CLK_MMUART0, "clk_periph_mmuart0", 5, 0), + CLK_PERIPH(CLK_MMUART1, "clk_periph_mmuart1", 6, 0), + CLK_PERIPH(CLK_MMUART2, "clk_periph_mmuart2", 7, 0), + CLK_PERIPH(CLK_MMUART3, "clk_periph_mmuart3", 8, 0), + CLK_PERIPH(CLK_MMUART4, "clk_periph_mmuart4", 9, 0), + CLK_PERIPH(CLK_SPI0, "clk_periph_spi0", 10, 0), + CLK_PERIPH(CLK_SPI1, "clk_periph_spi1", 11, 0), + CLK_PERIPH(CLK_I2C0, "clk_periph_i2c0", 12, 0), + CLK_PERIPH(CLK_I2C1, "clk_periph_i2c1", 13, 0), + CLK_PERIPH(CLK_CAN0, "clk_periph_can0", 14, 0), + CLK_PERIPH(CLK_CAN1, "clk_periph_can1", 15, 0), + CLK_PERIPH(CLK_USB, "clk_periph_usb", 16, 0), + CLK_PERIPH(CLK_RTC, "clk_periph_rtc", 18, 0), + CLK_PERIPH(CLK_QSPI, "clk_periph_qspi", 19, 0), + CLK_PERIPH(CLK_GPIO0, "clk_periph_gpio0", 20, 0), + CLK_PERIPH(CLK_GPIO1, "clk_periph_gpio1", 21, 0), + CLK_PERIPH(CLK_GPIO2, "clk_periph_gpio2", 22, 0), + CLK_PERIPH(CLK_DDRC, "clk_periph_ddrc", 23, CLK_IS_CRITICAL), + CLK_PERIPH(CLK_FIC0, "clk_periph_fic0", 24, 0), + CLK_PERIPH(CLK_FIC1, "clk_periph_fic1", 25, 0), + CLK_PERIPH(CLK_FIC2, "clk_periph_fic2", 26, 0), + CLK_PERIPH(CLK_FIC3, "clk_periph_fic3", 27, 0), + CLK_PERIPH(CLK_ATHENA, "clk_periph_athena", 28, 0), + CLK_PERIPH(CLK_CFM, "clk_periph_cfm", 29, 0), +}; + +int mpfs_clk_register_periphs(void __iomem *base, u32 clk_rate, + const char *parent_name) +{ + int ret; + int i, id, num_clks; + const char *name; + struct clk *hw; + + num_clks = ARRAY_SIZE(mpfs_periph_clks); + for (i = 0; i < num_clks; i++) { + hw = &mpfs_periph_clks[i].hw; + mpfs_periph_clks[i].sys_base = base; + mpfs_periph_clks[i].prate = clk_rate; + name = mpfs_periph_clks[i].periph.name; + ret = clk_register(hw, MPFS_PERIPH_CLOCK, name, parent_name); + if (ret) + ERR_PTR(ret); + id = mpfs_periph_clks[i].periph.id; + clk_dm(id, hw); + } + + return 0; +} + +const struct clk_ops mpfs_periph_clk_ops = { + .enable = mpfs_periph_clk_enable, + .disable = mpfs_periph_clk_disable, + .get_rate = mpfs_periph_clk_recalc_rate, +}; + +U_BOOT_DRIVER(mpfs_periph_clock) = { + .name = MPFS_PERIPH_CLOCK, + .id = UCLASS_CLK, + .ops = &mpfs_periph_clk_ops, +}; diff --git a/drivers/clk/ti/clk-am3-dpll.c b/drivers/clk/ti/clk-am3-dpll.c index 7916a24538..90b4cc69ef 100644 --- a/drivers/clk/ti/clk-am3-dpll.c +++ b/drivers/clk/ti/clk-am3-dpll.c @@ -260,7 +260,7 @@ U_BOOT_DRIVER(clk_ti_am3_dpll) = { .name = "ti_am3_dpll_clock", .id = UCLASS_CLK, .of_match = clk_ti_am3_dpll_of_match, - .ofdata_to_platdata = clk_ti_am3_dpll_of_to_plat, + .of_to_plat = clk_ti_am3_dpll_of_to_plat, .probe = clk_ti_am3_dpll_probe, .remove = clk_ti_am3_dpll_remove, .priv_auto = sizeof(struct clk_ti_am3_dpll_priv), diff --git a/drivers/clk/ti/clk-ctrl.c b/drivers/clk/ti/clk-ctrl.c index 940e8d6caf..3c6195b208 100644 --- a/drivers/clk/ti/clk-ctrl.c +++ b/drivers/clk/ti/clk-ctrl.c @@ -148,7 +148,7 @@ U_BOOT_DRIVER(clk_ti_ctrl) = { .name = "ti_ctrl_clk", .id = UCLASS_CLK, .of_match = clk_ti_ctrl_ids, - .ofdata_to_platdata = clk_ti_ctrl_of_to_plat, + .of_to_plat = clk_ti_ctrl_of_to_plat, .ops = &clk_ti_ctrl_ops, .priv_auto = sizeof(struct clk_ti_ctrl_priv), }; diff --git a/drivers/clk/ti/clk-divider.c b/drivers/clk/ti/clk-divider.c index a862637785..270f2fbdf0 100644 --- a/drivers/clk/ti/clk-divider.c +++ b/drivers/clk/ti/clk-divider.c @@ -373,7 +373,7 @@ U_BOOT_DRIVER(clk_ti_divider) = { .name = "ti_divider_clock", .id = UCLASS_CLK, .of_match = clk_ti_divider_of_match, - .ofdata_to_platdata = clk_ti_divider_of_to_plat, + .of_to_plat = clk_ti_divider_of_to_plat, .probe = clk_ti_divider_probe, .remove = clk_ti_divider_remove, .priv_auto = sizeof(struct clk_ti_divider_priv), diff --git a/drivers/clk/ti/clk-gate.c b/drivers/clk/ti/clk-gate.c index 236eaed6df..0ca453c8de 100644 --- a/drivers/clk/ti/clk-gate.c +++ b/drivers/clk/ti/clk-gate.c @@ -87,7 +87,7 @@ U_BOOT_DRIVER(clk_ti_gate) = { .name = "ti_gate_clock", .id = UCLASS_CLK, .of_match = clk_ti_gate_of_match, - .ofdata_to_platdata = clk_ti_gate_of_to_plat, + .of_to_plat = clk_ti_gate_of_to_plat, .priv_auto = sizeof(struct clk_ti_gate_priv), .ops = &clk_ti_gate_ops, }; diff --git a/drivers/clk/ti/clk-mux.c b/drivers/clk/ti/clk-mux.c index 419502c389..bb5e49e114 100644 --- a/drivers/clk/ti/clk-mux.c +++ b/drivers/clk/ti/clk-mux.c @@ -245,7 +245,7 @@ U_BOOT_DRIVER(clk_ti_mux) = { .name = "ti_mux_clock", .id = UCLASS_CLK, .of_match = clk_ti_mux_of_match, - .ofdata_to_platdata = clk_ti_mux_of_to_plat, + .of_to_plat = clk_ti_mux_of_to_plat, .probe = clk_ti_mux_probe, .remove = clk_ti_mux_remove, .priv_auto = sizeof(struct clk_ti_mux_priv), diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c index cdb975d5b3..f38122d54b 100644 --- a/drivers/core/uclass.c +++ b/drivers/core/uclass.c @@ -757,6 +757,25 @@ int uclass_pre_remove_device(struct udevice *dev) } #endif +int uclass_probe_all(enum uclass_id id) +{ + struct udevice *dev; + int ret; + + ret = uclass_first_device(id, &dev); + if (ret || !dev) + return ret; + + /* Scanning uclass to probe all devices */ + while (dev) { + ret = uclass_next_device(&dev); + if (ret) + return ret; + } + + return 0; +} + UCLASS_DRIVER(nop) = { .id = UCLASS_NOP, .name = "nop", diff --git a/drivers/dma/bcm6348-iudma.c b/drivers/dma/bcm6348-iudma.c index 98577601b5..c04aa55cb4 100644 --- a/drivers/dma/bcm6348-iudma.c +++ b/drivers/dma/bcm6348-iudma.c @@ -313,10 +313,10 @@ static int bcm6348_iudma_request(struct dma *dma) ch_priv->desc_id = 0; if (bcm6348_iudma_chan_is_rx(dma->id)) { ch_priv->desc_cnt = 0; - ch_priv->busy_desc = calloc(ch_priv->desc_cnt, sizeof(bool)); + ch_priv->busy_desc = NULL; } else { ch_priv->desc_cnt = ch_priv->dma_ring_size; - ch_priv->busy_desc = NULL; + ch_priv->busy_desc = calloc(ch_priv->desc_cnt, sizeof(bool)); } return 0; diff --git a/drivers/fastboot/fb_mmc.c b/drivers/fastboot/fb_mmc.c index ae8e8e512f..4e26cef941 100644 --- a/drivers/fastboot/fb_mmc.c +++ b/drivers/fastboot/fb_mmc.c @@ -508,7 +508,7 @@ void fastboot_mmc_flash_write(const char *cmd, void *download_buffer, fastboot_fail("invalid MBR partition", response); return; } - if (write_mbr_partition(dev_desc, download_buffer)) { + if (write_mbr_sector(dev_desc, download_buffer)) { printf("%s: writing MBR partition failed\n", __func__); fastboot_fail("writing MBR partition failed", response); diff --git a/drivers/fpga/intel_sdm_mb.c b/drivers/fpga/intel_sdm_mb.c index 9a1dc2c0c8..f5fd9a14c2 100644 --- a/drivers/fpga/intel_sdm_mb.c +++ b/drivers/fpga/intel_sdm_mb.c @@ -8,11 +8,149 @@ #include <log.h> #include <watchdog.h> #include <asm/arch/mailbox_s10.h> +#include <asm/arch/smc_api.h> #include <linux/delay.h> +#include <linux/intel-smc.h> #define RECONFIG_STATUS_POLL_RESP_TIMEOUT_MS 60000 #define RECONFIG_STATUS_INTERVAL_DELAY_US 1000000 +#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_ATF) + +#define BITSTREAM_CHUNK_SIZE 0xFFFF0 +#define RECONFIG_STATUS_POLL_RETRY_MAX 100 + +/* + * Polling the FPGA configuration status. + * Return 0 for success, non-zero for error. + */ +static int reconfig_status_polling_resp(void) +{ + int ret; + unsigned long start = get_timer(0); + + while (1) { + ret = invoke_smc(INTEL_SIP_SMC_FPGA_CONFIG_ISDONE, NULL, 0, + NULL, 0); + + if (!ret) + return 0; /* configuration success */ + + if (ret != INTEL_SIP_SMC_STATUS_BUSY) + return ret; + + if (get_timer(start) > RECONFIG_STATUS_POLL_RESP_TIMEOUT_MS) + return -ETIMEDOUT; /* time out */ + + puts("."); + udelay(RECONFIG_STATUS_INTERVAL_DELAY_US); + WATCHDOG_RESET(); + } + + return -ETIMEDOUT; +} + +static int send_bitstream(const void *rbf_data, size_t rbf_size) +{ + int i; + u64 res_buf[3]; + u64 args[2]; + u32 xfer_count = 0; + int ret, wr_ret = 0, retry = 0; + size_t buf_size = (rbf_size > BITSTREAM_CHUNK_SIZE) ? + BITSTREAM_CHUNK_SIZE : rbf_size; + + while (rbf_size || xfer_count) { + if (!wr_ret && rbf_size) { + args[0] = (u64)rbf_data; + args[1] = buf_size; + wr_ret = invoke_smc(INTEL_SIP_SMC_FPGA_CONFIG_WRITE, + args, 2, NULL, 0); + + debug("wr_ret = %d, rbf_data = %p, buf_size = %08lx\n", + wr_ret, rbf_data, buf_size); + + if (wr_ret) + continue; + + rbf_size -= buf_size; + rbf_data += buf_size; + + if (buf_size >= rbf_size) + buf_size = rbf_size; + + xfer_count++; + puts("."); + } else { + ret = invoke_smc( + INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE, + NULL, 0, res_buf, ARRAY_SIZE(res_buf)); + if (!ret) { + for (i = 0; i < ARRAY_SIZE(res_buf); i++) { + if (!res_buf[i]) + break; + xfer_count--; + wr_ret = 0; + retry = 0; + } + } else if (ret != + INTEL_SIP_SMC_STATUS_BUSY) + return ret; + else if (!xfer_count) + return INTEL_SIP_SMC_STATUS_ERROR; + + if (++retry >= RECONFIG_STATUS_POLL_RETRY_MAX) + return -ETIMEDOUT; + + udelay(20000); + } + WATCHDOG_RESET(); + } + + return 0; +} + +/* + * This is the interface used by FPGA driver. + * Return 0 for success, non-zero for error. + */ +int intel_sdm_mb_load(Altera_desc *desc, const void *rbf_data, size_t rbf_size) +{ + int ret; + u64 arg = 1; + + debug("Invoking FPGA_CONFIG_START...\n"); + + ret = invoke_smc(INTEL_SIP_SMC_FPGA_CONFIG_START, &arg, 1, NULL, 0); + + if (ret) { + puts("Failure in RECONFIG mailbox command!\n"); + return ret; + } + + ret = send_bitstream(rbf_data, rbf_size); + if (ret) { + puts("Error sending bitstream!\n"); + return ret; + } + + /* Make sure we don't send MBOX_RECONFIG_STATUS too fast */ + udelay(RECONFIG_STATUS_INTERVAL_DELAY_US); + + debug("Polling with MBOX_RECONFIG_STATUS...\n"); + ret = reconfig_status_polling_resp(); + if (ret) { + puts("FPGA reconfiguration failed!"); + return ret; + } + + puts("FPGA reconfiguration OK!\n"); + + return ret; +} + +#else + static const struct mbox_cfgstat_state { int err_no; const char *error_name; @@ -286,3 +424,4 @@ int intel_sdm_mb_load(Altera_desc *desc, const void *rbf_data, size_t rbf_size) return ret; } +#endif diff --git a/drivers/gpio/stm32_gpio.c b/drivers/gpio/stm32_gpio.c index 79d55e812d..7184db3c52 100644 --- a/drivers/gpio/stm32_gpio.c +++ b/drivers/gpio/stm32_gpio.c @@ -4,6 +4,8 @@ * Author(s): Vikas Manocha, <vikas.manocha@st.com> for STMicroelectronics. */ +#define LOG_CATEGORY UCLASS_GPIO + #include <common.h> #include <clk.h> #include <dm.h> @@ -331,7 +333,7 @@ static int gpio_stm32_probe(struct udevice *dev) dev_err(dev, "failed to enable clock\n"); return ret; } - debug("clock enabled for device %s\n", dev->name); + dev_dbg(dev, "clock enabled\n"); return 0; } diff --git a/drivers/hwspinlock/stm32_hwspinlock.c b/drivers/hwspinlock/stm32_hwspinlock.c index fdc1f6fd53..46ed64655a 100644 --- a/drivers/hwspinlock/stm32_hwspinlock.c +++ b/drivers/hwspinlock/stm32_hwspinlock.c @@ -3,6 +3,8 @@ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved */ +#define LOG_CATEGORY UCLASS_HWSPINLOCK + #include <common.h> #include <clk.h> #include <dm.h> diff --git a/drivers/i2c/stm32f7_i2c.c b/drivers/i2c/stm32f7_i2c.c index 6553bdc610..7b04a09de0 100644 --- a/drivers/i2c/stm32f7_i2c.c +++ b/drivers/i2c/stm32f7_i2c.c @@ -3,6 +3,8 @@ * (C) Copyright 2017 STMicroelectronics */ +#define LOG_CATEGORY UCLASS_I2C + #include <common.h> #include <clk.h> #include <dm.h> @@ -11,10 +13,10 @@ #include <regmap.h> #include <reset.h> #include <syscon.h> +#include <dm/device.h> +#include <dm/device_compat.h> #include <linux/bitops.h> #include <linux/delay.h> - -#include <dm/device.h> #include <linux/err.h> #include <linux/io.h> @@ -346,7 +348,7 @@ static int stm32_i2c_wait_flags(struct stm32_i2c_priv *i2c_priv, *status = readl(®s->isr); while (!(*status & flags)) { if (get_timer(time_start) > CONFIG_SYS_HZ) { - debug("%s: i2c timeout\n", __func__); + log_debug("i2c timeout\n"); return -ETIMEDOUT; } @@ -369,7 +371,7 @@ static int stm32_i2c_check_end_of_message(struct stm32_i2c_priv *i2c_priv) return ret; if (status & STM32_I2C_ISR_BERR) { - debug("%s: Bus error\n", __func__); + log_debug("Bus error\n"); /* Clear BERR flag */ setbits_le32(®s->icr, STM32_I2C_ICR_BERRCF); @@ -378,7 +380,7 @@ static int stm32_i2c_check_end_of_message(struct stm32_i2c_priv *i2c_priv) } if (status & STM32_I2C_ISR_ARLO) { - debug("%s: Arbitration lost\n", __func__); + log_debug("Arbitration lost\n"); /* Clear ARLO flag */ setbits_le32(®s->icr, STM32_I2C_ICR_ARLOCF); @@ -387,7 +389,7 @@ static int stm32_i2c_check_end_of_message(struct stm32_i2c_priv *i2c_priv) } if (status & STM32_I2C_ISR_NACKF) { - debug("%s: Receive NACK\n", __func__); + log_debug("Receive NACK\n"); /* Clear NACK flag */ setbits_le32(®s->icr, STM32_I2C_ICR_NACKCF); @@ -535,8 +537,8 @@ static int stm32_i2c_compute_solutions(struct stm32_i2c_setup *setup, if (sdadel_max < 0) sdadel_max = 0; - debug("%s: SDADEL(min/max): %i/%i, SCLDEL(Min): %i\n", __func__, - sdadel_min, sdadel_max, scldel_min); + log_debug("SDADEL(min/max): %i/%i, SCLDEL(Min): %i\n", + sdadel_min, sdadel_max, scldel_min); /* Compute possible values for PRESC, SCLDEL and SDADEL */ for (p = 0; p < STM32_PRESC_MAX; p++) { @@ -572,7 +574,7 @@ static int stm32_i2c_compute_solutions(struct stm32_i2c_setup *setup, } if (list_empty(solutions)) { - pr_err("%s: no Prescaler solution\n", __func__); + log_err("no Prescaler solution\n"); ret = -EPERM; } @@ -656,7 +658,7 @@ static int stm32_i2c_choose_solution(struct stm32_i2c_setup *setup, } if (!sol_found) { - pr_err("%s: no solution at all\n", __func__); + log_err("no solution at all\n"); ret = -EPERM; } @@ -686,23 +688,22 @@ static int stm32_i2c_compute_timing(struct stm32_i2c_priv *i2c_priv, specs = get_specs(setup->speed_freq); if (specs == ERR_PTR(-EINVAL)) { - pr_err("%s: speed out of bound {%d}\n", __func__, - setup->speed_freq); + log_err("speed out of bound {%d}\n", + setup->speed_freq); return -EINVAL; } if (setup->rise_time > specs->rise_max || setup->fall_time > specs->fall_max) { - pr_err("%s :timings out of bound Rise{%d>%d}/Fall{%d>%d}\n", - __func__, - setup->rise_time, specs->rise_max, - setup->fall_time, specs->fall_max); + log_err("timings out of bound Rise{%d>%d}/Fall{%d>%d}\n", + setup->rise_time, specs->rise_max, + setup->fall_time, specs->fall_max); return -EINVAL; } if (setup->dnf > STM32_I2C_DNF_MAX) { - pr_err("%s: DNF out of bound %d/%d\n", __func__, - setup->dnf, STM32_I2C_DNF_MAX); + log_err("DNF out of bound %d/%d\n", + setup->dnf, STM32_I2C_DNF_MAX); return -EINVAL; } @@ -715,10 +716,10 @@ static int stm32_i2c_compute_timing(struct stm32_i2c_priv *i2c_priv, if (ret) goto exit; - debug("%s: Presc: %i, scldel: %i, sdadel: %i, scll: %i, sclh: %i\n", - __func__, output->presc, - output->scldel, output->sdadel, - output->scll, output->sclh); + log_debug("Presc: %i, scldel: %i, sdadel: %i, scll: %i, sclh: %i\n", + output->presc, + output->scldel, output->sdadel, + output->scll, output->sclh); exit: /* Release list and memory */ @@ -751,20 +752,19 @@ static int stm32_i2c_setup_timing(struct stm32_i2c_priv *i2c_priv, setup->clock_src = clk_get_rate(&i2c_priv->clk); if (!setup->clock_src) { - pr_err("%s: clock rate is 0\n", __func__); + log_err("clock rate is 0\n"); return -EINVAL; } do { ret = stm32_i2c_compute_timing(i2c_priv, setup, timing); if (ret) { - debug("%s: failed to compute I2C timings.\n", - __func__); + log_debug("failed to compute I2C timings.\n"); if (setup->speed_freq > I2C_SPEED_STANDARD_RATE) { setup->speed_freq = get_lower_rate(setup->speed_freq); - debug("%s: downgrade I2C Speed Freq to (%i)\n", - __func__, setup->speed_freq); + log_debug("downgrade I2C Speed Freq to (%i)\n", + setup->speed_freq); } else { break; } @@ -772,16 +772,16 @@ static int stm32_i2c_setup_timing(struct stm32_i2c_priv *i2c_priv, } while (ret); if (ret) { - pr_err("%s: impossible to compute I2C timings.\n", __func__); + log_err("impossible to compute I2C timings.\n"); return ret; } - debug("%s: I2C Freq(%i), Clk Source(%i)\n", __func__, - setup->speed_freq, setup->clock_src); - debug("%s: I2C Rise(%i) and Fall(%i) Time\n", __func__, - setup->rise_time, setup->fall_time); - debug("%s: I2C Analog Filter(%s), DNF(%i)\n", __func__, - setup->analog_filter ? "On" : "Off", setup->dnf); + log_debug("I2C Freq(%i), Clk Source(%i)\n", + setup->speed_freq, setup->clock_src); + log_debug("I2C Rise(%i) and Fall(%i) Time\n", + setup->rise_time, setup->fall_time); + log_debug("I2C Analog Filter(%s), DNF(%i)\n", + setup->analog_filter ? "On" : "Off", setup->dnf); i2c_priv->speed = setup->speed_freq; @@ -848,12 +848,12 @@ static int stm32_i2c_hw_config(struct stm32_i2c_priv *i2c_priv) return 0; } -static int stm32_i2c_set_bus_speed(struct udevice *bus, unsigned int speed) +static int stm32_i2c_set_bus_speed(struct udevice *dev, unsigned int speed) { - struct stm32_i2c_priv *i2c_priv = dev_get_priv(bus); + struct stm32_i2c_priv *i2c_priv = dev_get_priv(dev); if (speed > I2C_SPEED_FAST_PLUS_RATE) { - debug("%s: Speed %d not supported\n", __func__, speed); + dev_dbg(dev, "Speed %d not supported\n", speed); return -EINVAL; } diff --git a/drivers/mailbox/stm32-ipcc.c b/drivers/mailbox/stm32-ipcc.c index 093b570414..69c86e059f 100644 --- a/drivers/mailbox/stm32-ipcc.c +++ b/drivers/mailbox/stm32-ipcc.c @@ -3,6 +3,8 @@ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved */ +#define LOG_CATEGORY UCLASS_MAILBOX + #include <common.h> #include <clk.h> #include <dm.h> @@ -44,11 +46,11 @@ static int stm32_ipcc_request(struct mbox_chan *chan) { struct stm32_ipcc *ipcc = dev_get_priv(chan->dev); - debug("%s(chan=%p)\n", __func__, chan); + dev_dbg(chan->dev, "chan=%p\n", chan); if (chan->id >= ipcc->n_chans) { - debug("%s failed to request channel: %ld\n", - __func__, chan->id); + dev_dbg(chan->dev, "failed to request channel: %ld\n", + chan->id); return -EINVAL; } @@ -57,7 +59,7 @@ static int stm32_ipcc_request(struct mbox_chan *chan) static int stm32_ipcc_free(struct mbox_chan *chan) { - debug("%s(chan=%p)\n", __func__, chan); + dev_dbg(chan->dev, "chan=%p\n", chan); return 0; } @@ -66,7 +68,7 @@ static int stm32_ipcc_send(struct mbox_chan *chan, const void *data) { struct stm32_ipcc *ipcc = dev_get_priv(chan->dev); - debug("%s(chan=%p, data=%p)\n", __func__, chan, data); + dev_dbg(chan->dev, "chan=%p, data=%p\n", chan, data); if (readl(ipcc->reg_proc + IPCC_XTOYSR) & BIT(chan->id)) return -EBUSY; @@ -83,7 +85,7 @@ static int stm32_ipcc_recv(struct mbox_chan *chan, void *data) u32 val; int proc_offset; - debug("%s(chan=%p, data=%p)\n", __func__, chan, data); + dev_dbg(chan->dev, "chan=%p, data=%p\n", chan, data); /* read 'channel occupied' status from other proc */ proc_offset = ipcc->proc_id ? -IPCC_PROC_OFFST : IPCC_PROC_OFFST; @@ -104,7 +106,7 @@ static int stm32_ipcc_probe(struct udevice *dev) struct clk clk; int ret; - debug("%s(dev=%p)\n", __func__, dev); + dev_dbg(dev, "\n"); addr = dev_read_addr(dev); if (addr == FDT_ADDR_T_NONE) diff --git a/drivers/memory/stm32-fmc2-ebi.c b/drivers/memory/stm32-fmc2-ebi.c index f3f48f8b38..212bb4f5dc 100644 --- a/drivers/memory/stm32-fmc2-ebi.c +++ b/drivers/memory/stm32-fmc2-ebi.c @@ -3,10 +3,13 @@ * Copyright (C) STMicroelectronics 2020 */ +#define LOG_CATEGORY UCLASS_NOP + #include <common.h> #include <clk.h> #include <dm.h> #include <reset.h> +#include <dm/device_compat.h> #include <linux/bitfield.h> #include <linux/err.h> #include <linux/iopoll.h> @@ -860,7 +863,7 @@ static int stm32_fmc2_ebi_parse_prop(struct stm32_fmc2_ebi *ebi, u32 setup = 0; if (!prop->set) { - pr_err("property %s is not well defined\n", prop->name); + log_err("property %s is not well defined\n", prop->name); return -EINVAL; } @@ -873,8 +876,8 @@ static int stm32_fmc2_ebi_parse_prop(struct stm32_fmc2_ebi *ebi, bprop = ofnode_read_bool(node, prop->name); if (prop->mprop && !bprop) { - pr_err("mandatory property %s not defined in the device tree\n", - prop->name); + log_err("mandatory property %s not defined in the device tree\n", + prop->name); return -EINVAL; } @@ -886,8 +889,8 @@ static int stm32_fmc2_ebi_parse_prop(struct stm32_fmc2_ebi *ebi, ret = ofnode_read_u32(node, prop->name, &val); if (prop->mprop && ret) { - pr_err("mandatory property %s not defined in the device tree\n", - prop->name); + log_err("mandatory property %s not defined in the device tree\n", + prop->name); return ret; } @@ -949,8 +952,8 @@ static int stm32_fmc2_ebi_setup_cs(struct stm32_fmc2_ebi *ebi, ret = stm32_fmc2_ebi_parse_prop(ebi, node, p, cs); if (ret) { - pr_err("property %s could not be set: %d\n", - p->name, ret); + log_err("property %s could not be set: %d\n", + p->name, ret); return ret; } } @@ -971,25 +974,24 @@ static int stm32_fmc2_ebi_parse_dt(struct udevice *dev, dev_for_each_subnode(child, dev) { ret = ofnode_read_u32(child, "reg", &bank); if (ret) { - pr_err("could not retrieve reg property: %d\n", ret); + dev_err(dev, "could not retrieve reg property: %d\n", ret); return ret; } if (bank >= FMC2_MAX_BANKS) { - pr_err("invalid reg value: %d\n", bank); + dev_err(dev, "invalid reg value: %d\n", bank); return -EINVAL; } if (ebi->bank_assigned & BIT(bank)) { - pr_err("bank already assigned: %d\n", bank); + dev_err(dev, "bank already assigned: %d\n", bank); return -EINVAL; } if (bank < FMC2_MAX_EBI_CE) { ret = stm32_fmc2_ebi_setup_cs(ebi, child, bank); if (ret) { - pr_err("setup chip select %d failed: %d\n", - bank, ret); + dev_err(dev, "setup chip select %d failed: %d\n", bank, ret); return ret; } } @@ -999,12 +1001,12 @@ static int stm32_fmc2_ebi_parse_dt(struct udevice *dev, } if (!child_found) { - pr_warn("no subnodes found, disable the driver.\n"); + dev_warn(dev, "no subnodes found, disable the driver.\n"); return -ENODEV; } if (stm32_fmc2_ebi_nwait_used_by_ctrls(ebi)) { - pr_err("NWAIT signal connected to EBI and NAND controllers\n"); + dev_err(dev, "NWAIT signal connected to EBI and NAND controllers\n"); return -EINVAL; } diff --git a/drivers/misc/stm32_rcc.c b/drivers/misc/stm32_rcc.c index 86275454be..f14d6e26d9 100644 --- a/drivers/misc/stm32_rcc.c +++ b/drivers/misc/stm32_rcc.c @@ -4,6 +4,8 @@ * Author(s): Patrice Chotard, <patrice.chotard@foss.st.com> for STMicroelectronics. */ +#define LOG_CATEGORY UCLASS_NOP + #include <common.h> #include <dm.h> #include <log.h> @@ -45,14 +47,14 @@ static int stm32_rcc_bind(struct udevice *dev) (struct stm32_rcc_clk *)dev_get_driver_data(dev); int ret; - debug("%s(dev=%p)\n", __func__, dev); + dev_dbg(dev, "RCC bind\n"); drv = lists_driver_lookup_name(rcc_clk->drv_name); if (!drv) { - debug("Cannot find driver '%s'\n", rcc_clk->drv_name); + dev_err(dev, "Cannot find driver '%s'\n", rcc_clk->drv_name); return -ENOENT; } - ret = device_bind_with_driver_data(dev, drv, rcc_clk->drv_name, + ret = device_bind_with_driver_data(dev, drv, dev->name, rcc_clk->soc, dev_ofnode(dev), &child); @@ -65,7 +67,7 @@ static int stm32_rcc_bind(struct udevice *dev) return -ENOENT; } - return device_bind_with_driver_data(dev, drv, "stm32_rcc_reset", + return device_bind_with_driver_data(dev, drv, dev->name, rcc_clk->soc, dev_ofnode(dev), &child); } diff --git a/drivers/mmc/ca_dw_mmc.c b/drivers/mmc/ca_dw_mmc.c index fad2ff5aaf..2b79356a20 100644 --- a/drivers/mmc/ca_dw_mmc.c +++ b/drivers/mmc/ca_dw_mmc.c @@ -40,7 +40,7 @@ struct ca_dwmmc_priv_data { u8 ds; }; -static void ca_dwmci_clksel(struct dwmci_host *host) +static int ca_dwmci_clksel(struct dwmci_host *host) { struct ca_dwmmc_priv_data *priv = host->priv; u32 val = readl(priv->sd_dll_reg); @@ -52,6 +52,8 @@ static void ca_dwmci_clksel(struct dwmci_host *host) val |= SD_CLK_SEL_100MHZ; writel(val, priv->sd_dll_reg); + + return 0; } static void ca_dwmci_board_init(struct dwmci_host *host) diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c index 7702f4be3f..7c8a312fa7 100644 --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -496,8 +496,13 @@ static int dwmci_set_ios(struct mmc *mmc) dwmci_writel(host, DWMCI_UHS_REG, regs); - if (host->clksel) - host->clksel(host); + if (host->clksel) { + int ret; + + ret = host->clksel(host); + if (ret) + return ret; + } #if CONFIG_IS_ENABLED(DM_REGULATOR) if (mmc->vqmmc_supply) { diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c index edb5a52c96..b4ff1c3fb4 100644 --- a/drivers/mmc/exynos_dw_mmc.c +++ b/drivers/mmc/exynos_dw_mmc.c @@ -44,7 +44,7 @@ struct dwmci_exynos_priv_data { * Function used as callback function to initialise the * CLKSEL register for every mmc channel. */ -static void exynos_dwmci_clksel(struct dwmci_host *host) +static int exynos_dwmci_clksel(struct dwmci_host *host) { #ifdef CONFIG_DM_MMC struct dwmci_exynos_priv_data *priv = @@ -53,6 +53,8 @@ static void exynos_dwmci_clksel(struct dwmci_host *host) struct dwmci_exynos_priv_data *priv = host->priv; #endif dwmci_writel(host, DWMCI_CLKSEL, priv->sdr_timing); + + return 0; } unsigned int exynos_dwmci_get_clk(struct dwmci_host *host, uint freq) diff --git a/drivers/mmc/fsl_esdhc_spl.c b/drivers/mmc/fsl_esdhc_spl.c index afe55fad9d..bee76572ac 100644 --- a/drivers/mmc/fsl_esdhc_spl.c +++ b/drivers/mmc/fsl_esdhc_spl.c @@ -91,20 +91,17 @@ void __noreturn mmc_boot(void) CONFIG_CFG_DATA_SECTOR, 1, tmp_buf); if (err != 1) { puts("spl: mmc read failed!!\n"); - free(tmp_buf); hang(); } val = *(tmp_buf + MBRDBR_BOOT_SIG_55); if (0x55 != val) { puts("spl: mmc signature is not valid!!\n"); - free(tmp_buf); hang(); } val = *(tmp_buf + MBRDBR_BOOT_SIG_AA); if (0xAA != val) { puts("spl: mmc signature is not valid!!\n"); - free(tmp_buf); hang(); } diff --git a/drivers/mmc/nexell_dw_mmc.c b/drivers/mmc/nexell_dw_mmc.c index 753c89d278..2723e4887c 100644 --- a/drivers/mmc/nexell_dw_mmc.c +++ b/drivers/mmc/nexell_dw_mmc.c @@ -51,7 +51,7 @@ struct nexell_dwmmc_priv { struct clk *clk_get(const char *id); -static void nx_dw_mmc_clksel(struct dwmci_host *host) +static int nx_dw_mmc_clksel(struct dwmci_host *host) { /* host->priv is pointer to "struct udevice" */ struct nexell_dwmmc_priv *priv = dev_get_priv(host->priv); @@ -65,6 +65,8 @@ static void nx_dw_mmc_clksel(struct dwmci_host *host) DWMCI_SET_DRV_CLK(DWMCI_SHIFT_0) | DWMCI_SET_DIV_RATIO(3); dwmci_writel(host, DWMCI_CLKSEL, val); + + return 0; } static void nx_dw_mmc_reset(int ch) diff --git a/drivers/mmc/pci_mmc.c b/drivers/mmc/pci_mmc.c index c71c495d58..b26eb034d0 100644 --- a/drivers/mmc/pci_mmc.c +++ b/drivers/mmc/pci_mmc.c @@ -52,9 +52,11 @@ static int pci_mmc_probe(struct udevice *dev) static int pci_mmc_of_to_plat(struct udevice *dev) { - struct pci_mmc_priv *priv = dev_get_priv(dev); + if (CONFIG_IS_ENABLED(DM_GPIO)) { + struct pci_mmc_priv *priv = dev_get_priv(dev); - gpio_request_by_name(dev, "cd-gpios", 0, &priv->cd_gpio, GPIOD_IS_IN); + gpio_request_by_name(dev, "cd-gpios", 0, &priv->cd_gpio, GPIOD_IS_IN); + } return 0; } diff --git a/drivers/mmc/socfpga_dw_mmc.c b/drivers/mmc/socfpga_dw_mmc.c index dc008c5e2f..aa0d3a2222 100644 --- a/drivers/mmc/socfpga_dw_mmc.c +++ b/drivers/mmc/socfpga_dw_mmc.c @@ -6,6 +6,7 @@ #include <common.h> #include <log.h> #include <asm/arch/clock_manager.h> +#include <asm/arch/secure_reg_helper.h> #include <asm/arch/system_manager.h> #include <clk.h> #include <dm.h> @@ -13,6 +14,7 @@ #include <errno.h> #include <fdtdec.h> #include <dm/device_compat.h> +#include <linux/intel-smc.h> #include <linux/libfdt.h> #include <linux/err.h> #include <malloc.h> @@ -46,7 +48,7 @@ static void socfpga_dwmci_reset(struct udevice *dev) reset_deassert_bulk(&reset_bulk); } -static void socfpga_dwmci_clksel(struct dwmci_host *host) +static int socfpga_dwmci_clksel(struct dwmci_host *host) { struct dwmci_socfpga_priv_data *priv = host->priv; u32 sdmmc_mask = ((priv->smplsel & 0x7) << SYSMGR_SDMMC_SMPLSEL_SHIFT) | @@ -58,14 +60,28 @@ static void socfpga_dwmci_clksel(struct dwmci_host *host) debug("%s: drvsel %d smplsel %d\n", __func__, priv->drvsel, priv->smplsel); + +#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_ATF) + int ret; + + ret = socfpga_secure_reg_write32(SOCFPGA_SECURE_REG_SYSMGR_SOC64_SDMMC, + sdmmc_mask); + if (ret) { + printf("DWMMC: Failed to set clksel via SMC call"); + return ret; + } +#else writel(sdmmc_mask, socfpga_get_sysmgr_addr() + SYSMGR_SDMMC); debug("%s: SYSMGR_SDMMCGRP_CTRL_REG = 0x%x\n", __func__, readl(socfpga_get_sysmgr_addr() + SYSMGR_SDMMC)); +#endif /* Enable SDMMC clock */ setbits_le32(socfpga_get_clkmgr_addr() + CLKMGR_PERPLL_EN, CLKMGR_PERPLLGRP_EN_SDMMCCLK_MASK); + + return 0; } static int socfpga_dwmmc_get_clk_rate(struct udevice *dev) diff --git a/drivers/mmc/stm32_sdmmc2.c b/drivers/mmc/stm32_sdmmc2.c index 3246f6b5e0..a3cdf7bcd9 100644 --- a/drivers/mmc/stm32_sdmmc2.c +++ b/drivers/mmc/stm32_sdmmc2.c @@ -4,6 +4,8 @@ * Author(s): Patrice Chotard, <patrice.chotard@foss.st.com> for STMicroelectronics. */ +#define LOG_CATEGORY UCLASS_MMC + #include <common.h> #include <clk.h> #include <cpu_func.h> @@ -13,6 +15,7 @@ #include <malloc.h> #include <asm/bitops.h> #include <asm/cache.h> +#include <dm/device_compat.h> #include <linux/bitops.h> #include <linux/delay.h> #include <linux/libfdt.h> @@ -200,10 +203,11 @@ struct stm32_sdmmc2_ctx { #define SDMMC_CMD_TIMEOUT 0xFFFFFFFF #define SDMMC_BUSYD0END_TIMEOUT_US 2000000 -static void stm32_sdmmc2_start_data(struct stm32_sdmmc2_priv *priv, +static void stm32_sdmmc2_start_data(struct udevice *dev, struct mmc_data *data, struct stm32_sdmmc2_ctx *ctx) { + struct stm32_sdmmc2_priv *priv = dev_get_priv(dev); u32 data_ctrl, idmabase0; /* Configure the SDMMC DPSM (Data Path State Machine) */ @@ -241,10 +245,11 @@ static void stm32_sdmmc2_start_data(struct stm32_sdmmc2_priv *priv, writel(SDMMC_IDMACTRL_IDMAEN, priv->base + SDMMC_IDMACTRL); } -static void stm32_sdmmc2_start_cmd(struct stm32_sdmmc2_priv *priv, +static void stm32_sdmmc2_start_cmd(struct udevice *dev, struct mmc_cmd *cmd, u32 cmd_param, struct stm32_sdmmc2_ctx *ctx) { + struct stm32_sdmmc2_priv *priv = dev_get_priv(dev); u32 timeout = 0; if (readl(priv->base + SDMMC_CMD) & SDMMC_CMD_CPSMEN) @@ -290,10 +295,11 @@ static void stm32_sdmmc2_start_cmd(struct stm32_sdmmc2_priv *priv, writel(cmd_param, priv->base + SDMMC_CMD); } -static int stm32_sdmmc2_end_cmd(struct stm32_sdmmc2_priv *priv, +static int stm32_sdmmc2_end_cmd(struct udevice *dev, struct mmc_cmd *cmd, struct stm32_sdmmc2_ctx *ctx) { + struct stm32_sdmmc2_priv *priv = dev_get_priv(dev); u32 mask = SDMMC_STA_CTIMEOUT; u32 status; int ret; @@ -311,22 +317,22 @@ static int stm32_sdmmc2_end_cmd(struct stm32_sdmmc2_priv *priv, 10000); if (ret < 0) { - debug("%s: timeout reading SDMMC_STA register\n", __func__); + dev_dbg(dev, "timeout reading SDMMC_STA register\n"); ctx->dpsm_abort = true; return ret; } /* Check status */ if (status & SDMMC_STA_CTIMEOUT) { - debug("%s: error SDMMC_STA_CTIMEOUT (0x%x) for cmd %d\n", - __func__, status, cmd->cmdidx); + dev_dbg(dev, "error SDMMC_STA_CTIMEOUT (0x%x) for cmd %d\n", + status, cmd->cmdidx); ctx->dpsm_abort = true; return -ETIMEDOUT; } if (status & SDMMC_STA_CCRCFAIL && cmd->resp_type & MMC_RSP_CRC) { - debug("%s: error SDMMC_STA_CCRCFAIL (0x%x) for cmd %d\n", - __func__, status, cmd->cmdidx); + dev_dbg(dev, "error SDMMC_STA_CCRCFAIL (0x%x) for cmd %d\n", + status, cmd->cmdidx); ctx->dpsm_abort = true; return -EILSEQ; } @@ -350,15 +356,15 @@ static int stm32_sdmmc2_end_cmd(struct stm32_sdmmc2_priv *priv, SDMMC_BUSYD0END_TIMEOUT_US); if (ret < 0) { - debug("%s: timeout reading SDMMC_STA\n", - __func__); + dev_dbg(dev, "timeout reading SDMMC_STA\n"); ctx->dpsm_abort = true; return ret; } if (status & SDMMC_STA_DTIMEOUT) { - debug("%s: error SDMMC_STA_DTIMEOUT (0x%x)\n", - __func__, status); + dev_dbg(dev, + "error SDMMC_STA_DTIMEOUT (0x%x)\n", + status); ctx->dpsm_abort = true; return -ETIMEDOUT; } @@ -368,11 +374,12 @@ static int stm32_sdmmc2_end_cmd(struct stm32_sdmmc2_priv *priv, return 0; } -static int stm32_sdmmc2_end_data(struct stm32_sdmmc2_priv *priv, +static int stm32_sdmmc2_end_data(struct udevice *dev, struct mmc_cmd *cmd, struct mmc_data *data, struct stm32_sdmmc2_ctx *ctx) { + struct stm32_sdmmc2_priv *priv = dev_get_priv(dev); u32 mask = SDMMC_STA_DCRCFAIL | SDMMC_STA_DTIMEOUT | SDMMC_STA_IDMATE | SDMMC_STA_DATAEND; u32 status; @@ -394,37 +401,37 @@ static int stm32_sdmmc2_end_data(struct stm32_sdmmc2_priv *priv, invalidate_dcache_range(ctx->cache_start, ctx->cache_end); if (status & SDMMC_STA_DCRCFAIL) { - debug("%s: error SDMMC_STA_DCRCFAIL (0x%x) for cmd %d\n", - __func__, status, cmd->cmdidx); + dev_dbg(dev, "error SDMMC_STA_DCRCFAIL (0x%x) for cmd %d\n", + status, cmd->cmdidx); if (readl(priv->base + SDMMC_DCOUNT)) ctx->dpsm_abort = true; return -EILSEQ; } if (status & SDMMC_STA_DTIMEOUT) { - debug("%s: error SDMMC_STA_DTIMEOUT (0x%x) for cmd %d\n", - __func__, status, cmd->cmdidx); + dev_dbg(dev, "error SDMMC_STA_DTIMEOUT (0x%x) for cmd %d\n", + status, cmd->cmdidx); ctx->dpsm_abort = true; return -ETIMEDOUT; } if (status & SDMMC_STA_TXUNDERR) { - debug("%s: error SDMMC_STA_TXUNDERR (0x%x) for cmd %d\n", - __func__, status, cmd->cmdidx); + dev_dbg(dev, "error SDMMC_STA_TXUNDERR (0x%x) for cmd %d\n", + status, cmd->cmdidx); ctx->dpsm_abort = true; return -EIO; } if (status & SDMMC_STA_RXOVERR) { - debug("%s: error SDMMC_STA_RXOVERR (0x%x) for cmd %d\n", - __func__, status, cmd->cmdidx); + dev_dbg(dev, "error SDMMC_STA_RXOVERR (0x%x) for cmd %d\n", + status, cmd->cmdidx); ctx->dpsm_abort = true; return -EIO; } if (status & SDMMC_STA_IDMATE) { - debug("%s: error SDMMC_STA_IDMATE (0x%x) for cmd %d\n", - __func__, status, cmd->cmdidx); + dev_dbg(dev, "error SDMMC_STA_IDMATE (0x%x) for cmd %d\n", + status, cmd->cmdidx); ctx->dpsm_abort = true; return -EIO; } @@ -448,19 +455,18 @@ retry_cmd: if (data) { ctx.data_length = data->blocks * data->blocksize; - stm32_sdmmc2_start_data(priv, data, &ctx); + stm32_sdmmc2_start_data(dev, data, &ctx); } - stm32_sdmmc2_start_cmd(priv, cmd, cmdat, &ctx); + stm32_sdmmc2_start_cmd(dev, cmd, cmdat, &ctx); - debug("%s: send cmd %d data: 0x%x @ 0x%x\n", - __func__, cmd->cmdidx, - data ? ctx.data_length : 0, (unsigned int)data); + dev_dbg(dev, "send cmd %d data: 0x%x @ 0x%x\n", + cmd->cmdidx, data ? ctx.data_length : 0, (unsigned int)data); - ret = stm32_sdmmc2_end_cmd(priv, cmd, &ctx); + ret = stm32_sdmmc2_end_cmd(dev, cmd, &ctx); if (data && !ret) - ret = stm32_sdmmc2_end_data(priv, cmd, data, &ctx); + ret = stm32_sdmmc2_end_data(dev, cmd, data, &ctx); /* Clear flags */ writel(SDMMC_ICR_STATIC_FLAGS, priv->base + SDMMC_ICR); @@ -478,26 +484,24 @@ retry_cmd: stop_cmd.cmdarg = 0; stop_cmd.resp_type = MMC_RSP_R1b; - debug("%s: send STOP command to abort dpsm treatments\n", - __func__); + dev_dbg(dev, "send STOP command to abort dpsm treatments\n"); ctx.data_length = 0; - stm32_sdmmc2_start_cmd(priv, &stop_cmd, + stm32_sdmmc2_start_cmd(dev, &stop_cmd, SDMMC_CMD_CMDSTOP, &ctx); - stm32_sdmmc2_end_cmd(priv, &stop_cmd, &ctx); + stm32_sdmmc2_end_cmd(dev, &stop_cmd, &ctx); writel(SDMMC_ICR_STATIC_FLAGS, priv->base + SDMMC_ICR); } if ((ret != -ETIMEDOUT) && (ret != 0) && retry) { - printf("%s: cmd %d failed, retrying ...\n", - __func__, cmd->cmdidx); + dev_err(dev, "cmd %d failed, retrying ...\n", cmd->cmdidx); retry--; goto retry_cmd; } - debug("%s: end for CMD %d, ret = %d\n", __func__, cmd->cmdidx, ret); + dev_dbg(dev, "end for CMD %d, ret = %d\n", cmd->cmdidx, ret); return ret; } @@ -579,8 +583,8 @@ static int stm32_sdmmc2_set_ios(struct udevice *dev) u32 sys_clock = clk_get_rate(&priv->clk); u32 clk = 0; - debug("%s: bus_with = %d, clock = %d\n", __func__, - mmc->bus_width, mmc->clock); + dev_dbg(dev, "bus_with = %d, clock = %d\n", + mmc->bus_width, mmc->clock); if (mmc->clk_disable) stm32_sdmmc2_pwrcycle(priv); @@ -616,7 +620,7 @@ static int stm32_sdmmc2_getcd(struct udevice *dev) { struct stm32_sdmmc2_priv *priv = dev_get_priv(dev); - debug("stm32_sdmmc2_getcd called\n"); + dev_dbg(dev, "%s called\n", __func__); if (dm_gpio_is_valid(&priv->cd_gpio)) return dm_gpio_get_value(&priv->cd_gpio); diff --git a/drivers/mmc/xenon_sdhci.c b/drivers/mmc/xenon_sdhci.c index b8e833e6a3..14fec4b8e7 100644 --- a/drivers/mmc/xenon_sdhci.c +++ b/drivers/mmc/xenon_sdhci.c @@ -104,18 +104,6 @@ DECLARE_GLOBAL_DATA_PTR; /* Hyperion only have one slot 0 */ #define XENON_MMC_SLOT_ID_HYPERION 0 -#define MMC_TIMING_LEGACY 0 -#define MMC_TIMING_MMC_HS 1 -#define MMC_TIMING_SD_HS 2 -#define MMC_TIMING_UHS_SDR12 3 -#define MMC_TIMING_UHS_SDR25 4 -#define MMC_TIMING_UHS_SDR50 5 -#define MMC_TIMING_UHS_SDR104 6 -#define MMC_TIMING_UHS_DDR50 7 -#define MMC_TIMING_MMC_DDR52 8 -#define MMC_TIMING_MMC_HS200 9 -#define MMC_TIMING_MMC_HS400 10 - #define XENON_MMC_MAX_CLK 400000000 #define XENON_MMC_3V3_UV 3300000 #define XENON_MMC_1V8_UV 1800000 diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile index 318788c5e2..6d77ebfaa5 100644 --- a/drivers/mtd/Makefile +++ b/drivers/mtd/Makefile @@ -11,7 +11,6 @@ mtd-$(CONFIG_ALTERA_QSPI) += altera_qspi.o mtd-$(CONFIG_FLASH_CFI_DRIVER) += cfi_flash.o mtd-$(CONFIG_FLASH_CFI_MTD) += cfi_mtd.o mtd-$(CONFIG_FLASH_CFI_LEGACY) += jedec_flash.o -mtd-$(CONFIG_MW_EEPROM) += mw_eeprom.o mtd-$(CONFIG_FLASH_PIC32) += pic32_flash.o mtd-$(CONFIG_ST_SMI) += st_smi.o mtd-$(CONFIG_STM32_FLASH) += stm32_flash.o diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index 1a4dec34d9..0d1f94c6cb 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -9,8 +9,6 @@ */ #ifndef __UBOOT__ -#include <log.h> -#include <dm/devres.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/ptrace.h> diff --git a/drivers/mtd/mw_eeprom.c b/drivers/mtd/mw_eeprom.c deleted file mode 100644 index 9837733bee..0000000000 --- a/drivers/mtd/mw_eeprom.c +++ /dev/null @@ -1,238 +0,0 @@ -/* Three-wire (MicroWire) serial eeprom driver (for 93C46 and compatibles) */ - -#include <common.h> -#include <eeprom.h> -#include <asm/ic/ssi.h> -#include <linux/delay.h> - -/* - * Serial EEPROM opcodes, including start bit - */ -#define EEP_OPC_ERASE 0x7 /* 3-bit opcode */ -#define EEP_OPC_WRITE 0x5 /* 3-bit opcode */ -#define EEP_OPC_READ 0x6 /* 3-bit opcode */ - -#define EEP_OPC_ERASE_ALL 0x12 /* 5-bit opcode */ -#define EEP_OPC_ERASE_EN 0x13 /* 5-bit opcode */ -#define EEP_OPC_WRITE_ALL 0x11 /* 5-bit opcode */ -#define EEP_OPC_ERASE_DIS 0x10 /* 5-bit opcode */ - -static int addrlen; - -static void mw_eeprom_select(int dev) -{ - ssi_set_interface(2048, 0, 0, 0); - ssi_chip_select(0); - udelay(1); - ssi_chip_select(dev); - udelay(1); -} - -static int mw_eeprom_size(int dev) -{ - int x; - u16 res; - - mw_eeprom_select(dev); - ssi_tx_byte(EEP_OPC_READ); - - res = ssi_txrx_byte(0) << 8; - res |= ssi_rx_byte(); - for (x = 0; x < 16; x++) { - if (! (res & 0x8000)) { - break; - } - res <<= 1; - } - ssi_chip_select(0); - - return x; -} - -int mw_eeprom_erase_enable(int dev) -{ - mw_eeprom_select(dev); - ssi_tx_byte(EEP_OPC_ERASE_EN); - ssi_tx_byte(0); - udelay(1); - ssi_chip_select(0); - - return 0; -} - -int mw_eeprom_erase_disable(int dev) -{ - mw_eeprom_select(dev); - ssi_tx_byte(EEP_OPC_ERASE_DIS); - ssi_tx_byte(0); - udelay(1); - ssi_chip_select(0); - - return 0; -} - - -u32 mw_eeprom_read_word(int dev, int addr) -{ - u16 rcv; - u16 res; - int bits; - - mw_eeprom_select(dev); - ssi_tx_byte((EEP_OPC_READ << 5) | ((addr >> (addrlen - 5)) & 0x1f)); - rcv = ssi_txrx_byte(addr << (13 - addrlen)); - res = rcv << (16 - addrlen); - bits = 4 + addrlen; - - while (bits>0) { - rcv = ssi_rx_byte(); - if (bits > 7) { - res |= rcv << (bits - 8); - } else { - res |= rcv >> (8 - bits); - } - bits -= 8; - } - - ssi_chip_select(0); - - return res; -} - -int mw_eeprom_write_word(int dev, int addr, u16 data) -{ - u8 byte1=0; - u8 byte2=0; - - mw_eeprom_erase_enable(dev); - mw_eeprom_select(dev); - - switch (addrlen) { - case 6: - byte1 = EEP_OPC_WRITE >> 2; - byte2 = (EEP_OPC_WRITE << 6)&0xc0; - byte2 |= addr; - break; - case 7: - byte1 = EEP_OPC_WRITE >> 1; - byte2 = (EEP_OPC_WRITE << 7)&0x80; - byte2 |= addr; - break; - case 8: - byte1 = EEP_OPC_WRITE; - byte2 = addr; - break; - case 9: - byte1 = EEP_OPC_WRITE << 1; - byte1 |= addr >> 8; - byte2 = addr & 0xff; - break; - case 10: - byte1 = EEP_OPC_WRITE << 2; - byte1 |= addr >> 8; - byte2 = addr & 0xff; - break; - default: - printf("Unsupported number of address bits: %d\n", addrlen); - return -1; - - } - - ssi_tx_byte(byte1); - ssi_tx_byte(byte2); - ssi_tx_byte(data >> 8); - ssi_tx_byte(data & 0xff); - ssi_chip_select(0); - udelay(10000); /* Worst case */ - mw_eeprom_erase_disable(dev); - - return 0; -} - - -int mw_eeprom_write(int dev, int addr, u8 *buffer, int len) -{ - int done; - - done = 0; - if (addr & 1) { - u16 temp = mw_eeprom_read_word(dev, addr >> 1); - temp &= 0xff00; - temp |= buffer[0]; - - mw_eeprom_write_word(dev, addr >> 1, temp); - len--; - addr++; - buffer++; - done++; - } - - while (len <= 2) { - mw_eeprom_write_word(dev, addr >> 1, *(u16*)buffer); - len-=2; - addr+=2; - buffer+=2; - done+=2; - } - - if (len) { - u16 temp = mw_eeprom_read_word(dev, addr >> 1); - temp &= 0x00ff; - temp |= buffer[0] << 8; - - mw_eeprom_write_word(dev, addr >> 1, temp); - len--; - addr++; - buffer++; - done++; - } - - return done; -} - - -int mw_eeprom_read(int dev, int addr, u8 *buffer, int len) -{ - int done; - - done = 0; - if (addr & 1) { - u16 temp = mw_eeprom_read_word(dev, addr >> 1); - buffer[0]= temp & 0xff; - - len--; - addr++; - buffer++; - done++; - } - - while (len <= 2) { - *(u16*)buffer = mw_eeprom_read_word(dev, addr >> 1); - len-=2; - addr+=2; - buffer+=2; - done+=2; - } - - if (len) { - u16 temp = mw_eeprom_read_word(dev, addr >> 1); - buffer[0] = temp >> 8; - - len--; - addr++; - buffer++; - done++; - } - - return done; -} - -int mw_eeprom_probe(int dev) -{ - addrlen = mw_eeprom_size(dev); - - if (addrlen < 6 || addrlen > 10) { - return -1; - } - return 0; -} diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig index 3cf3b14f05..ed151ee0a5 100644 --- a/drivers/mtd/nand/raw/Kconfig +++ b/drivers/mtd/nand/raw/Kconfig @@ -321,6 +321,18 @@ config NAND_STM32_FMC2 The controller supports a maximum 8k page size and supports a maximum 8-bit correction error per sector of 512 bytes. +config CORTINA_NAND + bool "Support for NAND controller on Cortina-Access SoCs" + depends on CORTINA_PLATFORM + select SYS_NAND_SELF_INIT + select DM_MTD + imply CMD_NAND + help + Enables support for NAND Flash chips on Coartina-Access SoCs platform + This controller is found on Presidio/Venus SoCs. + The controller supports a maximum 8k page size and supports + a maximum 40-bit error correction per sector of 1024 bytes. + comment "Generic NAND options" config SYS_NAND_BLOCK_SIZE diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile index 24c51b6924..f3f0e15a15 100644 --- a/drivers/mtd/nand/raw/Makefile +++ b/drivers/mtd/nand/raw/Makefile @@ -69,6 +69,7 @@ obj-$(CONFIG_NAND_PLAT) += nand_plat.o obj-$(CONFIG_NAND_SUNXI) += sunxi_nand.o obj-$(CONFIG_NAND_ZYNQ) += zynq_nand.o obj-$(CONFIG_NAND_STM32_FMC2) += stm32_fmc2_nand.o +obj-$(CONFIG_CORTINA_NAND) += cortina_nand.o else # minimal SPL drivers diff --git a/drivers/mtd/nand/raw/cortina_nand.c b/drivers/mtd/nand/raw/cortina_nand.c new file mode 100644 index 0000000000..12bd1ded83 --- /dev/null +++ b/drivers/mtd/nand/raw/cortina_nand.c @@ -0,0 +1,1390 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2020, Cortina Access Inc.. + */ + +#include <common.h> +#include <linux/delay.h> +#include <linux/bitops.h> +#include <linux/sizes.h> +#include <log.h> +#include <asm/io.h> +#include <memalign.h> +#include <nand.h> +#include <dm/device_compat.h> +#include <linux/bug.h> +#include <linux/delay.h> +#include <linux/iopoll.h> +#include <linux/errno.h> +#include <asm/gpio.h> +#include <fdtdec.h> +#include <bouncebuf.h> +#include <dm.h> +#include "cortina_nand.h" + +static unsigned int *pread, *pwrite; + +static const struct udevice_id cortina_nand_dt_ids[] = { + { + .compatible = "cortina,ca-nand", + }, + { /* sentinel */ } +}; + +static struct nand_ecclayout eccoob; + +/* Information about an attached NAND chip */ +struct fdt_nand { + int enabled; /* 1 to enable, 0 to disable */ + s32 width; /* bit width, must be 8 */ + u32 nand_ecc_strength; +}; + +struct nand_drv { + u32 fifo_index; + struct nand_ctlr *reg; + struct dma_global *dma_glb; + struct dma_ssp *dma_nand; + struct tx_descriptor_t *tx_desc; + struct rx_descriptor_t *rx_desc; + struct fdt_nand config; + unsigned int flash_base; +}; + +struct ca_nand_info { + struct udevice *dev; + struct nand_drv nand_ctrl; + struct nand_chip nand_chip; +}; + +/** + * Wait for command completion + * + * @param reg nand_ctlr structure + * @return + * 1 - Command completed + * 0 - Timeout + */ +static int nand_waitfor_cmd_completion(struct nand_ctlr *reg, unsigned int mask) +{ + unsigned int reg_v = 0; + + if (readl_poll_timeout(®->flash_flash_access_start, reg_v, + !(reg_v & mask), (FLASH_LONG_DELAY << 2))) { + pr_err("Nand CMD timeout!\n"); + return 0; + } + + return 1; +} + +/** + * Read one byte from the chip + * + * @param mtd MTD device structure + * @return data byte + * + * Read function for 8bit bus-width + */ +static uint8_t read_byte(struct mtd_info *mtd) +{ + struct nand_chip *chip = mtd_to_nand(mtd); + struct nand_drv *info; + u8 ret_v; + + info = (struct nand_drv *)nand_get_controller_data(chip); + + clrsetbits_le32(&info->reg->flash_flash_access_start, GENMASK(31, 0), + NFLASH_GO | NFLASH_RD); + + if (!nand_waitfor_cmd_completion(info->reg, NFLASH_GO)) + printf("%s: Command timeout\n", __func__); + + ret_v = readl(&info->reg->flash_nf_data) >> (8 * info->fifo_index++); + info->fifo_index %= 4; + + return (uint8_t)ret_v; +} + +/** + * Read len bytes from the chip into a buffer + * + * @param mtd MTD device structure + * @param buf buffer to store data to + * @param len number of bytes to read + * + * Read function for 8bit bus-width + */ +static void read_buf(struct mtd_info *mtd, uint8_t *buf, int len) +{ + int i; + unsigned int reg; + struct nand_chip *chip = mtd_to_nand(mtd); + struct nand_drv *info = + (struct nand_drv *)nand_get_controller_data(chip); + + for (i = 0; i < len; i++) { + clrsetbits_le32(&info->reg->flash_flash_access_start, + GENMASK(31, 0), NFLASH_GO | NFLASH_RD); + + if (!nand_waitfor_cmd_completion(info->reg, NFLASH_GO)) + printf("%s: Command timeout\n", __func__); + + reg = readl(&info->reg->flash_nf_data) >> + (8 * info->fifo_index++); + memcpy(buf + i, ®, 1); + info->fifo_index %= 4; + } +} + +/** + * Check READY pin status to see if it is ready or not + * + * @param mtd MTD device structure + * @return + * 1 - ready + * 0 - not ready + */ +static int nand_dev_ready(struct mtd_info *mtd) +{ + struct nand_chip *chip = mtd_to_nand(mtd); + int reg_val; + struct nand_drv *info = + (struct nand_drv *)nand_get_controller_data(chip); + + reg_val = readl(&info->reg->flash_status); + if (reg_val & NFLASH_READY) + return 1; + else + return 0; +} + +/* Dummy implementation: we don't support multiple chips */ +static void nand_select_chip(struct mtd_info *mtd, int chipnr) +{ + switch (chipnr) { + case -1: + case 0: + break; + + default: + WARN_ON(chipnr); + } +} + +int init_nand_dma(struct nand_chip *nand) +{ + int i; + struct nand_drv *info = + (struct nand_drv *)nand_get_controller_data(nand); + + setbits_le32(&info->dma_glb->dma_glb_dma_lso_ctrl, TX_DMA_ENABLE); + setbits_le32(&info->dma_glb->dma_glb_dma_ssp_rx_ctrl, + TX_DMA_ENABLE | DMA_CHECK_OWNER); + setbits_le32(&info->dma_glb->dma_glb_dma_ssp_tx_ctrl, + RX_DMA_ENABLE | DMA_CHECK_OWNER); + + info->tx_desc = malloc_cache_aligned((sizeof(struct tx_descriptor_t) * + CA_DMA_DESC_NUM)); + info->rx_desc = malloc_cache_aligned((sizeof(struct rx_descriptor_t) * + CA_DMA_DESC_NUM)); + + if (!info->rx_desc && info->tx_desc) { + printf("Fail to alloc DMA descript!\n"); + kfree(info->tx_desc); + return -ENOMEM; + } else if (info->rx_desc && !info->tx_desc) { + printf("Fail to alloc DMA descript!\n"); + kfree(info->tx_desc); + return -ENOMEM; + } + + /* set RX DMA base address and depth */ + clrsetbits_le32(&info->dma_nand->dma_q_rxq_base_depth, + GENMASK(31, 4), (uintptr_t)info->rx_desc); + clrsetbits_le32(&info->dma_nand->dma_q_rxq_base_depth, + GENMASK(3, 0), CA_DMA_DEPTH); + + /* set TX DMA base address and depth */ + clrsetbits_le32(&info->dma_nand->dma_q_txq_base_depth, + GENMASK(31, 4), (uintptr_t)info->tx_desc); + clrsetbits_le32(&info->dma_nand->dma_q_txq_base_depth, + GENMASK(3, 0), CA_DMA_DEPTH); + + memset((unsigned char *)info->tx_desc, 0, + (sizeof(struct tx_descriptor_t) * CA_DMA_DESC_NUM)); + memset((unsigned char *)info->rx_desc, 0, + (sizeof(struct rx_descriptor_t) * CA_DMA_DESC_NUM)); + + for (i = 0; i < CA_DMA_DESC_NUM; i++) { + /* set owner bit as SW */ + info->tx_desc[i].own = 1; + /* enable Scatter-Gather memory copy */ + info->tx_desc[i].sgm = 0x1; + } + + return 0; +} + +/** + * Send command to NAND device + * + * @param mtd MTD device structure + * @param command the command to be sent + * @param column the column address for this command, -1 if none + * @param page_addr the page address for this command, -1 if none + */ +static void ca_nand_command(struct mtd_info *mtd, unsigned int command, + int column, int page_addr) +{ + struct nand_chip *chip = mtd_to_nand(mtd); + struct nand_drv *info; + unsigned int reg_v = 0; + u32 cmd = 0, cnt = 0, addr1 = 0, addr2 = 0; + int ret; + + info = (struct nand_drv *)nand_get_controller_data(chip); + /* + * Write out the command to the device. + * + * Only command NAND_CMD_RESET or NAND_CMD_READID will come + * here before mtd->writesize is initialized. + */ + + /* Emulate NAND_CMD_READOOB */ + if (command == NAND_CMD_READOOB) { + assert(mtd->writesize != 0); + column += mtd->writesize; + command = NAND_CMD_READ0; + } + + /* Reset FIFO before issue new command */ + clrsetbits_le32(&info->reg->flash_nf_ecc_reset, GENMASK(31, 0), + ECC_RESET_ALL); + ret = + readl_poll_timeout(&info->reg->flash_nf_ecc_reset, reg_v, + !(reg_v & RESET_NFLASH_FIFO), FLASH_SHORT_DELAY); + if (ret) { + printf("FIFO reset timeout\n"); + clrsetbits_le32(&info->reg->flash_nf_ecc_reset, GENMASK(31, 0), + ECC_RESET_ALL); + udelay(10); + } + + /* Reset FIFO index + * Next read start from flash_nf_data[0] + */ + info->fifo_index = 0; + + clrsetbits_le32(&info->reg->flash_nf_access, GENMASK(11, 10), + NFLASH_REG_WIDTH_8); + + /* + * Program and erase have their own busy handlers + * status and sequential in needs no delay + */ + switch (command) { + case NAND_CMD_READID: + /* Command */ + clrsetbits_le32(&info->reg->flash_nf_command, GENMASK(31, 0), + NAND_CMD_READID); + /* 1 byte CMD cycle */ + clrsetbits_le32(&info->reg->flash_nf_count, GENMASK(1, 0), + REG_CMD_COUNT_1TOGO); + /* 1 byte CMD cycle */ + clrsetbits_le32(&info->reg->flash_nf_count, GENMASK(6, 4), + REG_ADDR_COUNT_1); + /* Data cycle */ + clrsetbits_le32(&info->reg->flash_nf_count, GENMASK(21, 8), + REG_DATA_COUNT_DATA_4); + /* 0 OOB cycle */ + clrsetbits_le32(&info->reg->flash_nf_count, GENMASK(31, 22), + REG_OOB_COUNT_EMPTY); + + /* addresses */ + clrsetbits_le32(&info->reg->flash_nf_address_1, GENMASK(31, 0), + column & ADDR1_MASK2); + clrsetbits_le32(&info->reg->flash_nf_address_2, GENMASK(31, 0), + 0); + + /* clear FLASH_NF_ACCESS */ + clrsetbits_le32(&info->reg->flash_nf_access, GENMASK(31, 0), + DISABLE_AUTO_RESET); + + break; + case NAND_CMD_PARAM: + /* Command */ + clrsetbits_le32(&info->reg->flash_nf_command, GENMASK(31, 0), + NAND_CMD_PARAM); + /* 1 byte CMD cycle */ + clrsetbits_le32(&info->reg->flash_nf_count, GENMASK(1, 0), + REG_CMD_COUNT_1TOGO); + /* 1 byte ADDR cycle */ + clrsetbits_le32(&info->reg->flash_nf_count, GENMASK(6, 4), + REG_ADDR_COUNT_1); + /* Data cycle */ + clrsetbits_le32(&info->reg->flash_nf_count, GENMASK(21, 8), + (SZ_4K - 1) << 8); + /* 0 OOB cycle */ + clrsetbits_le32(&info->reg->flash_nf_count, GENMASK(31, 22), + REG_OOB_COUNT_EMPTY); + + /* addresses */ + clrsetbits_le32(&info->reg->flash_nf_address_1, GENMASK(31, 0), + column & ADDR1_MASK2); + clrsetbits_le32(&info->reg->flash_nf_address_2, GENMASK(31, 0), + 0); + + break; + case NAND_CMD_READ0: + if (chip->chipsize < SZ_32M) { + cmd = NAND_CMD_READ0; + cnt = REG_CMD_COUNT_1TOGO | REG_ADDR_COUNT_3; + addr1 = (((page_addr & ADDR1_MASK0) << 8)); + addr2 = ((page_addr & ADDR2_MASK0) >> 24); + } else if (chip->chipsize >= SZ_32M && + (chip->chipsize <= SZ_128M)) { + cmd = NAND_CMD_READ0; + cnt = REG_ADDR_COUNT_4; + if (mtd->writesize > (REG_DATA_COUNT_512_DATA >> 8)) { + cmd |= (NAND_CMD_READSTART << 8); + cnt |= REG_CMD_COUNT_2TOGO; + } else { + cnt |= REG_CMD_COUNT_1TOGO; + } + addr1 = ((page_addr << 16) | (column & ADDR1_MASK1)); + addr2 = (page_addr >> 16); + } else { + cmd = NAND_CMD_READ0 | (NAND_CMD_READSTART << 8); + cnt = REG_CMD_COUNT_2TOGO | REG_ADDR_COUNT_5; + addr1 = ((page_addr << 16) | (column & ADDR1_MASK1)); + addr2 = (page_addr >> 16); + } + + /* Command */ + clrsetbits_le32(&info->reg->flash_nf_command, GENMASK(31, 0), + cmd); + /* CMD & ADDR cycle */ + clrsetbits_le32(&info->reg->flash_nf_count, GENMASK(7, 0), cnt); + /* Data cycle */ + clrsetbits_le32(&info->reg->flash_nf_count, GENMASK(21, 8), + (mtd->writesize - 1) << 8); + /* OOB cycle */ + clrsetbits_le32(&info->reg->flash_nf_count, GENMASK(31, 22), + (mtd->oobsize - 1) << 22); + + /* addresses */ + clrsetbits_le32(&info->reg->flash_nf_address_1, GENMASK(31, 0), + addr1); + clrsetbits_le32(&info->reg->flash_nf_address_2, GENMASK(31, 0), + addr2); + + return; + case NAND_CMD_SEQIN: + if (chip->chipsize < SZ_32M) { + cnt = REG_CMD_COUNT_2TOGO | REG_ADDR_COUNT_3; + addr1 = (((page_addr & ADDR1_MASK0) << 8)); + addr2 = ((page_addr & ADDR2_MASK0) >> 24); + } else if (chip->chipsize >= SZ_32M && + (chip->chipsize <= SZ_128M)) { + cnt = REG_CMD_COUNT_2TOGO | REG_ADDR_COUNT_4; + addr1 = ((page_addr << 16) | (column & ADDR1_MASK1)); + addr2 = (page_addr >> 16); + } else { + cnt = REG_CMD_COUNT_2TOGO | REG_ADDR_COUNT_5; + addr1 = ((page_addr << 16) | (column & ADDR1_MASK1)); + addr2 = (page_addr >> 16); + } + + /* Command */ + clrsetbits_le32(&info->reg->flash_nf_command, GENMASK(31, 0), + NAND_CMD_SEQIN | (NAND_CMD_PAGEPROG << 8)); + /* CMD cycle */ + clrsetbits_le32(&info->reg->flash_nf_count, GENMASK(7, 0), cnt); + /* Data cycle */ + clrsetbits_le32(&info->reg->flash_nf_count, GENMASK(21, 8), + (mtd->writesize - 1) << 8); + /* OOB cycle */ + clrsetbits_le32(&info->reg->flash_nf_count, GENMASK(31, 22), + (mtd->oobsize - 1) << 22); + + /* addresses */ + clrsetbits_le32(&info->reg->flash_nf_address_1, GENMASK(31, 0), + addr1); + clrsetbits_le32(&info->reg->flash_nf_address_2, GENMASK(31, 0), + addr2); + + return; + case NAND_CMD_PAGEPROG: + return; + case NAND_CMD_ERASE1: + /* Command */ + clrsetbits_le32(&info->reg->flash_nf_command, GENMASK(31, 0), + NAND_CMD_ERASE1 | (NAND_CMD_ERASE2 << 8)); + /* 2 byte CMD cycle */ + clrsetbits_le32(&info->reg->flash_nf_count, GENMASK(1, 0), + REG_CMD_COUNT_2TOGO); + /* 3 byte ADDR cycle */ + clrsetbits_le32(&info->reg->flash_nf_count, GENMASK(6, 4), + REG_ADDR_COUNT_3); + /* 0 Data cycle */ + clrsetbits_le32(&info->reg->flash_nf_count, GENMASK(21, 8), + REG_DATA_COUNT_EMPTY); + /* 0 OOB cycle */ + clrsetbits_le32(&info->reg->flash_nf_count, GENMASK(31, 22), + REG_OOB_COUNT_EMPTY); + + /* addresses */ + clrsetbits_le32(&info->reg->flash_nf_address_1, GENMASK(31, 0), + page_addr); + clrsetbits_le32(&info->reg->flash_nf_address_2, GENMASK(31, 0), + 0); + + /* Issue command */ + clrsetbits_le32(&info->reg->flash_flash_access_start, + GENMASK(31, 0), NFLASH_GO | NFLASH_RD); + break; + case NAND_CMD_ERASE2: + return; + case NAND_CMD_STATUS: + /* Command */ + clrsetbits_le32(&info->reg->flash_nf_command, GENMASK(31, 0), + NAND_CMD_STATUS); + /* 1 byte CMD cycle */ + clrbits_le32(&info->reg->flash_nf_count, GENMASK(1, 0)); + /* 0 byte Addr cycle */ + clrsetbits_le32(&info->reg->flash_nf_count, GENMASK(6, 4), + REG_ADDR_COUNT_EMPTY); + /* 1 Data cycle */ + clrbits_le32(&info->reg->flash_nf_count, GENMASK(21, 8)); + /* 0 OOB cycle */ + clrsetbits_le32(&info->reg->flash_nf_count, GENMASK(31, 22), + REG_OOB_COUNT_EMPTY); + + break; + case NAND_CMD_RESET: + /* Command */ + clrsetbits_le32(&info->reg->flash_nf_command, GENMASK(31, 0), + NAND_CMD_RESET); + /* 1 byte CMD cycle */ + clrbits_le32(&info->reg->flash_nf_count, GENMASK(1, 0)); + /* 0 byte Addr cycle */ + clrsetbits_le32(&info->reg->flash_nf_count, GENMASK(6, 4), + REG_ADDR_COUNT_EMPTY); + /* 0 Data cycle */ + clrsetbits_le32(&info->reg->flash_nf_count, GENMASK(21, 8), + REG_DATA_COUNT_EMPTY); + /* 0 OOB cycle */ + clrsetbits_le32(&info->reg->flash_nf_count, GENMASK(31, 22), + REG_OOB_COUNT_EMPTY); + + /* addresses */ + clrsetbits_le32(&info->reg->flash_nf_address_1, GENMASK(31, 0), + column & ADDR1_MASK2); + clrsetbits_le32(&info->reg->flash_nf_address_2, GENMASK(31, 0), + 0); + + /* Issue command */ + clrsetbits_le32(&info->reg->flash_flash_access_start, + GENMASK(31, 0), NFLASH_GO | NFLASH_WT); + + break; + case NAND_CMD_RNDOUT: + default: + printf("%s: Unsupported command %d\n", __func__, command); + return; + } + + if (!nand_waitfor_cmd_completion(info->reg, NFLASH_GO)) + printf("Command 0x%02X timeout\n", command); +} + +/** + * Set up NAND bus width and page size + * + * @param info nand_info structure + * @return 0 if ok, -1 on error + */ +static int set_bus_width_page_size(struct mtd_info *mtd) +{ + struct nand_chip *chip = mtd_to_nand(mtd); + struct nand_drv *info = + (struct nand_drv *)nand_get_controller_data(chip); + + if (info->config.width == SZ_8) { + clrsetbits_le32(&info->reg->flash_nf_access, GENMASK(31, 0), + NFLASH_REG_WIDTH_8); + } else if (info->config.width == SZ_16) { + clrsetbits_le32(&info->reg->flash_nf_access, GENMASK(31, 0), + NFLASH_REG_WIDTH_16); + } else { + debug("%s: Unsupported bus width %d\n", __func__, + info->config.width); + return -1; + } + + if (mtd->writesize == SZ_512) { + setbits_le32(&info->reg->flash_type, FLASH_TYPE_512); + } else if (mtd->writesize == SZ_2K) { + setbits_le32(&info->reg->flash_type, FLASH_TYPE_2K); + } else if (mtd->writesize == SZ_4K) { + setbits_le32(&info->reg->flash_type, FLASH_TYPE_4K); + } else if (mtd->writesize == SZ_8K) { + setbits_le32(&info->reg->flash_type, FLASH_TYPE_8K); + } else { + debug("%s: Unsupported page size %d\n", __func__, + mtd->writesize); + return -1; + } + + return 0; +} + +static int ca_do_bch_correction(struct nand_chip *chip, + unsigned int err_num, u8 *buff_ptr, int i) +{ + struct nand_drv *info = + (struct nand_drv *)nand_get_controller_data(chip); + unsigned int reg_v, err_loc0, err_loc1; + int k, max_bitflips; + + for (k = 0; k < (err_num + 1) / 2; k++) { + reg_v = readl(&info->reg->flash_nf_bch_error_loc01 + k); + err_loc0 = reg_v & BCH_ERR_LOC_MASK; + err_loc1 = (reg_v >> 16) & BCH_ERR_LOC_MASK; + + if (err_loc0 / 8 < BCH_DATA_UNIT) { + printf("pdata[%x]:%x =>", ((i / chip->ecc.bytes) * + chip->ecc.size + ((reg_v & 0x1fff) >> 3)), + buff_ptr[(reg_v & 0x1fff) >> 3]); + + buff_ptr[err_loc0 / 8] ^= + (1 << (reg_v & BCH_CORRECT_LOC_MASK)); + + printf("%x\n", buff_ptr[(reg_v & 0x1fff) >> 3]); + + max_bitflips++; + } + + if (((k + 1) * 2) <= err_num && ((err_loc1 / 8) < + BCH_DATA_UNIT)) { + printf("pdata[%x]:%x =>", ((i / chip->ecc.bytes) * + chip->ecc.size + (((reg_v >> 16) & 0x1fff) >> + 3)), buff_ptr[((reg_v >> 16) & 0x1fff) >> 3]); + + buff_ptr[err_loc1 / 8] ^= (1 << ((reg_v >> 16) & + BCH_CORRECT_LOC_MASK)); + + printf("%x\n", buff_ptr[((reg_v >> 16) & 0x1fff) >> 3]); + + max_bitflips++; + } + } + + return max_bitflips; +} + +static int ca_do_bch_decode(struct mtd_info *mtd, struct nand_chip *chip, + const u8 *buf, int page, unsigned int addr) +{ + struct nand_drv *info = + (struct nand_drv *)nand_get_controller_data(chip); + unsigned int reg_v, err_num; + unsigned char *ecc_code = chip->buffers->ecccode; + unsigned char *ecc_end_pos; + int ret, i, j, k, n, step, eccsteps, max_bitflips = 0; + u8 *buff_ptr = (u8 *)buf; + + for (i = 0; i < chip->ecc.total; i++) + ecc_code[i] = chip->oob_poi[eccoob.eccpos[i]]; + + for (i = 0, eccsteps = chip->ecc.steps; eccsteps; + i += chip->ecc.bytes, eccsteps--) { + ecc_end_pos = ecc_code + chip->ecc.bytes; + + for (j = 0, k = 0; j < chip->ecc.bytes; j += 4, k++) { + reg_v = 0; + for (n = 0; n < 4 && ecc_code != ecc_end_pos; + ++n, ++ecc_code) { + reg_v |= *ecc_code << (8 * n); + } + clrsetbits_le32(&info->reg->flash_nf_bch_oob0 + k, + GENMASK(31, 0), reg_v); + } + + /* Clear ECC buffer */ + setbits_le32(&info->reg->flash_nf_ecc_reset, RESET_NFLASH_ECC); + ret = readl_poll_timeout(&info->reg->flash_nf_ecc_reset, reg_v, + !(reg_v & RESET_NFLASH_ECC), + FLASH_SHORT_DELAY); + if (ret) + pr_err("Reset ECC buffer fail\n"); + + clrsetbits_le32(&info->reg->flash_nf_bch_control, GENMASK(8, 8), + BCH_DISABLE); + + /* Start BCH */ + step = i / chip->ecc.bytes; + clrsetbits_le32(&info->reg->flash_nf_bch_control, + GENMASK(6, 4), step << 4); + setbits_le32(&info->reg->flash_nf_bch_control, BCH_ENABLE); + udelay(10); + setbits_le32(&info->reg->flash_nf_bch_control, BCH_COMPARE); + + ret = readl_poll_timeout(&info->reg->flash_nf_bch_status, reg_v, + (reg_v & BCH_DECO_DONE), + FLASH_SHORT_DELAY); + if (ret) + pr_err("ECC Decode timeout\n"); + + /* Stop compare */ + clrbits_le32(&info->reg->flash_nf_bch_control, BCH_COMPARE); + + reg_v = readl(&info->reg->flash_nf_bch_status); + err_num = (reg_v >> 8) & BCH_ERR_NUM_MASK; + reg_v &= BCH_ERR_MASK; + + /* Uncorrectable */ + if (reg_v == BCH_UNCORRECTABLE) { + max_bitflips = + nand_check_erased_ecc_chunk(buff_ptr, + chip->ecc.size, + &chip->buffers->ecccode[i], + chip->ecc.bytes, + NULL, 0, + chip->ecc.strength); + + if (max_bitflips) { + mtd->ecc_stats.failed++; + pr_err("Uncorrectable error\n"); + pr_err(" Page:%x step:%d\n", page, step); + + return -1; + } + } else if (reg_v == BCH_CORRECTABLE_ERR) { + printf("Correctable error(%x)!! addr:%lx\n", + err_num, (unsigned long)addr - mtd->writesize); + printf("Dst buf: %p [ColSel:%x ]\n", + buff_ptr + reg_v * BCH_DATA_UNIT, step); + + max_bitflips = + ca_do_bch_correction(chip, err_num, buff_ptr, i); + } + + buff_ptr += BCH_DATA_UNIT; + } + + /* Disable BCH */ + clrsetbits_le32(&info->reg->flash_nf_bch_control, GENMASK(31, 0), + BCH_DISABLE); + + return max_bitflips; +} + +static int ca_do_bch_encode(struct mtd_info *mtd, struct nand_chip *chip, + int page) +{ + struct nand_drv *info; + unsigned int reg_v; + int i, j, n, eccsteps, gen_index; + + info = (struct nand_drv *)nand_get_controller_data(chip); + + for (i = 0, n = 0, eccsteps = chip->ecc.steps; eccsteps; + i += chip->ecc.bytes, eccsteps--, n++) { + gen_index = 0; + for (j = 0; j < chip->ecc.bytes; j += 4, gen_index++) { + reg_v = + readl(&info->reg->flash_nf_bch_gen0_0 + gen_index + + 18 * n); + chip->oob_poi[eccoob.eccpos[i + j]] = reg_v & OOB_MASK; + chip->oob_poi[eccoob.eccpos[i + j + 1]] = + (reg_v >> 8) & OOB_MASK; + chip->oob_poi[eccoob.eccpos[i + j + 2]] = + (reg_v >> 16) & OOB_MASK; + chip->oob_poi[eccoob.eccpos[i + j + 3]] = + (reg_v >> 24) & OOB_MASK; + } + } + + /* Disable BCH */ + clrsetbits_le32(&info->reg->flash_nf_bch_control, GENMASK(8, 8), + BCH_DISABLE); + + return 0; +} + +/** + * Page read/write function + * + * @param mtd mtd info structure + * @param chip nand chip info structure + * @param buf data buffer + * @param page page number + * @param with_ecc 1 to enable ECC, 0 to disable ECC + * @param is_writing 0 for read, 1 for write + * @return 0 when successfully completed + * -ETIMEDOUT when command timeout + */ +static int nand_rw_page(struct mtd_info *mtd, struct nand_chip *chip, + const u8 *buf, int page, int with_ecc, int is_writing) +{ + unsigned int reg_v, ext_addr, addr, dma_index; + struct tx_descriptor_t *tx_desc; + struct rx_descriptor_t *rx_desc; + struct nand_drv *info = + (struct nand_drv *)nand_get_controller_data(chip); + int ret; + + /* reset ecc control */ + clrsetbits_le32(&info->reg->flash_nf_ecc_reset, GENMASK(31, 0), + RESET_NFLASH_ECC); + + /* flash interrupt */ + clrsetbits_le32(&info->reg->flash_flash_interrupt, GENMASK(0, 0), + REGIRQ_CLEAR); + + /* reset ecc control */ + clrsetbits_le32(&info->reg->flash_nf_ecc_reset, GENMASK(31, 0), + RESET_NFLASH_ECC); + + /* Disable TXQ */ + clrbits_le32(&info->dma_nand->dma_q_txq_control, GENMASK(0, 0)); + + /* Clear interrupt */ + setbits_le32(&info->dma_nand->dma_q_rxq_coal_interrupt, GENMASK(0, 0)); + setbits_le32(&info->dma_nand->dma_q_txq_coal_interrupt, GENMASK(0, 0)); + + if (with_ecc == 1) { + switch (info->config.nand_ecc_strength) { + case ECC_STRENGTH_8: + reg_v = BCH_ERR_CAP_8; + break; + case ECC_STRENGTH_16: + reg_v = BCH_ERR_CAP_16; + break; + case ECC_STRENGTH_24: + reg_v = BCH_ERR_CAP_24; + break; + case ECC_STRENGTH_40: + reg_v = BCH_ERR_CAP_40; + break; + default: + reg_v = BCH_ERR_CAP_16; + break; + } + reg_v |= BCH_ENABLE; + + /* BCH decode for flash read */ + if (is_writing == 0) + reg_v |= BCH_DECODE; + clrsetbits_le32(&info->reg->flash_nf_bch_control, + GENMASK(31, 0), reg_v); + } else { + clrsetbits_le32(&info->reg->flash_nf_bch_control, + GENMASK(31, 0), 0); + } + + /* Fill Extend address */ + ext_addr = ((page << chip->page_shift) / EXT_ADDR_MASK); + + clrsetbits_le32(&info->reg->flash_nf_access, + GENMASK(7, 0), (uintptr_t)ext_addr); + + addr = (uintptr_t)((page << chip->page_shift) % EXT_ADDR_MASK); + addr = (uintptr_t)(addr + info->flash_base); + + dma_index = readl(&info->dma_nand->dma_q_txq_wptr) & CA_DMA_Q_PTR_MASK; + + tx_desc = info->tx_desc; + rx_desc = info->rx_desc; + + /* TX/RX descriptor for page data */ + tx_desc[dma_index].own = OWN_DMA; + tx_desc[dma_index].buf_len = mtd->writesize; + rx_desc[dma_index].own = OWN_DMA; + rx_desc[dma_index].buf_len = mtd->writesize; + if (is_writing == 0) { + tx_desc[dma_index].buf_adr = (uintptr_t)addr; + rx_desc[dma_index].buf_adr = (uintptr_t)(buf); + } else { + tx_desc[dma_index].buf_adr = (uintptr_t)buf; + rx_desc[dma_index].buf_adr = (uintptr_t)(addr); + } + + dma_index++; + dma_index %= CA_DMA_DESC_NUM; + + /* TX/RX descriptor for OOB area */ + addr = (uintptr_t)(addr + mtd->writesize); + tx_desc[dma_index].own = OWN_DMA; + tx_desc[dma_index].buf_len = mtd->oobsize; + rx_desc[dma_index].own = OWN_DMA; + rx_desc[dma_index].buf_len = mtd->oobsize; + if (is_writing) { + tx_desc[dma_index].buf_adr = (uintptr_t)(chip->oob_poi); + rx_desc[dma_index].buf_adr = (uintptr_t)addr; + } else { + tx_desc[dma_index].buf_adr = (uintptr_t)addr; + rx_desc[dma_index].buf_adr = (uintptr_t)(chip->oob_poi); + dma_index++; + dma_index %= CA_DMA_DESC_NUM; + } + + if (is_writing == 1) { + clrsetbits_le32(&info->reg->flash_fifo_control, GENMASK(1, 0), + FIFO_WRITE); + } else { + clrsetbits_le32(&info->reg->flash_fifo_control, GENMASK(1, 0), + FIFO_READ); + } + + /* Start FIFO request */ + clrsetbits_le32(&info->reg->flash_flash_access_start, GENMASK(2, 2), + NFLASH_FIFO_REQ); + + /* Update DMA write pointer */ + clrsetbits_le32(&info->dma_nand->dma_q_txq_wptr, GENMASK(12, 0), + dma_index); + + /* Start DMA */ + clrsetbits_le32(&info->dma_nand->dma_q_txq_control, GENMASK(0, 0), + TX_DMA_ENABLE); + + /* Wait TX DMA done */ + ret = + readl_poll_timeout(&info->dma_nand->dma_q_txq_coal_interrupt, + reg_v, (reg_v & 1), FLASH_LONG_DELAY); + if (ret) { + pr_err("TX DMA timeout\n"); + return -ETIMEDOUT; + } + /* clear tx interrupt */ + setbits_le32(&info->dma_nand->dma_q_txq_coal_interrupt, 1); + + /* Wait RX DMA done */ + ret = + readl_poll_timeout(&info->dma_nand->dma_q_rxq_coal_interrupt, reg_v, + (reg_v & 1), FLASH_LONG_DELAY); + if (ret) { + pr_err("RX DMA timeout\n"); + return -ETIMEDOUT; + } + /* clear rx interrupt */ + setbits_le32(&info->dma_nand->dma_q_rxq_coal_interrupt, 1); + + /* wait NAND CMD done */ + if (is_writing == 0) { + if (!nand_waitfor_cmd_completion(info->reg, NFLASH_FIFO_REQ)) + printf("%s: Command timeout\n", __func__); + } + + /* Update DMA read pointer */ + clrsetbits_le32(&info->dma_nand->dma_q_rxq_rptr, GENMASK(12, 0), + dma_index); + + /* ECC correction */ + if (with_ecc == 1) { + ret = + readl_poll_timeout(&info->reg->flash_nf_bch_status, + reg_v, (reg_v & BCH_GEN_DONE), + FLASH_LONG_DELAY); + + if (ret) { + pr_err("BCH_GEN timeout! flash_nf_bch_status=[0x%x]\n", + reg_v); + return -ETIMEDOUT; + } + + if (is_writing == 0) + ca_do_bch_decode(mtd, chip, buf, page, addr); + else + ca_do_bch_encode(mtd, chip, page); + } + + if (is_writing) { + dma_index++; + dma_index %= CA_DMA_DESC_NUM; + + /* Update DMA R/W pointer */ + clrsetbits_le32(&info->dma_nand->dma_q_txq_wptr, GENMASK(12, 0), + dma_index); + + /* Wait TX DMA done */ + ret = + readl_poll_timeout(&info->dma_nand->dma_q_txq_coal_interrupt, + reg_v, (reg_v & 1), FLASH_LONG_DELAY); + if (ret) { + pr_err("TX DMA timeout\n"); + return -ETIMEDOUT; + } + /* clear tx interrupt */ + setbits_le32(&info->dma_nand->dma_q_txq_coal_interrupt, 1); + + /* Wait RX DMA done */ + ret = + readl_poll_timeout(&info->dma_nand->dma_q_rxq_coal_interrupt, + reg_v, (reg_v & 1), FLASH_LONG_DELAY); + if (ret) { + pr_err("RX DMA timeout\n"); + return -ETIMEDOUT; + } + /* clear rx interrupt */ + setbits_le32(&info->dma_nand->dma_q_rxq_coal_interrupt, 1); + + /* wait NAND CMD done */ + if (!nand_waitfor_cmd_completion(info->reg, NFLASH_FIFO_REQ)) + printf("%s: Command timeout\n", __func__); + + /* Update DMA R/W pointer */ + clrsetbits_le32(&info->dma_nand->dma_q_rxq_rptr, GENMASK(12, 0), + dma_index); + } + + return 0; +} + +/** + * Hardware ecc based page read function + * + * @param mtd mtd info structure + * @param chip nand chip info structure + * @param buf buffer to store read data + * @param page page number to read + * @return 0 when successfully completed + * -ETIMEDOUT when command timeout + */ +static int nand_read_page_hwecc(struct mtd_info *mtd, + struct nand_chip *chip, uint8_t *buf, + int oob_required, int page) +{ + struct nand_drv *info = + (struct nand_drv *)nand_get_controller_data(chip); + int ret; + + ret = nand_rw_page(mtd, chip, buf, page, 1, 0); + if (ret) + return ret; + + /* Reset FIFO */ + clrsetbits_le32(&info->reg->flash_nf_ecc_reset, GENMASK(31, 0), + ECC_RESET_ALL); + + return 0; +} + +/** + * Hardware ecc based page write function + * + * @param mtd mtd info structure + * @param chip nand chip info structure + * @param buf data buffer + * @return 0 when successfully completed + * -ETIMEDOUT when command timeout + */ +static int nand_write_page_hwecc(struct mtd_info *mtd, + struct nand_chip *chip, const uint8_t *buf, + int oob_required, int page) +{ + struct nand_drv *info = + (struct nand_drv *)nand_get_controller_data(chip); + int ret; + + ret = nand_rw_page(mtd, chip, (uint8_t *)buf, page, 1, 1); + if (ret) + return ret; + + /* Reset FIFO */ + clrsetbits_le32(&info->reg->flash_nf_ecc_reset, GENMASK(31, 0), + ECC_RESET_ALL); + + return 0; +} + +/** + * Read raw page data without ecc + * + * @param mtd mtd info structure + * @param chip nand chip info structure + * @param buf buffer to store read data + * @param page page number to read + * @return 0 when successfully completed + * -ETIMEDOUT when command timeout + */ +static int nand_read_page_raw(struct mtd_info *mtd, + struct nand_chip *chip, uint8_t *buf, + int oob_required, int page) +{ + struct nand_drv *info = + (struct nand_drv *)nand_get_controller_data(chip); + int ret; + + ret = nand_rw_page(mtd, chip, buf, page, 0, 0); + if (ret) + return ret; + + /* Reset FIFO */ + clrsetbits_le32(&info->reg->flash_nf_ecc_reset, GENMASK(31, 0), + ECC_RESET_ALL); + + return 0; +} + +/** + * Raw page write function + * + * @param mtd mtd info structure + * @param chip nand chip info structure + * @param buf data buffer + * @return 0 when successfully completed + * -ETIMEDOUT when command timeout + */ +static int nand_write_page_raw(struct mtd_info *mtd, + struct nand_chip *chip, const uint8_t *buf, + int oob_required, int page) +{ + struct nand_drv *info = + (struct nand_drv *)nand_get_controller_data(chip); + int ret; + + ret = nand_rw_page(mtd, chip, buf, page, 0, 1); + if (ret) + return ret; + + /* Reset FIFO */ + clrsetbits_le32(&info->reg->flash_nf_ecc_reset, GENMASK(31, 0), + ECC_RESET_ALL); + + return 0; +} + +/** + * OOB data read/write function + * + * @param mtd mtd info structure + * @param chip nand chip info structure + * @param page page number to read + * @param with_ecc 1 to enable ECC, 0 to disable ECC + * @param is_writing 0 for read, 1 for write + * @return 0 when successfully completed + * -ETIMEDOUT when command timeout + */ +static int nand_rw_oob(struct mtd_info *mtd, struct nand_chip *chip, + int page, int with_ecc, int is_writing) +{ + struct nand_drv *info = + (struct nand_drv *)nand_get_controller_data(chip); + u32 reg_val; + int rw_index; + + if (is_writing) { + reg_val = NFLASH_GO | NFLASH_WT; + pwrite = (unsigned int *)chip->oob_poi; + } else { + reg_val = NFLASH_GO | NFLASH_RD; + pread = (unsigned int *)chip->oob_poi; + } + + for (rw_index = 0; rw_index < mtd->oobsize / 4; rw_index++) { + clrsetbits_le32(&info->reg->flash_nf_access, GENMASK(31, 0), + NFLASH_REG_WIDTH_32); + if (is_writing) + clrsetbits_le32(&info->reg->flash_nf_data, + GENMASK(31, 0), pwrite[rw_index]); + + clrsetbits_le32(&info->reg->flash_flash_access_start, + GENMASK(11, 10), reg_val); + + if (!nand_waitfor_cmd_completion(info->reg, NFLASH_GO)) + printf("%s: Command timeout\n", __func__); + + if (!is_writing) + pread[rw_index] = readl(&info->reg->flash_nf_data); + } + return 0; +} + +/** + * OOB data read function + * + * @param mtd mtd info structure + * @param chip nand chip info structure + * @param page page number to read + */ +static int nand_read_oob(struct mtd_info *mtd, struct nand_chip *chip, int page) +{ + struct nand_drv *info = + (struct nand_drv *)nand_get_controller_data(chip); + int ret; + + chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page); + if (mtd->writesize <= (REG_DATA_COUNT_512_DATA >> 8)) + clrsetbits_le32(&info->reg->flash_nf_command, GENMASK(7, 0), + NAND_CMD_READOOB); + ret = nand_rw_oob(mtd, chip, page, 0, 0); + + /* Reset FIFO */ + clrsetbits_le32(&info->reg->flash_nf_ecc_reset, + GENMASK(31, 0), ECC_RESET_ALL); + + return ret; +} + +/** + * OOB data write function + * + * @param mtd mtd info structure + * @param chip nand chip info structure + * @param page page number to write + * @return 0 when successfully completed + * -ETIMEDOUT when command timeout + */ +static int nand_write_oob(struct mtd_info *mtd, struct nand_chip *chip, + int page) +{ + struct nand_drv *info = + (struct nand_drv *)nand_get_controller_data(chip); + int ret; + + chip->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->writesize, page); + if (mtd->writesize <= (REG_DATA_COUNT_512_DATA >> 8)) { + clrsetbits_le32(&info->reg->flash_nf_command, GENMASK(31, 0), + NAND_CMD_READOOB | (NAND_CMD_SEQIN << 8) | + (NAND_CMD_PAGEPROG << 16)); + clrsetbits_le32(&info->reg->flash_nf_count, GENMASK(1, 0), + REG_CMD_COUNT_3TOGO); + } + ret = nand_rw_oob(mtd, chip, page, 1, 1); + + /* Reset FIFO */ + clrsetbits_le32(&info->reg->flash_nf_ecc_reset, + GENMASK(31, 0), ECC_RESET_ALL); + + return ret; +} + +/** + * Decode NAND parameters from the device tree + * + * @param dev Driver model device + * @param config Device tree NAND configuration + */ +static int fdt_decode_nand(struct udevice *dev, struct nand_drv *info) +{ + int ecc_strength; + + info->reg = (struct nand_ctlr *)dev_read_addr(dev); + info->dma_glb = (struct dma_global *)dev_read_addr_index(dev, 1); + info->dma_nand = (struct dma_ssp *)dev_read_addr_index(dev, 2); + info->config.enabled = dev_read_enabled(dev); + ecc_strength = dev_read_u32_default(dev, "nand-ecc-strength", 16); + info->flash_base = + dev_read_u32_default(dev, "nand_flash_base_addr", NAND_BASE_ADDR); + + switch (ecc_strength) { + case ECC_STRENGTH_8: + info->config.nand_ecc_strength = ECC_STRENGTH_8; + break; + case ECC_STRENGTH_16: + info->config.nand_ecc_strength = ECC_STRENGTH_16; + break; + case ECC_STRENGTH_24: + info->config.nand_ecc_strength = ECC_STRENGTH_24; + break; + case ECC_STRENGTH_40: + info->config.nand_ecc_strength = ECC_STRENGTH_40; + break; + default: + info->config.nand_ecc_strength = ECC_STRENGTH_16; + } + + return 0; +} + +/** + * config flash type + * + * @param chip nand chip info structure + */ +static void nand_config_flash_type(struct nand_chip *nand) +{ + struct nand_drv *info = + (struct nand_drv *)nand_get_controller_data(nand); + struct mtd_info *mtd = nand_to_mtd(nand); + + switch (mtd->writesize) { + case WRITE_SIZE_512: + clrsetbits_le32(&info->reg->flash_type, GENMASK(31, 0), + FLASH_PIN | FLASH_TYPE_512); + break; + case WRITE_SIZE_2048: + clrsetbits_le32(&info->reg->flash_type, GENMASK(31, 0), + FLASH_PIN | FLASH_TYPE_2K); + break; + case WRITE_SIZE_4096: + clrsetbits_le32(&info->reg->flash_type, GENMASK(31, 0), + FLASH_PIN | FLASH_TYPE_4K); + break; + case WRITE_SIZE_8192: + clrsetbits_le32(&info->reg->flash_type, GENMASK(31, 0), + FLASH_PIN | FLASH_TYPE_8K); + break; + default: + pr_err("Unsupported page size(0x%x)!", nand->ecc.size); + } +} + +/** + * config oob layout + * + * @param chip nand chip info structure + * @return 0 when successfully completed + * -EINVAL when ECC bytes exceed OOB size + */ +static int nand_config_oob_layout(struct nand_chip *nand) +{ + int i, ecc_start_offset; + struct mtd_info *mtd = nand_to_mtd(nand); + + /* Calculate byte count for ECC */ + eccoob.eccbytes = mtd->writesize / nand->ecc.size * nand->ecc.bytes; + + if (mtd->oobsize < eccoob.eccbytes) { + pr_err("Spare area(%d) too small for BCH%d\n", nand->ecc.bytes, + nand->ecc.strength / 8); + pr_err("page_sz: %d\n", nand->ecc.size); + pr_err("oob_sz: %d\n", nand->ecc.bytes); + return -EINVAL; + } + + /* Update OOB layout */ + ecc_start_offset = mtd->oobsize - eccoob.eccbytes; + memset(eccoob.eccpos, 0, sizeof(eccoob.eccpos)); + for (i = 0; i < eccoob.eccbytes; ++i) + eccoob.eccpos[i] = i + ecc_start_offset; + + /* Unused spare area + * OOB[0] is bad block marker. + * Extra two byte is reserved as + * erase marker just right before ECC code. + */ + eccoob.oobavail = nand->ecc.bytes - eccoob.eccbytes - 2; + eccoob.oobfree[0].offset = 2; + eccoob.oobfree[0].length = + mtd->oobsize - eccoob.eccbytes - eccoob.oobfree[0].offset - 1; + + return 0; +} + +static int ca_nand_probe(struct udevice *dev) +{ + struct ca_nand_info *ca_nand = dev_get_priv(dev); + struct nand_chip *nand = &ca_nand->nand_chip; + struct nand_drv *info = &ca_nand->nand_ctrl; + struct fdt_nand *config = &info->config; + struct mtd_info *our_mtd; + int ret; + + if (fdt_decode_nand(dev, info)) { + printf("Could not decode nand-flash in device tree\n"); + return -1; + } + if (!config->enabled) + return -1; + + nand->ecc.mode = NAND_ECC_HW; + nand->ecc.layout = &eccoob; + + nand->cmdfunc = ca_nand_command; + nand->read_byte = read_byte; + nand->read_buf = read_buf; + nand->ecc.read_page = nand_read_page_hwecc; + nand->ecc.write_page = nand_write_page_hwecc; + nand->ecc.read_page_raw = nand_read_page_raw; + nand->ecc.write_page_raw = nand_write_page_raw; + nand->ecc.read_oob = nand_read_oob; + nand->ecc.write_oob = nand_write_oob; + nand->ecc.strength = config->nand_ecc_strength; + nand->select_chip = nand_select_chip; + nand->dev_ready = nand_dev_ready; + nand_set_controller_data(nand, &ca_nand->nand_ctrl); + + /* Disable subpage writes as we do not provide ecc->hwctl */ + nand->options |= NAND_NO_SUBPAGE_WRITE | NAND_SKIP_BBTSCAN; + + /* Configure flash type as P-NAND */ + clrsetbits_le32(&info->reg->flash_type, FLASH_PIN, + FLASH_TYPE_4K | FLASH_SIZE_436OOB); + config->width = FLASH_WIDTH; + + our_mtd = nand_to_mtd(nand); + ret = nand_scan_ident(our_mtd, CONFIG_SYS_NAND_MAX_CHIPS, NULL); + if (ret) + return ret; + + nand->ecc.size = BCH_DATA_UNIT; + nand->ecc.bytes = BCH_GF_PARAM_M * (nand->ecc.strength / 8); + + /* Reconfig flash type according to ONFI */ + nand_config_flash_type(nand); + + ret = set_bus_width_page_size(our_mtd); + if (ret) + return ret; + + /* Set the bad block position */ + nand->badblockpos = + our_mtd->writesize > + 512 ? NAND_LARGE_BADBLOCK_POS : NAND_SMALL_BADBLOCK_POS; + + /* Arrange OOB layout */ + ret = nand_config_oob_layout(nand); + if (ret) + return ret; + + /* Init DMA descriptor ring */ + ret = init_nand_dma(nand); + if (ret) + return ret; + + ret = nand_scan_tail(our_mtd); + if (ret) + return ret; + + ret = nand_register(0, our_mtd); + if (ret) { + dev_err(dev, "Failed to register MTD: %d\n", ret); + return ret; + } + + ret = set_bus_width_page_size(our_mtd); + if (ret) + return ret; + + printf("P-NAND : %s\n", our_mtd->name); + printf("Chip Size: %lldMB\n", nand->chipsize / (1024 * 1024)); + printf("Block Size: %dKB\n", our_mtd->erasesize / 1024); + printf("Page Size: %dB\n", our_mtd->writesize); + printf("OOB Size: %dB\n", our_mtd->oobsize); + + return 0; +} + +U_BOOT_DRIVER(cortina_nand) = { + .name = "CA-PNAND", + .id = UCLASS_MTD, + .of_match = cortina_nand_dt_ids, + .probe = ca_nand_probe, + .priv_auto = sizeof(struct ca_nand_info), +}; + +void board_nand_init(void) +{ + struct udevice *dev; + int ret; + + ret = uclass_get_device_by_driver(UCLASS_MTD, + DM_DRIVER_GET(cortina_nand), &dev); + if (ret && ret != -ENODEV) + pr_err("Failed to initialize %s. (error %d)\n", dev->name, ret); +} diff --git a/drivers/mtd/nand/raw/cortina_nand.h b/drivers/mtd/nand/raw/cortina_nand.h new file mode 100644 index 0000000000..1e3e3bfd05 --- /dev/null +++ b/drivers/mtd/nand/raw/cortina_nand.h @@ -0,0 +1,293 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2020 Cortina Access Inc.. + */ + +/* Cortina NAND definition */ +#define NAND_BASE_ADDR 0xE0000000 +#define BCH_GF_PARAM_M 14 +#define BCH_DATA_UNIT 1024 +#define FLASH_SHORT_DELAY 100 +#define FLASH_LONG_DELAY 1000 +#define FLASH_WIDTH 16 +#define BBT_PAGE_MASK 0xffffff3f +#define WRITE_SIZE_512 512 +#define WRITE_SIZE_2048 2048 +#define WRITE_SIZE_4096 4096 +#define WRITE_SIZE_8192 8192 +#define ECC_STRENGTH_8 8 +#define ECC_STRENGTH_16 16 +#define ECC_STRENGTH_24 24 +#define ECC_STRENGTH_40 40 +#define EMPTY_PAGE 0xff +#define ADDR1_MASK0 0x00ffffff +#define ADDR2_MASK0 0xff000000 +#define ADDR1_MASK1 0xffff +#define ADDR1_MASK2 0xff +#define OOB_MASK 0xff +#define EXT_ADDR_MASK 0x8000000 + +/* Status bits */ +#define NAND_STATUS_FAIL 0x01 +#define NAND_STATUS_FAIL_N1 0x02 +#define NAND_STATUS_TRUE_READY 0x20 +#define NAND_STATUS_READY 0x40 +#define NAND_STATUS_WP 0x80 + +/* Bit field in FLAS_TYPE */ +#define FLASH_PIN BIT(15) +#define FLASH_TYPE_512 0x4000 +#define FLASH_TYPE_2K 0x5000 +#define FLASH_TYPE_4K 0x6000 +#define FLASH_TYPE_8K 0x7000 +#define FLASH_SIZE_CONFIGURABLEOOB (0x0 << 9) +#define FLASH_SIZE_400OOB (0x1 << 9) +#define FLASH_SIZE_436OOB (0x2 << 9) +#define FLASH_SIZE_640OOB (0x3 << 9) + +/* Bit field in FLASH_STATUS */ +#define NFLASH_READY BIT(26) + +/* Bit field in FLASH_NF_ACCESS */ +#define NFLASH_ENABLE_ALTERNATIVE (0x0 << 15) +#define AUTO_RESET BIT(16) +#define DISABLE_AUTO_RESET (0x0 << 16) +#define NFLASH_REG_WIDTH_RESERVED (0x3 << 10) +#define NFLASH_REG_WIDTH_32 (0x2 << 10) +#define NFLASH_REG_WIDTH_16 (0x1 << 10) +#define NFLASH_REG_WIDTH_8 (0x0 << 10) + +/* Bit field in FLASH_NF_COUNT */ +#define REG_CMD_COUNT_EMPTY 0x3 +#define REG_CMD_COUNT_3TOGO 0x2 +#define REG_CMD_COUNT_2TOGO 0x1 +#define REG_CMD_COUNT_1TOGO 0x0 +#define REG_ADDR_COUNT_EMPTY (0x7 << 4) +#define REG_ADDR_COUNT_5 (0x4 << 4) +#define REG_ADDR_COUNT_4 (0x3 << 4) +#define REG_ADDR_COUNT_3 (0x2 << 4) +#define REG_ADDR_COUNT_2 (0x1 << 4) +#define REG_ADDR_COUNT_1 (0x0 << 4) +#define REG_DATA_COUNT_EMPTY (0x3fff << 8) +#define REG_DATA_COUNT_512_DATA (0x1FF << 8) +#define REG_DATA_COUNT_2k_DATA (0x7FF << 8) +#define REG_DATA_COUNT_4k_DATA (0xFFF << 8) +#define REG_DATA_COUNT_DATA_1 (0x0 << 8) +#define REG_DATA_COUNT_DATA_2 (0x1 << 8) +#define REG_DATA_COUNT_DATA_3 (0x2 << 8) +#define REG_DATA_COUNT_DATA_4 (0x3 << 8) +#define REG_DATA_COUNT_DATA_5 (0x4 << 8) +#define REG_DATA_COUNT_DATA_6 (0x5 << 8) +#define REG_DATA_COUNT_DATA_7 (0x6 << 8) +#define REG_DATA_COUNT_DATA_8 (0x7 << 8) +#define REG_OOB_COUNT_EMPTY (0x3ff << 22) + +/* Bit field in FLASH_FLASH_ACCESS_START */ +#define NFLASH_GO BIT(0) +#define NFLASH_FIFO_REQ BIT(2) +#define NFLASH_RD BIT(13) +#define NFLASH_WT (BIT(12) | BIT(13)) + +/* Bit field in FLASH_NF_ECC_RESET */ +#define RESET_NFLASH_RESET BIT(2) +#define RESET_NFLASH_FIFO BIT(1) +#define RESET_NFLASH_ECC BIT(0) +#define ECC_RESET_ALL \ + RESET_NFLASH_RESET | RESET_NFLASH_FIFO | RESET_NFLASH_ECC + +/* Bit field in FLASH_NF_ECC_CONTROL */ +#define ENABLE_ECC_GENERATION BIT(8) +#define DISABLE_ECC_GENERATION (0 << 8) + +/* Flash FIFO control */ +#define FIFO_READ 2 +#define FIFO_WRITE 3 + +/* NFLASH INTERRUPT */ +#define REGIRQ_CLEAR BIT(0) +#define F_ADDR_ERR 2 + +/* BCH ECC field definition */ +#define BCH_COMPARE BIT(0) +#define BCH_ENABLE BIT(8) +#define BCH_DISABLE (0 << 8) +#define BCH_DECODE BIT(1) +#define BCH_ENCODE (0 << 1) +#define BCH_DECO_DONE BIT(30) +#define BCH_GEN_DONE BIT(31) +#define BCH_UNCORRECTABLE 0x3 +#define BCH_CORRECTABLE_ERR 0x2 +#define BCH_NO_ERR 0x1 +#define BCH_BUSY 0x0 +#define BCH_ERR_MASK 0x3 +#define BCH_ERR_NUM_MASK 0x3F +#define BCH_ERR_LOC_MASK 0x3FFF +#define BCH_CORRECT_LOC_MASK 0x7 +#define BCH_ERR_CAP_8 (0x0 << 9) +#define BCH_ERR_CAP_16 (0x1 << 9) +#define BCH_ERR_CAP_24 (0x2 << 9) +#define BCH_ERR_CAP_40 (0x3 << 9) + +#define BCH_GF_PARAM_M 14 + +struct nand_ctlr { + /* Cortina NAND controller register */ + u32 flash_id; + u32 flash_timeout; + u32 flash_status; + u32 flash_type; + u32 flash_flash_access_start; + u32 flash_flash_interrupt; + u32 flash_flash_mask; + u32 flash_fifo_control; + u32 flash_fifo_status; + u32 flash_fifo_address; + u32 flash_fifo_match_address; + u32 flash_fifo_data; + u32 flash_sf_access; + u32 flash_sf_ext_access; + u32 flash_sf_address; + u32 flash_sf_data; + u32 flash_sf_timing; + u32 resv[3]; + u32 flash_pf_access; // offset 0x050 + u32 flash_pf_timing; + u32 resv1[2]; + u32 flash_nf_access; // offset 0x060 + u32 flash_nf_count; + u32 flash_nf_command; + u32 flash_nf_address_1; + u32 flash_nf_address_2; + u32 flash_nf_data; + u32 flash_nf_timing; + u32 flash_nf_ecc_status; + u32 flash_nf_ecc_control; + u32 flash_nf_ecc_oob; + u32 flash_nf_ecc_gen0; + u32 resv3[15]; + u32 flash_nf_ecc_reset; // offset 0x0c8 + u32 flash_nf_bch_control; + u32 flash_nf_bch_status; + u32 flash_nf_bch_error_loc01; + u32 resv4[19]; + u32 flash_nf_bch_oob0; // offset 0x124 + u32 resv5[17]; + u32 flash_nf_bch_gen0_0; // offset 0x16c +}; + +/* Definition for DMA bitfield */ +#define TX_DMA_ENABLE BIT(0) +#define RX_DMA_ENABLE BIT(0) +#define DMA_CHECK_OWNER BIT(1) +#define OWN_DMA 0 +#define OWN_CPU 1 + +#define CA_DMA_DEPTH 3 +#define CA_DMA_DESC_NUM (BIT(0) << CA_DMA_DEPTH) +#define CA_DMA_Q_PTR_MASK 0x1fff + +struct dma_q_base_depth_t { + u32 depth : 4 ; /* bits 3:0 */ + u32 base : 28 ; /* bits 31:4 */ +}; + +struct tx_descriptor_t { + unsigned int buf_adr; /* Buff addr */ + unsigned int buf_adr_hi : 8 ; /* bits 7:0 */ + unsigned int buf_len : 16 ; /* bits 23:8 */ + unsigned int sgm : 1 ; /* bits 24 */ + unsigned int rsrvd : 6 ; /* bits 30:25 */ + unsigned int own : 1 ; /* bits 31:31 */ +}; + +struct rx_descriptor_t { + unsigned int buf_adr; /* Buff addr */ + unsigned int buf_adr_hi : 8 ; /* bits 7:0 */ + unsigned int buf_len : 16 ; /* bits 23:8 */ + unsigned int rsrvd : 7 ; /* bits 30:24 */ + unsigned int own : 1 ; /* bits 31:31 */ +}; + +struct dma_global { + u32 dma_glb_dma_lso_ctrl; + u32 dma_glb_lso_interrupt; + u32 dma_glb_lso_intenable; + u32 dma_glb_dma_lso_vlan_tag_type0; + u32 dma_glb_dma_lso_vlan_tag_type1; + u32 dma_glb_dma_lso_axi_user_sel0; + u32 dma_glb_axi_user_pat0; + u32 dma_glb_axi_user_pat1; + u32 dma_glb_axi_user_pat2; + u32 dma_glb_axi_user_pat3; + u32 dma_glb_fast_reg_pe0; + u32 dma_glb_fast_reg_pe1; + u32 dma_glb_dma_lso_tx_fdes_addr0; + u32 dma_glb_dma_lso_tx_fdes_addr1; + u32 dma_glb_dma_lso_tx_cdes_addr0; + u32 dma_glb_dma_lso_tx_cdes_addr1; + u32 dma_glb_dma_lso_tx_des_word0; + u32 dma_glb_dma_lso_tx_des_word1; + u32 dma_glb_dma_lso_lso_para_word0; + u32 dma_glb_dma_lso_lso_para_word1; + u32 dma_glb_dma_lso_debug0; + u32 dma_glb_dma_lso_debug1; + u32 dma_glb_dma_lso_debug2; + u32 dma_glb_dma_lso_spare0; + u32 dma_glb_dma_lso_spare1; + u32 dma_glb_dma_ssp_rx_ctrl; + u32 dma_glb_dma_ssp_tx_ctrl; + u32 dma_glb_dma_ssp_axi_user_sel0; + u32 dma_glb_dma_ssp_axi_user_sel1; + u32 dma_glb_dma_ssp_rx_fdes_addr0; + u32 dma_glb_dma_ssp_rx_fdes_addr1; + u32 dma_glb_dma_ssp_rx_cdes_addr0; + u32 dma_glb_dma_ssp_rx_cdes_addr1; + u32 dma_glb_dma_ssp_rx_des_word0; + u32 dma_glb_dma_ssp_rx_des_word1; + u32 dma_glb_dma_ssp_tx_fdes_addr0; + u32 dma_glb_dma_ssp_tx_fdes_addr1; + u32 dma_glb_dma_ssp_tx_cdes_addr0; + u32 dma_glb_dma_ssp_tx_cdes_addr1; + u32 dma_glb_dma_ssp_tx_des_word0; + u32 dma_glb_dma_ssp_tx_des_word1; + u32 dma_glb_dma_ssp_debug0; + u32 dma_glb_dma_ssp_debug1; + u32 dma_glb_dma_ssp_debug2; + u32 dma_glb_dma_ssp_spare0; + u32 dma_glb_dma_ssp_spare1; +}; + +struct dma_ssp { + u32 dma_q_rxq_control; + u32 dma_q_rxq_base_depth; + u32 dma_q_rxq_base; + u32 dma_q_rxq_wptr; + u32 dma_q_rxq_rptr; + u32 dma_q_rxq_pktcnt; + u32 dma_q_txq_control; + u32 dma_q_txq_base_depth; + u32 dma_q_txq_base; + u32 dma_q_txq_wptr; + u32 dma_q_txq_rptr; + u32 dma_q_txq_pktcnt; + u32 dma_q_rxq_interrupt; + u32 dma_q_rxq_intenable; + u32 dma_q_txq_interrupt; + u32 dma_q_txq_intenable; + u32 dma_q_rxq_misc_interrupt; + u32 dma_q_rxq_misc_intenable; + u32 dma_q_txq_misc_interrupt; + u32 dma_q_txq_misc_intenable; + u32 dma_q_rxq_coal_interrupt; + u32 dma_q_rxq_coal_intenable; + u32 dma_q_txq_coal_interrupt; + u32 dma_q_txq_coal_intenable; + u32 dma_q_rxq_frag_buff_addr0; + u32 dma_q_rxq_frag_buff_addr1; + u32 dma_q_rxq_frag_buff_size; + u32 dma_q_txq_frag_buff_addr0; + u32 dma_q_txq_frag_buff_addr1; + u32 dma_q_txq_frag_buff_size; + u32 dma_q_dma_spare_0; + u32 dma_q_dma_spare_1; +}; diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c b/drivers/mtd/nand/raw/stm32_fmc2_nand.c index b8561b2516..fd81a9500b 100644 --- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c +++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c @@ -4,12 +4,15 @@ * Author: Christophe Kerello <christophe.kerello@st.com> */ +#define LOG_CATEGORY UCLASS_MTD + #include <common.h> #include <clk.h> #include <dm.h> #include <log.h> #include <nand.h> #include <reset.h> +#include <dm/device_compat.h> #include <linux/bitfield.h> #include <linux/bitops.h> #include <linux/delay.h> @@ -324,7 +327,7 @@ static int stm32_fmc2_nfc_ham_calculate(struct mtd_info *mtd, const u8 *data, ret = readl_poll_timeout(nfc->io_base + FMC2_SR, sr, sr & FMC2_SR_NWRF, FMC2_TIMEOUT_5S); if (ret < 0) { - pr_err("Ham timeout\n"); + log_err("Ham timeout\n"); return ret; } @@ -409,7 +412,7 @@ static int stm32_fmc2_nfc_bch_calculate(struct mtd_info *mtd, const u8 *data, ret = readl_poll_timeout(nfc->io_base + FMC2_BCHISR, bchisr, bchisr & FMC2_BCHISR_EPBRF, FMC2_TIMEOUT_5S); if (ret < 0) { - pr_err("Bch timeout\n"); + log_err("Bch timeout\n"); return ret; } @@ -457,7 +460,7 @@ static int stm32_fmc2_nfc_bch_correct(struct mtd_info *mtd, u8 *dat, ret = readl_poll_timeout(nfc->io_base + FMC2_BCHISR, bchisr, bchisr & FMC2_BCHISR_DERF, FMC2_TIMEOUT_5S); if (ret < 0) { - pr_err("Bch timeout\n"); + log_err("Bch timeout\n"); return ret; } @@ -795,26 +798,24 @@ static int stm32_fmc2_nfc_parse_child(struct stm32_fmc2_nfc *nfc, ofnode node) nand->ncs /= sizeof(u32); if (!nand->ncs) { - pr_err("Invalid reg property size\n"); + log_err("Invalid reg property size\n"); return -EINVAL; } ret = ofnode_read_u32_array(node, "reg", cs, nand->ncs); if (ret < 0) { - pr_err("Could not retrieve reg property\n"); + log_err("Could not retrieve reg property\n"); return -EINVAL; } for (i = 0; i < nand->ncs; i++) { if (cs[i] >= FMC2_MAX_CE) { - pr_err("Invalid reg value: %d\n", - nand->cs_used[i]); + log_err("Invalid reg value: %d\n", nand->cs_used[i]); return -EINVAL; } if (nfc->cs_assigned & BIT(cs[i])) { - pr_err("Cs already assigned: %d\n", - nand->cs_used[i]); + log_err("Cs already assigned: %d\n", nand->cs_used[i]); return -EINVAL; } @@ -837,12 +838,12 @@ static int stm32_fmc2_nfc_parse_dt(struct udevice *dev, nchips++; if (!nchips) { - pr_err("NAND chip not defined\n"); + log_err("NAND chip not defined\n"); return -EINVAL; } if (nchips > 1) { - pr_err("Too many NAND chips defined\n"); + log_err("Too many NAND chips defined\n"); return -EINVAL; } @@ -918,24 +919,21 @@ static int stm32_fmc2_nfc_probe(struct udevice *dev) addr = dev_read_addr_index(dev, mem_region); if (addr == FDT_ADDR_T_NONE) { - pr_err("Resource data_base not found for cs%d", - chip_cs); + dev_err(dev, "Resource data_base not found for cs%d", chip_cs); return ret; } nfc->data_base[chip_cs] = addr; addr = dev_read_addr_index(dev, mem_region + 1); if (addr == FDT_ADDR_T_NONE) { - pr_err("Resource cmd_base not found for cs%d", - chip_cs); + dev_err(dev, "Resource cmd_base not found for cs%d", chip_cs); return ret; } nfc->cmd_base[chip_cs] = addr; addr = dev_read_addr_index(dev, mem_region + 2); if (addr == FDT_ADDR_T_NONE) { - pr_err("Resource addr_base not found for cs%d", - chip_cs); + dev_err(dev, "Resource addr_base not found for cs%d", chip_cs); return ret; } nfc->addr_base[chip_cs] = addr; @@ -985,14 +983,14 @@ static int stm32_fmc2_nfc_probe(struct udevice *dev) * ECC sector size = 512 */ if (chip->ecc.mode != NAND_ECC_HW) { - pr_err("Nand_ecc_mode is not well defined in the DT\n"); + dev_err(dev, "Nand_ecc_mode is not well defined in the DT\n"); return -EINVAL; } ret = nand_check_ecc_caps(chip, &stm32_fmc2_nfc_ecc_caps, mtd->oobsize - FMC2_BBM_LEN); if (ret) { - pr_err("No valid ECC settings set\n"); + dev_err(dev, "No valid ECC settings set\n"); return ret; } @@ -1045,6 +1043,6 @@ void board_nand_init(void) DM_DRIVER_GET(stm32_fmc2_nfc), &dev); if (ret && ret != -ENODEV) - pr_err("Failed to initialize STM32 FMC2 NFC controller. (error %d)\n", - ret); + log_err("Failed to initialize STM32 FMC2 NFC controller. (error %d)\n", + ret); } diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index 45a1648ad5..944412958d 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -209,6 +209,7 @@ struct eqos_dma_regs { #define EQOS_DMA_SYSBUS_MODE_BLEN8 BIT(2) #define EQOS_DMA_SYSBUS_MODE_BLEN4 BIT(1) +#define EQOS_DMA_CH0_CONTROL_DSL_SHIFT 18 #define EQOS_DMA_CH0_CONTROL_PBLX8 BIT(16) #define EQOS_DMA_CH0_TX_CONTROL_TXPBL_SHIFT 16 @@ -239,37 +240,15 @@ struct eqos_tegra186_regs { #define EQOS_AUTO_CAL_STATUS_ACTIVE BIT(31) /* Descriptors */ - -#define EQOS_DESCRIPTOR_WORDS 4 -#define EQOS_DESCRIPTOR_SIZE (EQOS_DESCRIPTOR_WORDS * 4) /* We assume ARCH_DMA_MINALIGN >= 16; 16 is the EQOS HW minimum */ #define EQOS_DESCRIPTOR_ALIGN ARCH_DMA_MINALIGN #define EQOS_DESCRIPTORS_TX 4 #define EQOS_DESCRIPTORS_RX 4 #define EQOS_DESCRIPTORS_NUM (EQOS_DESCRIPTORS_TX + EQOS_DESCRIPTORS_RX) -#define EQOS_DESCRIPTORS_SIZE ALIGN(EQOS_DESCRIPTORS_NUM * \ - EQOS_DESCRIPTOR_SIZE, ARCH_DMA_MINALIGN) #define EQOS_BUFFER_ALIGN ARCH_DMA_MINALIGN #define EQOS_MAX_PACKET_SIZE ALIGN(1568, ARCH_DMA_MINALIGN) #define EQOS_RX_BUFFER_SIZE (EQOS_DESCRIPTORS_RX * EQOS_MAX_PACKET_SIZE) -/* - * Warn if the cache-line size is larger than the descriptor size. In such - * cases the driver will likely fail because the CPU needs to flush the cache - * when requeuing RX buffers, therefore descriptors written by the hardware - * may be discarded. Architectures with full IO coherence, such as x86, do not - * experience this issue, and hence are excluded from this condition. - * - * This can be fixed by defining CONFIG_SYS_NONCACHED_MEMORY which will cause - * the driver to allocate descriptors from a pool of non-cached memory. - */ -#if EQOS_DESCRIPTOR_SIZE < ARCH_DMA_MINALIGN -#if !defined(CONFIG_SYS_NONCACHED_MEMORY) && \ - !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) && !defined(CONFIG_X86) -#warning Cache line size is larger than descriptor size -#endif -#endif - struct eqos_desc { u32 des0; u32 des1; @@ -282,12 +261,17 @@ struct eqos_desc { #define EQOS_DESC3_LD BIT(28) #define EQOS_DESC3_BUF1V BIT(24) +#define EQOS_AXI_WIDTH_32 4 +#define EQOS_AXI_WIDTH_64 8 +#define EQOS_AXI_WIDTH_128 16 + struct eqos_config { bool reg_access_always_ok; int mdio_wait; int swr_wait; int config_mac; int config_mac_mdio; + unsigned int axi_bus_width; phy_interface_t (*interface)(struct udevice *dev); struct eqos_ops *ops; }; @@ -330,9 +314,8 @@ struct eqos_priv { int phyaddr; u32 max_speed; void *descs; - struct eqos_desc *tx_descs; - struct eqos_desc *rx_descs; int tx_desc_idx, rx_desc_idx; + unsigned int desc_size; void *tx_dma_buf; void *rx_dma_buf; void *rx_pkt; @@ -358,63 +341,42 @@ struct eqos_priv { * not have the same constraints since they are 1536 bytes large, so they * are unlikely to share cache-lines. */ -static void *eqos_alloc_descs(unsigned int num) +static void *eqos_alloc_descs(struct eqos_priv *eqos, unsigned int num) { -#ifdef CONFIG_SYS_NONCACHED_MEMORY - return (void *)noncached_alloc(EQOS_DESCRIPTORS_SIZE, - EQOS_DESCRIPTOR_ALIGN); -#else - return memalign(EQOS_DESCRIPTOR_ALIGN, EQOS_DESCRIPTORS_SIZE); -#endif + eqos->desc_size = ALIGN(sizeof(struct eqos_desc), + (unsigned int)ARCH_DMA_MINALIGN); + + return memalign(eqos->desc_size, num * eqos->desc_size); } static void eqos_free_descs(void *descs) { -#ifdef CONFIG_SYS_NONCACHED_MEMORY - /* FIXME: noncached_alloc() has no opposite */ -#else free(descs); -#endif } -static void eqos_inval_desc_tegra186(void *desc) +static struct eqos_desc *eqos_get_desc(struct eqos_priv *eqos, + unsigned int num, bool rx) { -#ifndef CONFIG_SYS_NONCACHED_MEMORY - unsigned long start = (unsigned long)desc & ~(ARCH_DMA_MINALIGN - 1); - unsigned long end = ALIGN(start + EQOS_DESCRIPTOR_SIZE, - ARCH_DMA_MINALIGN); - - invalidate_dcache_range(start, end); -#endif + return eqos->descs + + ((rx ? EQOS_DESCRIPTORS_TX : 0) + num) * eqos->desc_size; } static void eqos_inval_desc_generic(void *desc) { -#ifndef CONFIG_SYS_NONCACHED_MEMORY - unsigned long start = rounddown((unsigned long)desc, ARCH_DMA_MINALIGN); - unsigned long end = roundup((unsigned long)desc + EQOS_DESCRIPTOR_SIZE, - ARCH_DMA_MINALIGN); + unsigned long start = (unsigned long)desc; + unsigned long end = ALIGN(start + sizeof(struct eqos_desc), + ARCH_DMA_MINALIGN); invalidate_dcache_range(start, end); -#endif -} - -static void eqos_flush_desc_tegra186(void *desc) -{ -#ifndef CONFIG_SYS_NONCACHED_MEMORY - flush_cache((unsigned long)desc, EQOS_DESCRIPTOR_SIZE); -#endif } static void eqos_flush_desc_generic(void *desc) { -#ifndef CONFIG_SYS_NONCACHED_MEMORY - unsigned long start = rounddown((unsigned long)desc, ARCH_DMA_MINALIGN); - unsigned long end = roundup((unsigned long)desc + EQOS_DESCRIPTOR_SIZE, - ARCH_DMA_MINALIGN); + unsigned long start = (unsigned long)desc; + unsigned long end = ALIGN(start + sizeof(struct eqos_desc), + ARCH_DMA_MINALIGN); flush_dcache_range(start, end); -#endif } static void eqos_inval_buffer_tegra186(void *buf, size_t size) @@ -1167,6 +1129,7 @@ static int eqos_start(struct udevice *dev) ulong rate; u32 val, tx_fifo_sz, rx_fifo_sz, tqs, rqs, pbl; ulong last_rx_desc; + ulong desc_pad; debug("%s(dev=%p):\n", __func__, dev); @@ -1405,8 +1368,12 @@ static int eqos_start(struct udevice *dev) EQOS_MAX_PACKET_SIZE << EQOS_DMA_CH0_RX_CONTROL_RBSZ_SHIFT); + desc_pad = (eqos->desc_size - sizeof(struct eqos_desc)) / + eqos->config->axi_bus_width; + setbits_le32(&eqos->dma_regs->ch0_control, - EQOS_DMA_CH0_CONTROL_PBLX8); + EQOS_DMA_CH0_CONTROL_PBLX8 | + (desc_pad << EQOS_DMA_CH0_CONTROL_DSL_SHIFT)); /* * Burst length must be < 1/2 FIFO size. @@ -1435,9 +1402,15 @@ static int eqos_start(struct udevice *dev) /* Set up descriptors */ - memset(eqos->descs, 0, EQOS_DESCRIPTORS_SIZE); + memset(eqos->descs, 0, eqos->desc_size * EQOS_DESCRIPTORS_NUM); + + for (i = 0; i < EQOS_DESCRIPTORS_TX; i++) { + struct eqos_desc *tx_desc = eqos_get_desc(eqos, i, false); + eqos->config->ops->eqos_flush_desc(tx_desc); + } + for (i = 0; i < EQOS_DESCRIPTORS_RX; i++) { - struct eqos_desc *rx_desc = &(eqos->rx_descs[i]); + struct eqos_desc *rx_desc = eqos_get_desc(eqos, i, true); rx_desc->des0 = (u32)(ulong)(eqos->rx_dma_buf + (i * EQOS_MAX_PACKET_SIZE)); rx_desc->des3 = EQOS_DESC3_OWN | EQOS_DESC3_BUF1V; @@ -1449,12 +1422,14 @@ static int eqos_start(struct udevice *dev) } writel(0, &eqos->dma_regs->ch0_txdesc_list_haddress); - writel((ulong)eqos->tx_descs, &eqos->dma_regs->ch0_txdesc_list_address); + writel((ulong)eqos_get_desc(eqos, 0, false), + &eqos->dma_regs->ch0_txdesc_list_address); writel(EQOS_DESCRIPTORS_TX - 1, &eqos->dma_regs->ch0_txdesc_ring_length); writel(0, &eqos->dma_regs->ch0_rxdesc_list_haddress); - writel((ulong)eqos->rx_descs, &eqos->dma_regs->ch0_rxdesc_list_address); + writel((ulong)eqos_get_desc(eqos, 0, true), + &eqos->dma_regs->ch0_rxdesc_list_address); writel(EQOS_DESCRIPTORS_RX - 1, &eqos->dma_regs->ch0_rxdesc_ring_length); @@ -1473,7 +1448,7 @@ static int eqos_start(struct udevice *dev) * that's not distinguishable from none of the descriptors being * available. */ - last_rx_desc = (ulong)&(eqos->rx_descs[(EQOS_DESCRIPTORS_RX - 1)]); + last_rx_desc = (ulong)eqos_get_desc(eqos, EQOS_DESCRIPTORS_RX - 1, true); writel(last_rx_desc, &eqos->dma_regs->ch0_rxdesc_tail_pointer); eqos->started = true; @@ -1558,7 +1533,7 @@ static int eqos_send(struct udevice *dev, void *packet, int length) memcpy(eqos->tx_dma_buf, packet, length); eqos->config->ops->eqos_flush_buffer(eqos->tx_dma_buf, length); - tx_desc = &(eqos->tx_descs[eqos->tx_desc_idx]); + tx_desc = eqos_get_desc(eqos, eqos->tx_desc_idx, false); eqos->tx_desc_idx++; eqos->tx_desc_idx %= EQOS_DESCRIPTORS_TX; @@ -1573,7 +1548,7 @@ static int eqos_send(struct udevice *dev, void *packet, int length) tx_desc->des3 = EQOS_DESC3_OWN | EQOS_DESC3_FD | EQOS_DESC3_LD | length; eqos->config->ops->eqos_flush_desc(tx_desc); - writel((ulong)(&(eqos->tx_descs[eqos->tx_desc_idx])), + writel((ulong)eqos_get_desc(eqos, eqos->tx_desc_idx, false), &eqos->dma_regs->ch0_txdesc_tail_pointer); for (i = 0; i < 1000000; i++) { @@ -1596,7 +1571,7 @@ static int eqos_recv(struct udevice *dev, int flags, uchar **packetp) debug("%s(dev=%p, flags=%x):\n", __func__, dev, flags); - rx_desc = &(eqos->rx_descs[eqos->rx_desc_idx]); + rx_desc = eqos_get_desc(eqos, eqos->rx_desc_idx, true); eqos->config->ops->eqos_inval_desc(rx_desc); if (rx_desc->des3 & EQOS_DESC3_OWN) { debug("%s: RX packet not available\n", __func__); @@ -1631,7 +1606,7 @@ static int eqos_free_pkt(struct udevice *dev, uchar *packet, int length) eqos->config->ops->eqos_inval_buffer(packet, length); - rx_desc = &(eqos->rx_descs[eqos->rx_desc_idx]); + rx_desc = eqos_get_desc(eqos, eqos->rx_desc_idx, true); rx_desc->des0 = 0; mb(); @@ -1663,17 +1638,12 @@ static int eqos_probe_resources_core(struct udevice *dev) debug("%s(dev=%p):\n", __func__, dev); - eqos->descs = eqos_alloc_descs(EQOS_DESCRIPTORS_TX + - EQOS_DESCRIPTORS_RX); + eqos->descs = eqos_alloc_descs(eqos, EQOS_DESCRIPTORS_NUM); if (!eqos->descs) { debug("%s: eqos_alloc_descs() failed\n", __func__); ret = -ENOMEM; goto err; } - eqos->tx_descs = (struct eqos_desc *)eqos->descs; - eqos->rx_descs = (eqos->tx_descs + EQOS_DESCRIPTORS_TX); - debug("%s: tx_descs=%p, rx_descs=%p\n", __func__, eqos->tx_descs, - eqos->rx_descs); eqos->tx_dma_buf = memalign(EQOS_BUFFER_ALIGN, EQOS_MAX_PACKET_SIZE); if (!eqos->tx_dma_buf) { @@ -2083,8 +2053,8 @@ static const struct eth_ops eqos_ops = { }; static struct eqos_ops eqos_tegra186_ops = { - .eqos_inval_desc = eqos_inval_desc_tegra186, - .eqos_flush_desc = eqos_flush_desc_tegra186, + .eqos_inval_desc = eqos_inval_desc_generic, + .eqos_flush_desc = eqos_flush_desc_generic, .eqos_inval_buffer = eqos_inval_buffer_tegra186, .eqos_flush_buffer = eqos_flush_buffer_tegra186, .eqos_probe_resources = eqos_probe_resources_tegra186, @@ -2105,6 +2075,7 @@ static const struct eqos_config __maybe_unused eqos_tegra186_config = { .swr_wait = 10, .config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB, .config_mac_mdio = EQOS_MAC_MDIO_ADDRESS_CR_20_35, + .axi_bus_width = EQOS_AXI_WIDTH_128, .interface = eqos_get_interface_tegra186, .ops = &eqos_tegra186_ops }; @@ -2132,6 +2103,7 @@ static const struct eqos_config __maybe_unused eqos_stm32_config = { .swr_wait = 50, .config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_AV, .config_mac_mdio = EQOS_MAC_MDIO_ADDRESS_CR_250_300, + .axi_bus_width = EQOS_AXI_WIDTH_64, .interface = eqos_get_interface_stm32, .ops = &eqos_stm32_ops }; @@ -2159,6 +2131,7 @@ struct eqos_config __maybe_unused eqos_imx_config = { .swr_wait = 50, .config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB, .config_mac_mdio = EQOS_MAC_MDIO_ADDRESS_CR_250_300, + .axi_bus_width = EQOS_AXI_WIDTH_64, .interface = eqos_get_interface_imx, .ops = &eqos_imx_ops }; diff --git a/drivers/net/dwmac_socfpga.c b/drivers/net/dwmac_socfpga.c index 939f199b1f..82fdff51da 100644 --- a/drivers/net/dwmac_socfpga.c +++ b/drivers/net/dwmac_socfpga.c @@ -6,6 +6,8 @@ */ #include <common.h> +#include <asm/arch/secure_reg_helper.h> +#include <asm/arch/system_manager.h> #include <asm/io.h> #include <dm.h> #include <clk.h> @@ -17,8 +19,6 @@ #include <dm/device_compat.h> #include <linux/err.h> -#include <asm/arch/system_manager.h> - struct dwmac_socfpga_plat { struct dw_eth_pdata dw_eth_pdata; void *phy_intf; @@ -64,6 +64,32 @@ static int dwmac_socfpga_of_to_plat(struct udevice *dev) return designware_eth_of_to_plat(dev); } +static int dwmac_socfpga_do_setphy(struct udevice *dev, u32 modereg) +{ + struct dwmac_socfpga_plat *pdata = dev_get_plat(dev); + u32 modemask = SYSMGR_EMACGRP_CTRL_PHYSEL_MASK << pdata->reg_shift; + +#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_ATF) + u32 index = ((u64)pdata->phy_intf - socfpga_get_sysmgr_addr() - + SYSMGR_SOC64_EMAC0) >> 2; + + u32 id = SOCFPGA_SECURE_REG_SYSMGR_SOC64_EMAC0 + index; + + int ret = socfpga_secure_reg_update32(id, + modemask, + modereg << pdata->reg_shift); + if (ret) { + dev_err(dev, "Failed to set PHY register via SMC call\n"); + return ret; + } +#else + clrsetbits_le32(pdata->phy_intf, modemask, + modereg << pdata->reg_shift); +#endif + + return 0; +} + static int dwmac_socfpga_probe(struct udevice *dev) { struct dwmac_socfpga_plat *pdata = dev_get_plat(dev); @@ -71,7 +97,6 @@ static int dwmac_socfpga_probe(struct udevice *dev) struct reset_ctl_bulk reset_bulk; int ret; u32 modereg; - u32 modemask; switch (edata->phy_interface) { case PHY_INTERFACE_MODE_MII: @@ -97,9 +122,9 @@ static int dwmac_socfpga_probe(struct udevice *dev) reset_assert_bulk(&reset_bulk); - modemask = SYSMGR_EMACGRP_CTRL_PHYSEL_MASK << pdata->reg_shift; - clrsetbits_le32(pdata->phy_intf, modemask, - modereg << pdata->reg_shift); + ret = dwmac_socfpga_do_setphy(dev, modereg); + if (ret) + return ret; reset_release_bulk(&reset_bulk); diff --git a/drivers/net/e1000.c b/drivers/net/e1000.c index 3b3dd104cd..733588302d 100644 --- a/drivers/net/e1000.c +++ b/drivers/net/e1000.c @@ -869,7 +869,6 @@ e1000_read_eeprom(struct e1000_hw *hw, uint16_t offset, return E1000_SUCCESS; } -#ifndef CONFIG_DM_ETH /****************************************************************************** * e1000_write_eeprom_srwr - Write to Shadow Ram using EEWR * @hw: pointer to the HW structure @@ -1035,7 +1034,6 @@ static int32_t e1000_update_eeprom_checksum_i210(struct e1000_hw *hw) out: return ret_val; } -#endif /****************************************************************************** * Verifies that the EEPROM has a valid checksum @@ -5660,13 +5658,24 @@ e1000_poll(struct eth_device *nic) return len ? 1 : 0; } +#endif /* !CONFIG_DM_ETH */ +#ifdef CONFIG_DM_ETH +static int e1000_write_hwaddr(struct udevice *dev) +#else static int e1000_write_hwaddr(struct eth_device *dev) +#endif { #ifndef CONFIG_E1000_NO_NVM - unsigned char *mac = dev->enetaddr; unsigned char current_mac[6]; +#ifdef CONFIG_DM_ETH + struct eth_pdata *plat = dev_get_plat(dev); + struct e1000_hw *hw = dev_get_priv(dev); + u8 *mac = plat->enetaddr; +#else struct e1000_hw *hw = dev->priv; + u8 *mac = dev->enetaddr; +#endif uint16_t data[3]; int ret_val, i; @@ -5700,6 +5709,7 @@ static int e1000_write_hwaddr(struct eth_device *dev) #endif } +#ifndef CONFIG_DM_ETH /************************************************************************** PROBE - Look for an adapter, this routine's visible to the outside You should omit the last argument struct pci_device * for a non-PCI NIC @@ -5926,6 +5936,7 @@ static const struct eth_ops e1000_eth_ops = { .recv = e1000_eth_recv, .stop = e1000_eth_stop, .free_pkt = e1000_free_pkt, + .write_hwaddr = e1000_write_hwaddr, }; static const struct udevice_id e1000_eth_ids[] = { diff --git a/drivers/net/ftgmac100.c b/drivers/net/ftgmac100.c index 69e299d6a3..0687230b4b 100644 --- a/drivers/net/ftgmac100.c +++ b/drivers/net/ftgmac100.c @@ -271,6 +271,28 @@ static int ftgmac100_set_mac(struct ftgmac100_data *priv, } /* + * Get MAC address + */ +static int ftgmac100_get_mac(struct ftgmac100_data *priv, + unsigned char *mac) +{ + struct ftgmac100 *ftgmac100 = priv->iobase; + unsigned int maddr = readl(&ftgmac100->mac_madr); + unsigned int laddr = readl(&ftgmac100->mac_ladr); + + debug("%s(%x %x)\n", __func__, maddr, laddr); + + mac[0] = (maddr >> 8) & 0xff; + mac[1] = maddr & 0xff; + mac[2] = (laddr >> 24) & 0xff; + mac[3] = (laddr >> 16) & 0xff; + mac[4] = (laddr >> 8) & 0xff; + mac[5] = laddr & 0xff; + + return 0; +} + +/* * disable transmitter, receiver */ static void ftgmac100_stop(struct udevice *dev) @@ -511,6 +533,14 @@ static int ftgmac100_write_hwaddr(struct udevice *dev) return ftgmac100_set_mac(priv, pdata->enetaddr); } +static int ftgmac_read_hwaddr(struct udevice *dev) +{ + struct eth_pdata *pdata = dev_get_plat(dev); + struct ftgmac100_data *priv = dev_get_priv(dev); + + return ftgmac100_get_mac(priv, pdata->enetaddr); +} + static int ftgmac100_of_to_plat(struct udevice *dev) { struct eth_pdata *pdata = dev_get_plat(dev); @@ -571,6 +601,8 @@ static int ftgmac100_probe(struct udevice *dev) goto out; } + ftgmac_read_hwaddr(dev); + out: if (ret) clk_release_bulk(&priv->clks); diff --git a/drivers/net/ks8851_mll.c b/drivers/net/ks8851_mll.c index 91c2d10ffc..9dd9b33955 100644 --- a/drivers/net/ks8851_mll.c +++ b/drivers/net/ks8851_mll.c @@ -251,7 +251,8 @@ static int ks_rcv(struct ks_net *ks, uchar *data) } ks_wrreg16(ks, KS_RXQCR, RXQCR_CMD_CNTL | RXQCR_RRXEF); - printf(DRIVERNAME ": bad packet\n"); + printf(DRIVERNAME ": bad packet (sts=0x%04x len=0x%04x)\n", sts, len); + ks->rxfc = 0; return 0; } diff --git a/drivers/net/macb.c b/drivers/net/macb.c index e287c29e69..2225b33ff6 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -83,7 +83,16 @@ struct macb_dma_desc { u32 ctrl; }; -#define DMA_DESC_BYTES(n) (n * sizeof(struct macb_dma_desc)) +struct macb_dma_desc_64 { + u32 addrh; + u32 unused; +}; + +#define HW_DMA_CAP_32B 0 +#define HW_DMA_CAP_64B 1 + +#define DMA_DESC_SIZE 16 +#define DMA_DESC_BYTES(n) ((n) * DMA_DESC_SIZE) #define MACB_TX_DMA_DESC_SIZE (DMA_DESC_BYTES(MACB_TX_RING_SIZE)) #define MACB_RX_DMA_DESC_SIZE (DMA_DESC_BYTES(MACB_RX_RING_SIZE)) #define MACB_TX_DUMMY_DMA_DESC_SIZE (DMA_DESC_BYTES(1)) @@ -137,6 +146,7 @@ struct macb_device { struct macb_config { unsigned int dma_burst_length; + unsigned int hw_dma_cap; int (*clk_init)(struct udevice *dev, ulong rate); }; @@ -307,6 +317,24 @@ static inline void macb_invalidate_rx_buffer(struct macb_device *macb) #if defined(CONFIG_CMD_NET) +static struct macb_dma_desc_64 *macb_64b_desc(struct macb_dma_desc *desc) +{ + return (struct macb_dma_desc_64 *)((void *)desc + + sizeof(struct macb_dma_desc)); +} + +static void macb_set_addr(struct macb_device *macb, struct macb_dma_desc *desc, + ulong addr) +{ + struct macb_dma_desc_64 *desc_64; + + if (macb->config->hw_dma_cap & HW_DMA_CAP_64B) { + desc_64 = macb_64b_desc(desc); + desc_64->addrh = upper_32_bits(addr); + } + desc->addr = lower_32_bits(addr); +} + static int _macb_send(struct macb_device *macb, const char *name, void *packet, int length) { @@ -325,8 +353,12 @@ static int _macb_send(struct macb_device *macb, const char *name, void *packet, macb->tx_head++; } + if (macb->config->hw_dma_cap & HW_DMA_CAP_64B) + tx_head = tx_head * 2; + macb->tx_ring[tx_head].ctrl = ctrl; - macb->tx_ring[tx_head].addr = paddr; + macb_set_addr(macb, &macb->tx_ring[tx_head], paddr); + barrier(); macb_flush_ring_desc(macb, TX); macb_writel(macb, NCR, MACB_BIT(TE) | MACB_BIT(RE) | MACB_BIT(TSTART)); @@ -363,19 +395,28 @@ static void reclaim_rx_buffers(struct macb_device *macb, unsigned int new_tail) { unsigned int i; + unsigned int count; i = macb->rx_tail; macb_invalidate_ring_desc(macb, RX); while (i > new_tail) { - macb->rx_ring[i].addr &= ~MACB_BIT(RX_USED); + if (macb->config->hw_dma_cap & HW_DMA_CAP_64B) + count = i * 2; + else + count = i; + macb->rx_ring[count].addr &= ~MACB_BIT(RX_USED); i++; if (i > MACB_RX_RING_SIZE) i = 0; } while (i < new_tail) { - macb->rx_ring[i].addr &= ~MACB_BIT(RX_USED); + if (macb->config->hw_dma_cap & HW_DMA_CAP_64B) + count = i * 2; + else + count = i; + macb->rx_ring[count].addr &= ~MACB_BIT(RX_USED); i++; } @@ -390,16 +431,25 @@ static int _macb_recv(struct macb_device *macb, uchar **packetp) void *buffer; int length; u32 status; + u8 flag = false; macb->wrapped = false; for (;;) { macb_invalidate_ring_desc(macb, RX); + if (macb->config->hw_dma_cap & HW_DMA_CAP_64B) + next_rx_tail = next_rx_tail * 2; + if (!(macb->rx_ring[next_rx_tail].addr & MACB_BIT(RX_USED))) return -EAGAIN; status = macb->rx_ring[next_rx_tail].ctrl; if (status & MACB_BIT(RX_SOF)) { + if (macb->config->hw_dma_cap & HW_DMA_CAP_64B) { + next_rx_tail = next_rx_tail / 2; + flag = true; + } + if (next_rx_tail != macb->rx_tail) reclaim_rx_buffers(macb, next_rx_tail); macb->wrapped = false; @@ -426,11 +476,22 @@ static int _macb_recv(struct macb_device *macb, uchar **packetp) *packetp = buffer; } + if (macb->config->hw_dma_cap & HW_DMA_CAP_64B) { + if (!flag) + next_rx_tail = next_rx_tail / 2; + } + if (++next_rx_tail >= MACB_RX_RING_SIZE) next_rx_tail = 0; macb->next_rx_tail = next_rx_tail; return length; } else { + if (macb->config->hw_dma_cap & HW_DMA_CAP_64B) { + if (!flag) + next_rx_tail = next_rx_tail / 2; + flag = false; + } + if (++next_rx_tail >= MACB_RX_RING_SIZE) { macb->wrapped = true; next_rx_tail = 0; @@ -470,6 +531,12 @@ static int macb_phy_find(struct macb_device *macb, const char *name) int i; u16 phy_id; + phy_id = macb_mdio_read(macb, macb->phy_addr, MII_PHYSID1); + if (phy_id != 0xffff) { + printf("%s: PHY present at %d\n", name, macb->phy_addr); + return 0; + } + /* Search for PHY... */ for (i = 0; i < 32; i++) { macb->phy_addr = i; @@ -718,6 +785,7 @@ static int gmac_init_multi_queues(struct macb_device *macb) { int i, num_queues = 1; u32 queue_mask; + unsigned long paddr; /* bit 0 is never set but queue 0 always exists */ queue_mask = gem_readl(macb, DCFG6) & 0xff; @@ -731,10 +799,18 @@ static int gmac_init_multi_queues(struct macb_device *macb) macb->dummy_desc->addr = 0; flush_dcache_range(macb->dummy_desc_dma, macb->dummy_desc_dma + ALIGN(MACB_TX_DUMMY_DMA_DESC_SIZE, PKTALIGN)); - - for (i = 1; i < num_queues; i++) - gem_writel_queue_TBQP(macb, macb->dummy_desc_dma, i - 1); - + paddr = macb->dummy_desc_dma; + + for (i = 1; i < num_queues; i++) { + gem_writel_queue_TBQP(macb, lower_32_bits(paddr), i - 1); + gem_writel_queue_RBQP(macb, lower_32_bits(paddr), i - 1); + if (macb->config->hw_dma_cap & HW_DMA_CAP_64B) { + gem_writel_queue_TBQPH(macb, upper_32_bits(paddr), + i - 1); + gem_writel_queue_RBQPH(macb, upper_32_bits(paddr), + i - 1); + } + } return 0; } @@ -760,6 +836,9 @@ static void gmac_configure_dma(struct macb_device *macb) dmacfg &= ~GEM_BIT(ENDIA_DESC); dmacfg &= ~GEM_BIT(ADDR64); + if (macb->config->hw_dma_cap & HW_DMA_CAP_64B) + dmacfg |= GEM_BIT(ADDR64); + gem_writel(macb, DMACFG, dmacfg); } @@ -775,6 +854,7 @@ static int _macb_init(struct macb_device *macb, const char *name) unsigned long paddr; int ret; int i; + int count; /* * macb_halt should have been called at some point before now, @@ -786,20 +866,28 @@ static int _macb_init(struct macb_device *macb, const char *name) for (i = 0; i < MACB_RX_RING_SIZE; i++) { if (i == (MACB_RX_RING_SIZE - 1)) paddr |= MACB_BIT(RX_WRAP); - macb->rx_ring[i].addr = paddr; - macb->rx_ring[i].ctrl = 0; + if (macb->config->hw_dma_cap & HW_DMA_CAP_64B) + count = i * 2; + else + count = i; + macb->rx_ring[count].ctrl = 0; + macb_set_addr(macb, &macb->rx_ring[count], paddr); paddr += macb->rx_buffer_size; } macb_flush_ring_desc(macb, RX); macb_flush_rx_buffer(macb); for (i = 0; i < MACB_TX_RING_SIZE; i++) { - macb->tx_ring[i].addr = 0; + if (macb->config->hw_dma_cap & HW_DMA_CAP_64B) + count = i * 2; + else + count = i; + macb_set_addr(macb, &macb->tx_ring[count], 0); if (i == (MACB_TX_RING_SIZE - 1)) - macb->tx_ring[i].ctrl = MACB_BIT(TX_USED) | + macb->tx_ring[count].ctrl = MACB_BIT(TX_USED) | MACB_BIT(TX_WRAP); else - macb->tx_ring[i].ctrl = MACB_BIT(TX_USED); + macb->tx_ring[count].ctrl = MACB_BIT(TX_USED); } macb_flush_ring_desc(macb, TX); @@ -812,8 +900,12 @@ static int _macb_init(struct macb_device *macb, const char *name) gem_writel(macb, DMACFG, MACB_ZYNQ_GEM_DMACR_INIT); #endif - macb_writel(macb, RBQP, macb->rx_ring_dma); - macb_writel(macb, TBQP, macb->tx_ring_dma); + macb_writel(macb, RBQP, lower_32_bits(macb->rx_ring_dma)); + macb_writel(macb, TBQP, lower_32_bits(macb->tx_ring_dma)); + if (macb->config->hw_dma_cap & HW_DMA_CAP_64B) { + macb_writel(macb, RBQPH, upper_32_bits(macb->rx_ring_dma)); + macb_writel(macb, TBQPH, upper_32_bits(macb->tx_ring_dma)); + } if (macb_is_gem(macb)) { /* Initialize DMA properties */ @@ -1217,6 +1309,7 @@ static int macb_enable_clk(struct udevice *dev) static const struct macb_config default_gem_config = { .dma_burst_length = 16, + .hw_dma_cap = HW_DMA_CAP_32B, .clk_init = NULL, }; @@ -1224,11 +1317,12 @@ static int macb_eth_probe(struct udevice *dev) { struct eth_pdata *pdata = dev_get_plat(dev); struct macb_device *macb = dev_get_priv(dev); + struct ofnode_phandle_args phandle_args; const char *phy_mode; int ret; - phy_mode = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "phy-mode", - NULL); + phy_mode = dev_read_prop(dev, "phy-mode", NULL); + if (phy_mode) macb->phy_interface = phy_get_interface_by_name(phy_mode); if (macb->phy_interface == -1) { @@ -1236,6 +1330,12 @@ static int macb_eth_probe(struct udevice *dev) return -EINVAL; } + /* Read phyaddr from DT */ + if (!dev_read_phandle_with_args(dev, "phy-handle", NULL, 0, 0, + &phandle_args)) + macb->phy_addr = ofnode_read_u32_default(phandle_args.node, + "reg", -1); + macb->regs = (void *)pdata->iobase; macb->is_big_endian = (cpu_to_be32(0x12345678) == 0x12345678); @@ -1304,13 +1404,21 @@ static int macb_eth_of_to_plat(struct udevice *dev) return macb_late_eth_of_to_plat(dev); } +static const struct macb_config microchip_config = { + .dma_burst_length = 16, + .hw_dma_cap = HW_DMA_CAP_64B, + .clk_init = NULL, +}; + static const struct macb_config sama5d4_config = { .dma_burst_length = 4, + .hw_dma_cap = HW_DMA_CAP_32B, .clk_init = NULL, }; static const struct macb_config sifive_config = { .dma_burst_length = 16, + .hw_dma_cap = HW_DMA_CAP_32B, .clk_init = macb_sifive_clk_init, }; @@ -1324,6 +1432,8 @@ static const struct udevice_id macb_eth_ids[] = { { .compatible = "cdns,zynq-gem" }, { .compatible = "sifive,fu540-c000-gem", .data = (ulong)&sifive_config }, + { .compatible = "microchip,mpfs-mss-gem", + .data = (ulong)µchip_config }, { } }; diff --git a/drivers/net/macb.h b/drivers/net/macb.h index 9b16383eba..72b84ae96e 100644 --- a/drivers/net/macb.h +++ b/drivers/net/macb.h @@ -768,5 +768,11 @@ #define GEM_RX_CSUM_CHECKED_MASK 2 #define gem_writel_queue_TBQP(port, value, queue_num) \ writel((value), (port)->regs + GEM_TBQP(queue_num)) +#define gem_writel_queue_TBQPH(port, value, queue_num) \ + writel((value), (port)->regs + GEM_TBQPH(queue_num)) +#define gem_writel_queue_RBQP(port, value, queue_num) \ + writel((value), (port)->regs + GEM_RBQP(queue_num)) +#define gem_writel_queue_RBQPH(port, value, queue_num) \ + writel((value), (port)->regs + GEM_RBQPH(queue_num)) #endif /* __DRIVERS_MACB_H__ */ diff --git a/drivers/net/phy/miiphybb.c b/drivers/net/phy/miiphybb.c index ba97a54c06..59a32c4913 100644 --- a/drivers/net/phy/miiphybb.c +++ b/drivers/net/phy/miiphybb.c @@ -105,7 +105,7 @@ int bb_miiphy_buses_num = sizeof(bb_miiphy_buses) / sizeof(bb_miiphy_buses[0]); #endif -void bb_miiphy_init(void) +int bb_miiphy_init(void) { int i; @@ -124,6 +124,8 @@ void bb_miiphy_init(void) bb_miiphy_buses[i].init(&bb_miiphy_buses[i]); } } + + return 0; } static inline struct bb_miiphy_bus *bb_miiphy_getbus(const char *devname) diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 65498bce1d..b1de38f766 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -281,6 +281,15 @@ config PCIE_ROCKCHIP Say Y here if you want to enable PCIe controller support on Rockchip SoCs. +config PCIE_DW_ROCKCHIP + bool "Rockchip DesignWare based PCIe controller" + depends on ARCH_ROCKCHIP + select DM_PCI + select PHY_ROCKCHIP_SNPS_PCIE3 + help + Say Y here if you want to enable DW PCIe controller support on + Rockchip SoCs. + config PCI_BRCMSTB bool "Broadcom STB PCIe controller" depends on DM_PCI diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 8b4d49a590..5ed94bc95c 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -48,5 +48,6 @@ obj-$(CONFIG_PCIE_INTEL_FPGA) += pcie_intel_fpga.o obj-$(CONFIG_PCI_KEYSTONE) += pcie_dw_ti.o obj-$(CONFIG_PCIE_MEDIATEK) += pcie_mediatek.o obj-$(CONFIG_PCIE_ROCKCHIP) += pcie_rockchip.o +obj-$(CONFIG_PCIE_DW_ROCKCHIP) += pcie_dw_rockchip.o obj-$(CONFIG_PCI_BRCMSTB) += pcie_brcmstb.o obj-$(CONFIG_PCI_OCTEONTX) += pci_octeontx.o diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index 4cdd06b125..ba65f47e80 100644 --- a/drivers/pci/pci-uclass.c +++ b/drivers/pci/pci-uclass.c @@ -1842,7 +1842,7 @@ U_BOOT_DRIVER(pci_generic_drv) = { .of_match = pci_generic_ids, }; -void pci_init(void) +int pci_init(void) { struct udevice *bus; @@ -1855,4 +1855,6 @@ void pci_init(void) uclass_next_device_check(&bus)) { ; } + + return 0; } diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 664e8379eb..a7453e5755 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -454,16 +454,18 @@ int pci_hose_scan(struct pci_controller *hose) return pci_hose_scan_bus(hose, hose->current_busno); } -void pci_init(void) +int pci_init(void) { hose_head = NULL; /* allow env to disable pci init/enum */ if (env_get("pcidisable") != NULL) - return; + return 0; /* now call board specific pci_init()... */ pci_init_board(); + + return 0; } /* Returns the address of the requested capability structure within the diff --git a/drivers/pci/pcie_dw_rockchip.c b/drivers/pci/pcie_dw_rockchip.c new file mode 100644 index 0000000000..15270627b0 --- /dev/null +++ b/drivers/pci/pcie_dw_rockchip.c @@ -0,0 +1,877 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Rockchip DesignWare based PCIe host controller driver + * + * Copyright (c) 2021 Rockchip, Inc. + */ + +#include <common.h> +#include <clk.h> +#include <dm.h> +#include <generic-phy.h> +#include <pci.h> +#include <power-domain.h> +#include <reset.h> +#include <syscon.h> +#include <asm/arch-rockchip/clock.h> +#include <asm/io.h> +#include <asm-generic/gpio.h> +#include <dm/device_compat.h> +#include <linux/iopoll.h> +#include <linux/delay.h> +#include <power/regulator.h> + +DECLARE_GLOBAL_DATA_PTR; + +/** + * struct rk_pcie - RK DW PCIe controller state + * + * @vpcie3v3: The 3.3v power supply for slot + * @dbi_base: The base address of dwc core regs + * @apb_base: The base address of vendor regs + * @cfg_base: The base address of config header space + * @cfg_size: The size of the configuration space which is needed + * as it gets written into the PCIE_ATU_LIMIT register + * @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 + * (PEX switches etc). + * @rst_gpio: The #PERST signal for slot + * @io: The IO space for EP's BAR + * @mem: The memory space for EP's BAR + */ +struct rk_pcie { + struct udevice *dev; + struct udevice *vpcie3v3; + void *dbi_base; + void *apb_base; + void *cfg_base; + fdt_size_t cfg_size; + struct phy phy; + struct clk_bulk clks; + int first_busno; + struct reset_ctl_bulk rsts; + struct gpio_desc rst_gpio; + struct pci_region io; + struct pci_region mem; +}; + +/* Parameters for the waiting for iATU enabled routine */ +#define PCIE_CLIENT_GENERAL_DEBUG 0x104 +#define PCIE_CLIENT_HOT_RESET_CTRL 0x180 +#define PCIE_LTSSM_ENABLE_ENHANCE BIT(4) +#define PCIE_CLIENT_LTSSM_STATUS 0x300 +#define SMLH_LINKUP BIT(16) +#define RDLH_LINKUP BIT(17) +#define PCIE_CLIENT_DBG_FIFO_MODE_CON 0x310 +#define PCIE_CLIENT_DBG_FIFO_PTN_HIT_D0 0x320 +#define PCIE_CLIENT_DBG_FIFO_PTN_HIT_D1 0x324 +#define PCIE_CLIENT_DBG_FIFO_TRN_HIT_D0 0x328 +#define PCIE_CLIENT_DBG_FIFO_TRN_HIT_D1 0x32c +#define PCIE_CLIENT_DBG_FIFO_STATUS 0x350 +#define PCIE_CLIENT_DBG_TRANSITION_DATA 0xffff0000 +#define PCIE_CLIENT_DBF_EN 0xffff0003 + +/* PCI DBICS registers */ +#define PCIE_LINK_STATUS_REG 0x80 +#define PCIE_LINK_STATUS_SPEED_OFF 16 +#define PCIE_LINK_STATUS_SPEED_MASK (0xf << PCIE_LINK_STATUS_SPEED_OFF) +#define PCIE_LINK_STATUS_WIDTH_OFF 20 +#define PCIE_LINK_STATUS_WIDTH_MASK (0xf << PCIE_LINK_STATUS_WIDTH_OFF) + +#define PCIE_LINK_CAPABILITY 0x7c +#define PCIE_LINK_CTL_2 0xa0 +#define TARGET_LINK_SPEED_MASK 0xf +#define LINK_SPEED_GEN_1 0x1 +#define LINK_SPEED_GEN_2 0x2 +#define LINK_SPEED_GEN_3 0x3 + +#define PCIE_MISC_CONTROL_1_OFF 0x8bc +#define PCIE_DBI_RO_WR_EN BIT(0) + +#define PCIE_LINK_WIDTH_SPEED_CONTROL 0x80c +#define PORT_LOGIC_SPEED_CHANGE BIT(17) + +/* + * iATU Unroll-specific register definitions + * From 4.80 core version the address translation will be made by unroll. + * The registers are offset from atu_base + */ +#define PCIE_ATU_UNR_REGION_CTRL1 0x00 +#define PCIE_ATU_UNR_REGION_CTRL2 0x04 +#define PCIE_ATU_UNR_LOWER_BASE 0x08 +#define PCIE_ATU_UNR_UPPER_BASE 0x0c +#define PCIE_ATU_UNR_LIMIT 0x10 +#define PCIE_ATU_UNR_LOWER_TARGET 0x14 +#define PCIE_ATU_UNR_UPPER_TARGET 0x18 + +#define PCIE_ATU_REGION_INDEX1 (0x1 << 0) +#define PCIE_ATU_REGION_INDEX0 (0x0 << 0) +#define PCIE_ATU_TYPE_MEM (0x0 << 0) +#define PCIE_ATU_TYPE_IO (0x2 << 0) +#define PCIE_ATU_TYPE_CFG0 (0x4 << 0) +#define PCIE_ATU_TYPE_CFG1 (0x5 << 0) +#define PCIE_ATU_ENABLE (0x1 << 31) +#define PCIE_ATU_BAR_MODE_ENABLE (0x1 << 30) +#define PCIE_ATU_BUS(x) (((x) & 0xff) << 24) +#define PCIE_ATU_DEV(x) (((x) & 0x1f) << 19) +#define PCIE_ATU_FUNC(x) (((x) & 0x7) << 16) + +/* Register address builder */ +#define PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(region) \ + ((0x3 << 20) | ((region) << 9)) + +/* Parameters for the waiting for iATU enabled routine */ +#define LINK_WAIT_MAX_IATU_RETRIES 5 +#define LINK_WAIT_IATU_US 10000 + +/* Parameters for the waiting for #perst signal */ +#define PERST_WAIT_MS 1000 + +static int rk_pcie_read(void __iomem *addr, int size, u32 *val) +{ + if ((uintptr_t)addr & (size - 1)) { + *val = 0; + return PCIBIOS_UNSUPPORTED; + } + + if (size == 4) { + *val = readl(addr); + } else if (size == 2) { + *val = readw(addr); + } else if (size == 1) { + *val = readb(addr); + } else { + *val = 0; + return -ENODEV; + } + + return 0; +} + +static int rk_pcie_write(void __iomem *addr, int size, u32 val) +{ + if ((uintptr_t)addr & (size - 1)) + return PCIBIOS_UNSUPPORTED; + + if (size == 4) + writel(val, addr); + else if (size == 2) + writew(val, addr); + else if (size == 1) + writeb(val, addr); + else + return -ENODEV; + + return 0; +} + +static u32 __rk_pcie_read_apb(struct rk_pcie *rk_pcie, void __iomem *base, + u32 reg, size_t size) +{ + int ret; + u32 val; + + ret = rk_pcie_read(base + reg, size, &val); + if (ret) + dev_err(rk_pcie->dev, "Read APB address failed\n"); + + return val; +} + +static void __rk_pcie_write_apb(struct rk_pcie *rk_pcie, void __iomem *base, + u32 reg, size_t size, u32 val) +{ + int ret; + + ret = rk_pcie_write(base + reg, size, val); + if (ret) + dev_err(rk_pcie->dev, "Write APB address failed\n"); +} + +/** + * rk_pcie_readl_apb() - Read vendor regs + * + * @rk_pcie: Pointer to the PCI controller state + * @reg: Offset of regs + */ +static inline u32 rk_pcie_readl_apb(struct rk_pcie *rk_pcie, u32 reg) +{ + return __rk_pcie_read_apb(rk_pcie, rk_pcie->apb_base, reg, 0x4); +} + +/** + * rk_pcie_writel_apb() - Write vendor regs + * + * @rk_pcie: Pointer to the PCI controller state + * @reg: Offset of regs + * @val: Value to be writen + */ +static inline void rk_pcie_writel_apb(struct rk_pcie *rk_pcie, u32 reg, + u32 val) +{ + __rk_pcie_write_apb(rk_pcie, rk_pcie->apb_base, reg, 0x4, val); +} + +static int rk_pcie_get_link_speed(struct rk_pcie *rk_pcie) +{ + return (readl(rk_pcie->dbi_base + PCIE_LINK_STATUS_REG) & + PCIE_LINK_STATUS_SPEED_MASK) >> PCIE_LINK_STATUS_SPEED_OFF; +} + +static int rk_pcie_get_link_width(struct rk_pcie *rk_pcie) +{ + return (readl(rk_pcie->dbi_base + PCIE_LINK_STATUS_REG) & + PCIE_LINK_STATUS_WIDTH_MASK) >> PCIE_LINK_STATUS_WIDTH_OFF; +} + +static void rk_pcie_writel_ob_unroll(struct rk_pcie *rk_pcie, u32 index, + u32 reg, u32 val) +{ + u32 offset = PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(index); + void __iomem *base = rk_pcie->dbi_base; + + writel(val, base + offset + reg); +} + +static u32 rk_pcie_readl_ob_unroll(struct rk_pcie *rk_pcie, u32 index, u32 reg) +{ + u32 offset = PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(index); + void __iomem *base = rk_pcie->dbi_base; + + return readl(base + offset + reg); +} + +static inline void rk_pcie_dbi_write_enable(struct rk_pcie *rk_pcie, bool en) +{ + u32 val; + + val = readl(rk_pcie->dbi_base + PCIE_MISC_CONTROL_1_OFF); + + if (en) + val |= PCIE_DBI_RO_WR_EN; + else + val &= ~PCIE_DBI_RO_WR_EN; + writel(val, rk_pcie->dbi_base + PCIE_MISC_CONTROL_1_OFF); +} + +/** + * rockchip_pcie_setup_host() - Setup the PCIe controller for RC opertaion + * + * @rk_pcie: Pointer to the PCI controller state + * + * Configure the host BARs of the PCIe controller root port so that + * PCI(e) devices may access the system memory. + */ +static void rk_pcie_setup_host(struct rk_pcie *rk_pcie) +{ + u32 val; + + rk_pcie_dbi_write_enable(rk_pcie, true); + + /* setup RC BARs */ + writel(PCI_BASE_ADDRESS_MEM_TYPE_64, + rk_pcie->dbi_base + PCI_BASE_ADDRESS_0); + writel(0x0, rk_pcie->dbi_base + PCI_BASE_ADDRESS_1); + + /* setup interrupt pins */ + clrsetbits_le32(rk_pcie->dbi_base + PCI_INTERRUPT_LINE, + 0xff00, 0x100); + + /* setup bus numbers */ + clrsetbits_le32(rk_pcie->dbi_base + PCI_PRIMARY_BUS, + 0xffffff, 0x00ff0100); + + /* setup command register */ + clrsetbits_le32(rk_pcie->dbi_base + PCI_PRIMARY_BUS, + 0xffff, + PCI_COMMAND_IO | PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER | PCI_COMMAND_SERR); + + /* program correct class for RC */ + writew(PCI_CLASS_BRIDGE_PCI, rk_pcie->dbi_base + PCI_CLASS_DEVICE); + /* Better disable write permission right after the update */ + + setbits_le32(rk_pcie->dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL, + PORT_LOGIC_SPEED_CHANGE) + + rk_pcie_dbi_write_enable(rk_pcie, false); +} + +/** + * rk_pcie_configure() - Configure link capabilities and speed + * + * @rk_pcie: Pointer to the PCI controller state + * @cap_speed: The capabilities and speed to configure + * + * Configure the link capabilities and speed in the PCIe root complex. + */ +static void rk_pcie_configure(struct rk_pcie *pci, u32 cap_speed) +{ + u32 val; + + rk_pcie_dbi_write_enable(pci, true); + + clrsetbits_le32(pci->dbi_base + PCIE_LINK_CAPABILITY, + TARGET_LINK_SPEED_MASK, cap_speed); + + clrsetbits_le32(pci->dbi_base + PCIE_LINK_CTL_2, + TARGET_LINK_SPEED_MASK, cap_speed); + + rk_pcie_dbi_write_enable(pci, false); +} + +/** + * rk_pcie_dw_prog_outbound_atu_unroll() - Configure ATU for outbound accesses + * + * @rk_pcie: Pointer to the PCI controller state + * @index: ATU region index + * @type: ATU accsess type + * @cpu_addr: the physical address for the translation entry + * @pci_addr: the pcie bus address for the translation entry + * @size: the size of the translation entry + * + * Return: 0 is successful and -1 is failure + */ +static int rk_pcie_prog_outbound_atu_unroll(struct rk_pcie *pci, int index, + int type, u64 cpu_addr, + u64 pci_addr, u32 size) +{ + u32 retries, val; + + dev_dbg(pci->dev, "ATU programmed with: index: %d, type: %d, cpu addr: %8llx, pci addr: %8llx, size: %8x\n", + index, type, cpu_addr, pci_addr, size); + + rk_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_LOWER_BASE, + lower_32_bits(cpu_addr)); + rk_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_UPPER_BASE, + upper_32_bits(cpu_addr)); + rk_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_LIMIT, + lower_32_bits(cpu_addr + size - 1)); + rk_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_LOWER_TARGET, + lower_32_bits(pci_addr)); + rk_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_UPPER_TARGET, + upper_32_bits(pci_addr)); + rk_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL1, + type); + rk_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL2, + PCIE_ATU_ENABLE); + + /* + * Make sure ATU enable takes effect before any subsequent config + * and I/O accesses. + */ + for (retries = 0; retries < LINK_WAIT_MAX_IATU_RETRIES; retries++) { + val = rk_pcie_readl_ob_unroll(pci, index, + PCIE_ATU_UNR_REGION_CTRL2); + if (val & PCIE_ATU_ENABLE) + return 0; + + udelay(LINK_WAIT_IATU_US); + } + dev_err(pci->dev, "outbound iATU is not being enabled\n"); + + return -1; +} + +/** + * rk_pcie_dw_addr_valid() - Check for valid bus address + * + * @d: The PCI device to access + * @first_busno: Bus number of the PCIe controller root complex + * + * Return 1 (true) if the PCI device can be accessed by this controller. + * + * Return: 1 on valid, 0 on invalid + */ +static int rk_pcie_addr_valid(pci_dev_t d, int first_busno) +{ + if ((PCI_BUS(d) == first_busno) && (PCI_DEV(d) > 0)) + return 0; + if ((PCI_BUS(d) == first_busno + 1) && (PCI_DEV(d) > 0)) + return 0; + + return 1; +} + +/** + * set_cfg_address() - Configure the PCIe controller config space access + * + * @rk_pcie: Pointer to the PCI controller state + * @d: PCI device to access + * @where: Offset in the configuration space + * + * Configures the PCIe controller to access the configuration space of + * a specific PCIe device and returns the address to use for this + * access. + * + * Return: Address that can be used to access the configation space + * of the requested device / offset + */ +static uintptr_t set_cfg_address(struct rk_pcie *pcie, + pci_dev_t d, uint where) +{ + int rel_bus = PCI_BUS(d) - pcie->first_busno; + uintptr_t va_address; + u32 atu_type; + int ret; + + /* Use dbi_base for own configuration read and write */ + if (!rel_bus) { + va_address = (uintptr_t)pcie->dbi_base; + goto out; + } + + if (rel_bus == 1) + /* + * For local bus whose primary bus number is root bridge, + * change TLP Type field to 4. + */ + atu_type = PCIE_ATU_TYPE_CFG0; + else + /* Otherwise, change TLP Type field to 5. */ + atu_type = PCIE_ATU_TYPE_CFG1; + + /* + * Not accessing root port configuration space? + * Region #0 is used for Outbound CFG space access. + * Direction = Outbound + * Region Index = 0 + */ + d = PCI_MASK_BUS(d); + d = PCI_ADD_BUS(rel_bus, d); + ret = rk_pcie_prog_outbound_atu_unroll(pcie, PCIE_ATU_REGION_INDEX1, + atu_type, (u64)pcie->cfg_base, + d << 8, pcie->cfg_size); + if (ret) + return (uintptr_t)ret; + + va_address = (uintptr_t)pcie->cfg_base; + +out: + va_address += where & ~0x3; + + return va_address; +} + +/** + * rockchip_pcie_rd_conf() - Read from configuration space + * + * @bus: Pointer to the PCI bus + * @bdf: Identifies the PCIe device to access + * @offset: The offset into the device's configuration space + * @valuep: A pointer at which to store the read value + * @size: Indicates the size of access to perform + * + * Read a value of size @size from offset @offset within the configuration + * space of the device identified by the bus, device & function numbers in @bdf + * on the PCI bus @bus. + * + * Return: 0 on success + */ +static int rockchip_pcie_rd_conf(const struct udevice *bus, pci_dev_t bdf, + uint offset, ulong *valuep, + enum pci_size_t size) +{ + struct rk_pcie *pcie = dev_get_priv(bus); + uintptr_t va_address; + ulong value; + + debug("PCIE CFG read: bdf=%2x:%2x:%2x\n", + PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf)); + + if (!rk_pcie_addr_valid(bdf, pcie->first_busno)) { + debug("- out of range\n"); + *valuep = pci_get_ff(size); + return 0; + } + + va_address = set_cfg_address(pcie, bdf, offset); + + value = readl(va_address); + + debug("(addr,val)=(0x%04x, 0x%08lx)\n", offset, value); + *valuep = pci_conv_32_to_size(value, offset, size); + + return rk_pcie_prog_outbound_atu_unroll(pcie, + PCIE_ATU_REGION_INDEX1, + PCIE_ATU_TYPE_IO, + pcie->io.phys_start, + pcie->io.bus_start, + pcie->io.size); +} + +/** + * rockchip_pcie_wr_conf() - Write to configuration space + * + * @bus: Pointer to the PCI bus + * @bdf: Identifies the PCIe device to access + * @offset: The offset into the device's configuration space + * @value: The value to write + * @size: Indicates the size of access to perform + * + * Write the value @value of size @size from offset @offset within the + * configuration space of the device identified by the bus, device & function + * numbers in @bdf on the PCI bus @bus. + * + * Return: 0 on success + */ +static int rockchip_pcie_wr_conf(struct udevice *bus, pci_dev_t bdf, + uint offset, ulong value, + enum pci_size_t size) +{ + struct rk_pcie *pcie = dev_get_priv(bus); + uintptr_t va_address; + ulong old; + + debug("PCIE CFG write: (b,d,f)=(%2d,%2d,%2d)\n", + PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf)); + debug("(addr,val)=(0x%04x, 0x%08lx)\n", offset, value); + + if (!rk_pcie_addr_valid(bdf, pcie->first_busno)) { + debug("- out of range\n"); + return 0; + } + + va_address = set_cfg_address(pcie, bdf, offset); + + old = readl(va_address); + value = pci_conv_size_to_32(old, value, offset, size); + writel(value, va_address); + + return rk_pcie_prog_outbound_atu_unroll(pcie, + PCIE_ATU_REGION_INDEX1, + PCIE_ATU_TYPE_IO, + pcie->io.phys_start, + pcie->io.bus_start, + pcie->io.size); + +} + +static void rk_pcie_enable_debug(struct rk_pcie *rk_pcie) +{ + rk_pcie_writel_apb(rk_pcie, PCIE_CLIENT_DBG_FIFO_PTN_HIT_D0, + PCIE_CLIENT_DBG_TRANSITION_DATA); + rk_pcie_writel_apb(rk_pcie, PCIE_CLIENT_DBG_FIFO_PTN_HIT_D1, + PCIE_CLIENT_DBG_TRANSITION_DATA); + rk_pcie_writel_apb(rk_pcie, PCIE_CLIENT_DBG_FIFO_TRN_HIT_D0, + PCIE_CLIENT_DBG_TRANSITION_DATA); + rk_pcie_writel_apb(rk_pcie, PCIE_CLIENT_DBG_FIFO_TRN_HIT_D1, + PCIE_CLIENT_DBG_TRANSITION_DATA); + rk_pcie_writel_apb(rk_pcie, PCIE_CLIENT_DBG_FIFO_MODE_CON, + PCIE_CLIENT_DBF_EN); +} + +static void rk_pcie_debug_dump(struct rk_pcie *rk_pcie) +{ + u32 loop; + + debug("ltssm = 0x%x\n", + rk_pcie_readl_apb(rk_pcie, PCIE_CLIENT_LTSSM_STATUS)); + for (loop = 0; loop < 64; loop++) + debug("fifo_status = 0x%x\n", + rk_pcie_readl_apb(rk_pcie, PCIE_CLIENT_DBG_FIFO_STATUS)); +} + +static inline void rk_pcie_link_status_clear(struct rk_pcie *rk_pcie) +{ + rk_pcie_writel_apb(rk_pcie, PCIE_CLIENT_GENERAL_DEBUG, 0x0); +} + +static inline void rk_pcie_disable_ltssm(struct rk_pcie *rk_pcie) +{ + rk_pcie_writel_apb(rk_pcie, 0x0, 0xc0008); +} + +static inline void rk_pcie_enable_ltssm(struct rk_pcie *rk_pcie) +{ + rk_pcie_writel_apb(rk_pcie, 0x0, 0xc000c); +} + +static int is_link_up(struct rk_pcie *priv) +{ + u32 val; + + val = rk_pcie_readl_apb(priv, PCIE_CLIENT_LTSSM_STATUS); + if ((val & (RDLH_LINKUP | SMLH_LINKUP)) == 0x30000 && + (val & GENMASK(5, 0)) == 0x11) + return 1; + + return 0; +} + +/** + * rk_pcie_link_up() - Wait for the link to come up + * + * @rk_pcie: Pointer to the PCI controller state + * @cap_speed: Desired link speed + * + * Return: 1 (true) for active line and negetive (false) for no link (timeout) + */ +static int rk_pcie_link_up(struct rk_pcie *priv, u32 cap_speed) +{ + int retries; + + if (is_link_up(priv)) { + printf("PCI Link already up before configuration!\n"); + return 1; + } + + /* DW pre link configurations */ + rk_pcie_configure(priv, cap_speed); + + /* Rest the device */ + if (dm_gpio_is_valid(&priv->rst_gpio)) { + dm_gpio_set_value(&priv->rst_gpio, 0); + /* + * Minimal is 100ms from spec but we see + * some wired devices need much more, such as 600ms. + * Add a enough delay to cover all cases. + */ + msleep(PERST_WAIT_MS); + dm_gpio_set_value(&priv->rst_gpio, 1); + } + + rk_pcie_disable_ltssm(priv); + rk_pcie_link_status_clear(priv); + rk_pcie_enable_debug(priv); + + /* Enable LTSSM */ + rk_pcie_enable_ltssm(priv); + + for (retries = 0; retries < 5; retries++) { + if (is_link_up(priv)) { + dev_info(priv->dev, "PCIe Link up, LTSSM is 0x%x\n", + rk_pcie_readl_apb(priv, PCIE_CLIENT_LTSSM_STATUS)); + rk_pcie_debug_dump(priv); + return 0; + } + + dev_info(priv->dev, "PCIe Linking... LTSSM is 0x%x\n", + rk_pcie_readl_apb(priv, PCIE_CLIENT_LTSSM_STATUS)); + rk_pcie_debug_dump(priv); + msleep(1000); + } + + dev_err(priv->dev, "PCIe-%d Link Fail\n", dev_seq(priv->dev)); + /* Link maybe in Gen switch recovery but we need to wait more 1s */ + msleep(1000); + return -EIO; +} + +static int rockchip_pcie_init_port(struct udevice *dev) +{ + int ret; + u32 val; + struct rk_pcie *priv = dev_get_priv(dev); + + /* Set power and maybe external ref clk input */ + if (priv->vpcie3v3) { + ret = regulator_set_value(priv->vpcie3v3, 3300000); + if (ret) { + dev_err(priv->dev, "failed to enable vpcie3v3 (ret=%d)\n", + ret); + return ret; + } + } + + msleep(1000); + + ret = generic_phy_init(&priv->phy); + if (ret) { + dev_err(dev, "failed to init phy (ret=%d)\n", ret); + return ret; + } + + ret = generic_phy_power_on(&priv->phy); + if (ret) { + dev_err(dev, "failed to power on phy (ret=%d)\n", ret); + goto err_exit_phy; + } + + ret = reset_deassert_bulk(&priv->rsts); + if (ret) { + dev_err(dev, "failed to deassert resets (ret=%d)\n", ret); + goto err_power_off_phy; + } + + ret = clk_enable_bulk(&priv->clks); + if (ret) { + dev_err(dev, "failed to enable clks (ret=%d)\n", ret); + goto err_deassert_bulk; + } + + /* LTSSM EN ctrl mode */ + val = rk_pcie_readl_apb(priv, PCIE_CLIENT_HOT_RESET_CTRL); + val |= PCIE_LTSSM_ENABLE_ENHANCE | (PCIE_LTSSM_ENABLE_ENHANCE << 16); + rk_pcie_writel_apb(priv, PCIE_CLIENT_HOT_RESET_CTRL, val); + + /* Set RC mode */ + rk_pcie_writel_apb(priv, 0x0, 0xf00040); + rk_pcie_setup_host(priv); + + ret = rk_pcie_link_up(priv, LINK_SPEED_GEN_3); + if (ret < 0) + goto err_link_up; + + return 0; +err_link_up: + clk_disable_bulk(&priv->clks); +err_deassert_bulk: + reset_assert_bulk(&priv->rsts); +err_power_off_phy: + generic_phy_power_off(&priv->phy); +err_exit_phy: + generic_phy_exit(&priv->phy); + + return ret; +} + +static int rockchip_pcie_parse_dt(struct udevice *dev) +{ + struct rk_pcie *priv = dev_get_priv(dev); + int ret; + + priv->dbi_base = (void *)dev_read_addr_index(dev, 0); + if (!priv->dbi_base) + return -ENODEV; + + dev_dbg(dev, "DBI address is 0x%p\n", priv->dbi_base); + + priv->apb_base = (void *)dev_read_addr_index(dev, 1); + if (!priv->apb_base) + return -ENODEV; + + dev_dbg(dev, "APB address is 0x%p\n", priv->apb_base); + + ret = gpio_request_by_name(dev, "reset-gpios", 0, + &priv->rst_gpio, GPIOD_IS_OUT); + if (ret) { + dev_err(dev, "failed to find reset-gpios property\n"); + return ret; + } + + ret = reset_get_bulk(dev, &priv->rsts); + if (ret) { + dev_err(dev, "Can't get reset: %d\n", ret); + return ret; + } + + ret = clk_get_bulk(dev, &priv->clks); + if (ret) { + dev_err(dev, "Can't get clock: %d\n", ret); + return ret; + } + + ret = device_get_supply_regulator(dev, "vpcie3v3-supply", + &priv->vpcie3v3); + if (ret && ret != -ENOENT) { + dev_err(dev, "failed to get vpcie3v3 supply (ret=%d)\n", ret); + return ret; + } + + ret = generic_phy_get_by_index(dev, 0, &priv->phy); + if (ret) { + dev_err(dev, "failed to get pcie phy (ret=%d)\n", ret); + return ret; + } + + return 0; +} + +/** + * rockchip_pcie_probe() - Probe the PCIe bus for active link + * + * @dev: A pointer to the device being operated on + * + * Probe for an active link on the PCIe bus and configure the controller + * to enable this port. + * + * Return: 0 on success, else -ENODEV + */ +static int rockchip_pcie_probe(struct udevice *dev) +{ + struct rk_pcie *priv = dev_get_priv(dev); + struct udevice *ctlr = pci_get_controller(dev); + struct pci_controller *hose = dev_get_uclass_priv(ctlr); + int reti = 0; + + priv->first_busno = dev_seq(dev); + priv->dev = dev; + + ret = rockchip_pcie_parse_dt(dev); + if (ret) + return ret; + + ret = rockchip_pcie_init_port(dev); + if (ret) + return ret; + + dev_info(dev, "PCIE-%d: Link up (Gen%d-x%d, Bus%d)\n", + dev_seq(dev), rk_pcie_get_link_speed(priv), + rk_pcie_get_link_width(priv), + hose->first_busno); + + for (ret = 0; ret < hose->region_count; ret++) { + if (hose->regions[ret].flags == PCI_REGION_IO) { + priv->io.phys_start = hose->regions[ret].phys_start; /* IO base */ + priv->io.bus_start = hose->regions[ret].bus_start; /* IO_bus_addr */ + priv->io.size = hose->regions[ret].size; /* IO size */ + } else if (hose->regions[ret].flags == PCI_REGION_MEM) { + priv->mem.phys_start = hose->regions[ret].phys_start; /* MEM base */ + priv->mem.bus_start = hose->regions[ret].bus_start; /* MEM_bus_addr */ + priv->mem.size = hose->regions[ret].size; /* MEM size */ + } else if (hose->regions[ret].flags == PCI_REGION_SYS_MEMORY) { + priv->cfg_base = (void *)(priv->io.phys_start - priv->io.size); + priv->cfg_size = priv->io.size; + } else { + dev_err(dev, "invalid flags type!\n"); + } + } + + dev_dbg(dev, "Config space: [0x%p - 0x%p, size 0x%llx]\n", + priv->cfg_base, priv->cfg_base + priv->cfg_size, + priv->cfg_size); + + dev_dbg(dev, "IO space: [0x%llx - 0x%llx, size 0x%lx]\n", + priv->io.phys_start, priv->io.phys_start + priv->io.size, + priv->io.size); + + dev_dbg(dev, "IO bus: [0x%lx - 0x%lx, size 0x%lx]\n", + priv->io.bus_start, priv->io.bus_start + priv->io.size, + priv->io.size); + + dev_dbg(dev, "MEM space: [0x%llx - 0x%llx, size 0x%lx]\n", + priv->mem.phys_start, priv->mem.phys_start + priv->mem.size, + priv->mem.size); + + dev_dbg(dev, "MEM bus: [0x%lx - 0x%lx, size 0x%lx]\n", + priv->mem.bus_start, priv->mem.bus_start + priv->mem.size, + priv->mem.size); + + return rk_pcie_prog_outbound_atu_unroll(priv, + PCIE_ATU_REGION_INDEX0, + PCIE_ATU_TYPE_MEM, + priv->mem.phys_start, + priv->mem.bus_start, + priv->mem.size); +} + +static const struct dm_pci_ops rockchip_pcie_ops = { + .read_config = rockchip_pcie_rd_conf, + .write_config = rockchip_pcie_wr_conf, +}; + +static const struct udevice_id rockchip_pcie_ids[] = { + { .compatible = "rockchip,rk3568-pcie" }, + { } +}; + +U_BOOT_DRIVER(rockchip_dw_pcie) = { + .name = "pcie_dw_rockchip", + .id = UCLASS_PCI, + .of_match = rockchip_pcie_ids, + .ops = &rockchip_pcie_ops, + .probe = rockchip_pcie_probe, + .priv_auto = sizeof(struct rk_pcie), +}; diff --git a/drivers/pci_endpoint/pci_ep-uclass.c b/drivers/pci_endpoint/pci_ep-uclass.c index 38a5f08376..aa89701de8 100644 --- a/drivers/pci_endpoint/pci_ep-uclass.c +++ b/drivers/pci_endpoint/pci_ep-uclass.c @@ -210,7 +210,7 @@ UCLASS_DRIVER(pci_ep) = { .flags = DM_UC_FLAG_SEQ_ALIAS, }; -void pci_ep_init(void) +int pci_ep_init(void) { struct udevice *dev; @@ -219,4 +219,6 @@ void pci_ep_init(void) uclass_next_device_check(&dev)) { ; } + + return 0; } diff --git a/drivers/phy/phy-stm32-usbphyc.c b/drivers/phy/phy-stm32-usbphyc.c index f23aef4fb0..02d859a039 100644 --- a/drivers/phy/phy-stm32-usbphyc.c +++ b/drivers/phy/phy-stm32-usbphyc.c @@ -3,6 +3,8 @@ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved */ +#define LOG_CATEGORY UCLASS_PHY + #include <common.h> #include <clk.h> #include <div64.h> @@ -98,8 +100,8 @@ static int stm32_usbphyc_pll_init(struct stm32_usbphyc *usbphyc) u32 usbphyc_pll; if ((clk_rate < PLL_INFF_MIN_RATE) || (clk_rate > PLL_INFF_MAX_RATE)) { - pr_debug("%s: input clk freq (%dHz) out of range\n", - __func__, clk_rate); + log_debug("input clk freq (%dHz) out of range\n", + clk_rate); return -EINVAL; } @@ -116,8 +118,8 @@ static int stm32_usbphyc_pll_init(struct stm32_usbphyc *usbphyc) writel(usbphyc_pll, usbphyc->base + STM32_USBPHYC_PLL); - pr_debug("%s: input clk freq=%dHz, ndiv=%d, frac=%d\n", __func__, - clk_rate, pll_params.ndiv, pll_params.frac); + log_debug("input clk freq=%dHz, ndiv=%d, frac=%d\n", + clk_rate, pll_params.ndiv, pll_params.frac); return 0; } @@ -154,7 +156,7 @@ static int stm32_usbphyc_phy_init(struct phy *phy) true : false; int ret; - pr_debug("%s phy ID = %lu\n", __func__, phy->id); + dev_dbg(phy->dev, "phy ID = %lu\n", phy->id); /* Check if one phy port has already configured the pll */ if (pllen && stm32_usbphyc_is_init(usbphyc)) goto initialized; @@ -200,7 +202,7 @@ static int stm32_usbphyc_phy_exit(struct phy *phy) struct stm32_usbphyc_phy *usbphyc_phy = usbphyc->phys + phy->id; int ret; - pr_debug("%s phy ID = %lu\n", __func__, phy->id); + dev_dbg(phy->dev, "phy ID = %lu\n", phy->id); usbphyc_phy->init = false; /* Check if other phy port requires pllen */ @@ -239,7 +241,7 @@ static int stm32_usbphyc_phy_power_on(struct phy *phy) struct stm32_usbphyc_phy *usbphyc_phy = usbphyc->phys + phy->id; int ret; - pr_debug("%s phy ID = %lu\n", __func__, phy->id); + dev_dbg(phy->dev, "phy ID = %lu\n", phy->id); if (usbphyc_phy->vdd) { ret = regulator_set_enable(usbphyc_phy->vdd, true); if (ret) @@ -262,7 +264,7 @@ static int stm32_usbphyc_phy_power_off(struct phy *phy) struct stm32_usbphyc_phy *usbphyc_phy = usbphyc->phys + phy->id; int ret; - pr_debug("%s phy ID = %lu\n", __func__, phy->id); + dev_dbg(phy->dev, "phy ID = %lu\n", phy->id); usbphyc_phy->powered = false; if (stm32_usbphyc_is_powered(usbphyc)) diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig index 2318e71f35..e477a6cd9e 100644 --- a/drivers/phy/rockchip/Kconfig +++ b/drivers/phy/rockchip/Kconfig @@ -18,6 +18,15 @@ config PHY_ROCKCHIP_PCIE help Enable this to support the Rockchip PCIe PHY. +config PHY_ROCKCHIP_SNPS_PCIE3 + bool "Rockchip Snps PCIe3 PHY Driver" + depends on PHY && ARCH_ROCKCHIP + help + Support for Rockchip PCIe3 PHY with Synopsys IP block. + It could support PCIe Gen3 single root complex, and could + also be able splited into multiple combinations of lanes. + + config PHY_ROCKCHIP_TYPEC bool "Rockchip TYPEC PHY Driver" depends on ARCH_ROCKCHIP diff --git a/drivers/phy/rockchip/Makefile b/drivers/phy/rockchip/Makefile index 44049154f9..f6ad3bf59a 100644 --- a/drivers/phy/rockchip/Makefile +++ b/drivers/phy/rockchip/Makefile @@ -5,4 +5,5 @@ obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB2) += phy-rockchip-inno-usb2.o obj-$(CONFIG_PHY_ROCKCHIP_PCIE) += phy-rockchip-pcie.o +obj-$(CONFIG_PHY_ROCKCHIP_SNPS_PCIE3) += phy-rockchip-snps-pcie3.o obj-$(CONFIG_PHY_ROCKCHIP_TYPEC) += phy-rockchip-typec.o diff --git a/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c b/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c new file mode 100644 index 0000000000..5ae41fbeee --- /dev/null +++ b/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c @@ -0,0 +1,157 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Rockchip PCIE3.0 phy driver + * + * Copyright (C) 2021 Rockchip Electronics Co., Ltd. + */ + +#include <common.h> +#include <clk.h> +#include <dm.h> +#include <generic-phy.h> +#include <regmap.h> +#include <reset-uclass.h> +#include <syscon.h> +#include <asm/io.h> +#include <dm/device_compat.h> +#include <dm/lists.h> + +#define GRF_PCIE30PHY_CON1 0x4 +#define GRF_PCIE30PHY_CON6 0x18 +#define GRF_PCIE30PHY_CON9 0x24 + +/** + * struct rockchip_p3phy_priv - RK DW PCIe PHY state + * + * @mmio: The base address of PHY internal registers + * @phy_grf: The regmap for controlling pipe signal + * @p30phy: The reset signal for PHY + * @ref_clk_m: The reference clock of M for PHY + * @ref_clk_n: The reference clock of N for PHY + * @pclk: The clock for accessing PHY blocks + */ +struct rockchip_p3phy_priv { + void __iomem *mmio; + struct regmap *phy_grf; + struct reset_ctl p30phy; + struct clk ref_clk_m; + struct clk ref_clk_n; + struct clk pclk; +}; + +static int rochchip_p3phy_init(struct phy *phy) +{ + struct rockchip_p3phy_priv *priv = dev_get_priv(phy->dev); + int ret; + + ret = clk_enable(&priv->ref_clk_m); + if (ret < 0 && ret != -ENOSYS) + return ret; + + ret = clk_enable(&priv->ref_clk_n); + if (ret < 0 && ret != -ENOSYS) + goto err_ref; + + ret = clk_enable(&priv->pclk); + if (ret < 0 && ret != -ENOSYS) + goto err_pclk; + + reset_assert(&priv->p30phy); + udelay(1); + + /* Deassert PCIe PMA output clamp mode */ + regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON9, + (0x1 << 15) | (0x1 << 31)); + + reset_deassert(&priv->p30phy); + udelay(1); + + return 0; +err_pclk: + clk_disable(&priv->ref_clk_n); +err_ref: + clk_disable(&priv->ref_clk_m); + + return ret; +} + +static int rochchip_p3phy_exit(struct phy *phy) +{ + struct rockchip_p3phy_priv *priv = dev_get_priv(phy->dev); + + clk_disable(&priv->ref_clk_m); + clk_disable(&priv->ref_clk_n); + clk_disable(&priv->pclk); + reset_assert(&priv->p30phy); + + return 0; +} + +static int rockchip_p3phy_probe(struct udevice *dev) +{ + struct rockchip_p3phy_priv *priv = dev_get_priv(dev); + struct udevice *syscon; + int ret; + + priv->mmio = (void __iomem *)dev_read_addr(dev); + if ((fdt_addr_t)priv->mmio == FDT_ADDR_T_NONE) + return -EINVAL; + + ret = uclass_get_device_by_phandle(UCLASS_SYSCON, dev, + "rockchip,phy-grf", &syscon); + if (ret) { + pr_err("unable to find syscon device for rockchip,phy-grf\n"); + return ret; + } + + priv->phy_grf = syscon_get_regmap(syscon); + if (IS_ERR(priv->phy_grf)) { + dev_err(dev, "failed to find rockchip,phy_grf regmap\n"); + return PTR_ERR(priv->phy_grf); + } + + ret = reset_get_by_name(dev, "phy", &priv->p30phy); + if (ret) { + dev_err(dev, "no phy reset control specified\n"); + return ret; + } + + ret = clk_get_by_name(dev, "refclk_m", &priv->ref_clk_m); + if (ret) { + dev_err(dev, "failed to find ref clock M\n"); + return PTR_ERR(&priv->ref_clk_m); + } + + ret = clk_get_by_name(dev, "refclk_n", &priv->ref_clk_n); + if (ret) { + dev_err(dev, "failed to find ref clock N\n"); + return PTR_ERR(&priv->ref_clk_n); + } + + ret = clk_get_by_name(dev, "pclk", &priv->pclk); + if (ret) { + dev_err(dev, "failed to find pclk\n"); + return PTR_ERR(&priv->pclk); + } + + return 0; +} + +static struct phy_ops rochchip_p3phy_ops = { + .init = rochchip_p3phy_init, + .exit = rochchip_p3phy_exit, +}; + +static const struct udevice_id rockchip_p3phy_of_match[] = { + { .compatible = "rockchip,rk3568-pcie3-phy" }, + { }, +}; + +U_BOOT_DRIVER(rockchip_pcie3phy) = { + .name = "rockchip_pcie3phy", + .id = UCLASS_PHY, + .of_match = rockchip_p3phy_of_match, + .ops = &rochchip_p3phy_ops, + .probe = rockchip_p3phy_probe, + .priv_auto = sizeof(struct rockchip_p3phy_priv), +}; diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c index 6553dde45c..4dd3f73ead 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c @@ -615,6 +615,7 @@ static int mtk_gpiochip_register(struct udevice *parent) if (!drv) return -ENOENT; + ret = -ENOENT; dev_for_each_subnode(node, parent) if (ofnode_read_bool(node, "gpio-controller")) { ret = 0; diff --git a/drivers/pinctrl/pinctrl_stm32.c b/drivers/pinctrl/pinctrl_stm32.c index 591cd1a0ec..a1f53a793b 100644 --- a/drivers/pinctrl/pinctrl_stm32.c +++ b/drivers/pinctrl/pinctrl_stm32.c @@ -3,6 +3,8 @@ * Copyright (C) 2017-2020 STMicroelectronics - All Rights Reserved */ +#define LOG_CATEGORY UCLASS_PINCTRL + #include <common.h> #include <dm.h> #include <hwspinlock.h> @@ -256,8 +258,8 @@ static int stm32_pinctrl_probe(struct udevice *dev) /* hwspinlock property is optional, just log the error */ ret = hwspinlock_get_by_index(dev, 0, &priv->hws); if (ret) - debug("%s: hwspinlock_get_by_index may have failed (%d)\n", - __func__, ret); + dev_dbg(dev, "hwspinlock_get_by_index may have failed (%d)\n", + ret); return 0; } @@ -305,8 +307,7 @@ static int prep_gpio_dsc(struct stm32_gpio_dsc *gpio_dsc, u32 port_pin) { gpio_dsc->port = (port_pin & 0x1F000) >> 12; gpio_dsc->pin = (port_pin & 0x0F00) >> 8; - debug("%s: GPIO:port= %d, pin= %d\n", __func__, gpio_dsc->port, - gpio_dsc->pin); + log_debug("GPIO:port= %d, pin= %d\n", gpio_dsc->port, gpio_dsc->pin); return 0; } @@ -347,9 +348,9 @@ static int prep_gpio_ctl(struct stm32_gpio_ctl *gpio_ctl, u32 gpio_fn, else gpio_ctl->pupd = STM32_GPIO_PUPD_NO; - debug("%s: gpio fn= %d, slew-rate= %x, op type= %x, pull-upd is = %x\n", - __func__, gpio_fn, gpio_ctl->speed, gpio_ctl->otype, - gpio_ctl->pupd); + log_debug("gpio fn= %d, slew-rate= %x, op type= %x, pull-upd is = %x\n", + gpio_fn, gpio_ctl->speed, gpio_ctl->otype, + gpio_ctl->pupd); return 0; } @@ -373,7 +374,7 @@ static int stm32_pinctrl_config(ofnode node) if (rv < 0) return rv; len = rv / sizeof(pin_mux[0]); - debug("%s: no of pinmux entries= %d\n", __func__, len); + log_debug("No of pinmux entries= %d\n", len); if (len > MAX_PINS_ONE_IP) return -EINVAL; rv = ofnode_read_u32_array(subnode, "pinmux", pin_mux, len); @@ -382,7 +383,7 @@ static int stm32_pinctrl_config(ofnode node) for (i = 0; i < len; i++) { struct gpio_desc desc; - debug("%s: pinmux = %x\n", __func__, *(pin_mux + i)); + log_debug("pinmux = %x\n", *(pin_mux + i)); prep_gpio_dsc(&gpio_dsc, *(pin_mux + i)); prep_gpio_ctl(&gpio_ctl, *(pin_mux + i), subnode); rv = uclass_get_device_by_seq(UCLASS_GPIO, @@ -392,7 +393,7 @@ static int stm32_pinctrl_config(ofnode node) return rv; desc.offset = gpio_dsc.pin; rv = stm32_gpio_config(&desc, &gpio_ctl); - debug("%s: rv = %d\n\n", __func__, rv); + log_debug("rv = %d\n\n", rv); if (rv) return rv; } @@ -408,7 +409,7 @@ static int stm32_pinctrl_bind(struct udevice *dev) int ret; dev_for_each_subnode(node, dev) { - debug("%s: bind %s\n", __func__, ofnode_get_name(node)); + dev_dbg(dev, "bind %s\n", ofnode_get_name(node)); ofnode_get_property(node, "gpio-controller", &ret); if (ret < 0) @@ -424,7 +425,7 @@ static int stm32_pinctrl_bind(struct udevice *dev) if (ret) return ret; - debug("%s: bind %s\n", __func__, name); + dev_dbg(dev, "bind %s\n", name); } return 0; @@ -448,7 +449,7 @@ static int stm32_pinctrl_set_state_simple(struct udevice *dev, if (!list) return -EINVAL; - debug("%s: periph->name = %s\n", __func__, periph->name); + dev_dbg(dev, "periph->name = %s\n", periph->name); size /= sizeof(*list); for (i = 0; i < size; i++) { @@ -456,7 +457,8 @@ static int stm32_pinctrl_set_state_simple(struct udevice *dev, config_node = ofnode_get_by_phandle(phandle); if (!ofnode_valid(config_node)) { - pr_err("prop pinctrl-0 index %d invalid phandle\n", i); + dev_err(periph, + "prop pinctrl-0 index %d invalid phandle\n", i); return -EINVAL; } diff --git a/drivers/pinctrl/renesas/pfc.c b/drivers/pinctrl/renesas/pfc.c index 8bb7e16f94..6ff948420c 100644 --- a/drivers/pinctrl/renesas/pfc.c +++ b/drivers/pinctrl/renesas/pfc.c @@ -44,6 +44,7 @@ enum sh_pfc_model { struct sh_pfc_pin_config { u32 type; + const char *name; }; struct sh_pfc_pinctrl { @@ -448,6 +449,30 @@ static const char *sh_pfc_pinctrl_get_group_name(struct udevice *dev, return priv->pfc.info->groups[selector].name; } +static int sh_pfc_pinctrl_get_pin_muxing(struct udevice *dev, + unsigned int selector, + char *buf, int size) +{ + struct sh_pfc_pinctrl_priv *priv = dev_get_priv(dev); + struct sh_pfc_pinctrl *pmx = &priv->pmx; + struct sh_pfc *pfc = &priv->pfc; + struct sh_pfc_pin_config *cfg; + const struct sh_pfc_pin *pin; + int idx; + + pin = &priv->pfc.info->pins[selector]; + if (!pin) { + snprintf(buf, size, "Unknown"); + return -EINVAL; + } + + idx = sh_pfc_get_pin_index(pfc, pin->pin); + cfg = &pmx->configs[idx]; + snprintf(buf, size, "%s", cfg->name); + + return 0; +} + static int sh_pfc_pinctrl_get_functions_count(struct udevice *dev) { struct sh_pfc_pinctrl_priv *priv = dev_get_priv(dev); @@ -487,14 +512,21 @@ static int sh_pfc_gpio_request_enable(struct udevice *dev, idx = sh_pfc_get_pin_index(pfc, pin->pin); cfg = &pmx->configs[idx]; - if (cfg->type != PINMUX_TYPE_NONE) + if (cfg->type != PINMUX_TYPE_NONE) { + if (!strcmp(cfg->name, pin->name)) + return 0; + + dev_err(pfc->dev, "Pin already used as %s\n", + cfg->name); return -EBUSY; + } ret = sh_pfc_config_mux(pfc, pin->enum_id, PINMUX_TYPE_GPIO); if (ret) return ret; cfg->type = PINMUX_TYPE_GPIO; + cfg->name = "gpio"; return 0; } @@ -524,6 +556,7 @@ static int sh_pfc_gpio_disable_free(struct udevice *dev, cfg = &pmx->configs[idx]; cfg->type = PINMUX_TYPE_NONE; + cfg->name = "none"; return 0; } @@ -537,11 +570,25 @@ static int sh_pfc_pinctrl_pin_set(struct udevice *dev, unsigned pin_selector, const struct sh_pfc_pin *pin = &priv->pfc.info->pins[pin_selector]; int idx = sh_pfc_get_pin_index(pfc, pin->pin); struct sh_pfc_pin_config *cfg = &pmx->configs[idx]; + int ret; - if (cfg->type != PINMUX_TYPE_NONE) + if (cfg->type != PINMUX_TYPE_NONE) { + if (!strcmp(cfg->name, pin->name)) + return 0; + + dev_err(pfc->dev, "Pin already used as %s\n", + cfg->name); return -EBUSY; + } + + ret = sh_pfc_config_mux(pfc, pin->enum_id, PINMUX_TYPE_FUNCTION); + if (ret) + return ret; - return sh_pfc_config_mux(pfc, pin->enum_id, PINMUX_TYPE_FUNCTION); + cfg->type = PINMUX_TYPE_FUNCTION; + cfg->name = "function"; + + return 0; } static int sh_pfc_pinctrl_group_set(struct udevice *dev, unsigned group_selector, @@ -551,23 +598,41 @@ static int sh_pfc_pinctrl_group_set(struct udevice *dev, unsigned group_selector struct sh_pfc_pinctrl *pmx = &priv->pmx; struct sh_pfc *pfc = &priv->pfc; const struct sh_pfc_pin_group *grp = &priv->pfc.info->groups[group_selector]; + bool grp_pins_configured = true; + struct sh_pfc_pin_config *cfg; unsigned int i; int ret = 0; + int idx; for (i = 0; i < grp->nr_pins; ++i) { - int idx = sh_pfc_get_pin_index(pfc, grp->pins[i]); - struct sh_pfc_pin_config *cfg = &pmx->configs[idx]; + idx = sh_pfc_get_pin_index(pfc, grp->pins[i]); + cfg = &pmx->configs[idx]; if (cfg->type != PINMUX_TYPE_NONE) { + if (!strcmp(cfg->name, grp->name)) + continue; + + dev_err(pfc->dev, "Pin already used as %s\n", + cfg->name); ret = -EBUSY; goto done; + } else { + grp_pins_configured = false; } } + if (grp_pins_configured) + return 0; + for (i = 0; i < grp->nr_pins; ++i) { ret = sh_pfc_config_mux(pfc, grp->mux[i], PINMUX_TYPE_FUNCTION); if (ret < 0) break; + + idx = sh_pfc_get_pin_index(pfc, grp->pins[i]); + cfg = &pmx->configs[idx]; + cfg->type = PINMUX_TYPE_FUNCTION; + cfg->name = priv->pfc.info->groups[group_selector].name; } done: @@ -774,6 +839,7 @@ static struct pinctrl_ops sh_pfc_pinctrl_ops = { .get_pin_name = sh_pfc_pinctrl_get_pin_name, .get_groups_count = sh_pfc_pinctrl_get_groups_count, .get_group_name = sh_pfc_pinctrl_get_group_name, + .get_pin_muxing = sh_pfc_pinctrl_get_pin_muxing, .get_functions_count = sh_pfc_pinctrl_get_functions_count, .get_function_name = sh_pfc_pinctrl_get_function_name, @@ -804,6 +870,7 @@ static int sh_pfc_map_pins(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx) for (i = 0; i < pfc->info->nr_pins; ++i) { struct sh_pfc_pin_config *cfg = &pmx->configs[i]; cfg->type = PINMUX_TYPE_NONE; + cfg->name = "none"; } return 0; diff --git a/drivers/power/domain/meson-ee-pwrc.c b/drivers/power/domain/meson-ee-pwrc.c index ef8274ce96..a4d50e701a 100644 --- a/drivers/power/domain/meson-ee-pwrc.c +++ b/drivers/power/domain/meson-ee-pwrc.c @@ -13,7 +13,9 @@ #include <syscon.h> #include <reset.h> #include <clk.h> +#include <dt-bindings/power/meson-axg-power.h> #include <dt-bindings/power/meson-g12a-power.h> +#include <dt-bindings/power/meson-gxbb-power.h> #include <dt-bindings/power/meson-sm1-power.h> #include <linux/bitops.h> #include <linux/delay.h> @@ -68,7 +70,7 @@ struct meson_ee_pwrc_domain_data { /* TOP Power Domains */ -static struct meson_ee_pwrc_top_domain g12a_pwrc_vpu = { +static struct meson_ee_pwrc_top_domain gx_pwrc_vpu = { .sleep_reg = AO_RTI_GEN_PWR_SLEEP0, .sleep_mask = BIT(8), .iso_reg = AO_RTI_GEN_PWR_SLEEP0, @@ -126,6 +128,17 @@ static struct meson_ee_pwrc_mem_domain g12a_pwrc_mem_vpu[] = { VPU_HHI_MEMPD(HHI_MEM_PD_REG0), }; +static struct meson_ee_pwrc_mem_domain axg_pwrc_mem_vpu[] = { + VPU_MEMPD(HHI_VPU_MEM_PD_REG0), + VPU_HHI_MEMPD(HHI_MEM_PD_REG0), +}; + +static struct meson_ee_pwrc_mem_domain gxbb_pwrc_mem_vpu[] = { + VPU_MEMPD(HHI_VPU_MEM_PD_REG0), + VPU_MEMPD(HHI_VPU_MEM_PD_REG1), + VPU_HHI_MEMPD(HHI_MEM_PD_REG0), +}; + static struct meson_ee_pwrc_mem_domain g12a_pwrc_mem_eth[] = { { HHI_MEM_PD_REG0, GENMASK(3, 2) }, }; @@ -159,6 +172,10 @@ static struct meson_ee_pwrc_mem_domain sm1_pwrc_mem_ge2d[] = { { HHI_MEM_PD_REG0, GENMASK(25, 18) }, }; +static struct meson_ee_pwrc_mem_domain axg_pwrc_mem_audio[] = { + { HHI_MEM_PD_REG0, GENMASK(5, 4) }, +}; + static struct meson_ee_pwrc_mem_domain sm1_pwrc_mem_audio[] = { { HHI_MEM_PD_REG0, GENMASK(5, 4) }, { HHI_AUDIO_MEM_PD_REG0, GENMASK(1, 0) }, @@ -201,11 +218,24 @@ static struct meson_ee_pwrc_mem_domain sm1_pwrc_mem_audio[] = { static bool pwrc_ee_get_power(struct power_domain *power_domain); static struct meson_ee_pwrc_domain_desc g12a_pwrc_domains[] = { - [PWRC_G12A_VPU_ID] = VPU_PD("VPU", &g12a_pwrc_vpu, g12a_pwrc_mem_vpu, + [PWRC_G12A_VPU_ID] = VPU_PD("VPU", &gx_pwrc_vpu, g12a_pwrc_mem_vpu, pwrc_ee_get_power, 11, 2), [PWRC_G12A_ETH_ID] = MEM_PD("ETH", g12a_pwrc_mem_eth), }; +static struct meson_ee_pwrc_domain_desc axg_pwrc_domains[] = { + [PWRC_AXG_VPU_ID] = VPU_PD("VPU", &gx_pwrc_vpu, axg_pwrc_mem_vpu, + pwrc_ee_get_power, 5, 2), + [PWRC_AXG_ETHERNET_MEM_ID] = MEM_PD("ETH", g12a_pwrc_mem_eth), + [PWRC_AXG_AUDIO_ID] = MEM_PD("AUDIO", axg_pwrc_mem_audio), +}; + +static struct meson_ee_pwrc_domain_desc gxbb_pwrc_domains[] = { + [PWRC_GXBB_VPU_ID] = VPU_PD("VPU", &gx_pwrc_vpu, gxbb_pwrc_mem_vpu, + pwrc_ee_get_power, 12, 2), + [PWRC_GXBB_ETHERNET_MEM_ID] = MEM_PD("ETH", g12a_pwrc_mem_eth), +}; + static struct meson_ee_pwrc_domain_desc sm1_pwrc_domains[] = { [PWRC_SM1_VPU_ID] = VPU_PD("VPU", &sm1_pwrc_vpu, sm1_pwrc_mem_vpu, pwrc_ee_get_power, 11, 2), @@ -369,6 +399,16 @@ static struct meson_ee_pwrc_domain_data meson_ee_g12a_pwrc_data = { .domains = g12a_pwrc_domains, }; +static struct meson_ee_pwrc_domain_data meson_ee_axg_pwrc_data = { + .count = ARRAY_SIZE(axg_pwrc_domains), + .domains = axg_pwrc_domains, +}; + +static struct meson_ee_pwrc_domain_data meson_ee_gxbb_pwrc_data = { + .count = ARRAY_SIZE(gxbb_pwrc_domains), + .domains = gxbb_pwrc_domains, +}; + static struct meson_ee_pwrc_domain_data meson_ee_sm1_pwrc_data = { .count = ARRAY_SIZE(sm1_pwrc_domains), .domains = sm1_pwrc_domains, @@ -380,6 +420,14 @@ static const struct udevice_id meson_ee_pwrc_ids[] = { .data = (unsigned long)&meson_ee_g12a_pwrc_data, }, { + .compatible = "amlogic,meson-gxbb-pwrc", + .data = (unsigned long)&meson_ee_gxbb_pwrc_data, + }, + { + .compatible = "amlogic,meson-axg-pwrc", + .data = (unsigned long)&meson_ee_axg_pwrc_data, + }, + { .compatible = "amlogic,meson-sm1-pwrc", .data = (unsigned long)&meson_ee_sm1_pwrc_data, }, diff --git a/drivers/power/pmic/Kconfig b/drivers/power/pmic/Kconfig index 7d51510d1b..583fd3ddcd 100644 --- a/drivers/power/pmic/Kconfig +++ b/drivers/power/pmic/Kconfig @@ -91,6 +91,21 @@ config DM_PMIC_FAN53555 The driver implements read/write operations for use with the FAN53555 regulator driver and binds the regulator driver to its node. +config DM_PMIC_MP5416 + bool "Enable Driver Model for PMIC MP5416" + depends on DM_PMIC + help + This config enables implementation of driver-model pmic uclass features + for PMIC MP5416. The driver implements read/write operations. + +config SPL_DM_PMIC_MP5416 + bool "Enable Driver Model for PMIC MP5416 in SPL stage" + depends on DM_PMIC + help + This config enables implementation of driver-model pmic uclass + features for PMIC MP5416. The driver implements read/write + operations. + config DM_PMIC_PCA9450 bool "Enable Driver Model for PMIC PCA9450" depends on DM_PMIC diff --git a/drivers/power/pmic/Makefile b/drivers/power/pmic/Makefile index 9cd6c375c0..2b2a6ddb56 100644 --- a/drivers/power/pmic/Makefile +++ b/drivers/power/pmic/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_DM_PMIC_MAX77686) += max77686.o obj-$(CONFIG_DM_PMIC_MAX8998) += max8998.o obj-$(CONFIG_DM_PMIC_MC34708) += mc34708.o obj-$(CONFIG_$(SPL_)DM_PMIC_BD71837) += bd71837.o +obj-$(CONFIG_$(SPL_)DM_PMIC_MP5416) += mp5416.o obj-$(CONFIG_$(SPL_)DM_PMIC_PFUZE100) += pfuze100.o obj-$(CONFIG_$(SPL_)DM_PMIC_PCA9450) += pca9450.o obj-$(CONFIG_PMIC_S2MPS11) += s2mps11.o diff --git a/drivers/power/pmic/mp5416.c b/drivers/power/pmic/mp5416.c new file mode 100644 index 0000000000..458c4df688 --- /dev/null +++ b/drivers/power/pmic/mp5416.c @@ -0,0 +1,98 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2020 Gateworks Corporation + */ +#include <common.h> +#include <errno.h> +#include <dm.h> +#include <i2c.h> +#include <log.h> +#include <power/pmic.h> +#include <power/regulator.h> +#include <power/mp5416.h> + +DECLARE_GLOBAL_DATA_PTR; + +static const struct pmic_child_info pmic_children_info[] = { + /* buck */ + { .prefix = "b", .driver = MP6416_REGULATOR_DRIVER }, + /* ldo */ + { .prefix = "l", .driver = MP6416_REGULATOR_DRIVER }, + { }, +}; + +static int mp5416_reg_count(struct udevice *dev) +{ + return MP5416_NUM_OF_REGS - 1; +} + +static int mp5416_write(struct udevice *dev, uint reg, const uint8_t *buff, + int len) +{ + if (dm_i2c_write(dev, reg, buff, len)) { + pr_err("write error to device: %p register: %#x!", dev, reg); + return -EIO; + } + + return 0; +} + +static int mp5416_read(struct udevice *dev, uint reg, uint8_t *buff, int len) +{ + if (dm_i2c_read(dev, reg, buff, len)) { + pr_err("read error from device: %p register: %#x!", dev, reg); + return -EIO; + } + + return 0; +} + +static int mp5416_bind(struct udevice *dev) +{ + int children; + ofnode regulators_node; + + debug("%s %s\n", __func__, dev->name); + regulators_node = dev_read_subnode(dev, "regulators"); + if (!ofnode_valid(regulators_node)) { + debug("%s: %s regulators subnode not found!\n", __func__, + dev->name); + return -ENXIO; + } + + debug("%s: '%s' - found regulators subnode\n", __func__, dev->name); + + children = pmic_bind_children(dev, regulators_node, pmic_children_info); + if (!children) + debug("%s: %s - no child found\n", __func__, dev->name); + + /* Always return success for this device */ + return 0; +} + +static int mp5416_probe(struct udevice *dev) +{ + debug("%s %s\n", __func__, dev->name); + + return 0; +} + +static struct dm_pmic_ops mp5416_ops = { + .reg_count = mp5416_reg_count, + .read = mp5416_read, + .write = mp5416_write, +}; + +static const struct udevice_id mp5416_ids[] = { + { .compatible = "mps,mp5416", }, + { } +}; + +U_BOOT_DRIVER(pmic_mp5416) = { + .name = "mp5416 pmic", + .id = UCLASS_PMIC, + .of_match = mp5416_ids, + .bind = mp5416_bind, + .probe = mp5416_probe, + .ops = &mp5416_ops, +}; diff --git a/drivers/power/regulator/Kconfig b/drivers/power/regulator/Kconfig index d431102462..fbbea18c7d 100644 --- a/drivers/power/regulator/Kconfig +++ b/drivers/power/regulator/Kconfig @@ -18,7 +18,7 @@ config DM_REGULATOR config SPL_DM_REGULATOR bool "Enable regulators for SPL" - depends on DM_REGULATOR + depends on DM_REGULATOR && SPL_POWER_SUPPORT ---help--- Regulators are seldom needed in SPL. Even if they are accessed, some code space can be saved by accessing the PMIC registers directly. diff --git a/drivers/power/regulator/stm32-vrefbuf.c b/drivers/power/regulator/stm32-vrefbuf.c index c2c5770fa5..c37998a4ba 100644 --- a/drivers/power/regulator/stm32-vrefbuf.c +++ b/drivers/power/regulator/stm32-vrefbuf.c @@ -6,6 +6,8 @@ * Originally based on the Linux kernel v4.16 drivers/regulator/stm32-vrefbuf.c */ +#define LOG_CATEGORY UCLASS_REGULATOR + #include <common.h> #include <clk.h> #include <dm.h> diff --git a/drivers/pwm/pwm-ti-ehrpwm.c b/drivers/pwm/pwm-ti-ehrpwm.c index ac3d731d22..f09914519b 100644 --- a/drivers/pwm/pwm-ti-ehrpwm.c +++ b/drivers/pwm/pwm-ti-ehrpwm.c @@ -461,7 +461,7 @@ U_BOOT_DRIVER(ti_ehrpwm) = { .id = UCLASS_PWM, .of_match = ti_ehrpwm_ids, .ops = &ti_ehrpwm_ops, - .ofdata_to_platdata = ti_ehrpwm_of_to_plat, + .of_to_plat = ti_ehrpwm_of_to_plat, .probe = ti_ehrpwm_probe, .remove = ti_ehrpwm_remove, .priv_auto = sizeof(struct ti_ehrpwm_priv), diff --git a/drivers/qe/qe.c b/drivers/qe/qe.c index 1a829b5a4c..259e4e3e67 100644 --- a/drivers/qe/qe.c +++ b/drivers/qe/qe.c @@ -288,7 +288,6 @@ void u_qe_init(void) struct mmc *mmc = find_mmc_device(CONFIG_SYS_MMC_ENV_DEV); if (!mmc) { - free(addr); printf("\nMMC cannot find device for ucode\n"); } else { printf("\nMMC read: dev # %u, block # %u, count %u ...\n", diff --git a/drivers/ram/aspeed/Kconfig b/drivers/ram/aspeed/Kconfig index 020c913188..049b9dc249 100644 --- a/drivers/ram/aspeed/Kconfig +++ b/drivers/ram/aspeed/Kconfig @@ -1,4 +1,5 @@ if RAM || SPL_RAM + config ASPEED_DDR4_DUALX8 bool "Enable Dual X8 DDR4 die" depends on DM && OF_CONTROL && ARCH_ASPEED @@ -7,4 +8,62 @@ config ASPEED_DDR4_DUALX8 Say Y if dual X8 DDR4 die is used on the board. The aspeed ddr sdram controller needs to know if the memory chip mounted on the board is dual x8 die or not. Or it may get the wrong size of the memory space. -endif + +if ASPEED_AST2600 + +choice + prompt "DDR4 target date rate" + default ASPEED_DDR4_1600 + +config ASPEED_DDR4_400 + bool "DDR4 targets at 400Mbps" + depends on DM && OF_CONTROL && ARCH_ASPEED + help + select DDR4 target data rate at 400M + +config ASPEED_DDR4_800 + bool "DDR4 targets at 800Mbps" + depends on DM && OF_CONTROL && ARCH_ASPEED + help + select DDR4 target data rate at 800M + +config ASPEED_DDR4_1333 + bool "DDR4 targets at 1333Mbps" + depends on DM && OF_CONTROL && ARCH_ASPEED + help + select DDR4 target data rate at 1333M + +config ASPEED_DDR4_1600 + bool "DDR4 targets at 1600Mbps" + depends on DM && OF_CONTROL && ARCH_ASPEED + help + select DDR4 target data rate at 1600M +endchoice + +config ASPEED_BYPASS_SELFTEST + bool "bypass self test during DRAM initialization" + default n + help + Say Y here to bypass DRAM self test to speed up the boot time + +config ASPEED_ECC + bool "aspeed SDRAM error correcting code" + depends on DM && OF_CONTROL && ARCH_ASPEED + default n + help + enable SDRAM ECC function + +if ASPEED_ECC +config ASPEED_ECC_SIZE + int "ECC size: 0=driver auto-caluated" + depends on ASPEED_ECC + default 0 + help + SDRAM size with the error correcting code enabled. The unit is + in Megabytes. Noted that only the 8/9 of the configured size + can be used by the system. The remaining 1/9 will be used by + the ECC engine. If the size is set to 0, the sdram driver will + calculate the SDRAM size and set the whole range be ECC enabled. +endif # end of ASPEED_ECC +endif # end of ASPEED_AST2600 +endif # end of RAM || SPL_RAM diff --git a/drivers/ram/aspeed/Makefile b/drivers/ram/aspeed/Makefile index af604f8a4b..7ac10af1c2 100644 --- a/drivers/ram/aspeed/Makefile +++ b/drivers/ram/aspeed/Makefile @@ -1,3 +1,4 @@ # SPDX-License-Identifier: GPL-2.0+ # -obj-$(CONFIG_ASPEED_AST2500) += sdram_ast2500.o
\ No newline at end of file +obj-$(CONFIG_ASPEED_AST2500) += sdram_ast2500.o +obj-$(CONFIG_ASPEED_AST2600) += sdram_ast2600.o diff --git a/drivers/ram/aspeed/sdram_ast2600.c b/drivers/ram/aspeed/sdram_ast2600.c new file mode 100644 index 0000000000..fd4235225a --- /dev/null +++ b/drivers/ram/aspeed/sdram_ast2600.c @@ -0,0 +1,1061 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) ASPEED Technology Inc. + */ +#include <common.h> +#include <clk.h> +#include <dm.h> +#include <errno.h> +#include <ram.h> +#include <regmap.h> +#include <reset.h> +#include <asm/io.h> +#include <asm/arch/scu_ast2600.h> +#include <asm/arch/sdram_ast2600.h> +#include <linux/err.h> +#include <linux/kernel.h> +#include <dt-bindings/clock/ast2600-clock.h> + +#define DDR_PHY_TBL_CHG_ADDR 0xaeeddeea +#define DDR_PHY_TBL_END 0xaeededed + +#if defined(CONFIG_ASPEED_DDR4_800) +u32 ast2600_sdramphy_config[165] = { + 0x1e6e0100, // start address + 0x00000000, // phyr000 + 0x0c002062, // phyr004 + 0x1a7a0063, // phyr008 + 0x5a7a0063, // phyr00c + 0x1a7a0063, // phyr010 + 0x1a7a0063, // phyr014 + 0x20000000, // phyr018 + 0x20000000, // phyr01c + 0x20000000, // phyr020 + 0x20000000, // phyr024 + 0x00000008, // phyr028 + 0x00000000, // phyr02c + 0x00077600, // phyr030 + 0x00000000, // phyr034 + 0x00000000, // phyr038 + 0x20000000, // phyr03c + 0x50506000, // phyr040 + 0x50505050, // phyr044 + 0x00002f07, // phyr048 + 0x00003080, // phyr04c + 0x04000000, // phyr050 + 0x00000200, // phyr054 + 0x03140201, // phyr058 + 0x04800000, // phyr05c + 0x0800044e, // phyr060 + 0x00000000, // phyr064 + 0x00180008, // phyr068 + 0x00e00400, // phyr06c + 0x00140206, // phyr070 + 0x1d4c0000, // phyr074 + 0x493e0107, // phyr078 + 0x08060404, // phyr07c + 0x90000a00, // phyr080 + 0x06420618, // phyr084 + 0x00001002, // phyr088 + 0x05701016, // phyr08c + 0x10000000, // phyr090 + 0xaeeddeea, // change address + 0x1e6e019c, // new address + 0x20202020, // phyr09c + 0x20202020, // phyr0a0 + 0x00002020, // phyr0a4 + 0x00002020, // phyr0a8 + 0x00000001, // phyr0ac + 0xaeeddeea, // change address + 0x1e6e01cc, // new address + 0x01010101, // phyr0cc + 0x01010101, // phyr0d0 + 0x80808080, // phyr0d4 + 0x80808080, // phyr0d8 + 0xaeeddeea, // change address + 0x1e6e0288, // new address + 0x80808080, // phyr188 + 0x80808080, // phyr18c + 0x80808080, // phyr190 + 0x80808080, // phyr194 + 0xaeeddeea, // change address + 0x1e6e02f8, // new address + 0x90909090, // phyr1f8 + 0x88888888, // phyr1fc + 0xaeeddeea, // change address + 0x1e6e0300, // new address + 0x00000000, // phyr200 + 0xaeeddeea, // change address + 0x1e6e0194, // new address + 0x80118260, // phyr094 + 0xaeeddeea, // change address + 0x1e6e019c, // new address + 0x20202020, // phyr09c + 0x20202020, // phyr0a0 + 0x00002020, // phyr0a4 + 0x80000000, // phyr0a8 + 0x00000001, // phyr0ac + 0xaeeddeea, // change address + 0x1e6e0318, // new address + 0x09222719, // phyr218 + 0x00aa4403, // phyr21c + 0xaeeddeea, // change address + 0x1e6e0198, // new address + 0x08060000, // phyr098 + 0xaeeddeea, // change address + 0x1e6e01b0, // new address + 0x00000000, // phyr0b0 + 0x00000000, // phyr0b4 + 0x00000000, // phyr0b8 + 0x00000000, // phyr0bc + 0x00000000, // phyr0c0 + 0x00000000, // phyr0c4 + 0x000aff2c, // phyr0c8 + 0xaeeddeea, // change address + 0x1e6e01dc, // new address + 0x00080000, // phyr0dc + 0x00000000, // phyr0e0 + 0xaa55aa55, // phyr0e4 + 0x55aa55aa, // phyr0e8 + 0xaaaa5555, // phyr0ec + 0x5555aaaa, // phyr0f0 + 0xaa55aa55, // phyr0f4 + 0x55aa55aa, // phyr0f8 + 0xaaaa5555, // phyr0fc + 0x5555aaaa, // phyr100 + 0xaa55aa55, // phyr104 + 0x55aa55aa, // phyr108 + 0xaaaa5555, // phyr10c + 0x5555aaaa, // phyr110 + 0xaa55aa55, // phyr114 + 0x55aa55aa, // phyr118 + 0xaaaa5555, // phyr11c + 0x5555aaaa, // phyr120 + 0x20202020, // phyr124 + 0x20202020, // phyr128 + 0x20202020, // phyr12c + 0x20202020, // phyr130 + 0x20202020, // phyr134 + 0x20202020, // phyr138 + 0x20202020, // phyr13c + 0x20202020, // phyr140 + 0x20202020, // phyr144 + 0x20202020, // phyr148 + 0x20202020, // phyr14c + 0x20202020, // phyr150 + 0x20202020, // phyr154 + 0x20202020, // phyr158 + 0x20202020, // phyr15c + 0x20202020, // phyr160 + 0x20202020, // phyr164 + 0x20202020, // phyr168 + 0x20202020, // phyr16c + 0x20202020, // phyr170 + 0xaeeddeea, // change address + 0x1e6e0298, // new address + 0x20200800, // phyr198 + 0x20202020, // phyr19c + 0x20202020, // phyr1a0 + 0x20202020, // phyr1a4 + 0x20202020, // phyr1a8 + 0x20202020, // phyr1ac + 0x20202020, // phyr1b0 + 0x20202020, // phyr1b4 + 0x20202020, // phyr1b8 + 0x20202020, // phyr1bc + 0x20202020, // phyr1c0 + 0x20202020, // phyr1c4 + 0x20202020, // phyr1c8 + 0x20202020, // phyr1cc + 0x20202020, // phyr1d0 + 0x20202020, // phyr1d4 + 0x20202020, // phyr1d8 + 0x20202020, // phyr1dc + 0x20202020, // phyr1e0 + 0x20202020, // phyr1e4 + 0x00002020, // phyr1e8 + 0xaeeddeea, // change address + 0x1e6e0304, // new address + 0x00000800, // phyr204 + 0xaeeddeea, // change address + 0x1e6e027c, // new address + 0x4e400000, // phyr17c + 0x59595959, // phyr180 + 0x40404040, // phyr184 + 0xaeeddeea, // change address + 0x1e6e02f4, // new address + 0x00000059, // phyr1f4 + 0xaeededed, // end +}; +#else +u32 ast2600_sdramphy_config[165] = { + 0x1e6e0100, // start address + 0x00000000, // phyr000 + 0x0c002062, // phyr004 + 0x1a7a0063, // phyr008 + 0x5a7a0063, // phyr00c + 0x1a7a0063, // phyr010 + 0x1a7a0063, // phyr014 + 0x20000000, // phyr018 + 0x20000000, // phyr01c + 0x20000000, // phyr020 + 0x20000000, // phyr024 + 0x00000008, // phyr028 + 0x00000000, // phyr02c + 0x00077600, // phyr030 + 0x00000000, // phyr034 + 0x00000000, // phyr038 + 0x20000000, // phyr03c + 0x50506000, // phyr040 + 0x50505050, // phyr044 + 0x00002f07, // phyr048 + 0x00003080, // phyr04c + 0x04000000, // phyr050 + 0x00000200, // phyr054 + 0x03140501, // phyr058-rtt:40 + 0x04800000, // phyr05c + 0x0800044e, // phyr060 + 0x00000000, // phyr064 + 0x00180008, // phyr068 + 0x00e00400, // phyr06c + 0x00140206, // phyr070 + 0x1d4c0000, // phyr074 + 0x493e0107, // phyr078 + 0x08060404, // phyr07c + 0x90000a00, // phyr080 + 0x06420c30, // phyr084 + 0x00001002, // phyr088 + 0x05701016, // phyr08c + 0x10000000, // phyr090 + 0xaeeddeea, // change address + 0x1e6e019c, // new address + 0x20202020, // phyr09c + 0x20202020, // phyr0a0 + 0x00002020, // phyr0a4 + 0x00002020, // phyr0a8 + 0x00000001, // phyr0ac + 0xaeeddeea, // change address + 0x1e6e01cc, // new address + 0x01010101, // phyr0cc + 0x01010101, // phyr0d0 + 0x80808080, // phyr0d4 + 0x80808080, // phyr0d8 + 0xaeeddeea, // change address + 0x1e6e0288, // new address + 0x80808080, // phyr188 + 0x80808080, // phyr18c + 0x80808080, // phyr190 + 0x80808080, // phyr194 + 0xaeeddeea, // change address + 0x1e6e02f8, // new address + 0x90909090, // phyr1f8 + 0x88888888, // phyr1fc + 0xaeeddeea, // change address + 0x1e6e0300, // new address + 0x00000000, // phyr200 + 0xaeeddeea, // change address + 0x1e6e0194, // new address + 0x801112e0, // phyr094 - bit12=1,15=0,- write window is ok + 0xaeeddeea, // change address + 0x1e6e019c, // new address + 0x20202020, // phyr09c + 0x20202020, // phyr0a0 + 0x00002020, // phyr0a4 + 0x80000000, // phyr0a8 + 0x00000001, // phyr0ac + 0xaeeddeea, // change address + 0x1e6e0318, // new address + 0x09222719, // phyr218 + 0x00aa4403, // phyr21c + 0xaeeddeea, // change address + 0x1e6e0198, // new address + 0x08060000, // phyr098 + 0xaeeddeea, // change address + 0x1e6e01b0, // new address + 0x00000000, // phyr0b0 + 0x00000000, // phyr0b4 + 0x00000000, // phyr0b8 + 0x00000000, // phyr0bc + 0x00000000, // phyr0c0 - ori + 0x00000000, // phyr0c4 + 0x000aff2c, // phyr0c8 + 0xaeeddeea, // change address + 0x1e6e01dc, // new address + 0x00080000, // phyr0dc + 0x00000000, // phyr0e0 + 0xaa55aa55, // phyr0e4 + 0x55aa55aa, // phyr0e8 + 0xaaaa5555, // phyr0ec + 0x5555aaaa, // phyr0f0 + 0xaa55aa55, // phyr0f4 + 0x55aa55aa, // phyr0f8 + 0xaaaa5555, // phyr0fc + 0x5555aaaa, // phyr100 + 0xaa55aa55, // phyr104 + 0x55aa55aa, // phyr108 + 0xaaaa5555, // phyr10c + 0x5555aaaa, // phyr110 + 0xaa55aa55, // phyr114 + 0x55aa55aa, // phyr118 + 0xaaaa5555, // phyr11c + 0x5555aaaa, // phyr120 + 0x20202020, // phyr124 + 0x20202020, // phyr128 + 0x20202020, // phyr12c + 0x20202020, // phyr130 + 0x20202020, // phyr134 + 0x20202020, // phyr138 + 0x20202020, // phyr13c + 0x20202020, // phyr140 + 0x20202020, // phyr144 + 0x20202020, // phyr148 + 0x20202020, // phyr14c + 0x20202020, // phyr150 + 0x20202020, // phyr154 + 0x20202020, // phyr158 + 0x20202020, // phyr15c + 0x20202020, // phyr160 + 0x20202020, // phyr164 + 0x20202020, // phyr168 + 0x20202020, // phyr16c + 0x20202020, // phyr170 + 0xaeeddeea, // change address + 0x1e6e0298, // new address + 0x20200800, // phyr198 + 0x20202020, // phyr19c + 0x20202020, // phyr1a0 + 0x20202020, // phyr1a4 + 0x20202020, // phyr1a8 + 0x20202020, // phyr1ac + 0x20202020, // phyr1b0 + 0x20202020, // phyr1b4 + 0x20202020, // phyr1b8 + 0x20202020, // phyr1bc + 0x20202020, // phyr1c0 + 0x20202020, // phyr1c4 + 0x20202020, // phyr1c8 + 0x20202020, // phyr1cc + 0x20202020, // phyr1d0 + 0x20202020, // phyr1d4 + 0x20202020, // phyr1d8 + 0x20202020, // phyr1dc + 0x20202020, // phyr1e0 + 0x20202020, // phyr1e4 + 0x00002020, // phyr1e8 + 0xaeeddeea, // change address + 0x1e6e0304, // new address + 0x00000800, // phyr204 + 0xaeeddeea, // change address + 0x1e6e027c, // new address + 0x4e400000, // phyr17c + 0x59595959, // phyr180 + 0x40404040, // phyr184 + 0xaeeddeea, // change address + 0x1e6e02f4, // new address + 0x00000059, // phyr1f4 + 0xaeededed, // end +}; +#endif + +/* MPLL configuration */ +#define SCU_MPLL_FREQ_400M 0x0008405F +#define SCU_MPLL_EXT_400M 0x0000002F +#define SCU_MPLL_FREQ_333M 0x00488299 +#define SCU_MPLL_EXT_333M 0x0000014C +#define SCU_MPLL_FREQ_200M 0x0078007F +#define SCU_MPLL_EXT_200M 0x0000003F +#define SCU_MPLL_FREQ_100M 0x0078003F +#define SCU_MPLL_EXT_100M 0x0000001F + +#if defined(CONFIG_ASPEED_DDR4_1600) +#define SCU_MPLL_FREQ_CFG SCU_MPLL_FREQ_400M +#define SCU_MPLL_EXT_CFG SCU_MPLL_EXT_400M +#elif defined(CONFIG_ASPEED_DDR4_1333) +#define SCU_MPLL_FREQ_CFG SCU_MPLL_FREQ_333M +#define SCU_MPLL_EXT_CFG SCU_MPLL_EXT_333M +#elif defined(CONFIG_ASPEED_DDR4_800) +#define SCU_MPLL_FREQ_CFG SCU_MPLL_FREQ_200M +#define SCU_MPLL_EXT_CFG SCU_MPLL_EXT_200M +#elif defined(CONFIG_ASPEED_DDR4_400) +#define SCU_MPLL_FREQ_CFG SCU_MPLL_FREQ_100M +#define SCU_MPLL_EXT_CFG SCU_MPLL_EXT_100M +#else +#error "undefined DDR4 target rate\n" +#endif + +/* + * AC timing and SDRAM mode register setting + * for real chip are derived from the model GDDR4-1600 + */ +#define DDR4_MR01_MODE 0x03010510 +#define DDR4_MR23_MODE 0x00000000 +#define DDR4_MR45_MODE 0x04000000 +#define DDR4_MR6_MODE 0x00000400 +#define DDR4_TRFC_1600 0x467299f1 +#define DDR4_TRFC_1333 0x3a5f80c9 +#define DDR4_TRFC_800 0x23394c78 +#define DDR4_TRFC_400 0x111c263c + +#if defined(CONFIG_ASPEED_DDR4_1600) +#define DDR4_TRFC DDR4_TRFC_1600 +#define DDR4_PHY_TRAIN_TRFC 0xc30 +#elif defined(CONFIG_ASPEED_DDR4_1333) +#define DDR4_TRFC DDR4_TRFC_1333 +#define DDR4_PHY_TRAIN_TRFC 0xa25 +#elif defined(CONFIG_ASPEED_DDR4_800) +#define DDR4_TRFC DDR4_TRFC_800 +#define DDR4_PHY_TRAIN_TRFC 0x618 +#elif defined(CONFIG_ASPEED_DDR4_400) +#define DDR4_TRFC DDR4_TRFC_400 +#define DDR4_PHY_TRAIN_TRFC 0x30c +#else +#error "undefined tRFC setting" +#endif + +/* supported SDRAM size */ +#define SDRAM_SIZE_1KB (1024U) +#define SDRAM_SIZE_1MB (SDRAM_SIZE_1KB * SDRAM_SIZE_1KB) +#define SDRAM_MIN_SIZE (256 * SDRAM_SIZE_1MB) +#define SDRAM_MAX_SIZE (2048 * SDRAM_SIZE_1MB) + +DECLARE_GLOBAL_DATA_PTR; + +static const u32 ddr4_ac_timing[4] = { + 0x040e0307, 0x0f4711f1, 0x0e060304, 0x00001240 }; +static const u32 ddr_max_grant_params[4] = { + 0x44444444, 0x44444444, 0x44444444, 0x44444444 }; + +struct dram_info { + struct ram_info info; + struct clk ddr_clk; + struct ast2600_sdrammc_regs *regs; + struct ast2600_scu *scu; + struct ast2600_ddr_phy *phy; + void __iomem *phy_setting; + void __iomem *phy_status; + ulong clock_rate; +}; + +static void ast2600_sdramphy_kick_training(struct dram_info *info) +{ + u32 data; + struct ast2600_sdrammc_regs *regs = info->regs; + + writel(SDRAM_PHYCTRL0_NRST, ®s->phy_ctrl[0]); + udelay(5); + writel(SDRAM_PHYCTRL0_NRST | SDRAM_PHYCTRL0_INIT, ®s->phy_ctrl[0]); + udelay(1000); + + while (1) { + data = readl(®s->phy_ctrl[0]) & SDRAM_PHYCTRL0_INIT; + if (~data) + break; + } +} + +/** + * @brief load DDR-PHY configurations table to the PHY registers + * @param[in] p_tbl - pointer to the configuration table + * @param[in] info - pointer to the DRAM info struct + * + * There are two sets of MRS (Mode Registers) configuration in ast2600 memory + * system: one is in the SDRAM MC (memory controller) which is used in run + * time, and the other is in the DDR-PHY IP which is used during DDR-PHY + * training. + */ +static void ast2600_sdramphy_init(u32 *p_tbl, struct dram_info *info) +{ + u32 reg_base = (u32)info->phy_setting; + u32 addr = p_tbl[0]; + u32 data; + int i = 1; + + writel(0, &info->regs->phy_ctrl[0]); + udelay(10); + + while (1) { + if (addr < reg_base) { + debug("invalid DDR-PHY addr: 0x%08x\n", addr); + break; + } + data = p_tbl[i++]; + + if (data == DDR_PHY_TBL_END) { + break; + } else if (data == DDR_PHY_TBL_CHG_ADDR) { + addr = p_tbl[i++]; + } else { + writel(data, addr); + addr += 4; + } + } + + data = readl(info->phy_setting + 0x84) & ~GENMASK(16, 0); + data |= DDR4_PHY_TRAIN_TRFC; + writel(data, info->phy_setting + 0x84); +} + +static int ast2600_sdramphy_check_status(struct dram_info *info) +{ + u32 value, tmp; + u32 reg_base = (u32)info->phy_status; + int need_retrain = 0; + + debug("\nSDRAM PHY training report:\n"); + + /* training status */ + value = readl(reg_base + 0x00); + debug("rO_DDRPHY_reg offset 0x00 = 0x%08x\n", value); + + if (value & BIT(3)) + debug("\tinitial PVT calibration fail\n"); + + if (value & BIT(5)) + debug("\truntime calibration fail\n"); + + /* PU & PD */ + value = readl(reg_base + 0x30); + debug("rO_DDRPHY_reg offset 0x30 = 0x%08x\n", value); + debug(" PU = 0x%02x\n", value & 0xff); + debug(" PD = 0x%02x\n", (value >> 16) & 0xff); + + /* read eye window */ + value = readl(reg_base + 0x68); + if (0 == (value & GENMASK(7, 0))) + need_retrain = 1; + + debug("rO_DDRPHY_reg offset 0x68 = 0x%08x\n", value); + debug(" rising edge of read data eye training pass window\n"); + tmp = (((value & GENMASK(7, 0)) >> 0) * 100) / 255; + debug(" B0:%d%%\n", tmp); + tmp = (((value & GENMASK(15, 8)) >> 8) * 100) / 255; + debug(" B1:%d%%\n", tmp); + + value = readl(reg_base + 0xC8); + debug("rO_DDRPHY_reg offset 0xC8 = 0x%08x\n", value); + debug(" falling edge of read data eye training pass window\n"); + tmp = (((value & GENMASK(7, 0)) >> 0) * 100) / 255; + debug(" B0:%d%%\n", tmp); + tmp = (((value & GENMASK(15, 8)) >> 8) * 100) / 255; + debug(" B1:%d%%\n", tmp); + + /* write eye window */ + value = readl(reg_base + 0x7c); + if (0 == (value & GENMASK(7, 0))) + need_retrain = 1; + + debug("rO_DDRPHY_reg offset 0x7C = 0x%08x\n", value); + debug(" rising edge of write data eye training pass window\n"); + tmp = (((value & GENMASK(7, 0)) >> 0) * 100) / 255; + debug(" B0:%d%%\n", tmp); + tmp = (((value & GENMASK(15, 8)) >> 8) * 100) / 255; + debug(" B1:%d%%\n", tmp); + + /* read Vref training result */ + value = readl(reg_base + 0x88); + debug("rO_DDRPHY_reg offset 0x88 = 0x%08x\n", value); + debug(" read Vref training result\n"); + tmp = (((value & GENMASK(7, 0)) >> 0) * 100) / 127; + debug(" B0:%d%%\n", tmp); + tmp = (((value & GENMASK(15, 8)) >> 8) * 100) / 127; + debug(" B1:%d%%\n", tmp); + + /* write Vref training result */ + value = readl(reg_base + 0x90); + debug("rO_DDRPHY_reg offset 0x90 = 0x%08x\n", value); + + /* gate train */ + value = readl(reg_base + 0x50); + if ((0 == (value & GENMASK(15, 0))) || + (0 == (value & GENMASK(31, 16)))) { + need_retrain = 1; + } + + debug("rO_DDRPHY_reg offset 0x50 = 0x%08x\n", value); + + return need_retrain; +} + +#ifndef CONFIG_ASPEED_BYPASS_SELFTEST +#define MC_TEST_PATTERN_N 8 +static u32 as2600_sdrammc_test_pattern[MC_TEST_PATTERN_N] = { + 0xcc33cc33, 0xff00ff00, 0xaa55aa55, 0x88778877, + 0x92cc4d6e, 0x543d3cde, 0xf1e843c7, 0x7c61d253 }; + +#define TIMEOUT_DRAM 5000000 +int ast2600_sdrammc_dg_test(struct dram_info *info, unsigned int datagen, u32 mode) +{ + unsigned int data; + unsigned int timeout = 0; + struct ast2600_sdrammc_regs *regs = info->regs; + + writel(0, ®s->ecc_test_ctrl); + + if (mode == 0) + writel(0x00000085 | (datagen << 3), ®s->ecc_test_ctrl); + else + writel(0x000000C1 | (datagen << 3), ®s->ecc_test_ctrl); + + do { + data = readl(®s->ecc_test_ctrl) & GENMASK(13, 12); + + if (data & BIT(13)) + return 0; + + if (++timeout > TIMEOUT_DRAM) { + debug("Timeout!!\n"); + writel(0, ®s->ecc_test_ctrl); + return -1; + } + } while (!data); + + writel(0, ®s->ecc_test_ctrl); + + return 0; +} + +int ast2600_sdrammc_cbr_test(struct dram_info *info) +{ + u32 i; + struct ast2600_sdrammc_regs *regs = info->regs; + + clrsetbits_le32(®s->test_addr, GENMASK(30, 4), 0x7ffff0); + + /* single */ + for (i = 0; i < 8; i++) + if (ast2600_sdrammc_dg_test(info, i, 0)) + return -1; + + /* burst */ + for (i = 0; i < 8; i++) + if (ast2600_sdrammc_dg_test(info, i, i)) + return -1; + + return 0; +} + +static int ast2600_sdrammc_test(struct dram_info *info) +{ + struct ast2600_sdrammc_regs *regs = info->regs; + + u32 pass_cnt = 0; + u32 fail_cnt = 0; + u32 target_cnt = 2; + u32 test_cnt = 0; + u32 pattern; + u32 i = 0; + bool finish = false; + + debug("sdram mc test:\n"); + while (!finish) { + pattern = as2600_sdrammc_test_pattern[i++]; + i = i % MC_TEST_PATTERN_N; + debug(" pattern = %08X : ", pattern); + writel(pattern, ®s->test_init_val); + + if (ast2600_sdrammc_cbr_test(info)) { + debug("fail\n"); + fail_cnt++; + } else { + debug("pass\n"); + pass_cnt++; + } + + if (++test_cnt == target_cnt) + finish = true; + } + debug("statistics: pass/fail/total:%d/%d/%d\n", pass_cnt, fail_cnt, + target_cnt); + + return fail_cnt; +} +#endif + +/* + * scu500[14:13] + * 2b'00: VGA memory size = 16MB + * 2b'01: VGA memory size = 16MB + * 2b'10: VGA memory size = 32MB + * 2b'11: VGA memory size = 64MB + * + * mcr04[3:2] + * 2b'00: VGA memory size = 8MB + * 2b'01: VGA memory size = 16MB + * 2b'10: VGA memory size = 32MB + * 2b'11: VGA memory size = 64MB + */ +static size_t ast2600_sdrammc_get_vga_mem_size(struct dram_info *info) +{ + u32 vga_hwconf; + size_t vga_mem_size_base = 8 * 1024 * 1024; + + vga_hwconf = + (readl(&info->scu->hwstrap1) & SCU_HWSTRAP1_VGA_MEM_MASK) >> + SCU_HWSTRAP1_VGA_MEM_SHIFT; + + if (vga_hwconf == 0) { + vga_hwconf = 1; + writel(vga_hwconf << SCU_HWSTRAP1_VGA_MEM_SHIFT, + &info->scu->hwstrap1); + } + + clrsetbits_le32(&info->regs->config, SDRAM_CONF_VGA_SIZE_MASK, + ((vga_hwconf << SDRAM_CONF_VGA_SIZE_SHIFT) & + SDRAM_CONF_VGA_SIZE_MASK)); + + /* no need to reserve VGA memory if efuse[VGA disable] is set */ + if (readl(&info->scu->efuse) & SCU_EFUSE_DIS_VGA) + return 0; + + return vga_mem_size_base << vga_hwconf; +} + +/* + * Find out RAM size and save it in dram_info + * + * The procedure is taken from Aspeed SDK + */ +static void ast2600_sdrammc_calc_size(struct dram_info *info) +{ + /* The controller supports 256/512/1024/2048 MB ram */ + size_t ram_size = SDRAM_MIN_SIZE; + const int write_test_offset = 0x100000; + u32 test_pattern = 0xdeadbeef; + u32 cap_param = SDRAM_CONF_CAP_2048M; + u32 refresh_timing_param = DDR4_TRFC; + const u32 write_addr_base = CONFIG_SYS_SDRAM_BASE + write_test_offset; + + for (ram_size = SDRAM_MAX_SIZE; ram_size > SDRAM_MIN_SIZE; + ram_size >>= 1) { + writel(test_pattern, write_addr_base + (ram_size >> 1)); + test_pattern = (test_pattern >> 4) | (test_pattern << 28); + } + + /* One last write to overwrite all wrapped values */ + writel(test_pattern, write_addr_base); + + /* Reset the pattern and see which value was really written */ + test_pattern = 0xdeadbeef; + for (ram_size = SDRAM_MAX_SIZE; ram_size > SDRAM_MIN_SIZE; + ram_size >>= 1) { + if (readl(write_addr_base + (ram_size >> 1)) == test_pattern) + break; + + --cap_param; + refresh_timing_param >>= 8; + test_pattern = (test_pattern >> 4) | (test_pattern << 28); + } + + clrsetbits_le32(&info->regs->ac_timing[1], + (SDRAM_AC_TRFC_MASK << SDRAM_AC_TRFC_SHIFT), + ((refresh_timing_param & SDRAM_AC_TRFC_MASK) + << SDRAM_AC_TRFC_SHIFT)); + + info->info.base = CONFIG_SYS_SDRAM_BASE; + info->info.size = ram_size - ast2600_sdrammc_get_vga_mem_size(info); + + clrsetbits_le32(&info->regs->config, SDRAM_CONF_CAP_MASK, + ((cap_param << SDRAM_CONF_CAP_SHIFT) & SDRAM_CONF_CAP_MASK)); +} + +static int ast2600_sdrammc_init_ddr4(struct dram_info *info) +{ + const u32 power_ctrl = MCR34_CKE_EN | MCR34_AUTOPWRDN_EN | + MCR34_MREQ_BYPASS_DIS | MCR34_RESETN_DIS | + MCR34_ODT_EN | MCR34_ODT_AUTO_ON | + (0x1 << MCR34_ODT_EXT_SHIFT); + + /* init SDRAM-PHY only on real chip */ + ast2600_sdramphy_init(ast2600_sdramphy_config, info); + writel((MCR34_CKE_EN | MCR34_MREQI_DIS | MCR34_RESETN_DIS), + &info->regs->power_ctrl); + udelay(5); + ast2600_sdramphy_kick_training(info); + udelay(500); + writel(SDRAM_RESET_DLL_ZQCL_EN, &info->regs->refresh_timing); + + writel(MCR30_SET_MR(3), &info->regs->mode_setting_control); + writel(MCR30_SET_MR(6), &info->regs->mode_setting_control); + writel(MCR30_SET_MR(5), &info->regs->mode_setting_control); + writel(MCR30_SET_MR(4), &info->regs->mode_setting_control); + writel(MCR30_SET_MR(2), &info->regs->mode_setting_control); + writel(MCR30_SET_MR(1), &info->regs->mode_setting_control); + writel(MCR30_SET_MR(0) | MCR30_RESET_DLL_DELAY_EN, + &info->regs->mode_setting_control); + + writel(SDRAM_REFRESH_EN | SDRAM_RESET_DLL_ZQCL_EN | + (0x5f << SDRAM_REFRESH_PERIOD_SHIFT), + &info->regs->refresh_timing); + + /* wait self-refresh idle */ + while (readl(&info->regs->power_ctrl) & + MCR34_SELF_REFRESH_STATUS_MASK) + ; + + writel(SDRAM_REFRESH_EN | SDRAM_LOW_PRI_REFRESH_EN | + SDRAM_REFRESH_ZQCS_EN | + (0x5f << SDRAM_REFRESH_PERIOD_SHIFT) | + (0x42aa << SDRAM_REFRESH_PERIOD_ZQCS_SHIFT), + &info->regs->refresh_timing); + + writel(power_ctrl, &info->regs->power_ctrl); + udelay(500); + + return 0; +} + +static void ast2600_sdrammc_unlock(struct dram_info *info) +{ + writel(SDRAM_UNLOCK_KEY, &info->regs->protection_key); + while (!readl(&info->regs->protection_key)) + ; +} + +static void ast2600_sdrammc_lock(struct dram_info *info) +{ + writel(~SDRAM_UNLOCK_KEY, &info->regs->protection_key); + while (readl(&info->regs->protection_key)) + ; +} + +static void ast2600_sdrammc_common_init(struct ast2600_sdrammc_regs *regs) +{ + int i; + + writel(MCR34_MREQI_DIS | MCR34_RESETN_DIS, ®s->power_ctrl); + writel(SDRAM_VIDEO_UNLOCK_KEY, ®s->gm_protection_key); + writel(0x10 << MCR38_RW_MAX_GRANT_CNT_RQ_SHIFT, + ®s->arbitration_ctrl); + writel(0xFFBBFFF4, ®s->req_limit_mask); + + for (i = 0; i < ARRAY_SIZE(ddr_max_grant_params); ++i) + writel(ddr_max_grant_params[i], ®s->max_grant_len[i]); + + writel(MCR50_RESET_ALL_INTR, ®s->intr_ctrl); + + writel(0x07FFFFFF, ®s->ecc_range_ctrl); + + writel(0, ®s->ecc_test_ctrl); + writel(0x80000001, ®s->test_addr); + writel(0, ®s->test_fail_dq_bit); + writel(0, ®s->test_init_val); + + writel(0xFFFFFFFF, ®s->req_input_ctrl); + writel(0, ®s->req_high_pri_ctrl); + + udelay(600); + +#ifdef CONFIG_ASPEED_DDR4_DUALX8 + writel(0x37, ®s->config); +#else + writel(0x17, ®s->config); +#endif + + /* load controller setting */ + for (i = 0; i < ARRAY_SIZE(ddr4_ac_timing); ++i) + writel(ddr4_ac_timing[i], ®s->ac_timing[i]); + + writel(DDR4_MR01_MODE, ®s->mr01_mode_setting); + writel(DDR4_MR23_MODE, ®s->mr23_mode_setting); + writel(DDR4_MR45_MODE, ®s->mr45_mode_setting); + writel(DDR4_MR6_MODE, ®s->mr6_mode_setting); +} + +/* + * Update size info according to the ECC HW setting + * + * Assume SDRAM has been initialized by SPL or the host. To get the RAM size, we + * don't need to calculate the ECC size again but read from MCR04 and derive the + * size from its value. + */ +static void ast2600_sdrammc_update_size(struct dram_info *info) +{ + struct ast2600_sdrammc_regs *regs = info->regs; + u32 conf = readl(®s->config); + u32 cap_param; + size_t ram_size = SDRAM_MAX_SIZE; + size_t hw_size; + + cap_param = (conf & SDRAM_CONF_CAP_MASK) >> SDRAM_CONF_CAP_SHIFT; + switch (cap_param) { + case SDRAM_CONF_CAP_2048M: + ram_size = 2048 * SDRAM_SIZE_1MB; + break; + case SDRAM_CONF_CAP_1024M: + ram_size = 1024 * SDRAM_SIZE_1MB; + break; + case SDRAM_CONF_CAP_512M: + ram_size = 512 * SDRAM_SIZE_1MB; + break; + case SDRAM_CONF_CAP_256M: + ram_size = 256 * SDRAM_SIZE_1MB; + break; + } + + info->info.base = CONFIG_SYS_SDRAM_BASE; + info->info.size = ram_size - ast2600_sdrammc_get_vga_mem_size(info); + + if (0 == (conf & SDRAM_CONF_ECC_SETUP)) + return; + + hw_size = readl(®s->ecc_range_ctrl) & SDRAM_ECC_RANGE_ADDR_MASK; + hw_size += (1 << SDRAM_ECC_RANGE_ADDR_SHIFT); + + info->info.size = hw_size; +} + +#ifdef CONFIG_ASPEED_ECC +static void ast2600_sdrammc_ecc_enable(struct dram_info *info) +{ + struct ast2600_sdrammc_regs *regs = info->regs; + size_t conf_size; + u32 reg; + + conf_size = CONFIG_ASPEED_ECC_SIZE * SDRAM_SIZE_1MB; + if (conf_size > info->info.size) { + printf("warning: ECC configured %dMB but actual size is %dMB\n", + CONFIG_ASPEED_ECC_SIZE, + info->info.size / SDRAM_SIZE_1MB); + conf_size = info->info.size; + } else if (conf_size == 0) { + conf_size = info->info.size; + } + + info->info.size = (((conf_size / 9) * 8) >> 20) << 20; + writel(((info->info.size >> 20) - 1) << 20, ®s->ecc_range_ctrl); + reg = readl(®s->config) | SDRAM_CONF_ECC_SETUP; + writel(reg, ®s->config); + + writel(0, ®s->test_init_val); + writel(0x80000001, ®s->test_addr); + writel(0x221, ®s->ecc_test_ctrl); + while (0 == (readl(®s->ecc_test_ctrl) & BIT(12))) + ; + writel(0, ®s->ecc_test_ctrl); + writel(BIT(31), ®s->intr_ctrl); + writel(0, ®s->intr_ctrl); +} +#endif + +static int ast2600_sdrammc_probe(struct udevice *dev) +{ + int ret; + u32 reg; + struct dram_info *priv = (struct dram_info *)dev_get_priv(dev); + struct ast2600_sdrammc_regs *regs = priv->regs; + struct udevice *clk_dev; + + /* find SCU base address from clock device */ + ret = uclass_get_device_by_driver(UCLASS_CLK, + DM_DRIVER_GET(aspeed_ast2600_scu), &clk_dev); + if (ret) { + debug("clock device not defined\n"); + return ret; + } + + priv->scu = devfdt_get_addr_ptr(clk_dev); + if (IS_ERR(priv->scu)) { + debug("%s(): can't get SCU\n", __func__); + return PTR_ERR(priv->scu); + } + + if (readl(&priv->scu->dram_hdshk) & SCU_DRAM_HDSHK_RDY) { + printf("already initialized, "); + ast2600_sdrammc_update_size(priv); + return 0; + } + + reg = readl(&priv->scu->mpll); + reg &= ~(SCU_PLL_BYPASS | SCU_PLL_DIV_MASK | + SCU_PLL_DENUM_MASK | SCU_PLL_NUM_MASK); + reg |= (SCU_PLL_RST | SCU_PLL_OFF | SCU_MPLL_FREQ_CFG); + writel(reg, &priv->scu->mpll); + writel(SCU_MPLL_EXT_CFG, &priv->scu->mpll_ext); + udelay(100); + reg &= ~(SCU_PLL_RST | SCU_PLL_OFF); + writel(reg, &priv->scu->mpll); + + while ((readl(&priv->scu->mpll_ext) & BIT(31)) == 0) + ; + + ast2600_sdrammc_unlock(priv); + ast2600_sdrammc_common_init(regs); +L_ast2600_sdramphy_train: + ast2600_sdrammc_init_ddr4(priv); + + /* make sure DDR-PHY is ready before access */ + do { + reg = readl(priv->phy_status) & BIT(1); + } while (reg == 0); + + if (ast2600_sdramphy_check_status(priv) != 0) { + printf("DDR4 PHY training fail, retrain\n"); + goto L_ast2600_sdramphy_train; + } + + ast2600_sdrammc_calc_size(priv); + +#ifndef CONFIG_ASPEED_BYPASS_SELFTEST + if (ast2600_sdrammc_test(priv) != 0) { + printf("%s: DDR4 init fail\n", __func__); + return -EINVAL; + } +#endif + +#ifdef CONFIG_ASPEED_ECC + ast2600_sdrammc_ecc_enable(priv); +#endif + + writel(readl(&priv->scu->dram_hdshk) | SCU_DRAM_HDSHK_RDY, + &priv->scu->dram_hdshk); + + clrbits_le32(®s->intr_ctrl, MCR50_RESET_ALL_INTR); + ast2600_sdrammc_lock(priv); + return 0; +} + +static int ast2600_sdrammc_of_to_plat(struct udevice *dev) +{ + struct dram_info *priv = dev_get_priv(dev); + + priv->regs = (void *)(uintptr_t)devfdt_get_addr_index(dev, 0); + priv->phy_setting = (void *)(uintptr_t)devfdt_get_addr_index(dev, 1); + priv->phy_status = (void *)(uintptr_t)devfdt_get_addr_index(dev, 2); + + priv->clock_rate = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), + "clock-frequency", 0); + if (!priv->clock_rate) { + debug("DDR Clock Rate not defined\n"); + return -EINVAL; + } + + return 0; +} + +static int ast2600_sdrammc_get_info(struct udevice *dev, struct ram_info *info) +{ + struct dram_info *priv = dev_get_priv(dev); + + *info = priv->info; + + return 0; +} + +static struct ram_ops ast2600_sdrammc_ops = { + .get_info = ast2600_sdrammc_get_info, +}; + +static const struct udevice_id ast2600_sdrammc_ids[] = { + { .compatible = "aspeed,ast2600-sdrammc" }, + { } +}; + +U_BOOT_DRIVER(sdrammc_ast2600) = { + .name = "aspeed_ast2600_sdrammc", + .id = UCLASS_RAM, + .of_match = ast2600_sdrammc_ids, + .ops = &ast2600_sdrammc_ops, + .of_to_plat = ast2600_sdrammc_of_to_plat, + .probe = ast2600_sdrammc_probe, + .priv_auto = sizeof(struct dram_info), +}; diff --git a/drivers/ram/k3-j721e/lpddr4.c b/drivers/ram/k3-j721e/lpddr4.c index fc80fb1e2c..68043d7cb6 100644 --- a/drivers/ram/k3-j721e/lpddr4.c +++ b/drivers/ram/k3-j721e/lpddr4.c @@ -719,7 +719,7 @@ uint32_t lpddr4_checkctlinterrupt(const lpddr4_privatedata * pd, /* MISRA compliance (Shifting operation) check */ if (fieldshift < WORD_SHIFT) { - if (((ctlirqstatus >> fieldshift) & BIT_MASK) > 0U) { + if ((ctlirqstatus >> fieldshift) & LPDDR4_BIT_MASK) { *irqstatus = true; } else { *irqstatus = false; @@ -746,11 +746,11 @@ uint32_t lpddr4_ackctlinterrupt(const lpddr4_privatedata * pd, if (localinterrupt > WORD_SHIFT) { localinterrupt = (localinterrupt - (uint32_t) WORD_SHIFT); - regval = ((uint32_t) BIT_MASK << localinterrupt); + regval = (uint32_t)LPDDR4_BIT_MASK << localinterrupt; CPS_REG_WRITE(&(ctlregbase->LPDDR4__INT_ACK_1__REG), regval); } else { - regval = ((uint32_t) BIT_MASK << localinterrupt); + regval = (uint32_t)LPDDR4_BIT_MASK << localinterrupt; CPS_REG_WRITE(&(ctlregbase->LPDDR4__INT_ACK_0__REG), regval); } @@ -823,7 +823,7 @@ uint32_t lpddr4_checkphyindepinterrupt(const lpddr4_privatedata * pd, phyindepirqstatus = CPS_REG_READ(&(ctlregbase->LPDDR4__PI_INT_STATUS__REG)); *irqstatus = - (((phyindepirqstatus >> (uint32_t) intr) & BIT_MASK) > 0U); + !!((phyindepirqstatus >> (uint32_t)intr) & LPDDR4_BIT_MASK); } return result; } @@ -841,7 +841,7 @@ uint32_t lpddr4_ackphyindepinterrupt(const lpddr4_privatedata * pd, lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase; /* Write 1 to the requested bit to ACk the interrupt */ - regval = ((uint32_t) BIT_MASK << ui32shiftinterrupt); + regval = (uint32_t)LPDDR4_BIT_MASK << ui32shiftinterrupt; CPS_REG_WRITE(&(ctlregbase->LPDDR4__PI_INT_ACK__REG), regval); } @@ -894,7 +894,7 @@ static void lpddr4_checkwrlvlerror(lpddr4_ctlregs * ctlregbase, (volatile uint32_t *)(&(ctlregbase->LPDDR4__PHY_WRLVL_ERROR_OBS_0__REG)); /* PHY_WRLVL_ERROR_OBS_X[1:0] should be zero */ - errbitmask = (BIT_MASK << 1) | (BIT_MASK); + errbitmask = (LPDDR4_BIT_MASK << 1) | LPDDR4_BIT_MASK; for (snum = 0U; snum < DSLICE_NUM; snum++) { regval = CPS_REG_READ(regaddress); if ((regval & errbitmask) != 0U) { @@ -1054,7 +1054,7 @@ static void lpddr4_seterrors(lpddr4_ctlregs * ctlregbase, lpddr4_debuginfo * debuginfo, bool * errfoundptr) { - uint32_t errbitmask = (BIT_MASK << 0x1U) | (BIT_MASK); + uint32_t errbitmask = (LPDDR4_BIT_MASK << 0x1U) | LPDDR4_BIT_MASK; /* Check PLL observation registers for PLL lock errors */ debuginfo->pllerror = diff --git a/drivers/ram/k3-j721e/lpddr4_private.h b/drivers/ram/k3-j721e/lpddr4_private.h index 42c923464a..3d5017ea47 100644 --- a/drivers/ram/k3-j721e/lpddr4_private.h +++ b/drivers/ram/k3-j721e/lpddr4_private.h @@ -14,9 +14,9 @@ #define VERSION_0 (0x54d5da40U) #define VERSION_1 (0xc1865a1U) -#define BIT_MASK (0x1U) -#define BYTE_MASK (0xffU) -#define NIBBLE_MASK (0xfU) +#define LPDDR4_BIT_MASK (0x1U) +#define BYTE_MASK (0xffU) +#define NIBBLE_MASK (0xfU) #define WORD_SHIFT (32U) #define WORD_MASK (0xffffffffU) @@ -46,11 +46,15 @@ #define IO_CALIB_DONE ((uint32_t)0x1U << 23U) #define IO_CALIB_FIELD ((uint32_t)NIBBLE_MASK << 28U) #define IO_CALIB_STATE ((uint32_t)0xBU << 28U) -#define RX_CAL_DONE ((uint32_t)BIT_MASK << 4U) -#define CA_TRAIN_RL (((uint32_t)BIT_MASK << 5U) | ((uint32_t)BIT_MASK << 4U)) +#define RX_CAL_DONE ((uint32_t)LPDDR4_BIT_MASK << 4U) +#define CA_TRAIN_RL (((uint32_t)LPDDR4_BIT_MASK << 5U) | \ + ((uint32_t)LPDDR4_BIT_MASK << 4U)) #define WR_LVL_STATE (((uint32_t)NIBBLE_MASK) << 13U) -#define GATE_LVL_ERROR_FIELDS (((uint32_t)BIT_MASK << 7U) | ((uint32_t)BIT_MASK << 6U)) -#define READ_LVL_ERROR_FIELDS ((((uint32_t)NIBBLE_MASK) << 28U) | (((uint32_t)BYTE_MASK) << 16U)) -#define DQ_LVL_STATUS (((uint32_t)BIT_MASK << 26U) | (((uint32_t)BYTE_MASK) << 18U)) +#define GATE_LVL_ERROR_FIELDS (((uint32_t)LPDDR4_BIT_MASK << 7U) | \ + ((uint32_t)LPDDR4_BIT_MASK << 6U)) +#define READ_LVL_ERROR_FIELDS ((((uint32_t)NIBBLE_MASK) << 28U) | \ + (((uint32_t)BYTE_MASK) << 16U)) +#define DQ_LVL_STATUS (((uint32_t)LPDDR4_BIT_MASK << 26U) | \ + (((uint32_t)BYTE_MASK) << 18U)) #endif /* LPDDR4_PRIV_H */ diff --git a/drivers/ram/stm32_sdram.c b/drivers/ram/stm32_sdram.c index 4003db0e50..540ad85138 100644 --- a/drivers/ram/stm32_sdram.c +++ b/drivers/ram/stm32_sdram.c @@ -4,6 +4,8 @@ * Author(s): Vikas Manocha, <vikas.manocha@st.com> for STMicroelectronics. */ +#define LOG_CATEGORY UCLASS_RAM + #include <common.h> #include <clk.h> #include <dm.h> @@ -272,7 +274,7 @@ static int stm32_fmc_of_to_plat(struct udevice *dev) ret = dev_read_phandle_with_args(dev, "st,syscfg", NULL, 0, 0, &args); if (ret) { - dev_dbg(dev, "%s: can't find syscon device (%d)\n", __func__, ret); + dev_dbg(dev, "can't find syscon device (%d)\n", ret); } else { syscfg_base = (u32 *)ofnode_get_addr(args.node); @@ -281,7 +283,7 @@ static int stm32_fmc_of_to_plat(struct udevice *dev) /* set memory mapping selection */ clrsetbits_le32(syscfg_base, MEM_MODE_MASK, mem_remap); } else { - dev_dbg(dev, "%s: cannot find st,mem_remap property\n", __func__); + dev_dbg(dev, "cannot find st,mem_remap property\n"); } swp_fmc = dev_read_u32_default(dev, "st,swp_fmc", NOT_FOUND); @@ -289,7 +291,7 @@ static int stm32_fmc_of_to_plat(struct udevice *dev) /* set fmc swapping selection */ clrsetbits_le32(syscfg_base, SWP_FMC_MASK, swp_fmc << SWP_FMC_OFFSET); } else { - dev_dbg(dev, "%s: cannot find st,swp_fmc property\n", __func__); + dev_dbg(dev, "cannot find st,swp_fmc property\n"); } dev_dbg(dev, "syscfg %x = %x\n", (u32)syscfg_base, *syscfg_base); @@ -348,7 +350,7 @@ static int stm32_fmc_of_to_plat(struct udevice *dev) } params->no_sdram_banks = bank; - debug("%s, no of banks = %d\n", __func__, params->no_sdram_banks); + dev_dbg(dev, "no of banks = %d\n", params->no_sdram_banks); return 0; } diff --git a/drivers/ram/stm32mp1/stm32mp1_ddr.c b/drivers/ram/stm32mp1/stm32mp1_ddr.c index bf3a4c97a4..0457166b12 100644 --- a/drivers/ram/stm32mp1/stm32mp1_ddr.c +++ b/drivers/ram/stm32mp1/stm32mp1_ddr.c @@ -3,6 +3,8 @@ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved */ +#define LOG_CATEGORY UCLASS_RAM + #include <common.h> #include <clk.h> #include <log.h> @@ -311,17 +313,17 @@ static void set_reg(const struct ddr_info *priv, u32 base_addr = get_base_addr(priv, base); const struct reg_desc *desc = ddr_registers[type].desc; - debug("init %s\n", ddr_registers[type].name); + log_debug("init %s\n", ddr_registers[type].name); for (i = 0; i < ddr_registers[type].size; i++) { ptr = (unsigned int *)(base_addr + desc[i].offset); if (desc[i].par_offset == INVALID_OFFSET) { - pr_err("invalid parameter offset for %s", desc[i].name); + log_err("invalid parameter offset for %s", desc[i].name); } else { value = *((u32 *)((u32)param + desc[i].par_offset)); writel(value, ptr); - debug("[0x%x] %s= 0x%08x\n", - (u32)ptr, desc[i].name, value); + log_debug("[0x%x] %s= 0x%08x\n", + (u32)ptr, desc[i].name, value); } } } @@ -564,16 +566,16 @@ static void ddrphy_idone_wait(struct stm32mp1_ddrphy *phy) DDRPHYC_PGSR_RVERR | DDRPHYC_PGSR_RVEIRR), 1000000); - debug("\n[0x%08x] pgsr = 0x%08x ret=%d\n", - (u32)&phy->pgsr, pgsr, ret); + log_debug("\n[0x%08x] pgsr = 0x%08x ret=%d\n", + (u32)&phy->pgsr, pgsr, ret); } void stm32mp1_ddrphy_init(struct stm32mp1_ddrphy *phy, u32 pir) { pir |= DDRPHYC_PIR_INIT; writel(pir, &phy->pir); - debug("[0x%08x] pir = 0x%08x -> 0x%08x\n", - (u32)&phy->pir, pir, readl(&phy->pir)); + log_debug("[0x%08x] pir = 0x%08x -> 0x%08x\n", + (u32)&phy->pir, pir, readl(&phy->pir)); /* need to wait 10 configuration clock before start polling */ udelay(10); @@ -603,7 +605,7 @@ static void wait_sw_done_ack(struct stm32mp1_ddrctl *ctl) panic("Timeout initialising DRAM : DDR->swstat = %x\n", swstat); - debug("[0x%08x] swstat = 0x%08x\n", (u32)&ctl->swstat, swstat); + log_debug("[0x%08x] swstat = 0x%08x\n", (u32)&ctl->swstat, swstat); } /* wait quasi dynamic register update */ @@ -634,7 +636,7 @@ static void wait_operating_mode(struct ddr_info *priv, int mode) if (ret) panic("Timeout DRAM : DDR->stat = %x\n", stat); - debug("[0x%08x] stat = 0x%08x\n", (u32)&priv->ctl->stat, stat); + log_debug("[0x%08x] stat = 0x%08x\n", (u32)&priv->ctl->stat, stat); } void stm32mp1_refresh_disable(struct stm32mp1_ddrctl *ctl) @@ -706,9 +708,9 @@ void stm32mp1_ddr_init(struct ddr_info *priv, panic("ddr power init failed\n"); start: - debug("name = %s\n", config->info.name); - debug("speed = %d kHz\n", config->info.speed); - debug("size = 0x%x\n", config->info.size); + log_debug("name = %s\n", config->info.name); + log_debug("speed = %d kHz\n", config->info.speed); + log_debug("size = 0x%x\n", config->info.size); /* * 1. Program the DWC_ddr_umctl2 registers * 1.1 RESETS: presetn, core_ddrc_rstn, aresetn @@ -745,8 +747,8 @@ start: /* 1.5. initialize registers ddr_umctl2 */ /* Stop uMCTL2 before PHY is ready */ clrbits_le32(&priv->ctl->dfimisc, DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN); - debug("[0x%08x] dfimisc = 0x%08x\n", - (u32)&priv->ctl->dfimisc, readl(&priv->ctl->dfimisc)); + log_debug("[0x%08x] dfimisc = 0x%08x\n", + (u32)&priv->ctl->dfimisc, readl(&priv->ctl->dfimisc)); set_reg(priv, REG_REG, &config->c_reg); set_reg(priv, REG_TIMING, &config->c_timing); @@ -809,9 +811,9 @@ start: wait_operating_mode(priv, DDRCTRL_STAT_OPERATING_MODE_NORMAL); if (config->p_cal_present) { - debug("DDR DQS training skipped.\n"); + log_debug("DDR DQS training skipped.\n"); } else { - debug("DDR DQS training : "); + log_debug("DDR DQS training : "); /* 8. Disable Auto refresh and power down by setting * - RFSHCTL3.dis_au_refresh = 1 * - PWRCTL.powerdown_en = 0 diff --git a/drivers/ram/stm32mp1/stm32mp1_interactive.c b/drivers/ram/stm32mp1/stm32mp1_interactive.c index 5a5d067046..e45a2489c5 100644 --- a/drivers/ram/stm32mp1/stm32mp1_interactive.c +++ b/drivers/ram/stm32mp1/stm32mp1_interactive.c @@ -3,6 +3,8 @@ * Copyright (C) 2019, STMicroelectronics - All Rights Reserved */ +#define LOG_CATEGORY UCLASS_RAM + #include <common.h> #include <command.h> #include <console.h> @@ -404,7 +406,7 @@ bool stm32mp1_ddr_interactive(void *priv, #endif } - debug("** step %d ** %s / %d\n", step, step_str[step], next_step); + log_debug("** step %d ** %s / %d\n", step, step_str[step], next_step); if (next_step < 0) return false; diff --git a/drivers/ram/stm32mp1/stm32mp1_ram.c b/drivers/ram/stm32mp1/stm32mp1_ram.c index 0b6d20f566..26f0b4f1ea 100644 --- a/drivers/ram/stm32mp1/stm32mp1_ram.c +++ b/drivers/ram/stm32mp1/stm32mp1_ram.c @@ -3,6 +3,8 @@ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved */ +#define LOG_CATEGORY UCLASS_RAM + #include <common.h> #include <clk.h> #include <dm.h> @@ -12,6 +14,7 @@ #include <regmap.h> #include <syscon.h> #include <asm/io.h> +#include <dm/device_compat.h> #include "stm32mp1_ddr.h" static const char *const clkname[] = { @@ -37,7 +40,7 @@ int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint32_t mem_speed) ret = clk_enable(&clk); if (ret) { - printf("error for %s : %d\n", clkname[idx], ret); + log_err("error for %s : %d\n", clkname[idx], ret); return ret; } } @@ -45,13 +48,13 @@ int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint32_t mem_speed) priv->clk = clk; ddrphy_clk = clk_get_rate(&priv->clk); - debug("DDR: mem_speed (%d kHz), RCC %d kHz\n", - mem_speed, (u32)(ddrphy_clk / 1000)); + log_debug("DDR: mem_speed (%d kHz), RCC %d kHz\n", + mem_speed, (u32)(ddrphy_clk / 1000)); /* max 10% frequency delta */ ddr_clk = abs(ddrphy_clk - mem_speed * 1000); if (ddr_clk > (mem_speed * 100)) { - pr_err("DDR expected freq %d kHz, current is %d kHz\n", - mem_speed, (u32)(ddrphy_clk / 1000)); + log_err("DDR expected freq %d kHz, current is %d kHz\n", + mem_speed, (u32)(ddrphy_clk / 1000)); return -EINVAL; } @@ -118,7 +121,7 @@ static __maybe_unused int stm32mp1_ddr_setup(struct udevice *dev) config.info.size = ofnode_read_u32_default(node, "st,mem-size", 0); config.info.name = ofnode_read_string(node, "st,mem-name"); if (!config.info.name) { - debug("%s: no st,mem-name\n", __func__); + dev_dbg(dev, "no st,mem-name\n"); return -EINVAL; } printf("RAM: %s\n", config.info.name); @@ -128,12 +131,12 @@ static __maybe_unused int stm32mp1_ddr_setup(struct udevice *dev) (void *)((u32)&config + param[idx].offset), param[idx].size); - debug("%s: %s[0x%x] = %d\n", __func__, - param[idx].name, param[idx].size, ret); + dev_dbg(dev, "%s: %s[0x%x] = %d\n", __func__, + param[idx].name, param[idx].size, ret); if (ret && (ret != -FDT_ERR_NOTFOUND || !param[idx].present)) { - pr_err("%s: Cannot read %s, error=%d\n", - __func__, param[idx].name, ret); + dev_err(dev, "Cannot read %s, error=%d\n", + param[idx].name, ret); return -EINVAL; } if (param[idx].present) { @@ -153,7 +156,7 @@ static __maybe_unused int stm32mp1_ddr_setup(struct udevice *dev) ret = clk_get_by_name(dev, "axidcg", &axidcg); if (ret) { - debug("%s: Cannot found axidcg\n", __func__); + dev_dbg(dev, "%s: Cannot found axidcg\n", __func__); return -EINVAL; } clk_disable(&axidcg); /* disable clock gating during init */ @@ -163,13 +166,13 @@ static __maybe_unused int stm32mp1_ddr_setup(struct udevice *dev) clk_enable(&axidcg); /* enable clock gating */ /* check size */ - debug("%s : get_ram_size(%x, %x)\n", __func__, - (u32)priv->info.base, (u32)STM32_DDR_SIZE); + dev_dbg(dev, "get_ram_size(%x, %x)\n", + (u32)priv->info.base, (u32)STM32_DDR_SIZE); priv->info.size = get_ram_size((long *)priv->info.base, STM32_DDR_SIZE); - debug("%s : %x\n", __func__, (u32)priv->info.size); + dev_dbg(dev, "info.size: %x\n", (u32)priv->info.size); /* check memory access for all memory */ if (config.info.size != priv->info.size) { @@ -186,12 +189,11 @@ static int stm32mp1_ddr_probe(struct udevice *dev) struct regmap *map; int ret; - debug("STM32MP1 DDR probe\n"); priv->dev = dev; ret = regmap_init_mem(dev_ofnode(dev), &map); if (ret) - return ret; + return log_ret(ret); priv->ctl = regmap_get_range(map, 0); priv->phy = regmap_get_range(map, 1); @@ -203,7 +205,9 @@ static int stm32mp1_ddr_probe(struct udevice *dev) #if !defined(CONFIG_TFABOOT) && \ (!defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)) priv->info.size = 0; - return stm32mp1_ddr_setup(dev); + ret = stm32mp1_ddr_setup(dev); + + return log_ret(ret); #else ofnode node = stm32mp1_ddr_get_ofnode(dev); priv->info.size = ofnode_read_u32_default(node, "st,mem-size", 0); diff --git a/drivers/ram/stm32mp1/stm32mp1_tests.c b/drivers/ram/stm32mp1/stm32mp1_tests.c index 952006aa14..1fcc7cfd69 100644 --- a/drivers/ram/stm32mp1/stm32mp1_tests.c +++ b/drivers/ram/stm32mp1/stm32mp1_tests.c @@ -2,6 +2,9 @@ /* * Copyright (C) 2019, STMicroelectronics - All Rights Reserved */ + +#define LOG_CATEGORY UCLASS_RAM + #include <common.h> #include <console.h> #include <init.h> @@ -197,8 +200,8 @@ static u32 databus(u32 *address) /* Read it back (immediately is okay for this test). */ read_value = readl(address); - debug("%x: %x <=> %x\n", - (u32)address, read_value, pattern); + log_debug("%x: %x <=> %x\n", + (u32)address, read_value, pattern); if (read_value != pattern) return pattern; @@ -252,8 +255,8 @@ static u32 *addressbus(u32 *address, u32 nb_bytes) for (offset = 1; (offset & mask) != 0; offset <<= 1) { read_value = readl(&address[offset]); - debug("%x: %x <=> %x\n", - (u32)&address[offset], read_value, pattern); + log_debug("%x: %x <=> %x\n", + (u32)&address[offset], read_value, pattern); if (read_value != pattern) return &address[offset]; } @@ -363,8 +366,8 @@ static enum test_result databuswalk0(struct stm32mp1_ddrctl *ctl, data = readl(addr + 4 * i); if (~(1 << i) != data) { error |= 1 << i; - debug("%x: error %x expected %x => error:%x\n", - addr + 4 * i, data, ~(1 << i), error); + log_debug("%x: error %x expected %x => error:%x\n", + addr + 4 * i, data, ~(1 << i), error); } } if (test_loop_end(&loop, nb_loop, 1000)) @@ -403,8 +406,8 @@ static enum test_result databuswalk1(struct stm32mp1_ddrctl *ctl, data = readl(addr + 4 * i); if ((1 << i) != data) { error |= 1 << i; - debug("%x: error %x expected %x => error:%x\n", - addr + 4 * i, data, (1 << i), error); + log_debug("%x: error %x expected %x => error:%x\n", + addr + 4 * i, data, (1 << i), error); } } if (test_loop_end(&loop, nb_loop, 1000)) diff --git a/drivers/ram/stm32mp1/stm32mp1_tuning.c b/drivers/ram/stm32mp1/stm32mp1_tuning.c index a8d6892bb0..c8cd7c3cea 100644 --- a/drivers/ram/stm32mp1/stm32mp1_tuning.c +++ b/drivers/ram/stm32mp1/stm32mp1_tuning.c @@ -2,6 +2,9 @@ /* * Copyright (C) 2019, STMicroelectronics - All Rights Reserved */ + +#define LOG_CATEGORY UCLASS_RAM + #include <common.h> #include <console.h> #include <clk.h> @@ -227,8 +230,7 @@ static u8 DQ_unit_index(struct stm32mp1_ddrphy *phy, u8 byte, u8 bit) index = (readl(addr) >> DDRPHYC_DXNDQTR_DQDLY_SHIFT(bit)) & DDRPHYC_DXNDQTR_DQDLY_LOW_MASK; - pr_debug("%s: [%x]: %x => DQ unit index = %x\n", - __func__, addr, readl(addr), index); + log_debug("[%x]: %x => DQ unit index = %x\n", addr, readl(addr), index); return index; } @@ -470,13 +472,13 @@ static void apply_deskew_results(struct stm32mp1_ddrphy *phy, u8 byte, for (bit_i = 0; bit_i < 8; bit_i++) { set_DQ_unit_delay(phy, byte, bit_i, deskew_delay[byte][bit_i]); index = DQ_unit_index(phy, byte, bit_i); - pr_debug("Byte %d ; bit %d : The new DQ delay (%d) index=%d [delta=%d, 3 is the default]", - byte, bit_i, deskew_delay[byte][bit_i], - index, index - 3); + log_debug("Byte %d ; bit %d : The new DQ delay (%d) index=%d [delta=%d, 3 is the default]", + byte, bit_i, deskew_delay[byte][bit_i], + index, index - 3); printf("Byte %d, bit %d, DQ delay = %d", byte, bit_i, deskew_delay[byte][bit_i]); if (deskew_non_converge[byte][bit_i] == 1) - pr_debug(" - not converged : still more skew"); + log_debug(" - not converged : still more skew"); printf("\n"); } } @@ -536,7 +538,7 @@ static enum test_result bit_deskew(struct stm32mp1_ddrctl *ctl, /* Config the BIST block */ config_BIST(ctl, phy); - pr_debug("BIST Config done.\n"); + log_debug("BIST Config done.\n"); /* Train each byte */ for (datx8 = 0; datx8 < nb_bytes; datx8++) { @@ -545,9 +547,9 @@ static enum test_result bit_deskew(struct stm32mp1_ddrctl *ctl, datx8 + 1, nb_bytes, error); return TEST_FAILED; } - pr_debug("\n======================\n"); - pr_debug("Start deskew byte %d .\n", datx8); - pr_debug("======================\n"); + log_debug("\n======================\n"); + log_debug("Start deskew byte %d .\n", datx8); + log_debug("======================\n"); /* Enable Byte (DXNGCR, bit DXEN) */ setbits_le32(DXNGCR(phy, datx8), DDRPHYC_DXNGCR_DXEN); @@ -584,7 +586,7 @@ static enum test_result bit_deskew(struct stm32mp1_ddrctl *ctl, * Else, look for Pass init condition */ if (!success) { - pr_debug("Fail at init condtion. Let's look for a good init condition.\n"); + log_debug("Fail at init condtion. Let's look for a good init condition.\n"); success = 0; /* init */ /* Make sure we start with a PASS condition before * looking for a fail condition. @@ -592,7 +594,7 @@ static enum test_result bit_deskew(struct stm32mp1_ddrctl *ctl, */ /* escape if we find a PASS */ - pr_debug("increase Phase idx\n"); + log_debug("increase Phase idx\n"); while (!success && (phase_idx <= MAX_DQS_PHASE_IDX)) { DQS_phase_delay(phy, datx8, phase_idx); BIST_test(phy, datx8, &result); @@ -618,7 +620,7 @@ static enum test_result bit_deskew(struct stm32mp1_ddrctl *ctl, * we have hold violation, lets try reduce DQS_unit * Delay */ - pr_debug("Still fail. Try decrease DQS Unit delay\n"); + log_debug("Still fail. Try decrease DQS Unit delay\n"); phase_idx = 0; dqs_unit_delay_index = 0; @@ -665,9 +667,9 @@ static enum test_result bit_deskew(struct stm32mp1_ddrctl *ctl, return TEST_FAILED; } - pr_debug("there is a pass region for phase idx %d\n", - phase_idx); - pr_debug("Step1: Find the first failing condition\n"); + log_debug("there is a pass region for phase idx %d\n", + phase_idx); + log_debug("Step1: Find the first failing condition\n"); /* Look for the first failing condition by PHASE stepping. * This part of the algo can finish without converging. */ @@ -692,9 +694,9 @@ static enum test_result bit_deskew(struct stm32mp1_ddrctl *ctl, * stepping (minimal delay) */ if (!success) { - pr_debug("Fail region (PHASE) found phase idx %d\n", - phase_idx); - pr_debug("Let's look for first success by DQS Unit steps\n"); + log_debug("Fail region (PHASE) found phase idx %d\n", + phase_idx); + log_debug("Let's look for first success by DQS Unit steps\n"); /* This part, the algo always converge */ phase_idx--; @@ -721,7 +723,7 @@ static enum test_result bit_deskew(struct stm32mp1_ddrctl *ctl, /*+1 to get back to current condition */ last_right_ok.unit = dqs_unit_delay_index + 1; last_right_ok.bits_delay = 0xFFFFFFFF; - pr_debug("Found %d\n", dqs_unit_delay_index); + log_debug("Found %d\n", dqs_unit_delay_index); } else { /* the last OK condition is then with the * previous phase_idx. @@ -735,8 +737,8 @@ static enum test_result bit_deskew(struct stm32mp1_ddrctl *ctl, */ last_right_ok.unit = 1; last_right_ok.bits_delay = 0xFFFFFFFF; - pr_debug("Not Found : try previous phase %d\n", - phase_idx - 1); + log_debug("Not Found : try previous phase %d\n", + phase_idx - 1); DQS_phase_delay(phy, datx8, phase_idx - 1); dqs_unit_delay_index = 0; @@ -749,8 +751,8 @@ static enum test_result bit_deskew(struct stm32mp1_ddrctl *ctl, BIST_test(phy, datx8, &result); success = result.test_result; dqs_unit_delay_index++; - pr_debug("dqs_unit_delay_index = %d, result = %d\n", - dqs_unit_delay_index, success); + log_debug("dqs_unit_delay_index = %d, result = %d\n", + dqs_unit_delay_index, success); } if (!success) { @@ -758,7 +760,7 @@ static enum test_result bit_deskew(struct stm32mp1_ddrctl *ctl, dqs_unit_delay_index - 1; } else { last_right_ok.unit = 0; - pr_debug("ERROR: failed region not FOUND"); + log_debug("ERROR: failed region not FOUND"); } } } else { @@ -775,7 +777,7 @@ static enum test_result bit_deskew(struct stm32mp1_ddrctl *ctl, last_right_ok.phase = MAX_DQS_PHASE_IDX; last_right_ok.unit = MAX_DQS_UNIT_IDX; last_right_ok.bits_delay = 0xFFFFFFFF; - pr_debug("Can't find the a fail condition\n"); + log_debug("Can't find the a fail condition\n"); } /* step 2: @@ -787,9 +789,9 @@ static enum test_result bit_deskew(struct stm32mp1_ddrctl *ctl, */ printf("Byte %d, DQS unit = %d, phase = %d\n", datx8, last_right_ok.unit, last_right_ok.phase); - pr_debug("Step2, unit = %d, phase = %d, bits delay=%x\n", - last_right_ok.unit, last_right_ok.phase, - last_right_ok.bits_delay); + log_debug("Step2, unit = %d, phase = %d, bits delay=%x\n", + last_right_ok.unit, last_right_ok.phase, + last_right_ok.bits_delay); /* Restore the last_right_ok condtion. */ DQS_unit_delay(phy, datx8, last_right_ok.unit); @@ -812,7 +814,7 @@ static enum test_result bit_deskew(struct stm32mp1_ddrctl *ctl, datx8 + 1, nb_bytes, error); return error; } - pr_debug("deskewing bit %d:\n", bit_i); + log_debug("deskewing bit %d:\n", bit_i); success = 1; /* init */ /* Set all DQDLYn to maximum value. * Only bit_i will be down-delayed @@ -855,10 +857,10 @@ static enum test_result bit_deskew(struct stm32mp1_ddrctl *ctl, * at one bit. */ fail_found = 1; - pr_debug("Fail found on bit %d, for delay = %d => deskew[%d][%d] = %d\n", - bit_i, bit_i_delay_index + 1, - datx8, bit_i, - deskew_delay[datx8][bit_i]); + log_debug("Fail found on bit %d, for delay = %d => deskew[%d][%d] = %d\n", + bit_i, bit_i_delay_index + 1, + datx8, bit_i, + deskew_delay[datx8][bit_i]); } else { /* if we can find a success condition by * back-delaying this bit, just set the delay @@ -870,20 +872,20 @@ static enum test_result bit_deskew(struct stm32mp1_ddrctl *ctl, * in the report. */ deskew_non_converge[datx8][bit_i] = 1; - pr_debug("Fail not found on bit %d => deskew[%d][%d] = %d\n", - bit_i, datx8, bit_i, - deskew_delay[datx8][bit_i]); + log_debug("Fail not found on bit %d => deskew[%d][%d] = %d\n", + bit_i, datx8, bit_i, + deskew_delay[datx8][bit_i]); } } - pr_debug("**********byte %d tuning complete************\n", - datx8); + log_debug("**********byte %d tuning complete************\n", + datx8); /* If we can't find any failure by back delaying DQ lines, * hold the default values */ if (!fail_found) { for (bit_i = 0; bit_i < 8; bit_i++) deskew_delay[datx8][bit_i] = 0; - pr_debug("The Deskew algorithm can't converge, there is too much margin in your design. Good job!\n"); + log_debug("The Deskew algorithm can't converge, there is too much margin in your design. Good job!\n"); } apply_deskew_results(phy, datx8, deskew_delay, @@ -986,7 +988,7 @@ static enum test_result eye_training(struct stm32mp1_ddrctl *ctl, dqs_unit_delay_index_pass = dqs_unit_delay_index; success = 0; - pr_debug("STEP0: Find Init delay\n"); + log_debug("STEP0: Find Init delay\n"); /* STEP0: Find Init delay: a delay that put the system * in a "Pass" condition then (TODO) update * dqs_unit_delay_index_pass & phase_idx_pass @@ -1035,7 +1037,7 @@ static enum test_result eye_training(struct stm32mp1_ddrctl *ctl, byte + 1, nb_bytes, error); return TEST_FAILED; } - pr_debug("STEP1: Find LEFT PHASE DQS Bound\n"); + log_debug("STEP1: Find LEFT PHASE DQS Bound\n"); /* STEP1: Find LEFT PHASE DQS Bound */ while ((phase_idx >= 0) && (phase_idx <= MAX_DQS_PHASE_IDX) && @@ -1069,7 +1071,7 @@ static enum test_result eye_training(struct stm32mp1_ddrctl *ctl, byte + 1, nb_bytes, error); return TEST_FAILED; } - pr_debug("STEP2: Find UNIT left bound\n"); + log_debug("STEP2: Find UNIT left bound\n"); /* STEP2: Find UNIT left bound */ while ((dqs_unit_delay_index >= 0) && !left_unit_bound_found) { @@ -1097,7 +1099,7 @@ static enum test_result eye_training(struct stm32mp1_ddrctl *ctl, byte + 1, nb_bytes, error); return TEST_FAILED; } - pr_debug("STEP3: Find PHase right bound\n"); + log_debug("STEP3: Find PHase right bound\n"); /* STEP3: Find PHase right bound, start with "pass" * condition */ @@ -1135,7 +1137,7 @@ static enum test_result eye_training(struct stm32mp1_ddrctl *ctl, byte + 1, nb_bytes, error); return TEST_FAILED; } - pr_debug("STEP4: Find UNIT right bound\n"); + log_debug("STEP4: Find UNIT right bound\n"); /* STEP4: Find UNIT right bound */ while ((dqs_unit_delay_index <= MAX_DQS_UNIT_IDX) && !right_unit_bound_found) { @@ -1174,12 +1176,12 @@ static enum test_result eye_training(struct stm32mp1_ddrctl *ctl, if (((right_bound.phase + left_bound.phase) % 2 == 1) && eye_training_val[byte][1] != MAX_DQS_UNIT_IDX) eye_training_val[byte][1]++; - pr_debug("** found phase : %d - %d & unit %d - %d\n", - right_bound.phase, left_bound.phase, - right_bound.unit, left_bound.unit); - pr_debug("** calculating mid region: phase: %d unit: %d (nominal is 3)\n", - eye_training_val[byte][0], - eye_training_val[byte][1]); + log_debug("** found phase : %d - %d & unit %d - %d\n", + right_bound.phase, left_bound.phase, + right_bound.unit, left_bound.unit); + log_debug("** calculating mid region: phase: %d unit: %d (nominal is 3)\n", + eye_training_val[byte][0], + eye_training_val[byte][1]); } else { /* PPPPPPPPPP, we're already good. * Set nominal values. @@ -1280,11 +1282,11 @@ static u8 set_midpoint_read_dqs_gating(struct stm32mp1_ddrphy *phy, u8 byte, * or pppppff or ffppppp */ if (left_bound_found || right_bound_found) { - pr_debug("idx0(%d): %d %d idx1(%d) : %d %d\n", - left_bound_found, - right_bound_idx[0], left_bound_idx[0], - right_bound_found, - right_bound_idx[1], left_bound_idx[1]); + log_debug("idx0(%d): %d %d idx1(%d) : %d %d\n", + left_bound_found, + right_bound_idx[0], left_bound_idx[0], + right_bound_found, + right_bound_idx[1], left_bound_idx[1]); dqs_gate_values[byte][0] = (right_bound_idx[0] + left_bound_idx[0]) / 2; dqs_gate_values[byte][1] = @@ -1319,14 +1321,14 @@ static u8 set_midpoint_read_dqs_gating(struct stm32mp1_ddrphy *phy, u8 byte, left_bound_idx[0]; } } - pr_debug("*******calculating mid region: system latency: %d phase: %d********\n", - dqs_gate_values[byte][0], - dqs_gate_values[byte][1]); - pr_debug("*******the nominal values were system latency: 0 phase: 2*******\n"); + log_debug("*******calculating mid region: system latency: %d phase: %d********\n", + dqs_gate_values[byte][0], + dqs_gate_values[byte][1]); + log_debug("*******the nominal values were system latency: 0 phase: 2*******\n"); } } else { /* if intermitant, restore defaut values */ - pr_debug("dqs gating:no regular fail/pass/fail found. defaults values restored.\n"); + log_debug("dqs gating:no regular fail/pass/fail found. defaults values restored.\n"); dqs_gate_values[byte][0] = 0; dqs_gate_values[byte][1] = 2; } diff --git a/drivers/remoteproc/stm32_copro.c b/drivers/remoteproc/stm32_copro.c index ec7694dda9..4c5f24857e 100644 --- a/drivers/remoteproc/stm32_copro.c +++ b/drivers/remoteproc/stm32_copro.c @@ -2,7 +2,8 @@ /* * Copyright (C) 2019, STMicroelectronics - All Rights Reserved */ -#define pr_fmt(fmt) "%s: " fmt, __func__ +#define LOG_CATEGORY UCLASS_REMOTEPROC + #include <common.h> #include <dm.h> #include <errno.h> diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 33c2736554..f5b3f8826f 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -81,6 +81,15 @@ config RESET_AST2500 Say Y if you want to control reset signals of different peripherals through System Control Unit (SCU). +config RESET_AST2600 + bool "Reset controller driver for AST2600 SoCs" + depends on DM_RESET + default y if ASPEED_AST2600 + help + Support for reset controller on AST2600 SoC. + Say Y if you want to control reset signals of different peripherals + through System Control Unit (SCU). + config RESET_ROCKCHIP bool "Reset controller driver for Rockchip SoCs" depends on DM_RESET && ARCH_ROCKCHIP && CLK diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index fa52aa3329..8a0f528076 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -15,6 +15,7 @@ obj-$(CONFIG_RESET_HSDK) += reset-hsdk.o obj-$(CONFIG_RESET_BCM6345) += reset-bcm6345.o obj-$(CONFIG_RESET_UNIPHIER) += reset-uniphier.o obj-$(CONFIG_RESET_AST2500) += reset-ast2500.o +obj-$(CONFIG_RESET_AST2600) += reset-ast2600.o obj-$(CONFIG_RESET_ROCKCHIP) += reset-rockchip.o obj-$(CONFIG_RESET_MESON) += reset-meson.o obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o diff --git a/drivers/reset/reset-ast2600.c b/drivers/reset/reset-ast2600.c new file mode 100644 index 0000000000..f64adaf74e --- /dev/null +++ b/drivers/reset/reset-ast2600.c @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2020 ASPEED Technology Inc. + */ + +#include <common.h> +#include <dm.h> +#include <log.h> +#include <misc.h> +#include <reset.h> +#include <reset-uclass.h> +#include <linux/err.h> +#include <asm/io.h> +#include <asm/arch/scu_ast2600.h> + +struct ast2600_reset_priv { + struct ast2600_scu *scu; +}; + +static int ast2600_reset_request(struct reset_ctl *reset_ctl) +{ + debug("%s(reset_ctl=%p) (dev=%p, id=%lu)\n", __func__, reset_ctl, + reset_ctl->dev, reset_ctl->id); + + return 0; +} + +static int ast2600_reset_free(struct reset_ctl *reset_ctl) +{ + debug("%s(reset_ctl=%p) (dev=%p, id=%lu)\n", __func__, reset_ctl, + reset_ctl->dev, reset_ctl->id); + + return 0; +} + +static int ast2600_reset_assert(struct reset_ctl *reset_ctl) +{ + struct ast2600_reset_priv *priv = dev_get_priv(reset_ctl->dev); + struct ast2600_scu *scu = priv->scu; + + debug("%s: reset_ctl->id: %lu\n", __func__, reset_ctl->id); + + if (reset_ctl->id < 32) + writel(BIT(reset_ctl->id), scu->modrst_ctrl1); + else + writel(BIT(reset_ctl->id - 32), scu->modrst_ctrl2); + + return 0; +} + +static int ast2600_reset_deassert(struct reset_ctl *reset_ctl) +{ + struct ast2600_reset_priv *priv = dev_get_priv(reset_ctl->dev); + struct ast2600_scu *scu = priv->scu; + + debug("%s: reset_ctl->id: %lu\n", __func__, reset_ctl->id); + + if (reset_ctl->id < 32) + writel(BIT(reset_ctl->id), scu->modrst_clr1); + else + writel(BIT(reset_ctl->id - 32), scu->modrst_clr2); + + return 0; +} + +static int ast2600_reset_probe(struct udevice *dev) +{ + int rc; + struct ast2600_reset_priv *priv = dev_get_priv(dev); + struct udevice *scu_dev; + + /* get SCU base from clock device */ + rc = uclass_get_device_by_driver(UCLASS_CLK, + DM_DRIVER_GET(aspeed_ast2600_scu), &scu_dev); + if (rc) { + debug("%s: clock device not found, rc=%d\n", __func__, rc); + return rc; + } + + priv->scu = devfdt_get_addr_ptr(scu_dev); + if (IS_ERR_OR_NULL(priv->scu)) { + debug("%s: invalid SCU base pointer\n", __func__); + return PTR_ERR(priv->scu); + } + + return 0; +} + +static const struct udevice_id ast2600_reset_ids[] = { + { .compatible = "aspeed,ast2600-reset" }, + { } +}; + +struct reset_ops ast2600_reset_ops = { + .request = ast2600_reset_request, + .rfree = ast2600_reset_free, + .rst_assert = ast2600_reset_assert, + .rst_deassert = ast2600_reset_deassert, +}; + +U_BOOT_DRIVER(ast2600_reset) = { + .name = "ast2600_reset", + .id = UCLASS_RESET, + .of_match = ast2600_reset_ids, + .probe = ast2600_reset_probe, + .ops = &ast2600_reset_ops, + .priv_auto = sizeof(struct ast2600_reset_priv), +}; diff --git a/drivers/reset/stm32-reset.c b/drivers/reset/stm32-reset.c index b84c9daec7..daa2e47ebb 100644 --- a/drivers/reset/stm32-reset.c +++ b/drivers/reset/stm32-reset.c @@ -4,6 +4,8 @@ * Author(s): Patrice Chotard, <patrice.chotard@foss.st.com> for STMicroelectronics. */ +#define LOG_CATEGORY UCLASS_RESET + #include <common.h> #include <dm.h> #include <errno.h> @@ -12,6 +14,7 @@ #include <reset-uclass.h> #include <stm32_rcc.h> #include <asm/io.h> +#include <dm/device_compat.h> #include <linux/bitops.h> /* offset of register without set/clear management */ @@ -39,8 +42,9 @@ static int stm32_reset_assert(struct reset_ctl *reset_ctl) struct stm32_reset_priv *priv = dev_get_priv(reset_ctl->dev); int bank = (reset_ctl->id / BITS_PER_LONG) * 4; int offset = reset_ctl->id % BITS_PER_LONG; - debug("%s: reset id = %ld bank = %d offset = %d)\n", __func__, - reset_ctl->id, bank, offset); + + dev_dbg(reset_ctl->dev, "reset id = %ld bank = %d offset = %d)\n", + reset_ctl->id, bank, offset); if (dev_get_driver_data(reset_ctl->dev) == STM32MP1) if (bank != RCC_MP_GCR_OFFSET) @@ -59,8 +63,9 @@ static int stm32_reset_deassert(struct reset_ctl *reset_ctl) struct stm32_reset_priv *priv = dev_get_priv(reset_ctl->dev); int bank = (reset_ctl->id / BITS_PER_LONG) * 4; int offset = reset_ctl->id % BITS_PER_LONG; - debug("%s: reset id = %ld bank = %d offset = %d)\n", __func__, - reset_ctl->id, bank, offset); + + dev_dbg(reset_ctl->dev, "reset id = %ld bank = %d offset = %d)\n", + reset_ctl->id, bank, offset); if (dev_get_driver_data(reset_ctl->dev) == STM32MP1) if (bank != RCC_MP_GCR_OFFSET) diff --git a/drivers/rtc/stm32_rtc.c b/drivers/rtc/stm32_rtc.c index f1d0ea90d3..1753283460 100644 --- a/drivers/rtc/stm32_rtc.c +++ b/drivers/rtc/stm32_rtc.c @@ -2,6 +2,9 @@ /* * Copyright (C) 2019, STMicroelectronics - All Rights Reserved */ + +#define LOG_CATEGORY UCLASS_RTC + #include <common.h> #include <clk.h> #include <dm.h> diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index b4805a2e4e..129494322c 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -134,6 +134,22 @@ config SERIAL_SEARCH_ALL If unsure, say N. +config SERIAL_PROBE_ALL + bool "Probe all available serial devices" + depends on DM_SERIAL + default n + help + The serial subsystem only probes for a single serial device, + but does not probe for other remaining serial devices. + With this option set, we make probing and searching for + all available devices optional. + Normally, U-Boot talks to one serial port at a time, but SBSA + compliant UART devices like PL011 require initialization + by firmware and to let the kernel use serial port for sending + and receiving the characters. + + If unsure, say N. + config SPL_DM_SERIAL bool "Enable Driver Model for serial drivers in SPL" depends on DM_SERIAL && SPL_DM diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c index 58a6541d8c..ead0193ad4 100644 --- a/drivers/serial/serial-uclass.c +++ b/drivers/serial/serial-uclass.c @@ -172,6 +172,15 @@ int serial_init(void) /* Called after relocation */ int serial_initialize(void) { + /* Scanning uclass to probe devices */ + if (IS_ENABLED(CONFIG_SERIAL_PROBE_ALL)) { + int ret; + + ret = uclass_probe_all(UCLASS_SERIAL); + if (ret) + return ret; + } + return serial_init(); } diff --git a/drivers/serial/serial_stm32.c b/drivers/serial/serial_stm32.c index 818c34cf11..f6cb708c37 100644 --- a/drivers/serial/serial_stm32.c +++ b/drivers/serial/serial_stm32.c @@ -4,6 +4,8 @@ * Author(s): Vikas Manocha, <vikas.manocha@st.com> for STMicroelectronics. */ +#define LOG_CATEGORY UCLASS_SERIAL + #include <common.h> #include <clk.h> #include <dm.h> @@ -13,6 +15,7 @@ #include <watchdog.h> #include <asm/io.h> #include <asm/arch/stm32.h> +#include <dm/device_compat.h> #include <linux/bitops.h> #include <linux/delay.h> #include "serial_stm32.h" diff --git a/drivers/spi/ca_sflash.c b/drivers/spi/ca_sflash.c index 00af6bffa6..84569845b7 100644 --- a/drivers/spi/ca_sflash.c +++ b/drivers/spi/ca_sflash.c @@ -571,6 +571,6 @@ U_BOOT_DRIVER(ca_sflash) = { .id = UCLASS_SPI, .of_match = ca_sflash_ids, .ops = &ca_sflash_ops, - .priv_auto_alloc_size = sizeof(struct ca_sflash_priv), + .priv_auto = sizeof(struct ca_sflash_priv), .probe = ca_sflash_probe, }; diff --git a/drivers/spi/stm32_qspi.c b/drivers/spi/stm32_qspi.c index 440085720a..75e5e840ed 100644 --- a/drivers/spi/stm32_qspi.c +++ b/drivers/spi/stm32_qspi.c @@ -7,6 +7,8 @@ * STM32 QSPI driver */ +#define LOG_CATEGORY UCLASS_SPI + #include <common.h> #include <clk.h> #include <dm.h> @@ -136,7 +138,7 @@ static int _stm32_qspi_wait_for_not_busy(struct stm32_qspi_priv *priv) !(sr & STM32_QSPI_SR_BUSY), STM32_BUSY_TIMEOUT_US); if (ret) - pr_err("busy timeout (stat:%#x)\n", sr); + log_err("busy timeout (stat:%#x)\n", sr); return ret; } @@ -154,9 +156,9 @@ static int _stm32_qspi_wait_cmd(struct stm32_qspi_priv *priv, sr & STM32_QSPI_SR_TCF, STM32_QSPI_CMD_TIMEOUT_US); if (ret) { - pr_err("cmd timeout (stat:%#x)\n", sr); + log_err("cmd timeout (stat:%#x)\n", sr); } else if (readl(&priv->regs->sr) & STM32_QSPI_SR_TEF) { - pr_err("transfer error (stat:%#x)\n", sr); + log_err("transfer error (stat:%#x)\n", sr); ret = -EIO; } @@ -198,7 +200,7 @@ static int _stm32_qspi_poll(struct stm32_qspi_priv *priv, sr & STM32_QSPI_SR_FTF, STM32_QSPI_FIFO_TIMEOUT_US); if (ret) { - pr_err("fifo timeout (len:%d stat:%#x)\n", len, sr); + log_err("fifo timeout (len:%d stat:%#x)\n", len, sr); return ret; } @@ -246,10 +248,10 @@ static int stm32_qspi_exec_op(struct spi_slave *slave, u8 mode = STM32_QSPI_CCR_IND_WRITE; int timeout, ret; - debug("%s: cmd:%#x mode:%d.%d.%d.%d addr:%#llx len:%#x\n", - __func__, op->cmd.opcode, op->cmd.buswidth, op->addr.buswidth, - op->dummy.buswidth, op->data.buswidth, - op->addr.val, op->data.nbytes); + dev_dbg(slave->dev, "cmd:%#x mode:%d.%d.%d.%d addr:%#llx len:%#x\n", + op->cmd.opcode, op->cmd.buswidth, op->addr.buswidth, + op->dummy.buswidth, op->data.buswidth, + op->addr.val, op->data.nbytes); ret = _stm32_qspi_wait_for_not_busy(priv); if (ret) @@ -320,7 +322,7 @@ abort: writel(STM32_QSPI_FCR_CTCF, &priv->regs->fcr); if (ret || timeout) - pr_err("%s ret:%d abort timeout:%d\n", __func__, ret, timeout); + dev_err(slave->dev, "ret:%d abort timeout:%d\n", ret, timeout); return ret; } @@ -353,8 +355,8 @@ static int stm32_qspi_probe(struct udevice *bus) if (priv->mm_size > STM32_QSPI_MAX_MMAP_SZ) return -EINVAL; - debug("%s: regs=<0x%p> mapped=<0x%p> mapped_size=<0x%lx>\n", - __func__, priv->regs, priv->mm_base, priv->mm_size); + dev_dbg(bus, "regs=<0x%p> mapped=<0x%p> mapped_size=<0x%lx>\n", + priv->regs, priv->mm_base, priv->mm_size); ret = clk_get_by_index(bus, 0, &clk); if (ret < 0) @@ -475,8 +477,8 @@ static int stm32_qspi_set_speed(struct udevice *bus, uint speed) STM32_QSPI_DCR_CSHT_MASK << STM32_QSPI_DCR_CSHT_SHIFT, csht << STM32_QSPI_DCR_CSHT_SHIFT); - debug("%s: regs=%p, speed=%d\n", __func__, priv->regs, - (qspi_clk / (prescaler + 1))); + dev_dbg(bus, "regs=%p, speed=%d\n", priv->regs, + (qspi_clk / (prescaler + 1))); return 0; } @@ -485,6 +487,7 @@ static int stm32_qspi_set_mode(struct udevice *bus, uint mode) { struct stm32_qspi_priv *priv = dev_get_priv(bus); int ret; + const char *str_rx, *str_tx; ret = _stm32_qspi_wait_for_not_busy(priv); if (ret) @@ -500,21 +503,22 @@ static int stm32_qspi_set_mode(struct udevice *bus, uint mode) if (mode & SPI_CS_HIGH) return -ENODEV; - debug("%s: regs=%p, mode=%d rx: ", __func__, priv->regs, mode); - if (mode & SPI_RX_QUAD) - debug("quad, tx: "); + str_rx = "quad"; else if (mode & SPI_RX_DUAL) - debug("dual, tx: "); + str_rx = "dual"; else - debug("single, tx: "); + str_rx = "single"; if (mode & SPI_TX_QUAD) - debug("quad\n"); + str_tx = "quad"; else if (mode & SPI_TX_DUAL) - debug("dual\n"); + str_tx = "dual"; else - debug("single\n"); + str_tx = "single"; + + dev_dbg(bus, "regs=%p, mode=%d rx: %s, tx: %s\n", + priv->regs, mode, str_rx, str_tx); return 0; } diff --git a/drivers/spi/stm32_spi.c b/drivers/spi/stm32_spi.c index 720103d517..bd8514033d 100644 --- a/drivers/spi/stm32_spi.c +++ b/drivers/spi/stm32_spi.c @@ -4,6 +4,9 @@ * * Driver for STMicroelectronics Serial peripheral interface (SPI) */ + +#define LOG_CATEGORY UCLASS_SPI + #include <common.h> #include <clk.h> #include <dm.h> @@ -138,7 +141,7 @@ static void stm32_spi_write_txfifo(struct stm32_spi_priv *priv) } } - debug("%s: %d bytes left\n", __func__, priv->tx_len); + log_debug("%d bytes left\n", priv->tx_len); } static void stm32_spi_read_rxfifo(struct stm32_spi_priv *priv) @@ -176,12 +179,12 @@ static void stm32_spi_read_rxfifo(struct stm32_spi_priv *priv) rxplvl = (sr & SPI_SR_RXPLVL) >> SPI_SR_RXPLVL_SHIFT; } - debug("%s: %d bytes left\n", __func__, priv->rx_len); + log_debug("%d bytes left\n", priv->rx_len); } static int stm32_spi_enable(struct stm32_spi_priv *priv) { - debug("%s\n", __func__); + log_debug("\n"); /* Enable the SPI hardware */ setbits_le32(priv->base + STM32_SPI_CR1, SPI_CR1_SPE); @@ -191,7 +194,7 @@ static int stm32_spi_enable(struct stm32_spi_priv *priv) static int stm32_spi_disable(struct stm32_spi_priv *priv) { - debug("%s\n", __func__); + log_debug("\n"); /* Disable the SPI hardware */ clrbits_le32(priv->base + STM32_SPI_CR1, SPI_CR1_SPE); @@ -204,7 +207,7 @@ static int stm32_spi_claim_bus(struct udevice *slave) struct udevice *bus = dev_get_parent(slave); struct stm32_spi_priv *priv = dev_get_priv(bus); - debug("%s\n", __func__); + dev_dbg(slave, "\n"); /* Enable the SPI hardware */ return stm32_spi_enable(priv); @@ -215,7 +218,7 @@ static int stm32_spi_release_bus(struct udevice *slave) struct udevice *bus = dev_get_parent(slave); struct stm32_spi_priv *priv = dev_get_priv(bus); - debug("%s\n", __func__); + dev_dbg(slave, "\n"); /* Disable the SPI hardware */ return stm32_spi_disable(priv); @@ -227,7 +230,7 @@ static void stm32_spi_stopxfer(struct udevice *dev) u32 cr1, sr; int ret; - debug("%s\n", __func__); + dev_dbg(dev, "\n"); cr1 = readl(priv->base + STM32_SPI_CR1); @@ -255,7 +258,7 @@ static int stm32_spi_set_cs(struct udevice *dev, unsigned int cs, bool enable) { struct stm32_spi_priv *priv = dev_get_priv(dev); - debug("%s: cs=%d enable=%d\n", __func__, cs, enable); + dev_dbg(dev, "cs=%d enable=%d\n", cs, enable); if (cs >= MAX_CS_COUNT) return -ENODEV; @@ -274,7 +277,7 @@ static int stm32_spi_set_mode(struct udevice *bus, uint mode) struct stm32_spi_priv *priv = dev_get_priv(bus); u32 cfg2_clrb = 0, cfg2_setb = 0; - debug("%s: mode=%d\n", __func__, mode); + dev_dbg(bus, "mode=%d\n", mode); if (mode & SPI_CPOL) cfg2_setb |= SPI_CFG2_CPOL; @@ -330,7 +333,7 @@ static int stm32_spi_set_speed(struct udevice *bus, uint hz) u32 mbrdiv; long div; - debug("%s: hz=%d\n", __func__, hz); + dev_dbg(bus, "hz=%d\n", hz); if (priv->cur_hz == hz) return 0; @@ -404,8 +407,8 @@ static int stm32_spi_xfer(struct udevice *slave, unsigned int bitlen, stm32_spi_enable(priv); } - debug("%s: priv->tx_len=%d priv->rx_len=%d\n", __func__, - priv->tx_len, priv->rx_len); + dev_dbg(bus, "priv->tx_len=%d priv->rx_len=%d\n", + priv->tx_len, priv->rx_len); slave_plat = dev_get_parent_plat(slave); if (flags & SPI_XFER_BEGIN) @@ -477,7 +480,7 @@ static int stm32_spi_get_fifo_size(struct udevice *dev) stm32_spi_disable(priv); - debug("%s %d x 8-bit fifo size\n", __func__, count); + dev_dbg(dev, "%d x 8-bit fifo size\n", count); return count; } @@ -522,7 +525,7 @@ static int stm32_spi_probe(struct udevice *dev) ret = gpio_request_list_by_name(dev, "cs-gpios", priv->cs_gpios, ARRAY_SIZE(priv->cs_gpios), 0); if (ret < 0) { - pr_err("Can't get %s cs gpios: %d", dev->name, ret); + dev_err(dev, "Can't get cs gpios: %d", ret); goto reset_err; } diff --git a/drivers/sysreset/sysreset_ast.c b/drivers/sysreset/sysreset_ast.c index ee941c7770..d747ed00a7 100644 --- a/drivers/sysreset/sysreset_ast.c +++ b/drivers/sysreset/sysreset_ast.c @@ -12,6 +12,7 @@ #include <asm/io.h> #include <asm/arch/wdt.h> #include <linux/err.h> +#include <hang.h> static int ast_sysreset_request(struct udevice *dev, enum sysreset_t type) { @@ -33,11 +34,15 @@ static int ast_sysreset_request(struct udevice *dev, enum sysreset_t type) return -EPROTONOSUPPORT; } +#if !defined(CONFIG_SPL_BUILD) ret = wdt_expire_now(wdt, reset_mode); if (ret) { debug("Sysreset failed: %d", ret); return ret; } +#else + hang(); +#endif return -EINPROGRESS; } diff --git a/drivers/timer/andes_plmt_timer.c b/drivers/timer/andes_plmt_timer.c index db2cf86f63..a3797b22c7 100644 --- a/drivers/timer/andes_plmt_timer.c +++ b/drivers/timer/andes_plmt_timer.c @@ -18,11 +18,30 @@ /* mtime register */ #define MTIME_REG(base) ((ulong)(base)) -static u64 andes_plmt_get_count(struct udevice *dev) +static u64 notrace andes_plmt_get_count(struct udevice *dev) { return readq((void __iomem *)MTIME_REG(dev_get_priv(dev))); } +#if CONFIG_IS_ENABLED(RISCV_MMODE) && IS_ENABLED(CONFIG_TIMER_EARLY) +/** + * timer_early_get_rate() - Get the timer rate before driver model + */ +unsigned long notrace timer_early_get_rate(void) +{ + return RISCV_MMODE_TIMER_FREQ; +} + +/** + * timer_early_get_count() - Get the timer count before driver model + * + */ +u64 notrace timer_early_get_count(void) +{ + return readq((void __iomem *)MTIME_REG(RISCV_MMODE_TIMERBASE)); +} +#endif + static const struct timer_ops andes_plmt_ops = { .get_count = andes_plmt_get_count, }; diff --git a/drivers/timer/mtk_timer.c b/drivers/timer/mtk_timer.c index 448a76a7e1..f6b97f868c 100644 --- a/drivers/timer/mtk_timer.c +++ b/drivers/timer/mtk_timer.c @@ -61,6 +61,16 @@ static int mtk_timer_probe(struct udevice *dev) if (!uc_priv->clock_rate) return -EINVAL; + /* + * Initialize the timer: + * 1. set clock source to system clock with clock divider setting to 1 + * 2. set timer mode to free running + * 3. reset timer counter to 0 then enable the timer + */ + writel(GPT4_CLK_SYS | GPT4_CLK_DIV1, priv->base + MTK_GPT4_CLK); + writel(GPT4_FREERUN | GPT4_CLEAR | GPT4_ENABLE, + priv->base + MTK_GPT4_CTRL); + return 0; } diff --git a/drivers/timer/riscv_timer.c b/drivers/timer/riscv_timer.c index 21ae184057..3627ed79b8 100644 --- a/drivers/timer/riscv_timer.c +++ b/drivers/timer/riscv_timer.c @@ -16,7 +16,7 @@ #include <timer.h> #include <asm/csr.h> -static u64 riscv_timer_get_count(struct udevice *dev) +static u64 notrace riscv_timer_get_count(struct udevice *dev) { __maybe_unused u32 hi, lo; @@ -31,6 +31,25 @@ static u64 riscv_timer_get_count(struct udevice *dev) return ((u64)hi << 32) | lo; } +#if CONFIG_IS_ENABLED(RISCV_SMODE) && IS_ENABLED(CONFIG_TIMER_EARLY) +/** + * timer_early_get_rate() - Get the timer rate before driver model + */ +unsigned long notrace timer_early_get_rate(void) +{ + return RISCV_SMODE_TIMER_FREQ; +} + +/** + * timer_early_get_count() - Get the timer count before driver model + * + */ +u64 notrace timer_early_get_count(void) +{ + return riscv_timer_get_count(NULL); +} +#endif + static int riscv_timer_probe(struct udevice *dev) { struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev); diff --git a/drivers/timer/sifive_clint_timer.c b/drivers/timer/sifive_clint_timer.c index de23b85404..de7b4b95c9 100644 --- a/drivers/timer/sifive_clint_timer.c +++ b/drivers/timer/sifive_clint_timer.c @@ -15,11 +15,30 @@ /* mtime register */ #define MTIME_REG(base) ((ulong)(base) + 0xbff8) -static u64 sifive_clint_get_count(struct udevice *dev) +static u64 notrace sifive_clint_get_count(struct udevice *dev) { return readq((void __iomem *)MTIME_REG(dev_get_priv(dev))); } +#if CONFIG_IS_ENABLED(RISCV_MMODE) && IS_ENABLED(CONFIG_TIMER_EARLY) +/** + * timer_early_get_rate() - Get the timer rate before driver model + */ +unsigned long notrace timer_early_get_rate(void) +{ + return RISCV_MMODE_TIMER_FREQ; +} + +/** + * timer_early_get_count() - Get the timer count before driver model + * + */ +u64 notrace timer_early_get_count(void) +{ + return readq((void __iomem *)MTIME_REG(RISCV_MMODE_TIMERBASE)); +} +#endif + static const struct timer_ops sifive_clint_ops = { .get_count = sifive_clint_get_count, }; diff --git a/drivers/timer/stm32_timer.c b/drivers/timer/stm32_timer.c index 215334f1b8..e34f5202fc 100644 --- a/drivers/timer/stm32_timer.c +++ b/drivers/timer/stm32_timer.c @@ -4,6 +4,8 @@ * Author(s): Patrice Chotard, <patrice.chotard@foss.st.com> for STMicroelectronics. */ +#define LOG_CATEGORY UCLASS_TIMER + #include <common.h> #include <clk.h> #include <dm.h> diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index a3f8eeba5d..d782eb806a 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -199,7 +199,7 @@ config PANEL config SIMPLE_PANEL bool "Enable simple panel support" - depends on PANEL + depends on PANEL && BACKLIGHT default y help This turns on a simple panel driver that enables a compatible @@ -449,6 +449,15 @@ config VIDEO_LCD_SSD2828_RESET The reset pin of SSD2828 chip. This takes a string in the format understood by 'name_to_gpio' function, e.g. PH1 for pin 1 of port H. +config VIDEO_LCD_TDO_TL070WSH30 + bool "TDO TL070WSH30 DSI LCD panel support" + depends on DM_VIDEO + select VIDEO_MIPI_DSI + default n + help + Say Y here if you want to enable support for TDO TL070WSH30 + 1024x600 DSI video mode panel. + config VIDEO_LCD_HITACHI_TX18D42VM bool "Hitachi tx18d42vm LVDS LCD panel support" depends on VIDEO diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 76e3914678..494e414a31 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -56,6 +56,7 @@ obj-$(CONFIG_VIDEO_LCD_HITACHI_TX18D42VM) += hitachi_tx18d42vm_lcd.o obj-$(CONFIG_VIDEO_LCD_ORISETECH_OTM8009A) += orisetech_otm8009a.o obj-$(CONFIG_VIDEO_LCD_RAYDIUM_RM68200) += raydium-rm68200.o obj-$(CONFIG_VIDEO_LCD_SSD2828) += ssd2828.o +obj-$(CONFIG_VIDEO_LCD_TDO_TL070WSH30) += tdo-tl070wsh30.o obj-$(CONFIG_VIDEO_MB862xx) += mb862xx.o videomodes.o obj-${CONFIG_VIDEO_MESON} += meson/ obj-${CONFIG_VIDEO_MIPI_DSI} += mipi_dsi.o diff --git a/drivers/video/seps525.c b/drivers/video/seps525.c index 369e5e6afc..74c8721e1e 100644 --- a/drivers/video/seps525.c +++ b/drivers/video/seps525.c @@ -299,7 +299,7 @@ static int seps525_probe(struct udevice *dev) static int seps525_bind(struct udevice *dev) { - struct video_uc_platdata *plat = dev_get_uclass_platdata(dev); + struct video_uc_plat *plat = dev_get_uclass_plat(dev); plat->size = WIDTH * HEIGHT * 16; @@ -320,8 +320,8 @@ U_BOOT_DRIVER(seps525_video) = { .id = UCLASS_VIDEO, .of_match = seps525_ids, .ops = &seps525_ops, - .platdata_auto_alloc_size = sizeof(struct video_uc_platdata), + .plat_auto = sizeof(struct video_uc_plat), .bind = seps525_bind, .probe = seps525_probe, - .priv_auto_alloc_size = sizeof(struct seps525_priv), + .priv_auto = sizeof(struct seps525_priv), }; diff --git a/drivers/video/stm32/stm32_dsi.c b/drivers/video/stm32/stm32_dsi.c index 266623b876..8891ca4b78 100644 --- a/drivers/video/stm32/stm32_dsi.c +++ b/drivers/video/stm32/stm32_dsi.c @@ -8,6 +8,8 @@ * drivers/gpu/drm/stm/dw_mipi_dsi-stm.c. */ +#define LOG_CATEGORY UCLASS_VIDEO_BRIDGE + #include <common.h> #include <clk.h> #include <dm.h> @@ -133,7 +135,7 @@ static enum dsi_color dsi_color_from_mipi(u32 fmt) case MIPI_DSI_FMT_RGB565: return DSI_RGB565_CONF1; default: - pr_err("MIPI color invalid, so we use rgb888\n"); + log_err("MIPI color invalid, so we use rgb888\n"); } return DSI_RGB888; } @@ -213,14 +215,14 @@ static int dsi_phy_init(void *priv_data) u32 val; int ret; - debug("Initialize DSI physical layer\n"); + dev_dbg(dev, "Initialize DSI physical layer\n"); /* Enable the regulator */ dsi_set(dsi, DSI_WRPCR, WRPCR_REGEN | WRPCR_BGREN); ret = readl_poll_timeout(dsi->base + DSI_WISR, val, val & WISR_RRS, TIMEOUT_US); if (ret) { - debug("!TIMEOUT! waiting REGU\n"); + dev_dbg(dev, "!TIMEOUT! waiting REGU\n"); return ret; } @@ -229,7 +231,7 @@ static int dsi_phy_init(void *priv_data) ret = readl_poll_timeout(dsi->base + DSI_WISR, val, val & WISR_PLLLS, TIMEOUT_US); if (ret) { - debug("!TIMEOUT! waiting PLL\n"); + dev_dbg(dev, "!TIMEOUT! waiting PLL\n"); return ret; } @@ -242,8 +244,8 @@ static void dsi_phy_post_set_mode(void *priv_data, unsigned long mode_flags) struct udevice *dev = device->dev; struct stm32_dsi_priv *dsi = dev_get_priv(dev); - debug("Set mode %p enable %ld\n", dsi, - mode_flags & MIPI_DSI_MODE_VIDEO); + dev_dbg(dev, "Set mode %p enable %ld\n", dsi, + mode_flags & MIPI_DSI_MODE_VIDEO); if (!dsi) return; @@ -325,8 +327,8 @@ static int dsi_get_lane_mbps(void *priv_data, struct display_timing *timings, *lane_mbps = pll_out_khz / 1000; - debug("pll_in %ukHz pll_out %ukHz lane_mbps %uMHz\n", - pll_in_khz, pll_out_khz, *lane_mbps); + dev_dbg(dev, "pll_in %ukHz pll_out %ukHz lane_mbps %uMHz\n", + pll_in_khz, pll_out_khz, *lane_mbps); return 0; } diff --git a/drivers/video/stm32/stm32_ltdc.c b/drivers/video/stm32/stm32_ltdc.c index dc10b8cfc1..f55a39498e 100644 --- a/drivers/video/stm32/stm32_ltdc.c +++ b/drivers/video/stm32/stm32_ltdc.c @@ -5,6 +5,8 @@ * Yannick Fertre <yannick.fertre@st.com> for STMicroelectronics. */ +#define LOG_CATEGORY UCLASS_VIDEO + #include <common.h> #include <clk.h> #include <display.h> @@ -176,13 +178,13 @@ static u32 stm32_ltdc_get_pixel_format(enum video_log2_bpp l2bpp) case VIDEO_BPP2: case VIDEO_BPP4: default: - pr_warn("%s: warning %dbpp not supported yet, %dbpp instead\n", - __func__, VNBITS(l2bpp), VNBITS(VIDEO_BPP16)); + log_warning("warning %dbpp not supported yet, %dbpp instead\n", + VNBITS(l2bpp), VNBITS(VIDEO_BPP16)); pf = PF_RGB565; break; } - debug("%s: %d bpp -> ltdc pf %d\n", __func__, VNBITS(l2bpp), pf); + log_debug("%d bpp -> ltdc pf %d\n", VNBITS(l2bpp), pf); return (u32)pf; } @@ -249,7 +251,7 @@ static void stm32_ltdc_set_mode(struct stm32_ltdc_priv *priv, /* Signal polarities */ val = 0; - debug("%s: timing->flags 0x%08x\n", __func__, timings->flags); + log_debug("timing->flags 0x%08x\n", timings->flags); if (timings->flags & DISPLAY_FLAGS_HSYNC_HIGH) val |= GCR_HSPOL; if (timings->flags & DISPLAY_FLAGS_VSYNC_HIGH) @@ -379,8 +381,8 @@ static int stm32_ltdc_probe(struct udevice *dev) dev_warn(dev, "fail to set pixel clock %d hz\n", timings.pixelclock.typ); - debug("%s: Set pixel clock req %d hz get %ld hz\n", __func__, - timings.pixelclock.typ, clk_get_rate(&pclk)); + dev_dbg(dev, "Set pixel clock req %d hz get %ld hz\n", + timings.pixelclock.typ, clk_get_rate(&pclk)); ret = reset_get_by_index(dev, 0, &rst); if (ret) { @@ -394,12 +396,13 @@ static int stm32_ltdc_probe(struct udevice *dev) if (IS_ENABLED(CONFIG_VIDEO_BRIDGE)) { ret = uclass_get_device(UCLASS_VIDEO_BRIDGE, 0, &bridge); if (ret) - debug("No video bridge, or no backlight on bridge\n"); + dev_dbg(dev, + "No video bridge, or no backlight on bridge\n"); if (bridge) { ret = video_bridge_attach(bridge); if (ret) { - dev_err(dev, "fail to attach bridge\n"); + dev_err(bridge, "fail to attach bridge\n"); return ret; } } @@ -414,12 +417,12 @@ static int stm32_ltdc_probe(struct udevice *dev) priv->crop_h = timings.vactive.typ; priv->alpha = 0xFF; - debug("%s: %dx%d %dbpp frame buffer at 0x%lx\n", __func__, - timings.hactive.typ, timings.vactive.typ, - VNBITS(priv->l2bpp), uc_plat->base); - debug("%s: crop %d,%d %dx%d bg 0x%08x alpha %d\n", __func__, - priv->crop_x, priv->crop_y, priv->crop_w, priv->crop_h, - priv->bg_col_argb, priv->alpha); + dev_dbg(dev, "%dx%d %dbpp frame buffer at 0x%lx\n", + timings.hactive.typ, timings.vactive.typ, + VNBITS(priv->l2bpp), uc_plat->base); + dev_dbg(dev, "crop %d,%d %dx%d bg 0x%08x alpha %d\n", + priv->crop_x, priv->crop_y, priv->crop_w, priv->crop_h, + priv->bg_col_argb, priv->alpha); /* Configure & start LTDC */ stm32_ltdc_set_mode(priv, &timings); @@ -457,7 +460,7 @@ static int stm32_ltdc_bind(struct udevice *dev) uc_plat->size = CONFIG_VIDEO_STM32_MAX_XRES * CONFIG_VIDEO_STM32_MAX_YRES * (CONFIG_VIDEO_STM32_MAX_BPP >> 3); - debug("%s: frame buffer max size %d bytes\n", __func__, uc_plat->size); + dev_dbg(dev, "frame buffer max size %d bytes\n", uc_plat->size); return 0; } diff --git a/drivers/video/tdo-tl070wsh30.c b/drivers/video/tdo-tl070wsh30.c new file mode 100644 index 0000000000..813b87a681 --- /dev/null +++ b/drivers/video/tdo-tl070wsh30.c @@ -0,0 +1,155 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2020 BayLibre, SAS + * Author: Neil Armstrong <narmstrong@baylibre.com> + */ +#include <common.h> +#include <backlight.h> +#include <dm.h> +#include <mipi_dsi.h> +#include <panel.h> +#include <asm/gpio.h> +#include <dm/device_compat.h> +#include <linux/delay.h> +#include <power/regulator.h> + +struct tl070wsh30_panel_priv { + struct udevice *reg; + struct udevice *backlight; + struct gpio_desc reset; +}; + +static const struct display_timing default_timing = { + .pixelclock.typ = 47250000, + .hactive.typ = 1024, + .hfront_porch.typ = 46, + .hback_porch.typ = 100, + .hsync_len.typ = 80, + .vactive.typ = 600, + .vfront_porch.typ = 5, + .vback_porch.typ = 20, + .vsync_len.typ = 5, + .flags = DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH, +}; + +static int tl070wsh30_panel_enable_backlight(struct udevice *dev) +{ + struct mipi_dsi_panel_plat *plat = dev_get_plat(dev); + struct mipi_dsi_device *device = plat->device; + struct tl070wsh30_panel_priv *priv = dev_get_priv(dev); + int ret; + + ret = mipi_dsi_attach(device); + if (ret < 0) + return ret; + + ret = mipi_dsi_dcs_exit_sleep_mode(device); + if (ret) + return ret; + + mdelay(200); + + ret = mipi_dsi_dcs_set_display_on(device); + if (ret) + return ret; + + mdelay(20); + + ret = backlight_enable(priv->backlight); + if (ret) + return ret; + + return 0; +} + +static int tl070wsh30_panel_get_display_timing(struct udevice *dev, + struct display_timing *timings) +{ + memcpy(timings, &default_timing, sizeof(*timings)); + + return 0; +} + +static int tl070wsh30_panel_of_to_plat(struct udevice *dev) +{ + struct tl070wsh30_panel_priv *priv = dev_get_priv(dev); + int ret; + + if (IS_ENABLED(CONFIG_DM_REGULATOR)) { + ret = device_get_supply_regulator(dev, "power-supply", + &priv->reg); + if (ret && ret != -ENOENT) { + dev_err(dev, "Warning: cannot get power supply\n"); + return ret; + } + } + + ret = gpio_request_by_name(dev, "reset-gpios", 0, &priv->reset, + GPIOD_IS_OUT); + if (ret) { + dev_err(dev, "Warning: cannot get reset GPIO\n"); + if (ret != -ENOENT) + return ret; + } + + ret = uclass_get_device_by_phandle(UCLASS_PANEL_BACKLIGHT, dev, + "backlight", &priv->backlight); + if (ret) { + dev_err(dev, "Cannot get backlight: ret=%d\n", ret); + return ret; + } + + return 0; +} + +static int tl070wsh30_panel_probe(struct udevice *dev) +{ + struct tl070wsh30_panel_priv *priv = dev_get_priv(dev); + struct mipi_dsi_panel_plat *plat = dev_get_plat(dev); + int ret; + + if (IS_ENABLED(CONFIG_DM_REGULATOR) && priv->reg) { + ret = regulator_set_enable(priv->reg, true); + if (ret) + return ret; + } + + mdelay(10); + + /* reset panel */ + dm_gpio_set_value(&priv->reset, true); + + mdelay(10); + + dm_gpio_set_value(&priv->reset, false); + + /* fill characteristics of DSI data link */ + plat->lanes = 4; + plat->format = MIPI_DSI_FMT_RGB888; + plat->mode_flags = MIPI_DSI_MODE_VIDEO | + MIPI_DSI_MODE_VIDEO_BURST | + MIPI_DSI_MODE_LPM; + + return 0; +} + +static const struct panel_ops tl070wsh30_panel_ops = { + .enable_backlight = tl070wsh30_panel_enable_backlight, + .get_display_timing = tl070wsh30_panel_get_display_timing, +}; + +static const struct udevice_id tl070wsh30_panel_ids[] = { + { .compatible = "tdo,tl070wsh30" }, + { } +}; + +U_BOOT_DRIVER(tl070wsh30_panel) = { + .name = "tl070wsh30_panel", + .id = UCLASS_PANEL, + .of_match = tl070wsh30_panel_ids, + .ops = &tl070wsh30_panel_ops, + .of_to_plat = tl070wsh30_panel_of_to_plat, + .probe = tl070wsh30_panel_probe, + .plat_auto = sizeof(struct mipi_dsi_panel_plat), + .priv_auto = sizeof(struct tl070wsh30_panel_priv), +}; diff --git a/drivers/video/ti/tilcdc-panel.c b/drivers/video/ti/tilcdc-panel.c index b90dfae4ae..df95086a51 100644 --- a/drivers/video/ti/tilcdc-panel.c +++ b/drivers/video/ti/tilcdc-panel.c @@ -165,7 +165,7 @@ U_BOOT_DRIVER(tilcdc_panel) = { .id = UCLASS_PANEL, .of_match = tilcdc_panel_ids, .ops = &tilcdc_panel_ops, - .ofdata_to_platdata = tilcdc_panel_of_to_plat, + .of_to_plat = tilcdc_panel_of_to_plat, .probe = tilcdc_panel_probe, .remove = tilcdc_panel_remove, .priv_auto = sizeof(struct tilcdc_panel_priv), diff --git a/drivers/video/ti/tilcdc.c b/drivers/video/ti/tilcdc.c index d13cc11801..814126af66 100644 --- a/drivers/video/ti/tilcdc.c +++ b/drivers/video/ti/tilcdc.c @@ -155,7 +155,7 @@ static ulong tilcdc_set_pixel_clk_rate(struct udevice *dev, ulong rate) static int tilcdc_remove(struct udevice *dev) { - struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev); + struct video_uc_plat *uc_plat = dev_get_uclass_plat(dev); struct tilcdc_priv *priv = dev_get_priv(dev); uc_plat->base -= 0x20; @@ -167,7 +167,7 @@ static int tilcdc_remove(struct udevice *dev) static int tilcdc_probe(struct udevice *dev) { - struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev); + struct video_uc_plat *uc_plat = dev_get_uclass_plat(dev); struct video_priv *uc_priv = dev_get_uclass_priv(dev); struct tilcdc_priv *priv = dev_get_priv(dev); struct tilcdc_regs *regs = priv->regs; @@ -399,7 +399,7 @@ static int tilcdc_of_to_plat(struct udevice *dev) static int tilcdc_bind(struct udevice *dev) { - struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev); + struct video_uc_plat *uc_plat = dev_get_uclass_plat(dev); uc_plat->size = ((LCDC_MAX_WIDTH * LCDC_MAX_HEIGHT * (1 << LCDC_MAX_LOG2_BPP)) >> 3) + 0x20; @@ -418,7 +418,7 @@ U_BOOT_DRIVER(tilcdc) = { .id = UCLASS_VIDEO, .of_match = tilcdc_ids, .bind = tilcdc_bind, - .ofdata_to_platdata = tilcdc_of_to_plat, + .of_to_plat = tilcdc_of_to_plat, .probe = tilcdc_probe, .remove = tilcdc_remove, .priv_auto = sizeof(struct tilcdc_priv) diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 4532a40e45..d5edabf3ef 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -86,6 +86,15 @@ config WDT_ASPEED It currently does not support Boot Flash Addressing Mode Detection or Second Boot. +config WDT_AST2600 + bool "Aspeed AST2600 watchdog timer support" + depends on WDT + default y if ASPEED_AST2600 + help + Select this to enable watchdog timer for Aspeed ast2500/ast2400 devices. + The watchdog timer is stopped when initialized. It performs reset, either + full SoC reset or CPU or just some peripherals, based on the flags. + config WDT_AT91 bool "AT91 watchdog timer support" depends on WDT diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 01b8231f2b..cbb6d8407c 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -19,6 +19,7 @@ obj-$(CONFIG_$(SPL_TPL_)WDT) += wdt-uclass.o obj-$(CONFIG_WDT_SANDBOX) += sandbox_wdt.o obj-$(CONFIG_WDT_ARMADA_37XX) += armada-37xx-wdt.o obj-$(CONFIG_WDT_ASPEED) += ast_wdt.o +obj-$(CONFIG_WDT_AST2600) += ast2600_wdt.o obj-$(CONFIG_WDT_BCM6345) += bcm6345_wdt.o obj-$(CONFIG_WDT_CORTINA) += cortina_wdt.o obj-$(CONFIG_WDT_ORION) += orion_wdt.o diff --git a/drivers/watchdog/ast2600_wdt.c b/drivers/watchdog/ast2600_wdt.c new file mode 100644 index 0000000000..bc9842089b --- /dev/null +++ b/drivers/watchdog/ast2600_wdt.c @@ -0,0 +1,110 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2020 Aspeed Technology, Inc + */ + +#include <common.h> +#include <dm.h> +#include <errno.h> +#include <log.h> +#include <wdt.h> +#include <asm/io.h> +#include <asm/arch/wdt_ast2600.h> +#include <linux/err.h> + +struct ast2600_wdt_priv { + struct ast2600_wdt *regs; +}; + +static int ast2600_wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags) +{ + struct ast2600_wdt_priv *priv = dev_get_priv(dev); + struct ast2600_wdt *wdt = priv->regs; + + /* WDT counts in the 1MHz frequency, namely 1us */ + writel((u32)(timeout_ms * 1000), &wdt->counter_reload_val); + writel(WDT_COUNTER_RESTART_VAL, &wdt->counter_restart); + writel(WDT_CTRL_EN | WDT_CTRL_RESET, &wdt->ctrl); + + return 0; +} + +static int ast2600_wdt_stop(struct udevice *dev) +{ + struct ast2600_wdt_priv *priv = dev_get_priv(dev); + struct ast2600_wdt *wdt = priv->regs; + + clrbits_le32(&wdt->ctrl, WDT_CTRL_EN); + + writel(WDT_RESET_MASK1_DEFAULT, &wdt->reset_mask1); + writel(WDT_RESET_MASK2_DEFAULT, &wdt->reset_mask2); + + return 0; +} + +static int ast2600_wdt_reset(struct udevice *dev) +{ + struct ast2600_wdt_priv *priv = dev_get_priv(dev); + struct ast2600_wdt *wdt = priv->regs; + + writel(WDT_COUNTER_RESTART_VAL, &wdt->counter_restart); + + return 0; +} + +static int ast2600_wdt_expire_now(struct udevice *dev, ulong flags) +{ + int ret; + struct ast2600_wdt_priv *priv = dev_get_priv(dev); + struct ast2600_wdt *wdt = priv->regs; + + ret = ast2600_wdt_start(dev, 1, flags); + if (ret) + return ret; + + while (readl(&wdt->ctrl) & WDT_CTRL_EN) + ; + + return ast2600_wdt_stop(dev); +} + +static int ast2600_wdt_of_to_plat(struct udevice *dev) +{ + struct ast2600_wdt_priv *priv = dev_get_priv(dev); + + priv->regs = dev_read_addr_ptr(dev); + if (!priv->regs) + return -EINVAL; + + return 0; +} + +static const struct wdt_ops ast2600_wdt_ops = { + .start = ast2600_wdt_start, + .reset = ast2600_wdt_reset, + .stop = ast2600_wdt_stop, + .expire_now = ast2600_wdt_expire_now, +}; + +static const struct udevice_id ast2600_wdt_ids[] = { + { .compatible = "aspeed,ast2600-wdt" }, + { } +}; + +static int ast2600_wdt_probe(struct udevice *dev) +{ + debug("%s() wdt%u\n", __func__, dev_seq(dev)); + ast2600_wdt_stop(dev); + + return 0; +} + +U_BOOT_DRIVER(ast2600_wdt) = { + .name = "ast2600_wdt", + .id = UCLASS_WDT, + .of_match = ast2600_wdt_ids, + .probe = ast2600_wdt_probe, + .priv_auto = sizeof(struct ast2600_wdt_priv), + .of_to_plat = ast2600_wdt_of_to_plat, + .ops = &ast2600_wdt_ops, +}; diff --git a/drivers/watchdog/stm32mp_wdt.c b/drivers/watchdog/stm32mp_wdt.c index 53586fdbfc..4be616c1b6 100644 --- a/drivers/watchdog/stm32mp_wdt.c +++ b/drivers/watchdog/stm32mp_wdt.c @@ -3,6 +3,8 @@ * Copyright (C) 2019, STMicroelectronics - All Rights Reserved */ +#define LOG_CATEGORY UCLASS_WDT + #include <common.h> #include <clk.h> #include <dm.h> @@ -10,6 +12,7 @@ #include <syscon.h> #include <wdt.h> #include <asm/io.h> +#include <dm/device_compat.h> #include <linux/bitops.h> #include <linux/iopoll.h> @@ -77,7 +80,7 @@ static int stm32mp_wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags) val & (SR_PVU | SR_RVU), CONFIG_SYS_HZ); if (ret < 0) { - pr_err("Updating IWDG registers timeout"); + dev_err(dev, "Updating IWDG registers timeout"); return -ETIMEDOUT; } @@ -90,7 +93,7 @@ static int stm32mp_wdt_probe(struct udevice *dev) struct clk clk; int ret; - debug("IWDG init\n"); + dev_dbg(dev, "IWDG init\n"); priv->base = dev_read_addr(dev); if (priv->base == FDT_ADDR_T_NONE) @@ -112,7 +115,7 @@ static int stm32mp_wdt_probe(struct udevice *dev) priv->wdt_clk_rate = clk_get_rate(&clk); - debug("IWDG init done\n"); + dev_dbg(dev, "IWDG init done\n"); return 0; } diff --git a/drivers/xen/hypervisor.c b/drivers/xen/hypervisor.c index 178c206f5b..2560894832 100644 --- a/drivers/xen/hypervisor.c +++ b/drivers/xen/hypervisor.c @@ -232,7 +232,7 @@ void clear_evtchn(uint32_t port) synch_clear_bit(port, &s->evtchn_pending[0]); } -void xen_init(void) +int xen_init(void) { debug("%s\n", __func__); @@ -240,6 +240,8 @@ void xen_init(void) init_events(); init_xenbus(); init_gnttab(); + + return 0; } void xen_fini(void) diff --git a/dts/Makefile b/dts/Makefile index 94967cf656..cb31113829 100644 --- a/dts/Makefile +++ b/dts/Makefile @@ -33,7 +33,7 @@ targets += dt.dtb $(DTB): arch-dtbs $(Q)test -e $@ || ( \ echo >&2; \ - echo >&2 "Device Tree Source is not correctly specified."; \ + echo >&2 "Device Tree Source ($@) is not correctly specified."; \ echo >&2 "Please define 'CONFIG_DEFAULT_DEVICE_TREE'"; \ echo >&2 "or build with 'DEVICE_TREE=<device_tree>' argument"; \ echo >&2; \ diff --git a/env/Kconfig b/env/Kconfig index 67ce93061b..b473d7cfe1 100644 --- a/env/Kconfig +++ b/env/Kconfig @@ -411,13 +411,14 @@ config ENV_IS_IN_UBI config SYS_REDUNDAND_ENVIRONMENT bool "Enable redundant environment support" - depends on ENV_IS_IN_EEPROM || ENV_IS_IN_FLASH || ENV_IS_IN_MMC || \ - ENV_IS_IN_NAND || ENV_IS_IN_SPI_FLASH || ENV_IS_IN_UBI help Normally, the environemt is stored in a single location. By selecting this option, you can then define where to hold a redundant copy of the environment data, so that there is a valid backup copy in case there is a power failure during a "saveenv" operation. + Also this config changes the binary environment structure handling + which is used by env import/export commands which are independent of + storing variables to redundant location on a non volatile device. config ENV_FAT_INTERFACE string "Name of the block device for the environment" diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 01e7cee520..b332ecb796 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -1030,7 +1030,6 @@ out: int close_ctree_fs_info(struct btrfs_fs_info *fs_info) { int ret; - int err = 0; free_fs_roots_tree(&fs_info->fs_root_tree); @@ -1038,9 +1037,7 @@ int close_ctree_fs_info(struct btrfs_fs_info *fs_info) ret = btrfs_close_devices(fs_info->fs_devices); btrfs_cleanup_all_caches(fs_info); btrfs_free_fs_info(fs_info); - if (!err) - err = ret; - return err; + return ret; } int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid) diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index fcf52d4b0f..4aaaeab663 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -1030,7 +1030,7 @@ again: */ stripe_nr = stripe_nr / map->stripe_len; - stripe_offset = stripe_nr * map->stripe_len; + stripe_offset = stripe_nr * (u64)map->stripe_len; BUG_ON(offset < stripe_offset); /* stripe_offset is the offset of this block in its stripe*/ @@ -1103,7 +1103,7 @@ again: rot = stripe_nr % map->num_stripes; /* Fill in the logical address of each stripe */ - tmp = stripe_nr * nr_data_stripes(map); + tmp = (u64)stripe_nr * nr_data_stripes(map); for (i = 0; i < nr_data_stripes(map); i++) raid_map[(i+rot) % map->num_stripes] = @@ -752,7 +752,8 @@ int do_load(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[], if (IS_ENABLED(CONFIG_CMD_BOOTEFI)) efi_set_bootdev(argv[1], (argc > 2) ? argv[2] : "", - (argc > 4) ? argv[4] : ""); + (argc > 4) ? argv[4] : "", map_sysmem(addr, 0), + len_read); printf("%llu bytes read in %lu ms", len_read, time); if (time > 0) { diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c index 5de69ac3ca..dca13bd1f1 100644 --- a/fs/squashfs/sqfs.c +++ b/fs/squashfs/sqfs.c @@ -1310,7 +1310,7 @@ int sqfs_read(const char *filename, void *buf, loff_t offset, loff_t len, { char *dir = NULL, *fragment_block, *datablock = NULL, *data_buffer = NULL; char *fragment = NULL, *file = NULL, *resolved, *data; - u64 start, n_blks, table_size, data_offset, table_offset; + u64 start, n_blks, table_size, data_offset, table_offset, sparse_size; int ret, j, i_number, datablk_count = 0; struct squashfs_super_block *sblk = ctxt.sblk; struct squashfs_fragment_block_entry frag_entry; @@ -1444,28 +1444,43 @@ int sqfs_read(const char *filename, void *buf, loff_t offset, loff_t len, n_blks = DIV_ROUND_UP(table_size + table_offset, ctxt.cur_dev->blksz); - data_buffer = malloc_cache_aligned(n_blks * ctxt.cur_dev->blksz); + /* Don't load any data for sparse blocks */ + if (finfo.blk_sizes[j] == 0) { + n_blks = 0; + table_offset = 0; + data_buffer = NULL; + data = NULL; + } else { + data_buffer = malloc_cache_aligned(n_blks * ctxt.cur_dev->blksz); - if (!data_buffer) { - ret = -ENOMEM; - goto out; - } + if (!data_buffer) { + ret = -ENOMEM; + goto out; + } - ret = sqfs_disk_read(start, n_blks, data_buffer); - if (ret < 0) { - /* - * Possible causes: too many data blocks or too large - * SquashFS block size. Tip: re-compile the SquashFS - * image with mksquashfs's -b <block_size> option. - */ - printf("Error: too many data blocks to be read.\n"); - goto out; - } + ret = sqfs_disk_read(start, n_blks, data_buffer); + if (ret < 0) { + /* + * Possible causes: too many data blocks or too large + * SquashFS block size. Tip: re-compile the SquashFS + * image with mksquashfs's -b <block_size> option. + */ + printf("Error: too many data blocks to be read.\n"); + goto out; + } - data = data_buffer + table_offset; + data = data_buffer + table_offset; + } /* Load the data */ - if (SQFS_COMPRESSED_BLOCK(finfo.blk_sizes[j])) { + if (finfo.blk_sizes[j] == 0) { + /* This is a sparse block */ + sparse_size = get_unaligned_le32(&sblk->block_size); + if ((*actread + sparse_size) > len) + sparse_size = len - *actread; + memset(buf + *actread, 0, sparse_size); + *actread += sparse_size; + } else if (SQFS_COMPRESSED_BLOCK(finfo.blk_sizes[j])) { dest_len = get_unaligned_le32(&sblk->block_size); ret = sqfs_decompress(&ctxt, datablock, &dest_len, data, table_size); @@ -1484,7 +1499,8 @@ int sqfs_read(const char *filename, void *buf, loff_t offset, loff_t len, } data_offset += table_size; - free(data_buffer); + if (data_buffer) + free(data_buffer); data_buffer = NULL; if (*actread >= len) break; diff --git a/fs/ubifs/io.c b/fs/ubifs/io.c index eb14b89544..9962cbe7eb 100644 --- a/fs/ubifs/io.c +++ b/fs/ubifs/io.c @@ -114,7 +114,7 @@ int ubifs_leb_read(const struct ubifs_info *c, int lnum, void *buf, int offs, int ubifs_leb_write(struct ubifs_info *c, int lnum, const void *buf, int offs, int len) { - int err; + int err = 0; ubifs_assert(!c->ro_media && !c->ro_mount); if (c->ro_error) @@ -136,7 +136,7 @@ int ubifs_leb_write(struct ubifs_info *c, int lnum, const void *buf, int offs, int ubifs_leb_change(struct ubifs_info *c, int lnum, const void *buf, int len) { - int err; + int err = 0; ubifs_assert(!c->ro_media && !c->ro_mount); if (c->ro_error) @@ -158,7 +158,7 @@ int ubifs_leb_change(struct ubifs_info *c, int lnum, const void *buf, int len) int ubifs_leb_unmap(struct ubifs_info *c, int lnum) { - int err; + int err = 0; ubifs_assert(!c->ro_media && !c->ro_mount); if (c->ro_error) @@ -179,7 +179,7 @@ int ubifs_leb_unmap(struct ubifs_info *c, int lnum) int ubifs_leb_map(struct ubifs_info *c, int lnum) { - int err; + int err = 0; ubifs_assert(!c->ro_media && !c->ro_mount); if (c->ro_error) diff --git a/include/api.h b/include/api.h index 84d81dc817..83412a7c87 100644 --- a/include/api.h +++ b/include/api.h @@ -7,6 +7,14 @@ #ifndef __API_H #define __API_H -void api_init(void); +/** + * api_init() - Initialize API for external applications + * + * Initialize API for external (standalone) applications running on top of + * U-Boot. It is called during the generic post-relocation init sequence. + * + * Return: 0 if OK + */ +int api_init(void); #endif diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h index efa09a1943..19f70393b4 100644 --- a/include/asm-generic/global_data.h +++ b/include/asm-generic/global_data.h @@ -412,12 +412,12 @@ struct global_data { * @new_bloblist: relocated blob list information */ struct bloblist_hdr *new_bloblist; -# ifdef CONFIG_SPL +#endif +#if CONFIG_IS_ENABLED(HANDOFF) /** * @spl_handoff: SPL hand-off information */ struct spl_handoff *spl_handoff; -# endif #endif #if defined(CONFIG_TRANSLATION_OFFSET) /** diff --git a/include/config_distro_bootcmd.h b/include/config_distro_bootcmd.h index c9862260a3..2627c2a6a5 100644 --- a/include/config_distro_bootcmd.h +++ b/include/config_distro_bootcmd.h @@ -123,14 +123,20 @@ #endif #endif - -#define BOOTENV_SHARED_EFI \ +#ifdef CONFIG_CMD_BOOTEFI_BOOTMGR +#define BOOTENV_EFI_BOOTMGR \ "boot_efi_bootmgr=" \ "if fdt addr ${fdt_addr_r}; then " \ "bootefi bootmgr ${fdt_addr_r};" \ "else " \ "bootefi bootmgr;" \ - "fi\0" \ + "fi\0" +#else +#define BOOTENV_EFI_BOOTMGR +#endif + +#define BOOTENV_SHARED_EFI \ + BOOTENV_EFI_BOOTMGR \ \ "boot_efi_binary=" \ "load ${devtype} ${devnum}:${distro_bootpart} " \ diff --git a/include/configs/ax25-ae350.h b/include/configs/ax25-ae350.h index b2606e794d..bd9c371f83 100644 --- a/include/configs/ax25-ae350.h +++ b/include/configs/ax25-ae350.h @@ -17,6 +17,11 @@ #endif #endif +#define RISCV_MMODE_TIMERBASE 0xe6000000 +#define RISCV_MMODE_TIMER_FREQ 60000000 + +#define RISCV_SMODE_TIMER_FREQ 60000000 + /* * CPU and Board Configuration Options */ diff --git a/include/configs/evb_ast2600.h b/include/configs/evb_ast2600.h new file mode 100644 index 0000000000..e7975bf66d --- /dev/null +++ b/include/configs/evb_ast2600.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) Aspeed Technology Inc. + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#include <configs/aspeed-common.h> + +#define CONFIG_SYS_UBOOT_BASE CONFIG_SYS_TEXT_BASE + +/* Memory Info */ +#define CONFIG_SYS_LOAD_ADDR 0x83000000 + +#endif /* __CONFIG_H */ diff --git a/include/configs/microchip_mpfs_icicle.h b/include/configs/microchip_mpfs_icicle.h index 8a7470545b..24990370cf 100644 --- a/include/configs/microchip_mpfs_icicle.h +++ b/include/configs/microchip_mpfs_icicle.h @@ -7,53 +7,34 @@ #ifndef __CONFIG_H #define __CONFIG_H -/* - * CPU and Board Configuration Options - */ +#include <linux/sizes.h> -/* - * Miscellaneous configurable options - */ -#define CONFIG_SYS_CBSIZE 1024 /* Console I/O Buffer Size */ +#define CONFIG_SYS_SDRAM_BASE 0x80000000 +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + SZ_2M) -/* - * Print Buffer Size - */ -#define CONFIG_SYS_PBSIZE \ - (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16) +#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + SZ_2M) -/* - * max number of command args - */ -#define CONFIG_SYS_MAXARGS 16 +#define CONFIG_SYS_MALLOC_LEN SZ_8M -/* - * Boot Argument Buffer Size - */ -#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE - -/* - * Size of malloc() pool - * 512kB is suggested, (CONFIG_ENV_SIZE + 128 * 1024) was not enough - */ -#define CONFIG_SYS_MALLOC_LEN (512 << 10) +#define CONFIG_SYS_BOOTM_LEN SZ_64M -/* - * Physical Memory Map - */ -#define PHYS_SDRAM_0 0x80000000 /* SDRAM Bank #1 */ -#define PHYS_SDRAM_0_SIZE 0x40000000 /* 1 GB */ -#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_0 +#define CONFIG_STANDALONE_LOAD_ADDR 0x80200000 -/* Init Stack Pointer */ -#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + 0x200000) +/* Environment options */ -#define CONFIG_SYS_LOAD_ADDR 0x80000000 /* SDRAM */ +#define BOOT_TARGET_DEVICES(func) \ + func(MMC, mmc, 0) \ + func(DHCP, dhcp, na) -/* - * memtest works on DRAM - */ +#include <config_distro_bootcmd.h> -/* When we use RAM as ENV */ +#define CONFIG_EXTRA_ENV_SETTINGS \ + "bootm_size=0x10000000\0" \ + "kernel_addr_r=0x84000000\0" \ + "fdt_addr_r=0x88000000\0" \ + "scriptaddr=0x88100000\0" \ + "pxefile_addr_r=0x88200000\0" \ + "ramdisk_addr_r=0x88300000\0" \ + BOOTENV #endif /* __CONFIG_H */ diff --git a/include/configs/presidio_asic.h b/include/configs/presidio_asic.h index 34235b5a00..710731efd5 100644 --- a/include/configs/presidio_asic.h +++ b/include/configs/presidio_asic.h @@ -67,4 +67,13 @@ #define CONFIG_SYS_MAXARGS 64 #define CONFIG_EXTRA_ENV_SETTINGS "silent=y\0" +/* nand driver parameters */ +#ifdef CONFIG_TARGET_PRESIDIO_ASIC + #define CONFIG_SYS_NAND_ONFI_DETECTION + #define CONFIG_SYS_MAX_NAND_DEVICE 1 + #define CONFIG_SYS_NAND_MAX_CHIPS 1 + #define CONFIG_SYS_NAND_BASE CONFIG_SYS_FLASH_BASE + #define CONFIG_SYS_NAND_BASE_LIST { CONFIG_SYS_NAND_BASE } +#endif + #endif /* __PRESIDIO_ASIC_H */ diff --git a/include/configs/qemu-riscv.h b/include/configs/qemu-riscv.h index a2f33587c2..5291de83f8 100644 --- a/include/configs/qemu-riscv.h +++ b/include/configs/qemu-riscv.h @@ -29,6 +29,11 @@ #define CONFIG_STANDALONE_LOAD_ADDR 0x80200000 +#define RISCV_MMODE_TIMERBASE 0x2000000 +#define RISCV_MMODE_TIMER_FREQ 1000000 + +#define RISCV_SMODE_TIMER_FREQ 1000000 + /* Environment options */ #ifndef CONFIG_SPL_BUILD diff --git a/include/configs/sifive-fu540.h b/include/configs/sifive-fu540.h index c1c79db147..0d69d1c548 100644 --- a/include/configs/sifive-fu540.h +++ b/include/configs/sifive-fu540.h @@ -36,6 +36,11 @@ #define CONFIG_STANDALONE_LOAD_ADDR 0x80200000 +#define RISCV_MMODE_TIMERBASE 0x2000000 +#define RISCV_MMODE_TIMER_FREQ 1000000 + +#define RISCV_SMODE_TIMER_FREQ 1000000 + /* Environment options */ #ifndef CONFIG_SPL_BUILD diff --git a/include/configs/sipeed-maix.h b/include/configs/sipeed-maix.h index 36ff522e4b..08acb25075 100644 --- a/include/configs/sipeed-maix.h +++ b/include/configs/sipeed-maix.h @@ -24,10 +24,13 @@ #ifndef CONFIG_EXTRA_ENV_SETTINGS #define CONFIG_EXTRA_ENV_SETTINGS \ "loadaddr=0x80060000\0" \ - "fdt_addr_r=0x80028000\0" \ + "fdt_addr_r=0x80400000\0" \ "scriptaddr=0x80020000\0" \ "kernel_addr_r=0x80060000\0" \ - "fdtfile=kendryte/" CONFIG_DEFAULT_DEVICE_TREE ".dtb\0" + "fdtfile=kendryte/" CONFIG_DEFAULT_DEVICE_TREE ".dtb\0" \ + "k210_bootcmd=load mmc 0:1 $loadaddr /uImage && " \ + "load mmc 0:1 $fdt_addr_r /k210.dtb && " \ + "bootm $loadaddr - $fdt_addr_r\0" #endif #endif /* CONFIGS_SIPEED_MAIX_H */ diff --git a/include/configs/socfpga_common.h b/include/configs/socfpga_common.h index 3d71759da4..62b327cd6e 100644 --- a/include/configs/socfpga_common.h +++ b/include/configs/socfpga_common.h @@ -22,8 +22,10 @@ #if defined(CONFIG_TARGET_SOCFPGA_GEN5) #define CONFIG_SYS_INIT_RAM_ADDR 0xFFFF0000 #define CONFIG_SYS_INIT_RAM_SIZE SOCFPGA_PHYS_OCRAM_SIZE +#define CONFIG_SPL_PAD_TO 0x10000 #elif defined(CONFIG_TARGET_SOCFPGA_ARRIA10) #define CONFIG_SYS_INIT_RAM_ADDR 0xFFE00000 +#define CONFIG_SPL_PAD_TO 0x40000 /* SPL memory allocation configuration, this is for FAT implementation */ #ifndef CONFIG_SYS_SPL_MALLOC_SIZE #define CONFIG_SYS_SPL_MALLOC_SIZE 0x10000 diff --git a/include/configs/socfpga_soc64_common.h b/include/configs/socfpga_soc64_common.h index fb5e2e8aaf..fdcd7d3e9a 100644 --- a/include/configs/socfpga_soc64_common.h +++ b/include/configs/socfpga_soc64_common.h @@ -40,9 +40,14 @@ */ #define CONFIG_SYS_INIT_RAM_ADDR 0xFFE00000 #define CONFIG_SYS_INIT_RAM_SIZE 0x40000 +#ifdef CONFIG_SPL_BUILD #define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_INIT_RAM_ADDR \ + CONFIG_SYS_INIT_RAM_SIZE \ - S10_HANDOFF_SIZE) +#else +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_TEXT_BASE \ + + 0x100000) +#endif #define CONFIG_SYS_INIT_SP_OFFSET (CONFIG_SYS_INIT_SP_ADDR) #define CONFIG_SYS_MALLOC_LEN (5 * 1024 * 1024) @@ -78,12 +83,20 @@ unsigned int cm_get_qspi_controller_clk_hz(void); * CONFIG_BOOTARGS goes into the environment value "bootargs". * Do note the value will override also the chosen node in FDT blob. */ + +#ifdef CONFIG_FIT +#define CONFIG_BOOTFILE "kernel.itb" +#define CONFIG_BOOTCOMMAND "run fatscript; run mmcfitload;run linux_qspi_enable;" \ + "run mmcfitboot" +#else +#define CONFIG_BOOTFILE "Image" #define CONFIG_BOOTCOMMAND "run fatscript; run mmcload;run linux_qspi_enable;" \ "run mmcboot" +#endif #define CONFIG_EXTRA_ENV_SETTINGS \ "loadaddr=" __stringify(CONFIG_SYS_LOAD_ADDR) "\0" \ - "bootfile=Image\0" \ + "bootfile=" CONFIG_BOOTFILE "\0" \ "fdt_addr=8000000\0" \ "fdtimage=" CONFIG_DEFAULT_DEVICE_TREE ".dtb\0" \ "mmcroot=/dev/mmcblk0p2\0" \ @@ -93,6 +106,11 @@ unsigned int cm_get_qspi_controller_clk_hz(void); "mmcload=mmc rescan;" \ "load mmc 0:1 ${loadaddr} ${bootfile};" \ "load mmc 0:1 ${fdt_addr} ${fdtimage}\0" \ + "mmcfitboot=setenv bootargs " CONFIG_BOOTARGS \ + " root=${mmcroot} rw rootwait;" \ + "bootm ${loadaddr}\0" \ + "mmcfitload=mmc rescan;" \ + "load mmc 0:1 ${loadaddr} ${bootfile}\0" \ "linux_qspi_enable=if sf probe; then " \ "echo Enabling QSPI at Linux DTB...;" \ "fdt addr ${fdt_addr}; fdt resize;" \ @@ -193,6 +211,10 @@ unsigned int cm_get_l4_sys_free_clk_hz(void); - CONFIG_SYS_SPL_MALLOC_SIZE) /* SPL SDMMC boot support */ +#ifdef CONFIG_SPL_LOAD_FIT +#define CONFIG_SPL_FS_LOAD_PAYLOAD_NAME "u-boot.itb" +#else #define CONFIG_SPL_FS_LOAD_PAYLOAD_NAME "u-boot.img" +#endif #endif /* __CONFIG_SOCFPGA_SOC64_COMMON_H__ */ diff --git a/include/configs/stm32mp1.h b/include/configs/stm32mp1.h index 1aa7514ac7..863b652ca4 100644 --- a/include/configs/stm32mp1.h +++ b/include/configs/stm32mp1.h @@ -69,7 +69,6 @@ /* Ethernet need */ #ifdef CONFIG_DWC_ETH_QOS -#define CONFIG_SYS_NONCACHED_MEMORY (1 * SZ_1M) /* 1M */ #define CONFIG_SERVERIP 192.168.1.1 #define CONFIG_BOOTP_SERVERIP #define CONFIG_SYS_AUTOLOAD "no" diff --git a/include/console.h b/include/console.h index 432f892b6c..7e628c0cf8 100644 --- a/include/console.h +++ b/include/console.h @@ -8,6 +8,7 @@ #define __CONSOLE_H #include <stdbool.h> +#include <stdio_dev.h> #include <linux/errno.h> extern char console_buffer[]; @@ -15,6 +16,8 @@ extern char console_buffer[]; /* common/console.c */ int console_init_f(void); /* Before relocation; uses the serial stuff */ int console_init_r(void); /* After relocation; uses the console stuff */ +int console_start(int file, struct stdio_dev *sdev); /* Start a console device */ +void console_stop(int file, struct stdio_dev *sdev); /* Stop a console device */ int console_assign(int file, const char *devname); /* Assign the console */ int ctrlc(void); int had_ctrlc(void); /* have we had a Control-C since last clear? */ @@ -22,6 +25,18 @@ void clear_ctrlc(void); /* clear the Control-C condition */ int disable_ctrlc(int); /* 1 to disable, 0 to enable Control-C detect */ int confirm_yesno(void); /* 1 if input is "y", "Y", "yes" or "YES" */ +/** + * console_search_dev() - search for stdio device with given flags and name + * @flags: device flags as per input/output/system + * @name: device name + * + * Iterates over registered STDIO devices and match them with given @flags + * and @name. + * + * @return pointer to the &struct stdio_dev if found, or NULL otherwise + */ +struct stdio_dev *console_search_dev(int flags, const char *name); + #ifdef CONFIG_CONSOLE_RECORD /** * console_record_init() - set up the console recording buffers diff --git a/include/dm/uclass.h b/include/dm/uclass.h index b5f066dbf4..d95683740c 100644 --- a/include/dm/uclass.h +++ b/include/dm/uclass.h @@ -377,6 +377,17 @@ int uclass_first_device_drvdata(enum uclass_id id, ulong driver_data, struct udevice **devp); /** + * uclass_probe_all() - Probe all devices based on an uclass ID + * + * This function probes all devices associated with a uclass by + * looking for its ID. + * + * @id: uclass ID to look up + * @return 0 if OK, other -ve on error + */ +int uclass_probe_all(enum uclass_id id); + +/** * uclass_id_foreach_dev() - Helper function to iteration through devices * * This creates a for() loop which works through the available devices in diff --git a/include/dt-bindings/clock/ast2600-clock.h b/include/dt-bindings/clock/ast2600-clock.h new file mode 100644 index 0000000000..36294a5140 --- /dev/null +++ b/include/dt-bindings/clock/ast2600-clock.h @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) ASPEED Technology Inc. + */ + +#define ASPEED_CLK_GATE_ECLK 0 +#define ASPEED_CLK_GATE_GCLK 1 +#define ASPEED_CLK_GATE_MCLK 2 +#define ASPEED_CLK_GATE_VCLK 3 +#define ASPEED_CLK_GATE_BCLK 4 +#define ASPEED_CLK_GATE_DCLK 5 +#define ASPEED_CLK_GATE_LCLK 6 +#define ASPEED_CLK_GATE_YCLK 7 +#define ASPEED_CLK_GATE_LHCCLK 8 +#define ASPEED_CLK_GATE_REFCLK 9 +#define ASPEED_CLK_GATE_ESPICLK 10 +#define ASPEED_CLK_GATE_UART1CLK 11 +#define ASPEED_CLK_GATE_UART2CLK 12 +#define ASPEED_CLK_GATE_UART3CLK 13 +#define ASPEED_CLK_GATE_UART4CLK 14 +#define ASPEED_CLK_GATE_UART5CLK 15 +#define ASPEED_CLK_GATE_UART6CLK 16 +#define ASPEED_CLK_GATE_UART7CLK 17 +#define ASPEED_CLK_GATE_UART8CLK 18 +#define ASPEED_CLK_GATE_UART9CLK 19 +#define ASPEED_CLK_GATE_UART10CLK 20 +#define ASPEED_CLK_GATE_UART11CLK 21 +#define ASPEED_CLK_GATE_UART12CLK 22 +#define ASPEED_CLK_GATE_UART13CLK 23 +#define ASPEED_CLK_GATE_MAC1CLK 24 +#define ASPEED_CLK_GATE_MAC2CLK 25 +#define ASPEED_CLK_GATE_MAC3CLK 26 +#define ASPEED_CLK_GATE_MAC4CLK 27 +#define ASPEED_CLK_GATE_RSACLK 28 +#define ASPEED_CLK_GATE_SDCLK 29 +#define ASPEED_CLK_GATE_SDEXTCLK 30 +#define ASPEED_CLK_GATE_EMMCCLK 31 +#define ASPEED_CLK_GATE_EMMCEXTCLK 32 +#define ASPEED_CLK_GATE_USBUHCICLK 33 +#define ASPEED_CLK_GATE_USBPORT1CLK 34 +#define ASPEED_CLK_GATE_USBPORT2CLK 35 +#define ASPEED_CLK_GATE_FSICLK 36 + +#define ASPEED_CLK_APLL 37 +#define ASPEED_CLK_EPLL 38 +#define ASPEED_CLK_DPLL 39 +#define ASPEED_CLK_HPLL 40 +#define ASPEED_CLK_AHB 41 +#define ASPEED_CLK_APB1 42 +#define ASPEED_CLK_APB2 43 +#define ASPEED_CLK_UART 44 +#define ASPEED_CLK_SDIO 45 +#define ASPEED_CLK_ECLK 46 +#define ASPEED_CLK_ECLK_MUX 47 +#define ASPEED_CLK_LHCLK 48 +#define ASPEED_CLK_MAC 49 +#define ASPEED_CLK_BCLK 50 +#define ASPEED_CLK_MPLL 51 +#define ASPEED_CLK_24M 52 +#define ASPEED_CLK_EMMC 53 +#define ASPEED_CLK_UARTX 54 +#define ASPEED_CLK_HUARTX 55 diff --git a/include/dt-bindings/clock/microchip-mpfs-clock.h b/include/dt-bindings/clock/microchip-mpfs-clock.h new file mode 100644 index 0000000000..55fe64693f --- /dev/null +++ b/include/dt-bindings/clock/microchip-mpfs-clock.h @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */ +/* + * Copyright (C) 2020 Microchip Technology Inc. + * Padmarao Begari <padmarao.begari@microchip.com> + */ + +#ifndef _DT_BINDINGS_CLK_MICROCHIP_MPFS_H_ +#define _DT_BINDINGS_CLK_MICROCHIP_MPFS_H_ + +#define CLK_CPU 0 +#define CLK_AXI 1 +#define CLK_AHB 2 + +#define CLK_ENVM 3 +#define CLK_MAC0 4 +#define CLK_MAC1 5 +#define CLK_MMC 6 +#define CLK_TIMER 7 +#define CLK_MMUART0 8 +#define CLK_MMUART1 9 +#define CLK_MMUART2 10 +#define CLK_MMUART3 11 +#define CLK_MMUART4 12 +#define CLK_SPI0 13 +#define CLK_SPI1 14 +#define CLK_I2C0 15 +#define CLK_I2C1 16 +#define CLK_CAN0 17 +#define CLK_CAN1 18 +#define CLK_USB 19 +#define CLK_RESERVED 20 +#define CLK_RTC 21 +#define CLK_QSPI 22 +#define CLK_GPIO0 23 +#define CLK_GPIO1 24 +#define CLK_GPIO2 25 +#define CLK_DDRC 26 +#define CLK_FIC0 27 +#define CLK_FIC1 28 +#define CLK_FIC2 29 +#define CLK_FIC3 30 +#define CLK_ATHENA 31 +#define CLK_CFM 32 + +#endif /* _DT_BINDINGS_CLK_MICROCHIP_MPFS_H_ */ diff --git a/include/dt-bindings/clock/mt8183-clk.h b/include/dt-bindings/clock/mt8183-clk.h new file mode 100644 index 0000000000..f7e6367ce8 --- /dev/null +++ b/include/dt-bindings/clock/mt8183-clk.h @@ -0,0 +1,329 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 MediaTek Inc. + * Author: Weiyi Lu <weiyi.lu@mediatek.com> + */ + +#ifndef _DT_BINDINGS_CLK_MT8183_H +#define _DT_BINDINGS_CLK_MT8183_H + +/* APMIXED */ +#define CLK_APMIXED_ARMPLL_LL 0 +#define CLK_APMIXED_ARMPLL_L 1 +#define CLK_APMIXED_CCIPLL 2 +#define CLK_APMIXED_MAINPLL 3 +#define CLK_APMIXED_UNIV2PLL 4 +#define CLK_APMIXED_MSDCPLL 5 +#define CLK_APMIXED_MMPLL 6 +#define CLK_APMIXED_MFGPLL 7 +#define CLK_APMIXED_TVDPLL 8 +#define CLK_APMIXED_APLL1 9 +#define CLK_APMIXED_APLL2 10 +#define CLK_APMIXED_SSUSB_26M 11 +#define CLK_APMIXED_APPLL_26M 12 +#define CLK_APMIXED_MIPIC0_26M 13 +#define CLK_APMIXED_MDPLLGP_26M 14 +#define CLK_APMIXED_MMSYS_26M 15 +#define CLK_APMIXED_UFS_26M 16 +#define CLK_APMIXED_MIPIC1_26M 17 +#define CLK_APMIXED_MEMPLL_26M 18 +#define CLK_APMIXED_CLKSQ_LVPLL_26M 19 +#define CLK_APMIXED_MIPID0_26M 20 +#define CLK_APMIXED_MIPID1_26M 21 +#define CLK_APMIXED_NR_CLK 22 + +/* TOPCKGEN */ +#define CLK_TOP_CLK26M 0 +#define CLK_TOP_ULPOSC 1 +#define CLK_TOP_UNIVP_192M 2 +#define CLK_TOP_CLK13M 3 +#define CLK_TOP_F26M_CK_D2 4 +#define CLK_TOP_SYSPLL_CK 5 +#define CLK_TOP_SYSPLL_D2 6 +#define CLK_TOP_SYSPLL_D3 7 +#define CLK_TOP_SYSPLL_D5 8 +#define CLK_TOP_SYSPLL_D7 9 +#define CLK_TOP_SYSPLL_D2_D2 10 +#define CLK_TOP_SYSPLL_D2_D4 11 +#define CLK_TOP_SYSPLL_D2_D8 12 +#define CLK_TOP_SYSPLL_D2_D16 13 +#define CLK_TOP_SYSPLL_D3_D2 14 +#define CLK_TOP_SYSPLL_D3_D4 15 +#define CLK_TOP_SYSPLL_D3_D8 16 +#define CLK_TOP_SYSPLL_D5_D2 17 +#define CLK_TOP_SYSPLL_D5_D4 18 +#define CLK_TOP_SYSPLL_D7_D2 19 +#define CLK_TOP_SYSPLL_D7_D4 20 +#define CLK_TOP_UNIVPLL_CK 21 +#define CLK_TOP_UNIVPLL_D2 22 +#define CLK_TOP_UNIVPLL_D3 23 +#define CLK_TOP_UNIVPLL_D5 24 +#define CLK_TOP_UNIVPLL_D7 25 +#define CLK_TOP_UNIVPLL_D2_D2 26 +#define CLK_TOP_UNIVPLL_D2_D4 27 +#define CLK_TOP_UNIVPLL_D2_D8 28 +#define CLK_TOP_UNIVPLL_D3_D2 29 +#define CLK_TOP_UNIVPLL_D3_D4 30 +#define CLK_TOP_UNIVPLL_D3_D8 31 +#define CLK_TOP_UNIVPLL_D5_D2 32 +#define CLK_TOP_UNIVPLL_D5_D4 33 +#define CLK_TOP_UNIVPLL_D5_D8 34 +#define CLK_TOP_UNIVP_192M_CK 35 +#define CLK_TOP_UNIVP_192M_D2 36 +#define CLK_TOP_UNIVP_192M_D4 37 +#define CLK_TOP_UNIVP_192M_D8 38 +#define CLK_TOP_UNIVP_192M_D16 39 +#define CLK_TOP_UNIVP_192M_D32 40 +#define CLK_TOP_APLL1_CK 41 +#define CLK_TOP_APLL1_D2 42 +#define CLK_TOP_APLL1_D4 43 +#define CLK_TOP_APLL1_D8 44 +#define CLK_TOP_APLL2_CK 45 +#define CLK_TOP_APLL2_D2 46 +#define CLK_TOP_APLL2_D4 47 +#define CLK_TOP_APLL2_D8 48 +#define CLK_TOP_TVDPLL_CK 49 +#define CLK_TOP_TVDPLL_D2 50 +#define CLK_TOP_TVDPLL_D4 51 +#define CLK_TOP_TVDPLL_D8 52 +#define CLK_TOP_TVDPLL_D16 53 +#define CLK_TOP_MMPLL_CK 54 +#define CLK_TOP_MMPLL_D4 55 +#define CLK_TOP_MMPLL_D4_D2 56 +#define CLK_TOP_MMPLL_D4_D4 57 +#define CLK_TOP_MMPLL_D5 58 +#define CLK_TOP_MMPLL_D5_D2 59 +#define CLK_TOP_MMPLL_D5_D4 60 +#define CLK_TOP_MMPLL_D6 61 +#define CLK_TOP_MMPLL_D7 62 +#define CLK_TOP_MFGPLL_CK 63 +#define CLK_TOP_MSDCPLL_CK 64 +#define CLK_TOP_MSDCPLL_D2 65 +#define CLK_TOP_MSDCPLL_D4 66 +#define CLK_TOP_MSDCPLL_D8 67 +#define CLK_TOP_MSDCPLL_D16 68 +#define CLK_TOP_AD_OSC_CK 69 +#define CLK_TOP_OSC_D2 70 +#define CLK_TOP_OSC_D4 71 +#define CLK_TOP_OSC_D8 72 +#define CLK_TOP_OSC_D16 73 +#define CLK_TOP_UNIVPLL 74 +#define CLK_TOP_UNIVPLL_D3_D16 75 +#define CLK_TOP_APLL12_DIV0 76 +#define CLK_TOP_APLL12_DIV1 77 +#define CLK_TOP_APLL12_DIV2 78 +#define CLK_TOP_APLL12_DIV3 79 +#define CLK_TOP_APLL12_DIV4 80 +#define CLK_TOP_APLL12_DIVB 81 +#define CLK_TOP_ARMPLL_DIV_PLL1 82 +#define CLK_TOP_ARMPLL_DIV_PLL2 83 +#define CLK_TOP_MUX_AXI 84 +#define CLK_TOP_MUX_MM 85 +#define CLK_TOP_MUX_IMG 86 +#define CLK_TOP_MUX_CAM 87 +#define CLK_TOP_MUX_DSP 88 +#define CLK_TOP_MUX_DSP1 89 +#define CLK_TOP_MUX_DSP2 90 +#define CLK_TOP_MUX_IPU_IF 91 +#define CLK_TOP_MUX_MFG 92 +#define CLK_TOP_MUX_F52M_MFG 93 +#define CLK_TOP_MUX_CAMTG 94 +#define CLK_TOP_MUX_CAMTG2 95 +#define CLK_TOP_MUX_CAMTG3 96 +#define CLK_TOP_MUX_CAMTG4 97 +#define CLK_TOP_MUX_UART 98 +#define CLK_TOP_MUX_SPI 99 +#define CLK_TOP_MUX_MSDC50_0_HCLK 100 +#define CLK_TOP_MUX_MSDC50_0 101 +#define CLK_TOP_MUX_MSDC30_1 102 +#define CLK_TOP_MUX_MSDC30_2 103 +#define CLK_TOP_MUX_AUDIO 104 +#define CLK_TOP_MUX_AUD_INTBUS 105 +#define CLK_TOP_MUX_PMICSPI 106 +#define CLK_TOP_MUX_FPWRAP_ULPOSC 107 +#define CLK_TOP_MUX_ATB 108 +#define CLK_TOP_MUX_SSPM 109 +#define CLK_TOP_MUX_DPI0 110 +#define CLK_TOP_MUX_SCAM 111 +#define CLK_TOP_MUX_DISP_PWM 112 +#define CLK_TOP_MUX_USB_TOP 113 +#define CLK_TOP_MUX_SSUSB_TOP_XHCI 114 +#define CLK_TOP_MUX_SPM 115 +#define CLK_TOP_MUX_I2C 116 +#define CLK_TOP_MUX_SCP 117 +#define CLK_TOP_MUX_SENINF 118 +#define CLK_TOP_MUX_DXCC 119 +#define CLK_TOP_MUX_AUD_ENG1 120 +#define CLK_TOP_MUX_AUD_ENG2 121 +#define CLK_TOP_MUX_FAES_UFSFDE 122 +#define CLK_TOP_MUX_FUFS 123 +#define CLK_TOP_MUX_AUD_1 124 +#define CLK_TOP_MUX_AUD_2 125 +#define CLK_TOP_MUX_APLL_I2S0 126 +#define CLK_TOP_MUX_APLL_I2S1 127 +#define CLK_TOP_MUX_APLL_I2S2 128 +#define CLK_TOP_MUX_APLL_I2S3 129 +#define CLK_TOP_MUX_APLL_I2S4 130 +#define CLK_TOP_MUX_APLL_I2S5 131 +#define CLK_TOP_NR_CLK 132 + +/* INFRACFG_AO */ +#define CLK_INFRA_PMIC_TMR 0 +#define CLK_INFRA_PMIC_AP 1 +#define CLK_INFRA_PMIC_MD 2 +#define CLK_INFRA_PMIC_CONN 3 +#define CLK_INFRA_SCPSYS 4 +#define CLK_INFRA_SEJ 5 +#define CLK_INFRA_APXGPT 6 +#define CLK_INFRA_ICUSB 7 +#define CLK_INFRA_GCE 8 +#define CLK_INFRA_THERM 9 +#define CLK_INFRA_I2C0 10 +#define CLK_INFRA_I2C1 11 +#define CLK_INFRA_I2C2 12 +#define CLK_INFRA_I2C3 13 +#define CLK_INFRA_PWM_HCLK 14 +#define CLK_INFRA_PWM1 15 +#define CLK_INFRA_PWM2 16 +#define CLK_INFRA_PWM3 17 +#define CLK_INFRA_PWM4 18 +#define CLK_INFRA_PWM 19 +#define CLK_INFRA_UART0 20 +#define CLK_INFRA_UART1 21 +#define CLK_INFRA_UART2 22 +#define CLK_INFRA_UART3 23 +#define CLK_INFRA_GCE_26M 24 +#define CLK_INFRA_CQ_DMA_FPC 25 +#define CLK_INFRA_BTIF 26 +#define CLK_INFRA_SPI0 27 +#define CLK_INFRA_MSDC0 28 +#define CLK_INFRA_MSDC1 29 +#define CLK_INFRA_MSDC2 30 +#define CLK_INFRA_MSDC0_SCK 31 +#define CLK_INFRA_DVFSRC 32 +#define CLK_INFRA_GCPU 33 +#define CLK_INFRA_TRNG 34 +#define CLK_INFRA_AUXADC 35 +#define CLK_INFRA_CPUM 36 +#define CLK_INFRA_CCIF1_AP 37 +#define CLK_INFRA_CCIF1_MD 38 +#define CLK_INFRA_AUXADC_MD 39 +#define CLK_INFRA_MSDC1_SCK 40 +#define CLK_INFRA_MSDC2_SCK 41 +#define CLK_INFRA_AP_DMA 42 +#define CLK_INFRA_XIU 43 +#define CLK_INFRA_DEVICE_APC 44 +#define CLK_INFRA_CCIF_AP 45 +#define CLK_INFRA_DEBUGSYS 46 +#define CLK_INFRA_AUDIO 47 +#define CLK_INFRA_CCIF_MD 48 +#define CLK_INFRA_DXCC_SEC_CORE 49 +#define CLK_INFRA_DXCC_AO 50 +#define CLK_INFRA_DRAMC_F26M 51 +#define CLK_INFRA_IRTX 52 +#define CLK_INFRA_DISP_PWM 53 +#define CLK_INFRA_CLDMA_BCLK 54 +#define CLK_INFRA_AUDIO_26M_BCLK 55 +#define CLK_INFRA_SPI1 56 +#define CLK_INFRA_I2C4 57 +#define CLK_INFRA_MODEM_TEMP_SHARE 58 +#define CLK_INFRA_SPI2 59 +#define CLK_INFRA_SPI3 60 +#define CLK_INFRA_UNIPRO_SCK 61 +#define CLK_INFRA_UNIPRO_TICK 62 +#define CLK_INFRA_UFS_MP_SAP_BCLK 63 +#define CLK_INFRA_MD32_BCLK 64 +#define CLK_INFRA_SSPM 65 +#define CLK_INFRA_UNIPRO_MBIST 66 +#define CLK_INFRA_SSPM_BUS_HCLK 67 +#define CLK_INFRA_I2C5 68 +#define CLK_INFRA_I2C5_ARBITER 69 +#define CLK_INFRA_I2C5_IMM 70 +#define CLK_INFRA_I2C1_ARBITER 71 +#define CLK_INFRA_I2C1_IMM 72 +#define CLK_INFRA_I2C2_ARBITER 73 +#define CLK_INFRA_I2C2_IMM 74 +#define CLK_INFRA_SPI4 75 +#define CLK_INFRA_SPI5 76 +#define CLK_INFRA_CQ_DMA 77 +#define CLK_INFRA_UFS 78 +#define CLK_INFRA_AES_UFSFDE 79 +#define CLK_INFRA_UFS_TICK 80 +#define CLK_INFRA_MSDC0_SELF 81 +#define CLK_INFRA_MSDC1_SELF 82 +#define CLK_INFRA_MSDC2_SELF 83 +#define CLK_INFRA_SSPM_26M_SELF 84 +#define CLK_INFRA_SSPM_32K_SELF 85 +#define CLK_INFRA_UFS_AXI 86 +#define CLK_INFRA_I2C6 87 +#define CLK_INFRA_AP_MSDC0 88 +#define CLK_INFRA_MD_MSDC0 89 +#define CLK_INFRA_USB 90 +#define CLK_INFRA_DEVMPU_BCLK 91 +#define CLK_INFRA_CCIF2_AP 92 +#define CLK_INFRA_CCIF2_MD 93 +#define CLK_INFRA_CCIF3_AP 94 +#define CLK_INFRA_CCIF3_MD 95 +#define CLK_INFRA_SEJ_F13M 96 +#define CLK_INFRA_AES_BCLK 97 +#define CLK_INFRA_I2C7 98 +#define CLK_INFRA_I2C8 99 +#define CLK_INFRA_FBIST2FPC 100 +#define CLK_INFRA_NR_CLK 101 + +/* MMSYS_CONFIG */ +#define CLK_MM_SMI_COMMON 0 +#define CLK_MM_SMI_LARB0 1 +#define CLK_MM_SMI_LARB1 2 +#define CLK_MM_GALS_COMM0 3 +#define CLK_MM_GALS_COMM1 4 +#define CLK_MM_GALS_CCU2MM 5 +#define CLK_MM_GALS_IPU12MM 6 +#define CLK_MM_GALS_IMG2MM 7 +#define CLK_MM_GALS_CAM2MM 8 +#define CLK_MM_GALS_IPU2MM 9 +#define CLK_MM_MDP_DL_TXCK 10 +#define CLK_MM_IPU_DL_TXCK 11 +#define CLK_MM_MDP_RDMA0 12 +#define CLK_MM_MDP_RDMA1 13 +#define CLK_MM_MDP_RSZ0 14 +#define CLK_MM_MDP_RSZ1 15 +#define CLK_MM_MDP_TDSHP 16 +#define CLK_MM_MDP_WROT0 17 +#define CLK_MM_FAKE_ENG 18 +#define CLK_MM_DISP_OVL0 19 +#define CLK_MM_DISP_OVL0_2L 20 +#define CLK_MM_DISP_OVL1_2L 21 +#define CLK_MM_DISP_RDMA0 22 +#define CLK_MM_DISP_RDMA1 23 +#define CLK_MM_DISP_WDMA0 24 +#define CLK_MM_DISP_COLOR0 25 +#define CLK_MM_DISP_CCORR0 26 +#define CLK_MM_DISP_AAL0 27 +#define CLK_MM_DISP_GAMMA0 28 +#define CLK_MM_DISP_DITHER0 29 +#define CLK_MM_DISP_SPLIT 30 +#define CLK_MM_DSI0_MM 31 +#define CLK_MM_DSI0_IF 32 +#define CLK_MM_DPI_MM 33 +#define CLK_MM_DPI_IF 34 +#define CLK_MM_FAKE_ENG2 35 +#define CLK_MM_MDP_DL_RX 36 +#define CLK_MM_IPU_DL_RX 37 +#define CLK_MM_26M 38 +#define CLK_MM_MMSYS_R2Y 39 +#define CLK_MM_DISP_RSZ 40 +#define CLK_MM_MDP_WDMA0 41 +#define CLK_MM_MDP_AAL 42 +#define CLK_MM_MDP_CCORR 43 +#define CLK_MM_DBI_MM 44 +#define CLK_MM_DBI_IF 45 +#define CLK_MM_NR_CLK 46 + +/* MCUCFG */ +#define CLK_MCU_MP0_SEL 0 +#define CLK_MCU_MP2_SEL 1 +#define CLK_MCU_BUS_SEL 2 +#define CLK_MCU_NR_CLK 3 + +#endif /* _DT_BINDINGS_CLK_MT8183_H */ diff --git a/include/dt-bindings/power/meson-axg-power.h b/include/dt-bindings/power/meson-axg-power.h new file mode 100644 index 0000000000..e5243884b2 --- /dev/null +++ b/include/dt-bindings/power/meson-axg-power.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */ +/* + * Copyright (c) 2020 BayLibre, SAS + * Author: Neil Armstrong <narmstrong@baylibre.com> + */ + +#ifndef _DT_BINDINGS_MESON_AXG_POWER_H +#define _DT_BINDINGS_MESON_AXG_POWER_H + +#define PWRC_AXG_VPU_ID 0 +#define PWRC_AXG_ETHERNET_MEM_ID 1 +#define PWRC_AXG_AUDIO_ID 2 + +#endif diff --git a/include/dt-bindings/power/meson-gxbb-power.h b/include/dt-bindings/power/meson-gxbb-power.h new file mode 100644 index 0000000000..1262dac696 --- /dev/null +++ b/include/dt-bindings/power/meson-gxbb-power.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */ +/* + * Copyright (c) 2019 BayLibre, SAS + * Author: Neil Armstrong <narmstrong@baylibre.com> + */ + +#ifndef _DT_BINDINGS_MESON_GXBB_POWER_H +#define _DT_BINDINGS_MESON_GXBB_POWER_H + +#define PWRC_GXBB_VPU_ID 0 +#define PWRC_GXBB_ETHERNET_MEM_ID 1 + +#endif diff --git a/include/dt-bindings/reset/ast2600-reset.h b/include/dt-bindings/reset/ast2600-reset.h new file mode 100644 index 0000000000..b6d0f79917 --- /dev/null +++ b/include/dt-bindings/reset/ast2600-reset.h @@ -0,0 +1,70 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) ASPEED Technology Inc. + */ + +#ifndef _ABI_MACH_ASPEED_AST2600_RESET_H_ +#define _ABI_MACH_ASPEED_AST2600_RESET_H_ + +#define ASPEED_RESET_FSI (59) +#define ASPEED_RESET_RESERVED58 (58) +#define ASPEED_RESET_RESERVED57 (57) +#define ASPEED_RESET_SD (56) +#define ASPEED_RESET_ADC (55) +#define ASPEED_RESET_JTAG_MASTER2 (54) +#define ASPEED_RESET_MAC4 (53) +#define ASPEED_RESET_MAC3 (52) +#define ASPEED_RESET_RESERVE51 (51) +#define ASPEED_RESET_RESERVE50 (50) +#define ASPEED_RESET_RESERVE49 (49) +#define ASPEED_RESET_RESERVE48 (48) +#define ASPEED_RESET_RESERVE47 (47) +#define ASPEED_RESET_RESERVE46 (46) +#define ASPEED_RESET_I3C5 (45) +#define ASPEED_RESET_I3C4 (44) +#define ASPEED_RESET_I3C3 (43) +#define ASPEED_RESET_I3C2 (42) +#define ASPEED_RESET_I3C1 (41) +#define ASPEED_RESET_I3C0 (40) +#define ASPEED_RESET_I3C_DMA (39) +#define ASPEED_RESET_RESERVED38 (38) +#define ASPEED_RESET_PWM (37) +#define ASPEED_RESET_PECI (36) +#define ASPEED_RESET_MII (35) +#define ASPEED_RESET_I2C (34) +#define ASPEED_RESET_RESERVED33 (33) +#define ASPEED_RESET_LPC_ESPI (32) +#define ASPEED_RESET_H2X (31) +#define ASPEED_RESET_GP_MCU (30) +#define ASPEED_RESET_DP_MCU (29) +#define ASPEED_RESET_DP (28) +#define ASPEED_RESET_RC_XDMA (27) +#define ASPEED_RESET_GRAPHICS (26) +#define ASPEED_RESET_DEV_XDMA (25) +#define ASPEED_RESET_DEV_MCTP (24) +#define ASPEED_RESET_RC_MCTP (23) +#define ASPEED_RESET_JTAG_MASTER (22) +#define ASPEED_RESET_PCIE_DEV_OE (21) +#define ASPEED_RESET_PCIE_DEV_O (20) +#define ASPEED_RESET_PCIE_RC_OE (19) +#define ASPEED_RESET_PCIE_RC_O (18) +#define ASPEED_RESET_RESERVED17 (17) +#define ASPEED_RESET_EMMC (16) +#define ASPEED_RESET_UHCI (15) +#define ASPEED_RESET_EHCI_P1 (14) +#define ASPEED_RESET_CRT (13) +#define ASPEED_RESET_MAC2 (12) +#define ASPEED_RESET_MAC1 (11) +#define ASPEED_RESET_RESERVED10 (10) +#define ASPEED_RESET_RVAS (9) +#define ASPEED_RESET_PCI_VGA (8) +#define ASPEED_RESET_2D (7) +#define ASPEED_RESET_VIDEO (6) +#define ASPEED_RESET_PCI_DP (5) +#define ASPEED_RESET_HACE (4) +#define ASPEED_RESET_EHCI_P2 (3) +#define ASPEED_RESET_RESERVED2 (2) +#define ASPEED_RESET_AHB (1) +#define ASPEED_RESET_SDRAM (0) + +#endif /* _ABI_MACH_ASPEED_AST2600_RESET_H_ */ diff --git a/include/dwmmc.h b/include/dwmmc.h index 51ab74ead3..5fc8ed8395 100644 --- a/include/dwmmc.h +++ b/include/dwmmc.h @@ -174,7 +174,7 @@ struct dwmci_host { struct mmc *mmc; void *priv; - void (*clksel)(struct dwmci_host *host); + int (*clksel)(struct dwmci_host *host); void (*board_init)(struct dwmci_host *host); /** diff --git a/include/efi.h b/include/efi.h index 5695273ce9..503fbf060b 100644 --- a/include/efi.h +++ b/include/efi.h @@ -20,6 +20,11 @@ #include <linux/string.h> #include <linux/types.h> +/* Type INTN in UEFI specification */ +#define efi_intn_t ssize_t +/* Type UINTN in UEFI specification*/ +#define efi_uintn_t size_t + /* * EFI on x86_64 uses the Microsoft ABI which is not the default for GCC. * diff --git a/include/efi_api.h b/include/efi_api.h index ecb43a0607..48e48a6263 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -34,8 +34,6 @@ enum efi_timer_delay { EFI_TIMER_RELATIVE = 2 }; -#define efi_intn_t ssize_t -#define efi_uintn_t size_t typedef void *efi_hii_handle_t; typedef u16 *efi_string_t; typedef u16 efi_string_id_t; @@ -703,10 +701,10 @@ struct efi_simple_text_output_protocol { char extended_verification); efi_status_t (EFIAPI *output_string)( struct efi_simple_text_output_protocol *this, - const efi_string_t str); + const u16 *str); efi_status_t (EFIAPI *test_string)( struct efi_simple_text_output_protocol *this, - const efi_string_t str); + const u16 *str); efi_status_t(EFIAPI *query_mode)( struct efi_simple_text_output_protocol *this, unsigned long mode_number, unsigned long *columns, @@ -1589,35 +1587,35 @@ struct efi_file_io_token { struct efi_file_handle { u64 rev; - efi_status_t (EFIAPI *open)(struct efi_file_handle *file, + efi_status_t (EFIAPI *open)(struct efi_file_handle *this, struct efi_file_handle **new_handle, u16 *file_name, u64 open_mode, u64 attributes); - efi_status_t (EFIAPI *close)(struct efi_file_handle *file); - efi_status_t (EFIAPI *delete)(struct efi_file_handle *file); - efi_status_t (EFIAPI *read)(struct efi_file_handle *file, + efi_status_t (EFIAPI *close)(struct efi_file_handle *this); + efi_status_t (EFIAPI *delete)(struct efi_file_handle *this); + efi_status_t (EFIAPI *read)(struct efi_file_handle *this, efi_uintn_t *buffer_size, void *buffer); - efi_status_t (EFIAPI *write)(struct efi_file_handle *file, + efi_status_t (EFIAPI *write)(struct efi_file_handle *this, efi_uintn_t *buffer_size, void *buffer); - efi_status_t (EFIAPI *getpos)(struct efi_file_handle *file, + efi_status_t (EFIAPI *getpos)(struct efi_file_handle *this, u64 *pos); - efi_status_t (EFIAPI *setpos)(struct efi_file_handle *file, + efi_status_t (EFIAPI *setpos)(struct efi_file_handle *this, u64 pos); - efi_status_t (EFIAPI *getinfo)(struct efi_file_handle *file, + efi_status_t (EFIAPI *getinfo)(struct efi_file_handle *this, const efi_guid_t *info_type, efi_uintn_t *buffer_size, void *buffer); - efi_status_t (EFIAPI *setinfo)(struct efi_file_handle *file, + efi_status_t (EFIAPI *setinfo)(struct efi_file_handle *this, const efi_guid_t *info_type, efi_uintn_t buffer_size, void *buffer); - efi_status_t (EFIAPI *flush)(struct efi_file_handle *file); - efi_status_t (EFIAPI *open_ex)(struct efi_file_handle *file, + efi_status_t (EFIAPI *flush)(struct efi_file_handle *this); + efi_status_t (EFIAPI *open_ex)(struct efi_file_handle *this, struct efi_file_handle **new_handle, u16 *file_name, u64 open_mode, u64 attributes, struct efi_file_io_token *token); - efi_status_t (EFIAPI *read_ex)(struct efi_file_handle *file, + efi_status_t (EFIAPI *read_ex)(struct efi_file_handle *this, struct efi_file_io_token *token); - efi_status_t (EFIAPI *write_ex)(struct efi_file_handle *file, + efi_status_t (EFIAPI *write_ex)(struct efi_file_handle *this, struct efi_file_io_token *token); - efi_status_t (EFIAPI *flush_ex)(struct efi_file_handle *file, + efi_status_t (EFIAPI *flush_ex)(struct efi_file_handle *this, struct efi_file_io_token *token); }; @@ -1695,10 +1693,6 @@ struct efi_driver_binding_protocol { efi_handle_t driver_binding_handle; }; -/* Deprecated version of the Unicode collation protocol */ -#define EFI_UNICODE_COLLATION_PROTOCOL_GUID \ - EFI_GUID(0x1d85cd7f, 0xf43d, 0x11d2, \ - 0x9a, 0x0c, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d) /* Current version of the Unicode collation protocol */ #define EFI_UNICODE_COLLATION_PROTOCOL2_GUID \ EFI_GUID(0xa4c751fc, 0x23ae, 0x4c3e, \ diff --git a/include/efi_dt_fixup.h b/include/efi_dt_fixup.h new file mode 100644 index 0000000000..9066e8dd8e --- /dev/null +++ b/include/efi_dt_fixup.h @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * EFI_DT_FIXUP_PROTOCOL + * + * Copyright (c) 2020 Heinrich Schuchardt + */ + +#include <efi_api.h> + +#define EFI_DT_FIXUP_PROTOCOL_GUID \ + EFI_GUID(0xe617d64c, 0xfe08, 0x46da, 0xf4, 0xdc, \ + 0xbb, 0xd5, 0x87, 0x0c, 0x73, 0x00) + +#define EFI_DT_FIXUP_PROTOCOL_REVISION 0x00010000 + +/* Add nodes and update properties */ +#define EFI_DT_APPLY_FIXUPS 0x00000001 +/* + * Reserve memory according to the /reserved-memory node + * and the memory reservation block + */ +#define EFI_DT_RESERVE_MEMORY 0x00000002 +/* Install the device-tree as configuration table */ +#define EFI_DT_INSTALL_TABLE 0x00000004 + +#define EFI_DT_ALL (EFI_DT_APPLY_FIXUPS | \ + EFI_DT_RESERVE_MEMORY | \ + EFI_DT_INSTALL_TABLE) + +struct efi_dt_fixup_protocol { + u64 revision; + efi_status_t (EFIAPI *fixup) (struct efi_dt_fixup_protocol *this, + void *dtb, + efi_uintn_t *buffer_size, + u32 flags); +}; + +extern struct efi_dt_fixup_protocol efi_dt_fixup_prot; +extern const efi_guid_t efi_guid_dt_fixup_protocol; diff --git a/include/efi_loader.h b/include/efi_loader.h index 4719fa93f0..f470bbd636 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -147,9 +147,6 @@ extern const struct efi_device_path_to_text_protocol efi_device_path_to_text; /* implementation of the EFI_DEVICE_PATH_UTILITIES_PROTOCOL */ extern const struct efi_device_path_utilities_protocol efi_device_path_utilities; -/* deprecated version of the EFI_UNICODE_COLLATION_PROTOCOL */ -extern const struct efi_unicode_collation_protocol - efi_unicode_collation_protocol; /* current version of the EFI_UNICODE_COLLATION_PROTOCOL */ extern const struct efi_unicode_collation_protocol efi_unicode_collation_protocol2; @@ -411,6 +408,8 @@ void efi_runtime_detach(void); /* efi_convert_pointer() - convert pointer to virtual address */ efi_status_t EFIAPI efi_convert_pointer(efi_uintn_t debug_disposition, void **address); +/* Carve out DT reserved memory ranges */ +void efi_carve_out_dt_rsv(void *fdt); /* Called by bootefi to make console interface available */ efi_status_t efi_console_register(void); /* Called by bootefi to make all disk storage accessible as EFI objects */ @@ -460,6 +459,8 @@ efi_status_t efi_set_watchdog(unsigned long timeout); /* Called from places to check whether a timer expired */ void efi_timer_check(void); +/* Check if a buffer contains a PE-COFF image */ +efi_status_t efi_check_pe(void *buffer, size_t size, void **nt_header); /* PE loader implementation */ efi_status_t efi_load_pe(struct efi_loaded_image_obj *handle, void *efi, size_t efi_size, @@ -472,7 +473,8 @@ void efi_restore_gd(void); /* Call this to relocate the runtime section to an address space */ void efi_runtime_relocate(ulong offset, struct efi_mem_desc *map); /* Call this to set the current device name */ -void efi_set_bootdev(const char *dev, const char *devnr, const char *path); +void efi_set_bootdev(const char *dev, const char *devnr, const char *path, + void *buffer, size_t buffer_size); /* Add a new object to the object list. */ void efi_add_handle(efi_handle_t obj); /* Create handle */ @@ -559,7 +561,7 @@ struct efi_file_handle *efi_file_from_path(struct efi_device_path *fp); * @size: size in bytes * Return: size in pages */ -#define efi_size_in_pages(size) ((size + EFI_PAGE_MASK) >> EFI_PAGE_SHIFT) +#define efi_size_in_pages(size) (((size) + EFI_PAGE_MASK) >> EFI_PAGE_SHIFT) /* Generic EFI memory allocator, call this to get memory */ void *efi_alloc(uint64_t len, int memory_type); /* More specific EFI memory allocator, called by EFI payloads */ @@ -871,7 +873,8 @@ static inline efi_status_t efi_add_runtime_mmio(void *mmio_ptr, u64 len) /* No loader configured, stub out EFI_ENTRY */ static inline void efi_restore_gd(void) { } static inline void efi_set_bootdev(const char *dev, const char *devnr, - const char *path) { } + const char *path, void *buffer, + size_t buffer_size) { } static inline void efi_net_set_dhcp_ack(void *pkt, int len) { } static inline void efi_print_image_infos(void *pc) { } static inline efi_status_t efi_launch_capsules(void) diff --git a/include/efi_variable.h b/include/efi_variable.h index bf5076233e..4623a64142 100644 --- a/include/efi_variable.h +++ b/include/efi_variable.h @@ -306,4 +306,15 @@ efi_status_t __efi_runtime EFIAPI efi_get_next_variable_name_runtime(efi_uintn_t *variable_name_size, u16 *variable_name, efi_guid_t *guid); +/** + * efi_var_buf_update() - udpate memory buffer for variables + * + * @var_buf: source buffer + * + * This function copies to the memory buffer for UEFI variables. Call this + * function in ExitBootServices() if memory backed variables are only used + * at runtime to fill the buffer. + */ +void efi_var_buf_update(struct efi_var_file *var_buf); + #endif diff --git a/include/exports.h b/include/exports.h index b300554091..faf0f59244 100644 --- a/include/exports.h +++ b/include/exports.h @@ -15,8 +15,14 @@ struct cmd_tbl; struct spi_slave; -/* Set up the jump table for use by the API */ -void jumptable_init(void); +/** + * jumptable_init() - Set up the jump table for use by the API + * + * It is called during the generic post-relocation init sequence. + * + * Return: 0 if OK + */ +int jumptable_init(void); /* These are declarations of exported functions available in C code */ unsigned long get_version(void); diff --git a/include/init.h b/include/init.h index 0f48ccb57a..980be27993 100644 --- a/include/init.h +++ b/include/init.h @@ -164,6 +164,41 @@ int arch_setup_bdinfo(void); int setup_bdinfo(void); /** + * cpu_secondary_init_r() - CPU-specific secondary initialization + * + * After non-volatile devices, environment and cpu code are setup, have + * another round to deal with any initialization that might require + * full access to the environment or loading of some image (firmware) + * from a non-volatile device. + * + * It is called during the generic post-relocation init sequence. + * + * Return: 0 if OK + */ +int cpu_secondary_init_r(void); + +/** + * pci_ep_init() - Initialize pci endpoint devices + * + * It is called during the generic post-relocation init sequence. + * + * Return: 0 if OK + */ +int pci_ep_init(void); + +/** + * pci_init() - Enumerate pci devices + * + * It is called during the generic post-relocation init sequence to enumerate + * pci buses. This is needed, for instance, in the case of DM PCI-based + * Ethernet devices, which will not be detected without having the enumeration + * performed earlier. + * + * Return: 0 if OK + */ +int pci_init(void); + +/** * init_cache_f_r() - Turn on the cache in preparation for relocation * * Return: 0 if OK, -ve on error @@ -234,8 +269,6 @@ int mac_read_from_eeprom(void); int set_cpu_clk_info(void); int update_flash_size(int flash_size); int arch_early_init_r(void); -void pci_init(void); -void pci_ep_init(void); int misc_init_r(void); #if defined(CONFIG_VID) int init_func_vid(void); @@ -267,7 +300,15 @@ int board_early_init_r(void); /* TODO(sjg@chromium.org): Drop this when DM_PCI migration is completed */ void pci_init_board(void); -void trap_init(unsigned long reloc_addr); +/** + * arch_initr_trap() - Init traps + * + * Arch specific routine for initializing traps. It is called during the + * generic board init sequence, after relocation. + * + * Return: 0 if OK + */ +int arch_initr_trap(void); /** * main_loop() - Enter the main loop of U-Boot diff --git a/include/iomux.h b/include/iomux.h index e6e1097db5..da7ff697d2 100644 --- a/include/iomux.h +++ b/include/iomux.h @@ -26,6 +26,5 @@ extern int cd_count[MAX_FILES]; int iomux_doenv(const int, const char *); void iomux_printdevs(const int); -struct stdio_dev *search_device(int, const char *); #endif /* _IO_MUX_H */ diff --git a/include/linux/intel-smc.h b/include/linux/intel-smc.h new file mode 100644 index 0000000000..cacb410691 --- /dev/null +++ b/include/linux/intel-smc.h @@ -0,0 +1,573 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2017-2018, Intel Corporation + */ + +#ifndef __INTEL_SMC_H +#define __INTEL_SMC_H + +#include <linux/arm-smccc.h> +#include <linux/bitops.h> + +/* + * This file defines the Secure Monitor Call (SMC) message protocol used for + * service layer driver in normal world (EL1) to communicate with secure + * monitor software in Secure Monitor Exception Level 3 (EL3). + * + * This file is shared with secure firmware (FW) which is out of u-boot tree. + * + * An ARM SMC instruction takes a function identifier and up to 6 64-bit + * register values as arguments, and can return up to 4 64-bit register + * values. The operation of the secure monitor is determined by the parameter + * values passed in through registers. + + * EL1 and EL3 communicates pointer as physical address rather than the + * virtual address. + */ + +/* + * Functions specified by ARM SMC Calling convention: + * + * FAST call executes atomic operations, returns when the requested operation + * has completed. + * STD call starts a operation which can be preempted by a non-secure + * interrupt. The call can return before the requested operation has + * completed. + * + * a0..a7 is used as register names in the descriptions below, on arm32 + * that translates to r0..r7 and on arm64 to w0..w7. + */ + +#define INTEL_SIP_SMC_STD_CALL_VAL(func_num) \ + ARM_SMCCC_CALL_VAL(ARM_SMCCC_STD_CALL, ARM_SMCCC_SMC_64, \ + ARM_SMCCC_OWNER_SIP, (func_num)) + +#define INTEL_SIP_SMC_FAST_CALL_VAL(func_num) \ + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_64, \ + ARM_SMCCC_OWNER_SIP, (func_num)) + +/* + * Return values in INTEL_SIP_SMC_* call + * + * INTEL_SIP_SMC_RETURN_UNKNOWN_FUNCTION: + * Secure monitor software doesn't recognize the request. + * + * INTEL_SIP_SMC_STATUS_OK: + * SMC call completed successfully, + * In case of FPGA configuration write operation, it means secure monitor + * software can accept the next chunk of FPGA configuration data. + * + * INTEL_SIP_SMC_STATUS_BUSY: + * In case of FPGA configuration write operation, it means secure monitor + * software is still processing previous data & can't accept the next chunk + * of data. Service driver needs to issue + * INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE call to query the + * completed block(s). + * + * INTEL_SIP_SMC_STATUS_ERROR: + * There is error during the SMC call process. + * + * INTEL_SIP_SMC_REG_ERROR: + * There is error during a read or write operation of the protected + * registers. + */ +#define INTEL_SIP_SMC_RETURN_UNKNOWN_FUNCTION 0xFFFFFFFF +#define INTEL_SIP_SMC_STATUS_OK 0x0 +#define INTEL_SIP_SMC_STATUS_BUSY 0x1 +#define INTEL_SIP_SMC_STATUS_REJECTED 0x2 +#define INTEL_SIP_SMC_STATUS_ERROR 0x4 +#define INTEL_SIP_SMC_REG_ERROR 0x5 +#define INTEL_SIP_SMC_RSU_ERROR 0x7 + +/* + * Request INTEL_SIP_SMC_FPGA_CONFIG_START + * + * Sync call used by service driver at EL1 to request the FPGA in EL3 to + * be prepare to receive a new configuration. + * + * Call register usage: + * a0: INTEL_SIP_SMC_FPGA_CONFIG_START. + * a1: flag for full or partial configuration + * 0 full reconfiguration. + * 1 partial reconfiguration. + * a2-7: not used. + * + * Return status: + * a0: INTEL_SIP_SMC_STATUS_OK, or INTEL_SIP_SMC_STATUS_ERROR. + * a1-3: not used. + */ +#define INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_START 1 +#define INTEL_SIP_SMC_FPGA_CONFIG_START \ + INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_START) + +/* + * Request INTEL_SIP_SMC_FPGA_CONFIG_WRITE + * + * Async call used by service driver at EL1 to provide FPGA configuration data + * to secure world. + * + * Call register usage: + * a0: INTEL_SIP_SMC_FPGA_CONFIG_WRITE. + * a1: 64bit physical address of the configuration data memory block + * a2: Size of configuration data block. + * a3-7: not used. + * + * Return status: + * a0: INTEL_SIP_SMC_STATUS_OK, INTEL_SIP_SMC_STATUS_BUSY, + * INTEL_SIP_SMC_STATUS_REJECTED or INTEL_SIP_SMC_STATUS_ERROR. + * a1: 64bit physical address of 1st completed memory block if any completed + * block, otherwise zero value. + * a2: 64bit physical address of 2nd completed memory block if any completed + * block, otherwise zero value. + * a3: 64bit physical address of 3rd completed memory block if any completed + * block, otherwise zero value. + */ +#define INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_WRITE 2 +#define INTEL_SIP_SMC_FPGA_CONFIG_WRITE \ + INTEL_SIP_SMC_STD_CALL_VAL(INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_WRITE) + +/* + * Request INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE + * + * Sync call used by service driver at EL1 to track the completed write + * transactions. This request is called after INTEL_SIP_SMC_FPGA_CONFIG_WRITE + * call returns INTEL_SIP_SMC_STATUS_BUSY. + * + * Call register usage: + * a0: INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE. + * a1-7: not used. + * + * Return status: + * a0: INTEL_SIP_SMC_STATUS_OK, INTEL_SIP_SMC_STATUS_BUSY or + * INTEL_SIP_SMC_STATUS_ERROR. + * a1: 64bit physical address of 1st completed memory block. + * a2: 64bit physical address of 2nd completed memory block if + * any completed block, otherwise zero value. + * a3: 64bit physical address of 3rd completed memory block if + * any completed block, otherwise zero value. + */ +#define INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_COMPLETED_WRITE 3 +#define INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE \ +INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_COMPLETED_WRITE) + +/* + * Request INTEL_SIP_SMC_FPGA_CONFIG_ISDONE + * + * Sync call used by service driver at EL1 to inform secure world that all + * data are sent, to check whether or not the secure world had completed + * the FPGA configuration process. + * + * Call register usage: + * a0: INTEL_SIP_SMC_FPGA_CONFIG_ISDONE. + * a1-7: not used. + * + * Return status: + * a0: INTEL_SIP_SMC_STATUS_OK, INTEL_SIP_SMC_STATUS_BUSY or + * INTEL_SIP_SMC_STATUS_ERROR. + * a1-3: not used. + */ +#define INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_ISDONE 4 +#define INTEL_SIP_SMC_FPGA_CONFIG_ISDONE \ + INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_ISDONE) + +/* + * Request INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM + * + * Sync call used by service driver at EL1 to query the physical address of + * memory block reserved by secure monitor software. + * + * Call register usage: + * a0:INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM. + * a1-7: not used. + * + * Return status: + * a0: INTEL_SIP_SMC_STATUS_OK or INTEL_SIP_SMC_STATUS_ERROR. + * a1: start of physical address of reserved memory block. + * a2: size of reserved memory block. + * a3: not used. + */ +#define INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_GET_MEM 5 +#define INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM \ + INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_GET_MEM) + +/* + * Request INTEL_SIP_SMC_FPGA_CONFIG_LOOPBACK + * + * For SMC loop-back mode only, used for internal integration, debugging + * or troubleshooting. + * + * Call register usage: + * a0: INTEL_SIP_SMC_FPGA_CONFIG_LOOPBACK. + * a1-7: not used. + * + * Return status: + * a0: INTEL_SIP_SMC_STATUS_OK or INTEL_SIP_SMC_STATUS_ERROR. + * a1-3: not used. + */ +#define INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_LOOPBACK 6 +#define INTEL_SIP_SMC_FPGA_CONFIG_LOOPBACK \ + INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_LOOPBACK) + +/* + * Request INTEL_SIP_SMC_REG_READ + * + * Read a protected register using SMCCC + * + * Call register usage: + * a0: INTEL_SIP_SMC_REG_READ. + * a1: register address. + * a2-7: not used. + * + * Return status: + * a0: INTEL_SIP_SMC_STATUS_OK or INTEL_SIP_SMC_REG_ERROR. + * a1: Value in the register + * a2-3: not used. + */ +#define INTEL_SIP_SMC_FUNCID_REG_READ 7 +#define INTEL_SIP_SMC_REG_READ \ + INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_REG_READ) + +/* + * Request INTEL_SIP_SMC_REG_WRITE + * + * Write a protected register using SMCCC + * + * Call register usage: + * a0: INTEL_SIP_SMC_REG_WRITE. + * a1: register address + * a2: value to program into register. + * a3-7: not used. + * + * Return status: + * a0: INTEL_SIP_SMC_STATUS_OK or INTEL_SIP_SMC_REG_ERROR. + * a1-3: not used. + */ +#define INTEL_SIP_SMC_FUNCID_REG_WRITE 8 +#define INTEL_SIP_SMC_REG_WRITE \ + INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_REG_WRITE) + +/* + * Request INTEL_SIP_SMC_FUNCID_REG_UPDATE + * + * Update one or more bits in a protected register using a + * read-modify-write operation. + * + * Call register usage: + * a0: INTEL_SIP_SMC_REG_UPDATE. + * a1: register address + * a2: Write Mask. + * a3: Value to write. + * a4-7: not used. + * + * Return status: + * a0: INTEL_SIP_SMC_STATUS_OK or INTEL_SIP_SMC_REG_ERROR. + * a1-3: Not used. + */ +#define INTEL_SIP_SMC_FUNCID_REG_UPDATE 9 +#define INTEL_SIP_SMC_REG_UPDATE \ + INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_REG_UPDATE) + +/* +* Request INTEL_SIP_SMC_RSU_STATUS +* +* Sync call used by service driver at EL1 to query the RSU status +* +* Call register usage: +* a0 INTEL_SIP_SMC_RSU_STATUS +* a1-7 not used +* +* Return status +* a0: Current Image +* a1: Last Failing Image +* a2: Version [width 32 bit] | State [width 32 bit] +* a3: Error details [width 32 bit] | Error location [width 32 bit] +* +* Or +* +* a0: INTEL_SIP_SMC_RSU_ERROR +*/ +#define INTEL_SIP_SMC_FUNCID_RSU_STATUS 11 +#define INTEL_SIP_SMC_RSU_STATUS \ + INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_RSU_STATUS) + +/* +* Request INTEL_SIP_SMC_RSU_UPDATE +* +* Sync call used by service driver at EL1 to tell you next reboot is RSU_UPDATE +* +* Call register usage: +* a0 INTEL_SIP_SMC_RSU_UPDATE +* a1 64bit physical address of the configuration data memory in flash +* a2-7 not used +* +* Return status + * a0 INTEL_SIP_SMC_STATUS_OK +*/ +#define INTEL_SIP_SMC_FUNCID_RSU_UPDATE 12 +#define INTEL_SIP_SMC_RSU_UPDATE \ + INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_RSU_UPDATE) + +/* + * Request INTEL_SIP_SMC_ECC_DBE + * + * Sync call used by service driver at EL1 alert EL3 that a Double Bit + * ECC error has occurred. + * + * Call register usage: + * a0 INTEL_SIP_SMC_ECC_DBE + * a1 SysManager Double Bit Error value + * a2-7 not used + * + * Return status + * a0 INTEL_SIP_SMC_STATUS_OK + */ +#define INTEL_SIP_SMC_FUNCID_ECC_DBE 13 +#define INTEL_SIP_SMC_ECC_DBE \ + INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_ECC_DBE) + +/* +* Request INTEL_SIP_SMC_RSU_NOTIFY +* +* Sync call used by service driver at EL1 to report HPS software execution stage +* +* Call register usage: +* a0 INTEL_SIP_SMC_RSU_NOTIFY +* a1 32bit HPS software execution stage +* a2-7 not used +* +* Return status + * a0 INTEL_SIP_SMC_STATUS_OK or INTEL_SIP_SMC_REG_ERROR. +*/ +#define INTEL_SIP_SMC_FUNCID_RSU_NOTIFY 14 +#define INTEL_SIP_SMC_RSU_NOTIFY \ + INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_RSU_NOTIFY) + +/* + * Request INTEL_SIP_SMC_RSU_RETRY_COUNTER + * + * Sync call used by service driver at EL1 to query the RSU retry counter + * + * Call register usage: + * a0 INTEL_SIP_SMC_RSU_RETRY_COUNTER + * a1-7 not used + * + * Return status + * a0 INTEL_SIP_SMC_STATUS_OK or INTEL_SIP_SMC_RSU_ERROR. + * a1 retry counter +*/ +#define INTEL_SIP_SMC_FUNCID_RSU_RETRY_COUNTER 15 +#define INTEL_SIP_SMC_RSU_RETRY_COUNTER \ + INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_RSU_RETRY_COUNTER) + +/* + * Request INTEL_SIP_SMC_RSU_DCMF_VERSION + * + * Sync call used by service driver at EL1 to query DCMF version + * + * Call register usage: + * a0 INTEL_SIP_SMC_RSU_DCMF_VERSION + * a1-7 not used + * + * Return status + * a0 INTEL_SIP_SMC_STATUS_OK + * a1 dcmf1 version | dcmf0 version + * a2 dcmf3 version | dcmf2 version + * + * Or + * + * a0 INTEL_SIP_SMC_RSU_ERROR + */ +#define INTEL_SIP_SMC_FUNCID_RSU_DCMF_VERSION 16 +#define INTEL_SIP_SMC_RSU_DCMF_VERSION \ + INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_RSU_DCMF_VERSION) + +/* + * Request INTEL_SIP_SMC_RSU_COPY_DCMF_VERSION + * + * Sync call used by SSBL (EL2) to copy DCMF version to ATF memory + * + * Call register usage: + * a0 INTEL_SIP_SMC_RSU_COPY_DCMF_VERSION + * a1 dcmf1 version | dcmf0 version + * a2 dcmf3 version | dcmf2 version + * + * Return status + * a0 INTEL_SIP_SMC_STATUS_OK + */ +#define INTEL_SIP_SMC_FUNCID_RSU_COPY_DCMF_VERSION 17 +#define INTEL_SIP_SMC_RSU_COPY_DCMF_VERSION \ + INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_RSU_COPY_DCMF_VERSION) + +/* + * Request INTEL_SIP_SMC_RSU_MAX_RETRY + * + * Sync call used by service driver at EL1 to query max_retry parameter + * + * Call register usage: + * a0 INTEL_SIP_SMC_RSU_MAX_RETRY + * a1-7 not used + * + * Return status + * a0 INTEL_SIP_SMC_STATUS_OK + * a1 max_retry + * + * Or + * + * a0 INTEL_SIP_SMC_RSU_ERROR + */ +#define INTEL_SIP_SMC_FUNCID_RSU_MAX_RETRY 18 +#define INTEL_SIP_SMC_RSU_MAX_RETRY \ + INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_RSU_MAX_RETRY) + +/* + * Request INTEL_SIP_SMC_RSU_COPY_MAX_RETRY + * + * Sync call used by SSBL (EL2) to copy RSU 'max retry' to ATF memory + * + * Call register usage: + * a0 INTEL_SIP_SMC_RSU_COPY_MAX_RETRY + * a1 max retry + * a2-7 not used + * + * Return status + * a0 INTEL_SIP_SMC_STATUS_OK + */ +#define INTEL_SIP_SMC_FUNCID_RSU_COPY_MAX_RETRY 19 +#define INTEL_SIP_SMC_RSU_COPY_MAX_RETRY \ + INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_RSU_COPY_MAX_RETRY) + +/* + * Request INTEL_SIP_SMC_RSU_DCMF_STATUS + * + * Sync call used by service driver at EL1 to query DCMF status + * + * Call register usage: + * a0 INTEL_SIP_SMC_RSU_DCMF_STATUS + * a1-7 not used + * + * Return status + * a0 INTEL_SIP_SMC_STATUS_OK + * a1 dcmf3 status | dcmf2 status | dcmf1 status | dcmf0 status + * + * Or + * + * a0 INTEL_SIP_SMC_RSU_ERROR + */ +#define INTEL_SIP_SMC_FUNCID_RSU_DCMF_STATUS 20 +#define INTEL_SIP_SMC_RSU_DCMF_STATUS \ + INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_RSU_DCMF_STATUS) + +/* + * Request INTEL_SIP_SMC_RSU_COPY_DCMF_STATUS + * + * Sync call used by SSBL (EL2) to copy RSU 'dcmf status' to ATF memory + * + * Call register usage: + * a0 INTEL_SIP_SMC_RSU_COPY_DCMF_STATUS + * a1 dcmf status + * a2-7 not used + * + * Return status + * a0 INTEL_SIP_SMC_STATUS_OK + */ +#define INTEL_SIP_SMC_FUNCID_RSU_COPY_DCMF_STATUS 21 +#define INTEL_SIP_SMC_RSU_COPY_DCMF_STATUS \ + INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_RSU_COPY_DCMF_STATUS) + +/* + * Request INTEL_SIP_SMC_HPS_SET_BRIDGES + * + * Enable/disable the SoC FPGA bridges + * + * Call register usage: + * a0 INTEL_SIP_SMC_HPS_SET_BRIDGES + * a1 Set bridges status: + * 0 - Disable + * 1 - Enable + * a2-7 not used + * + * Return status + * a0 INTEL_SIP_SMC_STATUS_OK + */ +#define INTEL_SIP_SMC_FUNCID_HPS_SET_BRIDGES 50 +#define INTEL_SIP_SMC_HPS_SET_BRIDGES \ + INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_HPS_SET_BRIDGES) + +/* + * Request INTEL_SIP_SMC_MBOX_SEND_CMD + * + * Send mailbox command to SDM + * + * Call register usage: + * a0 INTEL_SIP_SMC_MBOX_SEND_CMD + * a1 Mailbox command + * a2 64bit physical address pointer to command's arguments + * a3 Length of the argument + * a4 Urgent command: + * 0 - Disable + * 1 - Enable + * a5 64bit physical address pointer to a buffer for receiving responses + * a6 Length of the buffer + * + * Return status + * a0 INTEL_SIP_SMC_STATUS_OK or INTEL_SIP_SMC_STATUS_ERROR + * a1 Status of mailbox response + * a2 Received length in the buffer + */ +#define INTEL_SIP_SMC_FUNCID_MBOX_SEND_CMD 60 +#define INTEL_SIP_SMC_MBOX_SEND_CMD \ + INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_MBOX_SEND_CMD) + +/* + * Request INTEL_SIP_SMC_HPS_SET_PHYINTF + * + * Select EMACx PHY interface + * + * Call register usage: + * a0 INTEL_SIP_SMC_HPS_SET_PHYINTF + * a1 EMAC number: + * 0 - EMAC0 + * 1 - EMAC1 + * 2 - EMAC2 + * a2 Type of PHY interface: + * 0 - GMII_MII + * 1 - RGMII + * 2 - RMII + * 3 - RESET + * a3-7 not used + * + * Return status + * a0 INTEL_SIP_SMC_STATUS_OK or INTEL_SIP_SMC_STATUS_ERROR + */ +#define INTEL_SIP_SMC_FUNCID_HPS_SET_PHYINTF 61 +#define INTEL_SIP_SMC_HPS_SET_PHYINTF \ + INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_HPS_SET_PHYINTF) + +/* + * Request INTEL_SIP_SMC_HPS_SET_SDMMC_CCLK + * + * Select which phase shift of the clocks (drvsel & smplsel) for SDMMC + * + * Call register usage: + * a0 INTEL_SIP_SMC_HPS_SET_SDMMC_CCLK + * a1 Select which phase shift of the clock for cclk_in_drv (drvsel): + * 0 - 0 degree + * 1 - 45 degrees + * 2 - 90 degrees + * 3 - 135 degrees + * 4 - 180 degrees + * 5 - 225 degrees + * 6 - 270 degrees + * 7 - 315 degrees + * a2 Select which phase shift of the clock for cclk_in_sample (smplsel): + * (Same as above) + * a3-7 not used + * + * Return status + * a0 INTEL_SIP_SMC_STATUS_OK + */ +#define INTEL_SIP_SMC_FUNCID_HPS_SET_SDMMC_CCLK 62 +#define INTEL_SIP_SMC_HPS_SET_SDMMC_CCLK \ + INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_HPS_SET_SDMMC_CCLK) + +#endif diff --git a/include/log.h b/include/log.h index 6bce560648..2d27f9f657 100644 --- a/include/log.h +++ b/include/log.h @@ -156,6 +156,9 @@ static inline int _log_nop(enum log_category_t cat, enum log_level_t level, */ #if CONFIG_IS_ENABLED(LOG) #define _LOG_MAX_LEVEL CONFIG_VAL(LOG_MAX_LEVEL) +#define log_emer(_fmt...) log(LOG_CATEGORY, LOGL_EMERG, ##_fmt) +#define log_alert(_fmt...) log(LOG_CATEGORY, LOGL_ALERT, ##_fmt) +#define log_crit(_fmt...) log(LOG_CATEGORY, LOGL_CRIT, ##_fmt) #define log_err(_fmt...) log(LOG_CATEGORY, LOGL_ERR, ##_fmt) #define log_warning(_fmt...) log(LOG_CATEGORY, LOGL_WARNING, ##_fmt) #define log_notice(_fmt...) log(LOG_CATEGORY, LOGL_NOTICE, ##_fmt) @@ -163,12 +166,17 @@ static inline int _log_nop(enum log_category_t cat, enum log_level_t level, #define log_debug(_fmt...) log(LOG_CATEGORY, LOGL_DEBUG, ##_fmt) #define log_content(_fmt...) log(LOG_CATEGORY, LOGL_DEBUG_CONTENT, ##_fmt) #define log_io(_fmt...) log(LOG_CATEGORY, LOGL_DEBUG_IO, ##_fmt) +#define log_cont(_fmt...) log(LOGC_CONT, LOGL_CONT, ##_fmt) #else #define _LOG_MAX_LEVEL LOGL_INFO +#define log_emerg(_fmt, ...) printf(_fmt, ##__VA_ARGS__) +#define log_alert(_fmt, ...) printf(_fmt, ##__VA_ARGS__) +#define log_crit(_fmt, ...) printf(_fmt, ##__VA_ARGS__) #define log_err(_fmt, ...) printf(_fmt, ##__VA_ARGS__) #define log_warning(_fmt, ...) printf(_fmt, ##__VA_ARGS__) #define log_notice(_fmt, ...) printf(_fmt, ##__VA_ARGS__) #define log_info(_fmt, ...) printf(_fmt, ##__VA_ARGS__) +#define log_cont(_fmt, ...) printf(_fmt, ##__VA_ARGS__) #define log_debug(_fmt, ...) debug(_fmt, ##__VA_ARGS__) #define log_content(_fmt...) log_nop(LOG_CATEGORY, \ LOGL_DEBUG_CONTENT, ##_fmt) @@ -217,10 +225,9 @@ static inline int _log_nop(enum log_category_t cat, enum log_level_t level, #if !_DEBUG && CONFIG_IS_ENABLED(LOG) #define debug_cond(cond, fmt, args...) \ - do { \ - if (1) \ - log(LOG_CATEGORY, LOGL_DEBUG, fmt, ##args); \ - } while (0) +({ \ + log(LOG_CATEGORY, LOGL_DEBUG, fmt, ##args); \ +}) #else /* _DEBUG */ @@ -229,11 +236,11 @@ static inline int _log_nop(enum log_category_t cat, enum log_level_t level, * computed by a preprocessor in the best case, allowing for the best * optimization. */ -#define debug_cond(cond, fmt, args...) \ - do { \ - if (cond) \ - printf(pr_fmt(fmt), ##args); \ - } while (0) +#define debug_cond(cond, fmt, args...) \ +({ \ + if (cond) \ + printf(pr_fmt(fmt), ##args); \ +}) #endif /* _DEBUG */ diff --git a/include/miiphy.h b/include/miiphy.h index 61c136b114..8b77bac01e 100644 --- a/include/miiphy.h +++ b/include/miiphy.h @@ -81,7 +81,15 @@ struct bb_miiphy_bus { extern struct bb_miiphy_bus bb_miiphy_buses[]; extern int bb_miiphy_buses_num; -void bb_miiphy_init(void); +/** + * bb_miiphy_init() - Initialize bit-banged MII bus driver + * + * It is called during the generic post-relocation init sequence. + * + * Return: 0 if OK + */ +int bb_miiphy_init(void); + int bb_miiphy_read(struct mii_dev *miidev, int addr, int devad, int reg); int bb_miiphy_write(struct mii_dev *miidev, int addr, int devad, int reg, u16 value); diff --git a/include/part.h b/include/part.h index 55be724d20..815515aa80 100644 --- a/include/part.h +++ b/include/part.h @@ -9,6 +9,7 @@ #include <blk.h> #include <ide.h> #include <uuid.h> +#include <linker_lists.h> #include <linux/list.h> struct block_drvr { @@ -465,16 +466,49 @@ int get_disk_guid(struct blk_desc *dev_desc, char *guid); int is_valid_dos_buf(void *buf); /** - * write_mbr_partition() - write DOS MBR + * write_mbr_sector() - write DOS MBR * * @param dev_desc - block device descriptor * @param buf - buffer which contains the MBR * * @return - '0' on success, otherwise error */ -int write_mbr_partition(struct blk_desc *dev_desc, void *buf); +int write_mbr_sector(struct blk_desc *dev_desc, void *buf); + +int write_mbr_partitions(struct blk_desc *dev, + struct disk_partition *p, int count, unsigned int disksig); +int layout_mbr_partitions(struct disk_partition *p, int count, + lbaint_t total_sectors); #endif +#ifdef CONFIG_PARTITIONS +/** + * part_driver_get_count() - get partition driver count + * + * @return - number of partition drivers + */ +static inline int part_driver_get_count(void) +{ + return ll_entry_count(struct part_driver, part_driver); +} + +/** + * part_driver_get_first() - get first partition driver + * + * @return - pointer to first partition driver on success, otherwise NULL + */ +static inline struct part_driver *part_driver_get_first(void) +{ + return ll_entry_start(struct part_driver, part_driver); +} + +#else +static inline int part_driver_get_count(void) +{ return 0; } + +static inline struct part_driver *part_driver_get_first(void) +{ return NULL; } +#endif /* CONFIG_PARTITIONS */ #endif /* _PART_H */ diff --git a/include/part_efi.h b/include/part_efi.h index 1929e4400f..c68529b4da 100644 --- a/include/part_efi.h +++ b/include/part_efi.h @@ -56,6 +56,9 @@ #define PARTITION_LINUX_LVM_GUID \ EFI_GUID( 0xe6d6d379, 0xf507, 0x44c2, \ 0xa2, 0x3c, 0x23, 0x8f, 0x2a, 0x3d, 0xf9, 0x28) +#define PARTITION_U_BOOT_ENVIRONMENT \ + EFI_GUID( 0x3de21764, 0x95bd, 0x54bd, \ + 0xa5, 0xc3, 0x4a, 0xbe, 0x78, 0x6f, 0x38, 0xa8) /* linux/include/efi.h */ typedef u16 efi_char16_t; diff --git a/include/post.h b/include/post.h index eb218acde5..5695e2b533 100644 --- a/include/post.h +++ b/include/post.h @@ -107,7 +107,6 @@ int post_init_f (void); void post_bootmode_init (void); int post_bootmode_get (unsigned int * last_test); void post_bootmode_clear (void); -void post_output_backlog ( void ); int post_run (char *name, int flags); int post_info (char *name); int post_log (char *format, ...); @@ -116,6 +115,16 @@ void post_reloc (void); #endif unsigned long post_time_ms (unsigned long base); +/** + * post_output_backlog() - Print POST results + * + * Print POST results during the generic board init sequence, after + * relocation. + * + * Return: 0 if OK + */ +int post_output_backlog(void); + extern struct post_test post_list[]; extern unsigned int post_list_size; extern int post_hotkeys_pressed(void); diff --git a/include/power/mp5416.h b/include/power/mp5416.h new file mode 100644 index 0000000000..dc096fed3f --- /dev/null +++ b/include/power/mp5416.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* Copyright (C) 2020 Gateworks Corporation */ + +#ifndef MP5416_H_ +#define MP5416_H_ + +#define MP6416_REGULATOR_DRIVER "mp5416_regulator" + +enum { + MP5416_CTL0 = 0x00, + MP5416_CTL1 = 0x01, + MP5416_CTL2 = 0x02, + MP5416_ILIMIT = 0x03, + MP5416_VSET_SW1 = 0x04, + MP5416_VSET_SW2 = 0x05, + MP5416_VSET_SW3 = 0x06, + MP5416_VSET_SW4 = 0x07, + MP5416_VSET_LDO2 = 0x08, + MP5416_VSET_LDO3 = 0x09, + MP5416_VSET_LDO4 = 0x0a, + MP5416_VSET_LDO5 = 0x0b, + MP5416_STATUS1 = 0x0d, + MP5416_STATUS2 = 0x0e, + MP5416_STATUS3 = 0x0f, + MP5416_ID2 = 0x11, + MP5416_NUM_OF_REGS = 0x12, +}; + +#define MP5416_VSET_EN BIT(7) +#define MP5416_VSET_SW1_GVAL(x) ((((x) & 0x7f) * 12500) + 600000) +#define MP5416_VSET_SW2_GVAL(x) ((((x) & 0x7f) * 25000) + 800000) +#define MP5416_VSET_SW3_GVAL(x) ((((x) & 0x7f) * 12500) + 600000) +#define MP5416_VSET_SW4_GVAL(x) ((((x) & 0x7f) * 25000) + 800000) +#define MP5416_VSET_LDO_GVAL(x) ((((x) & 0x7f) * 25000) + 800000) +#define MP5416_VSET_LDO_SVAL(x) ((((x) & 0x7f) * 25000) + 800000) +#define MP5416_VSET_SW1_SVAL(x) (((x) - 600000) / 12500) +#define MP5416_VSET_SW2_SVAL(x) (((x) - 800000) / 25000) +#define MP5416_VSET_SW3_SVAL(x) (((x) - 600000) / 12500) +#define MP5416_VSET_SW4_SVAL(x) (((x) - 800000) / 25000) + +#endif diff --git a/include/test/ut.h b/include/test/ut.h index 3f2ee7514b..17400c73ea 100644 --- a/include/test/ut.h +++ b/include/test/ut.h @@ -338,4 +338,22 @@ ulong ut_check_free(void); */ long ut_check_delta(ulong last); +/** + * ut_silence_console() - Silence the console if requested by the user + * + * This stops test output from appear on the console. It is the default on + * sandbox, unless the -v flag is given. For other boards, this does nothing. + * + * @uts: Test state (in case in future we want to keep state here) + */ +void ut_silence_console(struct unit_test_state *uts); + +/** + * ut_unsilence_console() - Unsilence the console after a test + * + * This restarts console output again and turns off console recording. This + * happens on all boards, including sandbox. + */ +void ut_unsilence_console(struct unit_test_state *uts); + #endif diff --git a/include/uuid.h b/include/uuid.h index 73c5a89ec7..0c653cb087 100644 --- a/include/uuid.h +++ b/include/uuid.h @@ -39,10 +39,8 @@ int uuid_str_to_bin(const char *uuid_str, unsigned char *uuid_bin, int str_format); void uuid_bin_to_str(const unsigned char *uuid_bin, char *uuid_str, int str_format); -#ifdef CONFIG_PARTITION_TYPE_GUID int uuid_guid_get_bin(const char *guid_str, unsigned char *guid_bin); -int uuid_guid_get_str(const unsigned char *guid_bin, char *guid_str); -#endif +const char *uuid_guid_get_str(const unsigned char *guid_bin); void gen_rand_uuid(unsigned char *uuid_bin); void gen_rand_uuid_str(char *uuid_str, int str_format); #endif diff --git a/include/xen.h b/include/xen.h index a952a2c84b..868132156e 100644 --- a/include/xen.h +++ b/include/xen.h @@ -11,7 +11,7 @@ * Map Xen memory pages, initialize event handler and xenbus, * setup the grant table. */ -void xen_init(void); +int xen_init(void); /** * xen_fini() - Board cleanup before Linux kernel start diff --git a/lib/Kconfig b/lib/Kconfig index a704568443..b35a71ac36 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -210,6 +210,7 @@ config BITREVERSE config TRACE bool "Support for tracing of function calls and timing" imply CMD_TRACE + select TIMER_EARLY help Enables function tracing within U-Boot. This allows recording of call traces including timing information. The command can write data to @@ -695,8 +696,8 @@ config LIB_DATE config LIB_ELF bool help - Supoort basic elf loading/validating functions. - This supports fir 32 bit and 64 bit versions. + Support basic elf loading/validating functions. + This supports for 32 bit and 64 bit versions. endmenu @@ -619,7 +619,7 @@ void aes_decrypt(u32 key_len, u8 *in, u8 *expkey, u8 *out) static void debug_print_vector(char *name, u32 num_bytes, u8 *data) { #ifdef DEBUG - printf("%s [%d] @0x%08x", name, num_bytes, (u32)data); + printf("%s [%d] @0x%p", name, num_bytes, data); print_buffer(0, data, 1, num_bytes, 16); #endif } diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index fdf245dea3..e729f727df 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -27,6 +27,14 @@ config EFI_LOADER if EFI_LOADER +config CMD_BOOTEFI_BOOTMGR + bool "UEFI Boot Manager" + default y + help + Select this option if you want to select the UEFI binary to be booted + via UEFI variables Boot####, BootOrder, and BootNext. This enables the + 'bootefi bootmgr' command. + config EFI_SETUP_EARLY bool default n @@ -200,6 +208,21 @@ config EFI_DEVICE_PATH_TO_TEXT The device path to text protocol converts device nodes and paths to human readable strings. +config EFI_DEVICE_PATH_UTIL + bool "Device path utilities protocol" + default y + help + The device path utilities protocol creates and manipulates device + paths and device nodes. It is required to run the EFI Shell. + +config EFI_DT_FIXUP + bool "Device tree fixup protocol" + depends on !GENERATE_ACPI_TABLE + default y + help + The EFI device-tree fix-up protocol provides a function to let the + firmware apply fix-ups. This may be used by boot loaders. + config EFI_LOADER_HII bool "HII protocols" default y @@ -229,17 +252,6 @@ config EFI_UNICODE_CAPITALIZATION set, only the the correct handling of the letters of the codepage used by the FAT file system is ensured. -config EFI_UNICODE_COLLATION_PROTOCOL - bool "Deprecated version of the Unicode collation protocol" - default n - help - In EFI 1.10 a version of the Unicode collation protocol using ISO - 639-2 language codes existed. This protocol is not part of the UEFI - specification any longer. Unfortunately it is required to run the - UEFI Self Certification Test (SCT) II, version 2.6, 2017. - - Choose this option for testing only. It is bound to be removed. - endif config EFI_LOADER_BOUNCE_BUFFER diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile index 462d4d9ac4..10b42e8847 100644 --- a/lib/efi_loader/Makefile +++ b/lib/efi_loader/Makefile @@ -21,17 +21,21 @@ targets += helloworld.o endif obj-$(CONFIG_CMD_BOOTEFI_HELLO) += helloworld_efi.o -obj-y += efi_bootmgr.o +obj-$(CONFIG_CMD_BOOTEFI_BOOTMGR) += efi_bootmgr.o obj-y += efi_boottime.o obj-$(CONFIG_EFI_HAVE_CAPSULE_SUPPORT) += efi_capsule.o obj-$(CONFIG_EFI_CAPSULE_FIRMWARE) += efi_firmware.o obj-y += efi_console.o obj-y += efi_device_path.o obj-$(CONFIG_EFI_DEVICE_PATH_TO_TEXT) += efi_device_path_to_text.o -obj-y += efi_device_path_utilities.o +obj-$(CONFIG_EFI_DEVICE_PATH_UTIL) += efi_device_path_utilities.o +ifeq ($(CONFIG_GENERATE_ACPI_TABLE),) +obj-y += efi_dt_fixup.o +endif obj-y += efi_file.o obj-$(CONFIG_EFI_LOADER_HII) += efi_hii.o obj-y += efi_image_loader.o +obj-y += efi_load_options.o obj-y += efi_memory.o obj-y += efi_root_node.o obj-y += efi_runtime.o diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c index d3be2f94c6..25f5cebfdb 100644 --- a/lib/efi_loader/efi_bootmgr.c +++ b/lib/efi_loader/efi_bootmgr.c @@ -31,141 +31,6 @@ static const struct efi_runtime_services *rs; */ /** - * efi_set_load_options() - set the load options of a loaded image - * - * @handle: the image handle - * @load_options_size: size of load options - * @load_options: pointer to load options - * Return: status code - */ -efi_status_t efi_set_load_options(efi_handle_t handle, - efi_uintn_t load_options_size, - void *load_options) -{ - struct efi_loaded_image *loaded_image_info; - efi_status_t ret; - - ret = EFI_CALL(systab.boottime->open_protocol( - handle, - &efi_guid_loaded_image, - (void **)&loaded_image_info, - efi_root, NULL, - EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL)); - if (ret != EFI_SUCCESS) - return EFI_INVALID_PARAMETER; - - loaded_image_info->load_options = load_options; - loaded_image_info->load_options_size = load_options_size; - - return EFI_CALL(systab.boottime->close_protocol(handle, - &efi_guid_loaded_image, - efi_root, NULL)); -} - - -/** - * efi_deserialize_load_option() - parse serialized data - * - * Parse serialized data describing a load option and transform it to the - * efi_load_option structure. - * - * @lo: pointer to target - * @data: serialized data - * @size: size of the load option, on return size of the optional data - * Return: status code - */ -efi_status_t efi_deserialize_load_option(struct efi_load_option *lo, u8 *data, - efi_uintn_t *size) -{ - efi_uintn_t len; - - len = sizeof(u32); - if (*size < len + 2 * sizeof(u16)) - return EFI_INVALID_PARAMETER; - lo->attributes = get_unaligned_le32(data); - data += len; - *size -= len; - - len = sizeof(u16); - lo->file_path_length = get_unaligned_le16(data); - data += len; - *size -= len; - - lo->label = (u16 *)data; - len = u16_strnlen(lo->label, *size / sizeof(u16) - 1); - if (lo->label[len]) - return EFI_INVALID_PARAMETER; - len = (len + 1) * sizeof(u16); - if (*size < len) - return EFI_INVALID_PARAMETER; - data += len; - *size -= len; - - len = lo->file_path_length; - if (*size < len) - return EFI_INVALID_PARAMETER; - lo->file_path = (struct efi_device_path *)data; - if (efi_dp_check_length(lo->file_path, len) < 0) - return EFI_INVALID_PARAMETER; - data += len; - *size -= len; - - lo->optional_data = data; - - return EFI_SUCCESS; -} - -/** - * efi_serialize_load_option() - serialize load option - * - * Serialize efi_load_option structure into byte stream for BootXXXX. - * - * @data: buffer for serialized data - * @lo: load option - * Return: size of allocated buffer - */ -unsigned long efi_serialize_load_option(struct efi_load_option *lo, u8 **data) -{ - unsigned long label_len; - unsigned long size; - u8 *p; - - label_len = (u16_strlen(lo->label) + 1) * sizeof(u16); - - /* total size */ - size = sizeof(lo->attributes); - size += sizeof(lo->file_path_length); - size += label_len; - size += lo->file_path_length; - if (lo->optional_data) - size += (utf8_utf16_strlen((const char *)lo->optional_data) - + 1) * sizeof(u16); - p = malloc(size); - if (!p) - return 0; - - /* copy data */ - *data = p; - memcpy(p, &lo->attributes, sizeof(lo->attributes)); - p += sizeof(lo->attributes); - - memcpy(p, &lo->file_path_length, sizeof(lo->file_path_length)); - p += sizeof(lo->file_path_length); - - memcpy(p, lo->label, label_len); - p += label_len; - - memcpy(p, lo->file_path, lo->file_path_length); - p += lo->file_path_length; - - if (lo->optional_data) { - utf8_utf16_strcpy((u16 **)&p, (const char *)lo->optional_data); - p += sizeof(u16); /* size of trailing \0 */ - } - return size; -} - -/** * get_var() - get UEFI variable * * It is the caller's duty to free the returned buffer. diff --git a/lib/efi_loader/efi_console.c b/lib/efi_loader/efi_console.c index 705109596e..edcfce7bec 100644 --- a/lib/efi_loader/efi_console.c +++ b/lib/efi_loader/efi_console.c @@ -141,12 +141,12 @@ static int term_read_reply(int *n, int num, char end_char) */ static efi_status_t EFIAPI efi_cout_output_string( struct efi_simple_text_output_protocol *this, - const efi_string_t string) + const u16 *string) { struct simple_text_output_mode *con = &efi_con_mode; struct cout_mode *mode = &efi_cout_modes[con->mode]; char *buf, *pos; - u16 *p; + const u16 *p; efi_status_t ret = EFI_SUCCESS; EFI_ENTRY("%p, %p", this, string); @@ -230,7 +230,7 @@ out: */ static efi_status_t EFIAPI efi_cout_test_string( struct efi_simple_text_output_protocol *this, - const efi_string_t string) + const u16 *string) { EFI_ENTRY("%p, %p", this, string); return EFI_EXIT(EFI_SUCCESS); diff --git a/lib/efi_loader/efi_dt_fixup.c b/lib/efi_loader/efi_dt_fixup.c new file mode 100644 index 0000000000..3850ab3b0f --- /dev/null +++ b/lib/efi_loader/efi_dt_fixup.c @@ -0,0 +1,166 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * EFI_DT_FIXUP_PROTOCOL + * + * Copyright (c) 2020 Heinrich Schuchardt + */ + +#include <common.h> +#include <efi_dt_fixup.h> +#include <efi_loader.h> +#include <mapmem.h> + +const efi_guid_t efi_guid_dt_fixup_protocol = EFI_DT_FIXUP_PROTOCOL_GUID; + +/** + * efi_reserve_memory() - add reserved memory to memory map + * + * @addr: start address of the reserved memory range + * @size: size of the reserved memory range + * @nomap: indicates that the memory range shall not be accessed by the + * UEFI payload + */ +static void efi_reserve_memory(u64 addr, u64 size, bool nomap) +{ + int type; + efi_uintn_t ret; + + /* Convert from sandbox address space. */ + addr = (uintptr_t)map_sysmem(addr, 0); + + if (nomap) + type = EFI_RESERVED_MEMORY_TYPE; + else + type = EFI_BOOT_SERVICES_DATA; + + ret = efi_add_memory_map(addr, size, type); + if (ret != EFI_SUCCESS) + log_err("Reserved memory mapping failed addr %llx size %llx\n", + addr, size); +} + +/** + * efi_carve_out_dt_rsv() - Carve out DT reserved memory ranges + * + * The mem_rsv entries of the FDT are added to the memory map. Any failures are + * ignored because this is not critical and we would rather continue to try to + * boot. + * + * @fdt: Pointer to device tree + */ +void efi_carve_out_dt_rsv(void *fdt) +{ + int nr_rsv, i; + u64 addr, size; + int nodeoffset, subnode; + + nr_rsv = fdt_num_mem_rsv(fdt); + + /* Look for an existing entry and add it to the efi mem map. */ + for (i = 0; i < nr_rsv; i++) { + if (fdt_get_mem_rsv(fdt, i, &addr, &size) != 0) + continue; + efi_reserve_memory(addr, size, false); + } + + /* process reserved-memory */ + nodeoffset = fdt_subnode_offset(fdt, 0, "reserved-memory"); + if (nodeoffset >= 0) { + subnode = fdt_first_subnode(fdt, nodeoffset); + while (subnode >= 0) { + fdt_addr_t fdt_addr; + fdt_size_t fdt_size; + + /* check if this subnode has a reg property */ + fdt_addr = fdtdec_get_addr_size_auto_parent( + fdt, nodeoffset, subnode, + "reg", 0, &fdt_size, false); + /* + * The /reserved-memory node may have children with + * a size instead of a reg property. + */ + if (fdt_addr != FDT_ADDR_T_NONE && + fdtdec_get_is_enabled(fdt, subnode)) { + bool nomap; + + nomap = !!fdt_getprop(fdt, subnode, "no-map", + NULL); + efi_reserve_memory(fdt_addr, fdt_size, nomap); + } + subnode = fdt_next_subnode(fdt, subnode); + } + } +} + +/** + * efi_dt_fixup() - fix up device tree + * + * This function implements the Fixup() service of the + * EFI Device Tree Fixup Protocol. + * + * @this: instance of the protocol + * @dtb: device tree provided by caller + * @buffer_size: size of buffer for the device tree including free space + * @flags: bit field designating action to be performed + * Return: status code + */ +static efi_status_t __maybe_unused EFIAPI +efi_dt_fixup(struct efi_dt_fixup_protocol *this, void *dtb, + efi_uintn_t *buffer_size, u32 flags) +{ + efi_status_t ret; + size_t required_size; + bootm_headers_t img = { 0 }; + + EFI_ENTRY("%p, %p, %p, %d", this, dtb, buffer_size, flags); + + if (this != &efi_dt_fixup_prot || !dtb || !buffer_size || + !flags || (flags & ~EFI_DT_ALL)) { + ret = EFI_INVALID_PARAMETER; + goto out; + } + if (fdt_check_header(dtb)) { + ret = EFI_INVALID_PARAMETER; + goto out; + } + if (flags & EFI_DT_APPLY_FIXUPS) { + required_size = fdt_off_dt_strings(dtb) + + fdt_size_dt_strings(dtb) + + 0x3000; + } else { + required_size = fdt_totalsize(dtb); + } + if (required_size > *buffer_size) { + *buffer_size = required_size; + ret = EFI_BUFFER_TOO_SMALL; + goto out; + } + fdt_set_totalsize(dtb, *buffer_size); + + if (flags & EFI_DT_APPLY_FIXUPS) { + if (image_setup_libfdt(&img, dtb, 0, NULL)) { + log_err("failed to process device tree\n"); + ret = EFI_INVALID_PARAMETER; + goto out; + } + } + if (flags & EFI_DT_RESERVE_MEMORY) + efi_carve_out_dt_rsv(dtb); + + if (EFI_DT_INSTALL_TABLE) { + ret = efi_install_configuration_table(&efi_guid_fdt, dtb); + if (ret != EFI_SUCCESS) { + log_err("ERROR: failed to install device tree\n"); + goto out; + } + } + + ret = EFI_SUCCESS; +out: + return EFI_EXIT(ret); +} + +struct efi_dt_fixup_protocol efi_dt_fixup_prot = { + .revision = EFI_DT_FIXUP_PROTOCOL_REVISION, + .fixup = efi_dt_fixup +}; diff --git a/lib/efi_loader/efi_file.c b/lib/efi_loader/efi_file.c index 72b7ec1e63..8ece8e71ee 100644 --- a/lib/efi_loader/efi_file.c +++ b/lib/efi_loader/efi_file.c @@ -246,18 +246,16 @@ error: return NULL; } -static efi_status_t EFIAPI efi_file_open(struct efi_file_handle *file, - struct efi_file_handle **new_handle, - u16 *file_name, u64 open_mode, u64 attributes) +static efi_status_t efi_file_open_int(struct efi_file_handle *this, + struct efi_file_handle **new_handle, + u16 *file_name, u64 open_mode, + u64 attributes) { - struct file_handle *fh = to_fh(file); + struct file_handle *fh = to_fh(this); efi_status_t ret; - EFI_ENTRY("%p, %p, \"%ls\", %llx, %llu", file, new_handle, - file_name, open_mode, attributes); - /* Check parameters */ - if (!file || !new_handle || !file_name) { + if (!this || !new_handle || !file_name) { ret = EFI_INVALID_PARAMETER; goto out; } @@ -292,6 +290,75 @@ static efi_status_t EFIAPI efi_file_open(struct efi_file_handle *file, ret = EFI_NOT_FOUND; } out: + return ret; +} + +/** + * efi_file_open_() + * + * This function implements the Open service of the File Protocol. + * See the UEFI spec for details. + * + * @this: EFI_FILE_PROTOCOL instance + * @new_handle: on return pointer to file handle + * @file_name: file name + * @open_mode: mode to open the file (read, read/write, create/read/write) + * @attributes: attributes for newly created file + */ +static efi_status_t EFIAPI efi_file_open(struct efi_file_handle *this, + struct efi_file_handle **new_handle, + u16 *file_name, u64 open_mode, + u64 attributes) +{ + efi_status_t ret; + + EFI_ENTRY("%p, %p, \"%ls\", %llx, %llu", this, new_handle, + file_name, open_mode, attributes); + + ret = efi_file_open_int(this, new_handle, file_name, open_mode, + attributes); + + return EFI_EXIT(ret); +} + +/** + * efi_file_open_ex() - open file asynchronously + * + * This function implements the OpenEx service of the File Protocol. + * See the UEFI spec for details. + * + * @this: EFI_FILE_PROTOCOL instance + * @new_handle: on return pointer to file handle + * @file_name: file name + * @open_mode: mode to open the file (read, read/write, create/read/write) + * @attributes: attributes for newly created file + * @token: transaction token + */ +static efi_status_t EFIAPI efi_file_open_ex(struct efi_file_handle *this, + struct efi_file_handle **new_handle, + u16 *file_name, u64 open_mode, + u64 attributes, + struct efi_file_io_token *token) +{ + efi_status_t ret; + + EFI_ENTRY("%p, %p, \"%ls\", %llx, %llu, %p", this, new_handle, + file_name, open_mode, attributes, token); + + if (!token) { + ret = EFI_INVALID_PARAMETER; + goto out; + } + + ret = efi_file_open_int(this, new_handle, file_name, open_mode, + attributes); + + if (ret == EFI_SUCCESS && token->event) { + token->status = EFI_SUCCESS; + efi_signal_event(token->event); + } + +out: return EFI_EXIT(ret); } @@ -441,19 +508,15 @@ static efi_status_t dir_read(struct file_handle *fh, u64 *buffer_size, return EFI_SUCCESS; } -static efi_status_t EFIAPI efi_file_read(struct efi_file_handle *file, - efi_uintn_t *buffer_size, void *buffer) +static efi_status_t efi_file_read_int(struct efi_file_handle *this, + efi_uintn_t *buffer_size, void *buffer) { - struct file_handle *fh = to_fh(file); + struct file_handle *fh = to_fh(this); efi_status_t ret = EFI_SUCCESS; u64 bs; - EFI_ENTRY("%p, %p, %p", file, buffer_size, buffer); - - if (!buffer_size) { - ret = EFI_INVALID_PARAMETER; - goto error; - } + if (!this || !buffer_size || !buffer) + return EFI_INVALID_PARAMETER; bs = *buffer_size; if (fh->isdir) @@ -465,34 +528,77 @@ static efi_status_t EFIAPI efi_file_read(struct efi_file_handle *file, else *buffer_size = SIZE_MAX; -error: + return ret; +} + +/** + * efi_file_read() - read file + * + * This function implements the Read() service of the EFI_FILE_PROTOCOL. + * + * See the Unified Extensible Firmware Interface (UEFI) specification for + * details. + * + * @this: file protocol instance + * @buffer_size: number of bytes to read + * @buffer: read buffer + * Return: status code + */ +static efi_status_t EFIAPI efi_file_read(struct efi_file_handle *this, + efi_uintn_t *buffer_size, void *buffer) +{ + efi_status_t ret; + + EFI_ENTRY("%p, %p, %p", this, buffer_size, buffer); + + ret = efi_file_read_int(this, buffer_size, buffer); + return EFI_EXIT(ret); } /** - * efi_file_write() - write to file + * efi_file_read_ex() - read file asynchonously * - * This function implements the Write() service of the EFI_FILE_PROTOCOL. + * This function implements the ReadEx() service of the EFI_FILE_PROTOCOL. * * See the Unified Extensible Firmware Interface (UEFI) specification for * details. * - * @file: file handle - * @buffer_size: number of bytes to write - * @buffer: buffer with the bytes to write + * @this: file protocol instance + * @token: transaction token * Return: status code */ -static efi_status_t EFIAPI efi_file_write(struct efi_file_handle *file, - efi_uintn_t *buffer_size, - void *buffer) +static efi_status_t EFIAPI efi_file_read_ex(struct efi_file_handle *this, + struct efi_file_io_token *token) { - struct file_handle *fh = to_fh(file); + efi_status_t ret; + + EFI_ENTRY("%p, %p", this, token); + + if (!token) { + ret = EFI_INVALID_PARAMETER; + goto out; + } + + ret = efi_file_read_int(this, &token->buffer_size, token->buffer); + + if (ret == EFI_SUCCESS && token->event) { + token->status = EFI_SUCCESS; + efi_signal_event(token->event); + } + +out: + return EFI_EXIT(ret); +} + +static efi_status_t efi_file_write_int(struct efi_file_handle *this, + efi_uintn_t *buffer_size, void *buffer) +{ + struct file_handle *fh = to_fh(this); efi_status_t ret = EFI_SUCCESS; loff_t actwrite; - EFI_ENTRY("%p, %p, %p", file, buffer_size, buffer); - - if (!file || !buffer_size || !buffer) { + if (!this || !buffer_size || !buffer) { ret = EFI_INVALID_PARAMETER; goto out; } @@ -521,6 +627,67 @@ static efi_status_t EFIAPI efi_file_write(struct efi_file_handle *file, fh->offset += actwrite; out: + return ret; +} + +/** + * efi_file_write() - write to file + * + * This function implements the Write() service of the EFI_FILE_PROTOCOL. + * + * See the Unified Extensible Firmware Interface (UEFI) specification for + * details. + * + * @this: file protocol instance + * @buffer_size: number of bytes to write + * @buffer: buffer with the bytes to write + * Return: status code + */ +static efi_status_t EFIAPI efi_file_write(struct efi_file_handle *this, + efi_uintn_t *buffer_size, + void *buffer) +{ + efi_status_t ret; + + EFI_ENTRY("%p, %p, %p", this, buffer_size, buffer); + + ret = efi_file_write_int(this, buffer_size, buffer); + + return EFI_EXIT(ret); +} + +/** + * efi_file_write_ex() - write to file + * + * This function implements the WriteEx() service of the EFI_FILE_PROTOCOL. + * + * See the Unified Extensible Firmware Interface (UEFI) specification for + * details. + * + * @this: file protocol instance + * @token: transaction token + * Return: status code + */ +static efi_status_t EFIAPI efi_file_write_ex(struct efi_file_handle *this, + struct efi_file_io_token *token) +{ + efi_status_t ret; + + EFI_ENTRY("%p, %p", this, token); + + if (!token) { + ret = EFI_INVALID_PARAMETER; + goto out; + } + + ret = efi_file_write_int(this, &token->buffer_size, token->buffer); + + if (ret == EFI_SUCCESS && token->event) { + token->status = EFI_SUCCESS; + efi_signal_event(token->event); + } + +out: return EFI_EXIT(ret); } @@ -761,36 +928,84 @@ out: return EFI_EXIT(ret); } -static efi_status_t EFIAPI efi_file_flush(struct efi_file_handle *file) +/** + * efi_file_flush_int() - flush file + * + * This is the internal implementation of the Flush() and FlushEx() services of + * the EFI_FILE_PROTOCOL. + * + * @this: file protocol instance + * Return: status code + */ +static efi_status_t efi_file_flush_int(struct efi_file_handle *this) { - EFI_ENTRY("%p", file); - return EFI_EXIT(EFI_SUCCESS); -} + struct file_handle *fh = to_fh(this); -static efi_status_t EFIAPI efi_file_open_ex(struct efi_file_handle *file, - struct efi_file_handle **new_handle, - u16 *file_name, u64 open_mode, u64 attributes, - struct efi_file_io_token *token) -{ - return EFI_UNSUPPORTED; -} + if (!this) + return EFI_INVALID_PARAMETER; -static efi_status_t EFIAPI efi_file_read_ex(struct efi_file_handle *file, - struct efi_file_io_token *token) -{ - return EFI_UNSUPPORTED; + if (!(fh->open_mode & EFI_FILE_MODE_WRITE)) + return EFI_ACCESS_DENIED; + + /* TODO: flush for file position after end of file */ + return EFI_SUCCESS; } -static efi_status_t EFIAPI efi_file_write_ex(struct efi_file_handle *file, - struct efi_file_io_token *token) +/** + * efi_file_flush() - flush file + * + * This function implements the Flush() service of the EFI_FILE_PROTOCOL. + * + * See the Unified Extensible Firmware Interface (UEFI) specification for + * details. + * + * @this: file protocol instance + * Return: status code + */ +static efi_status_t EFIAPI efi_file_flush(struct efi_file_handle *this) { - return EFI_UNSUPPORTED; + efi_status_t ret; + + EFI_ENTRY("%p", this); + + ret = efi_file_flush_int(this); + + return EFI_EXIT(ret); } -static efi_status_t EFIAPI efi_file_flush_ex(struct efi_file_handle *file, - struct efi_file_io_token *token) +/** + * efi_file_flush_ex() - flush file + * + * This function implements the FlushEx() service of the EFI_FILE_PROTOCOL. + * + * See the Unified Extensible Firmware Interface (UEFI) specification for + * details. + * + * @this: file protocol instance + * @token: transaction token + * Return: status code + */ +static efi_status_t EFIAPI efi_file_flush_ex(struct efi_file_handle *this, + struct efi_file_io_token *token) { - return EFI_UNSUPPORTED; + efi_status_t ret; + + EFI_ENTRY("%p, %p", this, token); + + if (!token) { + ret = EFI_INVALID_PARAMETER; + goto out; + } + + ret = efi_file_flush_int(this); + + if (ret == EFI_SUCCESS && token->event) { + token->status = EFI_SUCCESS; + efi_signal_event(token->event); + } + +out: + return EFI_EXIT(ret); } static const struct efi_file_handle efi_file_handle_protocol = { diff --git a/lib/efi_loader/efi_image_loader.c b/lib/efi_loader/efi_image_loader.c index 94f76ef6b8..d4dd9e9433 100644 --- a/lib/efi_loader/efi_image_loader.c +++ b/lib/efi_loader/efi_image_loader.c @@ -675,6 +675,46 @@ static bool efi_image_authenticate(void *efi, size_t efi_size) } #endif /* CONFIG_EFI_SECURE_BOOT */ + +/** + * efi_check_pe() - check if a memory buffer contains a PE-COFF image + * + * @buffer: buffer to check + * @size: size of buffer + * @nt_header: on return pointer to NT header of PE-COFF image + * Return: EFI_SUCCESS if the buffer contains a PE-COFF image + */ +efi_status_t efi_check_pe(void *buffer, size_t size, void **nt_header) +{ + IMAGE_DOS_HEADER *dos = buffer; + IMAGE_NT_HEADERS32 *nt; + + if (size < sizeof(*dos)) + return EFI_INVALID_PARAMETER; + + /* Check for DOS magix */ + if (dos->e_magic != IMAGE_DOS_SIGNATURE) + return EFI_INVALID_PARAMETER; + + /* + * Check if the image section header fits into the file. Knowing that at + * least one section header follows we only need to check for the length + * of the 64bit header which is longer than the 32bit header. + */ + if (size < dos->e_lfanew + sizeof(IMAGE_NT_HEADERS32)) + return EFI_INVALID_PARAMETER; + nt = (IMAGE_NT_HEADERS32 *)((u8 *)buffer + dos->e_lfanew); + + /* Check for PE-COFF magic */ + if (nt->Signature != IMAGE_NT_SIGNATURE) + return EFI_INVALID_PARAMETER; + + if (nt_header) + *nt_header = nt; + + return EFI_SUCCESS; +} + /** * efi_load_pe() - relocate EFI binary * @@ -705,36 +745,10 @@ efi_status_t efi_load_pe(struct efi_loaded_image_obj *handle, int supported = 0; efi_status_t ret; - /* Sanity check for a file header */ - if (efi_size < sizeof(*dos)) { - log_err("Truncated DOS Header\n"); - ret = EFI_LOAD_ERROR; - goto err; - } - - dos = efi; - if (dos->e_magic != IMAGE_DOS_SIGNATURE) { - log_err("Invalid DOS Signature\n"); - ret = EFI_LOAD_ERROR; - goto err; - } - - /* - * Check if the image section header fits into the file. Knowing that at - * least one section header follows we only need to check for the length - * of the 64bit header which is longer than the 32bit header. - */ - if (efi_size < dos->e_lfanew + sizeof(IMAGE_NT_HEADERS64)) { - log_err("Invalid offset for Extended Header\n"); - ret = EFI_LOAD_ERROR; - goto err; - } - - nt = (void *) ((char *)efi + dos->e_lfanew); - if (nt->Signature != IMAGE_NT_SIGNATURE) { - log_err("Invalid NT Signature\n"); - ret = EFI_LOAD_ERROR; - goto err; + ret = efi_check_pe(efi, efi_size, (void **)&nt); + if (ret != EFI_SUCCESS) { + log_err("Not a PE-COFF file\n"); + return EFI_LOAD_ERROR; } for (i = 0; machines[i]; i++) @@ -746,8 +760,7 @@ efi_status_t efi_load_pe(struct efi_loaded_image_obj *handle, if (!supported) { log_err("Machine type 0x%04x is not supported\n", nt->FileHeader.Machine); - ret = EFI_LOAD_ERROR; - goto err; + return EFI_LOAD_ERROR; } num_sections = nt->FileHeader.NumberOfSections; @@ -757,8 +770,7 @@ efi_status_t efi_load_pe(struct efi_loaded_image_obj *handle, if (efi_size < ((void *)sections + sizeof(sections[0]) * num_sections - efi)) { log_err("Invalid number of sections: %d\n", num_sections); - ret = EFI_LOAD_ERROR; - goto err; + return EFI_LOAD_ERROR; } /* Authenticate an image */ diff --git a/lib/efi_loader/efi_load_options.c b/lib/efi_loader/efi_load_options.c new file mode 100644 index 0000000000..68cd85ba2e --- /dev/null +++ b/lib/efi_loader/efi_load_options.c @@ -0,0 +1,149 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * EFI boot manager + * + * Copyright (c) 2018 AKASHI Takahiro, et.al. + */ + +#define LOG_CATEGORY LOGC_EFI + +#include <common.h> +#include <charset.h> +#include <log.h> +#include <malloc.h> +#include <efi_loader.h> +#include <asm/unaligned.h> + +/** + * efi_set_load_options() - set the load options of a loaded image + * + * @handle: the image handle + * @load_options_size: size of load options + * @load_options: pointer to load options + * Return: status code + */ +efi_status_t efi_set_load_options(efi_handle_t handle, + efi_uintn_t load_options_size, + void *load_options) +{ + struct efi_loaded_image *loaded_image_info; + efi_status_t ret; + + ret = EFI_CALL(systab.boottime->open_protocol( + handle, + &efi_guid_loaded_image, + (void **)&loaded_image_info, + efi_root, NULL, + EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL)); + if (ret != EFI_SUCCESS) + return EFI_INVALID_PARAMETER; + + loaded_image_info->load_options = load_options; + loaded_image_info->load_options_size = load_options_size; + + return EFI_CALL(systab.boottime->close_protocol(handle, + &efi_guid_loaded_image, + efi_root, NULL)); +} + +/** + * efi_deserialize_load_option() - parse serialized data + * + * Parse serialized data describing a load option and transform it to the + * efi_load_option structure. + * + * @lo: pointer to target + * @data: serialized data + * @size: size of the load option, on return size of the optional data + * Return: status code + */ +efi_status_t efi_deserialize_load_option(struct efi_load_option *lo, u8 *data, + efi_uintn_t *size) +{ + efi_uintn_t len; + + len = sizeof(u32); + if (*size < len + 2 * sizeof(u16)) + return EFI_INVALID_PARAMETER; + lo->attributes = get_unaligned_le32(data); + data += len; + *size -= len; + + len = sizeof(u16); + lo->file_path_length = get_unaligned_le16(data); + data += len; + *size -= len; + + lo->label = (u16 *)data; + len = u16_strnlen(lo->label, *size / sizeof(u16) - 1); + if (lo->label[len]) + return EFI_INVALID_PARAMETER; + len = (len + 1) * sizeof(u16); + if (*size < len) + return EFI_INVALID_PARAMETER; + data += len; + *size -= len; + + len = lo->file_path_length; + if (*size < len) + return EFI_INVALID_PARAMETER; + lo->file_path = (struct efi_device_path *)data; + if (efi_dp_check_length(lo->file_path, len) < 0) + return EFI_INVALID_PARAMETER; + data += len; + *size -= len; + + lo->optional_data = data; + + return EFI_SUCCESS; +} + +/** + * efi_serialize_load_option() - serialize load option + * + * Serialize efi_load_option structure into byte stream for BootXXXX. + * + * @data: buffer for serialized data + * @lo: load option + * Return: size of allocated buffer + */ +unsigned long efi_serialize_load_option(struct efi_load_option *lo, u8 **data) +{ + unsigned long label_len; + unsigned long size; + u8 *p; + + label_len = (u16_strlen(lo->label) + 1) * sizeof(u16); + + /* total size */ + size = sizeof(lo->attributes); + size += sizeof(lo->file_path_length); + size += label_len; + size += lo->file_path_length; + if (lo->optional_data) + size += (utf8_utf16_strlen((const char *)lo->optional_data) + + 1) * sizeof(u16); + p = malloc(size); + if (!p) + return 0; + + /* copy data */ + *data = p; + memcpy(p, &lo->attributes, sizeof(lo->attributes)); + p += sizeof(lo->attributes); + + memcpy(p, &lo->file_path_length, sizeof(lo->file_path_length)); + p += sizeof(lo->file_path_length); + + memcpy(p, lo->label, label_len); + p += label_len; + + memcpy(p, lo->file_path, lo->file_path_length); + p += lo->file_path_length; + + if (lo->optional_data) { + utf8_utf16_strcpy((u16 **)&p, (const char *)lo->optional_data); + p += sizeof(u16); /* size of trailing \0 */ + } + return size; +} diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c index 11e755363e..a3106aba7f 100644 --- a/lib/efi_loader/efi_memory.c +++ b/lib/efi_loader/efi_memory.c @@ -541,8 +541,6 @@ efi_status_t efi_free_pages(uint64_t memory, efi_uintn_t pages) ret = efi_add_memory_map_pg(memory, pages, EFI_CONVENTIONAL_MEMORY, false); - /* Merging of adjacent free regions is missing */ - if (ret != EFI_SUCCESS) return EFI_NOT_FOUND; diff --git a/lib/efi_loader/efi_root_node.c b/lib/efi_loader/efi_root_node.c index b17db312f7..739c6867f4 100644 --- a/lib/efi_loader/efi_root_node.c +++ b/lib/efi_loader/efi_root_node.c @@ -7,6 +7,7 @@ #include <common.h> #include <malloc.h> +#include <efi_dt_fixup.h> #include <efi_loader.h> const efi_guid_t efi_u_boot_guid = U_BOOT_GUID; @@ -57,16 +58,17 @@ efi_status_t efi_root_node_register(void) &efi_guid_device_path_to_text_protocol, (void *)&efi_device_path_to_text, #endif +#ifdef CONFIG_EFI_DEVICE_PATH_UTIL /* Device path utilities protocol */ &efi_guid_device_path_utilities_protocol, (void *)&efi_device_path_utilities, -#if CONFIG_IS_ENABLED(EFI_UNICODE_COLLATION_PROTOCOL2) -#if CONFIG_IS_ENABLED(EFI_UNICODE_COLLATION_PROTOCOL) - /* Deprecated Unicode collation protocol */ - &efi_guid_unicode_collation_protocol, - (void *)&efi_unicode_collation_protocol, #endif - /* Current Unicode collation protocol */ +#ifdef CONFIG_EFI_DT_FIXUP + /* Device-tree fix-up protocol */ + &efi_guid_dt_fixup_protocol, + (void *)&efi_dt_fixup_prot, +#endif +#if CONFIG_IS_ENABLED(EFI_UNICODE_COLLATION_PROTOCOL2) &efi_guid_unicode_collation_protocol2, (void *)&efi_unicode_collation_protocol2, #endif diff --git a/lib/efi_loader/efi_unicode_collation.c b/lib/efi_loader/efi_unicode_collation.c index 6655c68092..f6c875bc33 100644 --- a/lib/efi_loader/efi_unicode_collation.c +++ b/lib/efi_loader/efi_unicode_collation.c @@ -38,7 +38,7 @@ const efi_guid_t efi_guid_unicode_collation_protocol2 = * @s2: second string * * This function implements the StriColl() service of the - * EFI_UNICODE_COLLATION_PROTOCOL. + * EFI_UNICODE_COLLATION_PROTOCOL2. * * See the Unified Extensible Firmware Interface (UEFI) specification for * details. @@ -179,7 +179,7 @@ static bool metai_match(const u16 *string, const u16 *pattern) * - [<char1>-<char2>] matches any character in the range * * This function implements the MetaMatch() service of the - * EFI_UNICODE_COLLATION_PROTOCOL. + * EFI_UNICODE_COLLATION_PROTOCOL2. * * Return: true if the string is matched. */ @@ -204,7 +204,7 @@ static bool EFIAPI efi_metai_match(struct efi_unicode_collation_protocol *this, * same number of words this does not pose a problem. * * This function implements the StrLwr() service of the - * EFI_UNICODE_COLLATION_PROTOCOL. + * EFI_UNICODE_COLLATION_PROTOCOL2. */ static void EFIAPI efi_str_lwr(struct efi_unicode_collation_protocol *this, u16 *string) @@ -225,7 +225,7 @@ static void EFIAPI efi_str_lwr(struct efi_unicode_collation_protocol *this, * same number of words this does not pose a problem. * * This function implements the StrUpr() service of the - * EFI_UNICODE_COLLATION_PROTOCOL. + * EFI_UNICODE_COLLATION_PROTOCOL2. */ static void EFIAPI efi_str_upr(struct efi_unicode_collation_protocol *this, u16 *string) @@ -245,7 +245,7 @@ static void EFIAPI efi_str_upr(struct efi_unicode_collation_protocol *this, * @string: converted string * * This function implements the FatToStr() service of the - * EFI_UNICODE_COLLATION_PROTOCOL. + * EFI_UNICODE_COLLATION_PROTOCOL2. */ static void EFIAPI efi_fat_to_str(struct efi_unicode_collation_protocol *this, efi_uintn_t fat_size, char *fat, u16 *string) @@ -276,7 +276,7 @@ static void EFIAPI efi_fat_to_str(struct efi_unicode_collation_protocol *this, * @fat: converted string * * This function implements the StrToFat() service of the - * EFI_UNICODE_COLLATION_PROTOCOL. + * EFI_UNICODE_COLLATION_PROTOCOL2. * * Return: true if an illegal character was substituted by '_'. */ @@ -337,30 +337,3 @@ const struct efi_unicode_collation_protocol efi_unicode_collation_protocol2 = { .str_to_fat = efi_str_to_fat, .supported_languages = "en", }; - -/* - * In EFI 1.10 a version of the Unicode collation protocol using ISO 639-2 - * language codes existed. This protocol is not part of the UEFI specification - * any longer. Unfortunately it is required to run the UEFI Self Certification - * Test (SCT) II, version 2.6, 2017. So we implement it here for the sole - * purpose of running the SCT. It can be removed when a compliant SCT is - * available. - */ -#if CONFIG_IS_ENABLED(EFI_UNICODE_COLLATION_PROTOCOL) - -/* GUID of the EFI_UNICODE_COLLATION_PROTOCOL */ -const efi_guid_t efi_guid_unicode_collation_protocol = - EFI_UNICODE_COLLATION_PROTOCOL_GUID; - -const struct efi_unicode_collation_protocol efi_unicode_collation_protocol = { - .stri_coll = efi_stri_coll, - .metai_match = efi_metai_match, - .str_lwr = efi_str_lwr, - .str_upr = efi_str_upr, - .fat_to_str = efi_fat_to_str, - .str_to_fat = efi_str_to_fat, - /* ISO 639-2 language code */ - .supported_languages = "eng", -}; - -#endif diff --git a/lib/efi_loader/efi_var_mem.c b/lib/efi_loader/efi_var_mem.c index d155f25f60..3d335a8274 100644 --- a/lib/efi_loader/efi_var_mem.c +++ b/lib/efi_loader/efi_var_mem.c @@ -10,7 +10,13 @@ #include <efi_variable.h> #include <u-boot/crc.h> -struct efi_var_file __efi_runtime_data *efi_var_buf; +/* + * The variables efi_var_file and efi_var_entry must be static to avoid + * referencing them via the global offset table (section .got). The GOT + * is neither mapped as EfiRuntimeServicesData nor do we support its + * relocation during SetVirtualAddressMap(). + */ +static struct efi_var_file __efi_runtime_data *efi_var_buf; static struct efi_var_entry __efi_runtime_data *efi_current_var; /** @@ -339,3 +345,8 @@ efi_get_next_variable_name_mem(efi_uintn_t *variable_name_size, return EFI_SUCCESS; } + +void efi_var_buf_update(struct efi_var_file *var_buf) +{ + memcpy(efi_var_buf, var_buf, EFI_VAR_BUF_SIZE); +} diff --git a/lib/efi_loader/efi_variable_tee.c b/lib/efi_loader/efi_variable_tee.c index b8808fdeca..51920bcb51 100644 --- a/lib/efi_loader/efi_variable_tee.c +++ b/lib/efi_loader/efi_variable_tee.c @@ -702,7 +702,7 @@ void efi_variables_boot_exit_notify(void) if (ret != EFI_SUCCESS) log_err("Can't populate EFI variables. No runtime variables will be available\n"); else - memcpy(efi_var_buf, var_buf, len); + efi_var_buf_update(var_buf); free(var_buf); /* Update runtime service table */ diff --git a/lib/efi_loader/helloworld.c b/lib/efi_loader/helloworld.c index 9ae2ee3389..5c8b7a96f9 100644 --- a/lib/efi_loader/helloworld.c +++ b/lib/efi_loader/helloworld.c @@ -1,43 +1,41 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * EFI hello world + * Hello world EFI application * - * Copyright (c) 2016 Google, Inc - * Written by Simon Glass <sjg@chromium.org> + * Copyright 2020, Heinrich Schuchardt <xypron.glpk@gmx.de> * - * This program demonstrates calling a boottime service. - * It writes a greeting and the load options to the console. + * This test program is used to test the invocation of an EFI application. + * It writes + * + * * a greeting + * * the firmware's UEFI version + * * the installed configuration tables + * * the boot device's device path and the file path + * + * to the console. */ -#include <common.h> #include <efi_api.h> static const efi_guid_t loaded_image_guid = EFI_LOADED_IMAGE_PROTOCOL_GUID; +static const efi_guid_t device_path_to_text_protocol_guid = + EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID; +static const efi_guid_t device_path_guid = EFI_DEVICE_PATH_PROTOCOL_GUID; static const efi_guid_t fdt_guid = EFI_FDT_GUID; static const efi_guid_t acpi_guid = EFI_ACPI_TABLE_GUID; static const efi_guid_t smbios_guid = SMBIOS_TABLE_GUID; +static struct efi_system_table *systable; +static struct efi_boot_services *boottime; +static struct efi_simple_text_output_protocol *con_out; + /** - * efi_main() - entry point of the EFI application. - * - * @handle: handle of the loaded image - * @systable: system table - * @return: status code + * print_uefi_revision() - print UEFI revision number */ -efi_status_t EFIAPI efi_main(efi_handle_t handle, - struct efi_system_table *systable) +static void print_uefi_revision(void) { - struct efi_simple_text_output_protocol *con_out = systable->con_out; - struct efi_boot_services *boottime = systable->boottime; - struct efi_loaded_image *loaded_image; - efi_status_t ret; - efi_uintn_t i; u16 rev[] = L"0.0.0"; - /* UEFI requires CR LF */ - con_out->output_string(con_out, L"Hello, world!\r\n"); - - /* Print the revision number */ rev[0] = (systable->hdr.revision >> 16) + '0'; rev[4] = systable->hdr.revision & 0xffff; for (; rev[4] >= 10;) { @@ -53,15 +51,15 @@ efi_status_t EFIAPI efi_main(efi_handle_t handle, con_out->output_string(con_out, L"Running on UEFI "); con_out->output_string(con_out, rev); con_out->output_string(con_out, L"\r\n"); +} + +/** + * print_config_tables() - print configuration tables + */ +static void print_config_tables(void) +{ + efi_uintn_t i; - /* Get the loaded image protocol */ - ret = boottime->handle_protocol(handle, &loaded_image_guid, - (void **)&loaded_image); - if (ret != EFI_SUCCESS) { - con_out->output_string - (con_out, L"Cannot open loaded image protocol\r\n"); - goto out; - } /* Find configuration tables */ for (i = 0; i < systable->nr_tables; ++i) { if (!memcmp(&systable->tables[i].guid, &fdt_guid, @@ -77,6 +75,16 @@ efi_status_t EFIAPI efi_main(efi_handle_t handle, con_out->output_string (con_out, L"Have SMBIOS table\r\n"); } +} + +/** + * print_load_options() - print load options + * + * @systable: system table + * @con_out: simple text output protocol + */ +void print_load_options(struct efi_loaded_image *loaded_image) +{ /* Output the load options */ con_out->output_string(con_out, L"Load options: "); if (loaded_image->load_options_size && loaded_image->load_options) @@ -85,6 +93,105 @@ efi_status_t EFIAPI efi_main(efi_handle_t handle, else con_out->output_string(con_out, L"<none>"); con_out->output_string(con_out, L"\r\n"); +} + +/** + * print_device_path() - print device path + * + * @device_path: device path to print + * @dp2txt: device path to text protocol + */ +efi_status_t print_device_path(struct efi_device_path *device_path, + struct efi_device_path_to_text_protocol *dp2txt) +{ + u16 *string; + efi_status_t ret; + + if (!device_path) { + con_out->output_string(con_out, L"<none>\r\n"); + return EFI_SUCCESS; + } + + string = dp2txt->convert_device_path_to_text(device_path, true, false); + if (!string) { + con_out->output_string + (con_out, L"Cannot convert device path to text\r\n"); + return EFI_OUT_OF_RESOURCES; + } + con_out->output_string(con_out, string); + con_out->output_string(con_out, L"\r\n"); + ret = boottime->free_pool(string); + if (ret != EFI_SUCCESS) { + con_out->output_string(con_out, L"Cannot free pool memory\r\n"); + return ret; + } + return EFI_SUCCESS; +} + +/** + * efi_main() - entry point of the EFI application. + * + * @handle: handle of the loaded image + * @systab: system table + * @return: status code + */ +efi_status_t EFIAPI efi_main(efi_handle_t handle, + struct efi_system_table *systab) +{ + struct efi_loaded_image *loaded_image; + struct efi_device_path_to_text_protocol *device_path_to_text; + struct efi_device_path *device_path; + efi_status_t ret; + + systable = systab; + boottime = systable->boottime; + con_out = systable->con_out; + + /* UEFI requires CR LF */ + con_out->output_string(con_out, L"Hello, world!\r\n"); + + print_uefi_revision(); + print_config_tables(); + + /* Get the loaded image protocol */ + ret = boottime->handle_protocol(handle, &loaded_image_guid, + (void **)&loaded_image); + if (ret != EFI_SUCCESS) { + con_out->output_string + (con_out, L"Cannot open loaded image protocol\r\n"); + goto out; + } + print_load_options(loaded_image); + + /* Get the device path to text protocol */ + ret = boottime->locate_protocol(&device_path_to_text_protocol_guid, + NULL, (void **)&device_path_to_text); + if (ret != EFI_SUCCESS) { + con_out->output_string + (con_out, L"Cannot open device path to text protocol\r\n"); + goto out; + } + if (!loaded_image->device_handle) { + con_out->output_string + (con_out, L"Missing device handle\r\n"); + goto out; + } + ret = boottime->handle_protocol(loaded_image->device_handle, + &device_path_guid, + (void **)&device_path); + if (ret != EFI_SUCCESS) { + con_out->output_string + (con_out, L"Missing devide path for device handle\r\n"); + goto out; + } + con_out->output_string(con_out, L"Boot device: "); + ret = print_device_path(device_path, device_path_to_text); + if (ret != EFI_SUCCESS) + goto out; + con_out->output_string(con_out, L"File path: "); + ret = print_device_path(loaded_image->file_path, device_path_to_text); + if (ret != EFI_SUCCESS) + goto out; out: boottime->exit(handle, ret, 0, NULL); diff --git a/lib/efi_selftest/Makefile b/lib/efi_selftest/Makefile index 426552bfa0..7d6ea30102 100644 --- a/lib/efi_selftest/Makefile +++ b/lib/efi_selftest/Makefile @@ -14,6 +14,8 @@ CFLAGS_efi_selftest_miniapp_exit.o := $(CFLAGS_EFI) -Os -ffreestanding CFLAGS_REMOVE_efi_selftest_miniapp_exit.o := $(CFLAGS_NON_EFI) CFLAGS_efi_selftest_miniapp_return.o := $(CFLAGS_EFI) -Os -ffreestanding CFLAGS_REMOVE_efi_selftest_miniapp_return.o := $(CFLAGS_NON_EFI) +CFLAGS_initrddump_exit.o := $(CFLAGS_EFI) -Os -ffreestanding +CFLAGS_REMOVE_initrddump.o := $(CFLAGS_NON_EFI) obj-y += \ efi_selftest.o \ @@ -78,8 +80,13 @@ efi_selftest_miniapp_exception.efi \ efi_selftest_miniapp_exit.efi \ efi_selftest_miniapp_return.efi -always += \ -dtbdump.efi +ifeq ($(CONFIG_GENERATE_ACPI_TABLE),) +always += dtbdump.efi +endif + +ifdef CONFIG_EFI_LOAD_FILE2_INITRD +always += initrddump.efi +endif $(obj)/efi_miniapp_file_image_exception.h: $(obj)/efi_selftest_miniapp_exception.efi $(obj)/../../tools/file2include $(obj)/efi_selftest_miniapp_exception.efi > \ diff --git a/lib/efi_selftest/dtbdump.c b/lib/efi_selftest/dtbdump.c index d90e3eb768..953b264d9d 100644 --- a/lib/efi_selftest/dtbdump.c +++ b/lib/efi_selftest/dtbdump.c @@ -8,10 +8,12 @@ #include <common.h> #include <efi_api.h> +#include <efi_dt_fixup.h> #define BUFFER_SIZE 64 #define ESC 0x17 -#define DEFAULT_FILENAME L"dtb.dtb" + +#define efi_size_in_pages(size) ((size + EFI_PAGE_MASK) >> EFI_PAGE_SHIFT) static struct efi_simple_text_output_protocol *cerr; static struct efi_simple_text_output_protocol *cout; @@ -21,9 +23,79 @@ static const efi_guid_t fdt_guid = EFI_FDT_GUID; static const efi_guid_t loaded_image_guid = EFI_LOADED_IMAGE_PROTOCOL_GUID; static const efi_guid_t guid_simple_file_system_protocol = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID; +static efi_handle_t handle; +static struct efi_system_table *systable; +static const efi_guid_t efi_dt_fixup_protocol_guid = EFI_DT_FIXUP_PROTOCOL_GUID; +static const efi_guid_t efi_file_info_guid = EFI_FILE_INFO_GUID; + +/** + * print() - print string + * + * @string: text + */ +static void print(u16 *string) +{ + cout->output_string(cout, string); +} + +/** + * error() - print error string + * + * @string: error text + */ +static void error(u16 *string) +{ + cout->set_attribute(cout, EFI_LIGHTRED | EFI_BACKGROUND_BLACK); + print(string); + cout->set_attribute(cout, EFI_LIGHTBLUE | EFI_BACKGROUND_BLACK); +} + +/** + * efi_input_yn() - get answer to yes/no question + * + * Return: + * y or Y + * EFI_SUCCESS + * n or N + * EFI_ACCESS_DENIED + * ESC + * EFI_ABORTED + */ +static efi_status_t efi_input_yn(void) +{ + struct efi_input_key key = {0}; + efi_uintn_t index; + efi_status_t ret; + + /* Drain the console input */ + ret = cin->reset(cin, true); + for (;;) { + ret = bs->wait_for_event(1, &cin->wait_for_key, &index); + if (ret != EFI_SUCCESS) + continue; + ret = cin->read_key_stroke(cin, &key); + if (ret != EFI_SUCCESS) + continue; + switch (key.scan_code) { + case 0x17: /* Escape */ + return EFI_ABORTED; + default: + break; + } + /* Convert to lower case */ + switch (key.unicode_char | 0x20) { + case 'y': + return EFI_SUCCESS; + case 'n': + return EFI_ACCESS_DENIED; + default: + break; + } + } +} /** - * input() - read string from console + * efi_input() - read string from console * * @buffer: input buffer * @buffer_size: buffer size @@ -39,6 +111,7 @@ static efi_status_t efi_input(u16 *buffer, efi_uintn_t buffer_size) /* Drain the console input */ ret = cin->reset(cin, true); + *buffer = 0; for (;;) { ret = bs->wait_for_event(1, &cin->wait_for_key, &index); if (ret != EFI_SUCCESS) @@ -48,7 +121,7 @@ static efi_status_t efi_input(u16 *buffer, efi_uintn_t buffer_size) continue; switch (key.scan_code) { case 0x17: /* Escape */ - cout->output_string(cout, L"\nAborted\n"); + print(L"\r\nAborted\r\n"); return EFI_ABORTED; default: break; @@ -57,11 +130,12 @@ static efi_status_t efi_input(u16 *buffer, efi_uintn_t buffer_size) case 0x08: /* Backspace */ if (pos) { buffer[pos--] = 0; - cout->output_string(cout, L"\b \b"); + print(L"\b \b"); } break; case 0x0a: /* Linefeed */ case 0x0d: /* Carriage return */ + print(L"\r\n"); return EFI_SUCCESS; default: break; @@ -73,7 +147,8 @@ static efi_status_t efi_input(u16 *buffer, efi_uintn_t buffer_size) pos < buffer_size - 1) { *outbuf = key.unicode_char; buffer[pos++] = key.unicode_char; - cout->output_string(cout, outbuf); + buffer[pos] = 0; + print(outbuf); } } } @@ -117,60 +192,228 @@ void *get_dtb(struct efi_system_table *systable) } /** - * efi_main() - entry point of the EFI application. + * skip_whitespace() - skip over leading whitespace * - * @handle: handle of the loaded image - * @systable: system table - * @return: status code + * @pos: UTF-16 string + * Return: pointer to first non-whitespace */ -efi_status_t EFIAPI efi_main(efi_handle_t handle, - struct efi_system_table *systable) +u16 *skip_whitespace(u16 *pos) { - efi_uintn_t ret; - u16 filename[BUFFER_SIZE] = {0}; - efi_uintn_t dtb_size; + for (; *pos && *pos <= 0x20; ++pos) + ; + return pos; +} + +/** + * starts_with() - check if @string starts with @keyword + * + * @string: string to search for keyword + * @keyword: keyword to be searched + * Return: true fi @string starts with the keyword + */ +bool starts_with(u16 *string, u16 *keyword) +{ + for (; *keyword; ++string, ++keyword) { + if (*string != *keyword) + return false; + } + return true; +} + +/** + * do_help() - print help + */ +void do_help(void) +{ + error(L"load <dtb> - load device-tree from file\r\n"); + error(L"save <dtb> - save device-tree to file\r\n"); + error(L"exit - exit the shell\r\n"); +} + +/** + * do_load() - load and install device-tree + * + * @filename: file name + * Return: status code + */ +efi_status_t do_load(u16 *filename) +{ + struct efi_dt_fixup_protocol *dt_fixup_prot; struct efi_loaded_image *loaded_image; struct efi_simple_file_system_protocol *file_system; - struct efi_file_handle *root, *file; + struct efi_file_handle *root = NULL, *file = NULL; + u64 addr = 0; + struct efi_file_info *info; struct fdt_header *dtb; + efi_uintn_t buffer_size; + efi_uintn_t pages; + efi_status_t ret, ret2; - cerr = systable->std_err; - cout = systable->con_out; - cin = systable->con_in; - bs = systable->boottime; + ret = bs->locate_protocol(&efi_dt_fixup_protocol_guid, NULL, + (void **)&dt_fixup_prot); + if (ret != EFI_SUCCESS) { + error(L"Device-tree fix-up protocol not found\r\n"); + return ret; + } - cout->set_attribute(cout, EFI_LIGHTGRAY | EFI_BACKGROUND_BLACK); - cout->clear_screen(cout); - cout->set_attribute(cout, EFI_YELLOW | EFI_BACKGROUND_BLACK); - cout->output_string(cout, L"DTB Dump\n\n"); - cout->set_attribute(cout, EFI_LIGHTGRAY | EFI_BACKGROUND_BLACK); + filename = skip_whitespace(filename); + + ret = bs->open_protocol(handle, &loaded_image_guid, + (void **)&loaded_image, NULL, NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (ret != EFI_SUCCESS) { + error(L"Loaded image protocol not found\r\n"); + return ret; + } + /* Open the simple file system protocol */ + ret = bs->open_protocol(loaded_image->device_handle, + &guid_simple_file_system_protocol, + (void **)&file_system, NULL, NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (ret != EFI_SUCCESS) { + error(L"Failed to open simple file system protocol\r\n"); + goto out; + } + + /* Open volume */ + ret = file_system->open_volume(file_system, &root); + if (ret != EFI_SUCCESS) { + error(L"Failed to open volume\r\n"); + goto out; + } + + /* Open file */ + ret = root->open(root, &file, filename, EFI_FILE_MODE_READ, 0); + if (ret != EFI_SUCCESS) { + error(L"File not found\r\n"); + goto out; + } + /* Get file size */ + buffer_size = 0; + ret = file->getinfo(file, &efi_file_info_guid, &buffer_size, NULL); + if (ret != EFI_BUFFER_TOO_SMALL) { + error(L"Can't get file info size\r\n"); + goto out; + } + ret = bs->allocate_pool(EFI_LOADER_DATA, buffer_size, (void **)&info); + if (ret != EFI_SUCCESS) { + error(L"Out of memory\r\n"); + goto out; + } + ret = file->getinfo(file, &efi_file_info_guid, &buffer_size, info); + if (ret != EFI_SUCCESS) { + error(L"Can't get file info\r\n"); + goto out; + } + buffer_size = info->file_size; + pages = efi_size_in_pages(buffer_size); + ret = bs->free_pool(info); + if (ret != EFI_SUCCESS) + error(L"Can't free memory pool\r\n"); + /* Read file */ + ret = bs->allocate_pages(EFI_ALLOCATE_ANY_PAGES, + EFI_ACPI_RECLAIM_MEMORY, + pages, &addr); + if (ret != EFI_SUCCESS) { + error(L"Out of memory\r\n"); + goto out; + } + dtb = (struct fdt_header *)(uintptr_t)addr; + ret = file->read(file, &buffer_size, dtb); + if (ret != EFI_SUCCESS) { + error(L"Can't read file\r\n"); + goto out; + } + /* Fixup file, expecting EFI_BUFFER_TOO_SMALL */ + ret = dt_fixup_prot->fixup(dt_fixup_prot, dtb, &buffer_size, + EFI_DT_APPLY_FIXUPS | EFI_DT_RESERVE_MEMORY | + EFI_DT_INSTALL_TABLE); + if (ret == EFI_BUFFER_TOO_SMALL) { + /* Read file into larger buffer */ + ret = bs->free_pages(addr, pages); + if (ret != EFI_SUCCESS) + error(L"Can't free memory pages\r\n"); + pages = efi_size_in_pages(buffer_size); + ret = bs->allocate_pages(EFI_ALLOCATE_ANY_PAGES, + EFI_ACPI_RECLAIM_MEMORY, + pages, &addr); + if (ret != EFI_SUCCESS) { + error(L"Out of memory\r\n"); + goto out; + } + dtb = (struct fdt_header *)(uintptr_t)addr; + ret = file->setpos(file, 0); + if (ret != EFI_SUCCESS) { + error(L"Can't position file\r\n"); + goto out; + } + ret = file->read(file, &buffer_size, dtb); + if (ret != EFI_SUCCESS) { + error(L"Can't read file\r\n"); + goto out; + } + buffer_size = pages << EFI_PAGE_SHIFT; + ret = dt_fixup_prot->fixup( + dt_fixup_prot, dtb, &buffer_size, + EFI_DT_APPLY_FIXUPS | EFI_DT_RESERVE_MEMORY | + EFI_DT_INSTALL_TABLE); + } + if (ret == EFI_SUCCESS) + print(L"device-tree installed\r\n"); + else + error(L"Device-tree fix-up failed\r\n"); +out: + if (addr) { + ret2 = bs->free_pages(addr, pages); + if (ret2 != EFI_SUCCESS) + error(L"Can't free memory pages\r\n"); + } + if (file) { + ret2 = file->close(file); + if (ret2 != EFI_SUCCESS) + error(L"Can't close file\r\n"); + } + if (root) { + ret2 = root->close(root); + if (ret2 != EFI_SUCCESS) + error(L"Can't close volume\r\n"); + } + return ret; +} + +/** + * do_save() - save current device-tree + * + * @filename: file name + * Return: status code + */ +efi_status_t do_save(u16 *filename) +{ + struct efi_loaded_image *loaded_image; + struct efi_simple_file_system_protocol *file_system; + efi_uintn_t dtb_size; + struct efi_file_handle *root, *file; + struct fdt_header *dtb; + efi_uintn_t ret; dtb = get_dtb(systable); if (!dtb) { - cerr->output_string(cout, L"DTB not found\n"); + error(L"DTB not found\r\n"); return EFI_NOT_FOUND; } if (f2h(dtb->magic) != FDT_MAGIC) { - cerr->output_string(cout, L"Wrong device tree magic\n"); + error(L"Wrong device tree magic\r\n"); return EFI_NOT_FOUND; } dtb_size = f2h(dtb->totalsize); - cout->output_string(cout, L"Filename (" DEFAULT_FILENAME ")?\n"); - ret = efi_input(filename, sizeof(filename)); - if (ret != EFI_SUCCESS) - return ret; - if (!*filename) - memcpy(filename, DEFAULT_FILENAME, sizeof(DEFAULT_FILENAME)); - - cout->output_string(cout, L"\n"); + filename = skip_whitespace(filename); ret = bs->open_protocol(handle, &loaded_image_guid, (void **)&loaded_image, NULL, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); if (ret != EFI_SUCCESS) { - cerr->output_string(cout, - L"Loaded image protocol not found\n"); + error(L"Loaded image protocol not found\r\n"); return ret; } @@ -180,17 +423,30 @@ efi_status_t EFIAPI efi_main(efi_handle_t handle, (void **)&file_system, NULL, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); if (ret != EFI_SUCCESS) { - cerr->output_string( - cout, L"Failed to open simple file system protocol\n"); + error(L"Failed to open simple file system protocol\r\n"); return ret; } /* Open volume */ ret = file_system->open_volume(file_system, &root); if (ret != EFI_SUCCESS) { - cerr->output_string(cerr, L"Failed to open volume\n"); + error(L"Failed to open volume\r\n"); return ret; } + /* Check if file already exists */ + ret = root->open(root, &file, filename, EFI_FILE_MODE_READ, 0); + if (ret == EFI_SUCCESS) { + file->close(file); + print(L"Overwrite existing file (y/n)? "); + ret = efi_input_yn(); + print(L"\r\n"); + if (ret != EFI_SUCCESS) { + root->close(root); + error(L"Aborted by user\r\n"); + return ret; + } + } + /* Create file */ ret = root->open(root, &file, filename, EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | @@ -199,17 +455,65 @@ efi_status_t EFIAPI efi_main(efi_handle_t handle, /* Write file */ ret = file->write(file, &dtb_size, dtb); if (ret != EFI_SUCCESS) - cerr->output_string(cerr, L"Failed to write file\n"); + error(L"Failed to write file\r\n"); file->close(file); } else { - cerr->output_string(cerr, L"Failed to open file\n"); + error(L"Failed to open file\r\n"); } root->close(root); if (ret == EFI_SUCCESS) { - cout->output_string(cout, filename); - cout->output_string(cout, L" written\n"); + print(filename); + print(L" written\r\n"); } return ret; } + +/** + * efi_main() - entry point of the EFI application. + * + * @handle: handle of the loaded image + * @systab: system table + * @return: status code + */ +efi_status_t EFIAPI efi_main(efi_handle_t image_handle, + struct efi_system_table *systab) +{ + handle = image_handle; + systable = systab; + cerr = systable->std_err; + cout = systable->con_out; + cin = systable->con_in; + bs = systable->boottime; + + cout->set_attribute(cout, EFI_LIGHTBLUE | EFI_BACKGROUND_BLACK); + cout->clear_screen(cout); + cout->set_attribute(cout, EFI_WHITE | EFI_BACKGROUND_BLACK); + print(L"DTB Dump\r\n========\r\n\r\n"); + cout->set_attribute(cout, EFI_LIGHTBLUE | EFI_BACKGROUND_BLACK); + + for (;;) { + u16 command[BUFFER_SIZE]; + u16 *pos; + efi_uintn_t ret; + + print(L"=> "); + ret = efi_input(command, sizeof(command)); + if (ret == EFI_ABORTED) + break; + pos = skip_whitespace(command); + if (starts_with(pos, L"exit")) + break; + else if (starts_with(pos, L"load ")) + do_load(pos + 5); + else if (starts_with(pos, L"save ")) + do_save(pos + 5); + else + do_help(); + } + + cout->set_attribute(cout, EFI_LIGHTGRAY | EFI_BACKGROUND_BLACK); + cout->clear_screen(cout); + return EFI_SUCCESS; +} diff --git a/lib/efi_selftest/efi_selftest_console.c b/lib/efi_selftest/efi_selftest_console.c index 0219bd70e0..ffd88a1e26 100644 --- a/lib/efi_selftest/efi_selftest_console.c +++ b/lib/efi_selftest/efi_selftest_console.c @@ -46,11 +46,10 @@ static void mac(void *pointer, u16 **buf) /* * printx() - print hexadecimal number to an u16 string * - * @pointer: pointer + * @p: value to print * @prec: minimum number of digits to print * @buf: pointer to buffer address, * on return position of terminating zero word - * @size: size of value to be printed in bytes */ static void printx(u64 p, int prec, u16 **buf) { diff --git a/lib/efi_selftest/initrddump.c b/lib/efi_selftest/initrddump.c new file mode 100644 index 0000000000..c23a05c718 --- /dev/null +++ b/lib/efi_selftest/initrddump.c @@ -0,0 +1,449 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2020, Heinrich Schuchardt <xypron.glpk@gmx.de> + * + * initrddump.efi saves the initial RAM disk provided via the + * EFI_LOAD_FILE2_PROTOCOL. + */ + +#include <common.h> +#include <efi_api.h> +#include <efi_load_initrd.h> + +#define BUFFER_SIZE 64 +#define ESC 0x17 + +#define efi_size_in_pages(size) (((size) + EFI_PAGE_MASK) >> EFI_PAGE_SHIFT) + +static struct efi_system_table *systable; +static struct efi_boot_services *bs; +static struct efi_simple_text_output_protocol *cerr; +static struct efi_simple_text_output_protocol *cout; +static struct efi_simple_text_input_protocol *cin; +static const efi_guid_t loaded_image_guid = EFI_LOADED_IMAGE_PROTOCOL_GUID; +static const efi_guid_t guid_simple_file_system_protocol = + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID; +static const efi_guid_t load_file2_guid = EFI_LOAD_FILE2_PROTOCOL_GUID; +static efi_handle_t handle; + +/* + * Device path defined by Linux to identify the handle providing the + * EFI_LOAD_FILE2_PROTOCOL used for loading the initial ramdisk. + */ +static const struct efi_initrd_dp initrd_dp = { + .vendor = { + { + DEVICE_PATH_TYPE_MEDIA_DEVICE, + DEVICE_PATH_SUB_TYPE_VENDOR_PATH, + sizeof(initrd_dp.vendor), + }, + EFI_INITRD_MEDIA_GUID, + }, + .end = { + DEVICE_PATH_TYPE_END, + DEVICE_PATH_SUB_TYPE_END, + sizeof(initrd_dp.end), + } +}; + +/** + * print() - print string + * + * @string: text + */ +static void print(u16 *string) +{ + cout->output_string(cout, string); +} + +/** + * error() - print error string + * + * @string: error text + */ +static void error(u16 *string) +{ + cout->set_attribute(cout, EFI_LIGHTRED | EFI_BACKGROUND_BLACK); + print(string); + cout->set_attribute(cout, EFI_LIGHTBLUE | EFI_BACKGROUND_BLACK); +} + +/* + * printx() - print hexadecimal number + * + * @val: value to print; + * @prec: minimum number of digits to print + */ +static void printx(u64 val, u32 prec) +{ + int i; + u16 c; + u16 buf[16]; + u16 *pos = buf; + + for (i = 2 * sizeof(val) - 1; i >= 0; --i) { + c = (val >> (4 * i)) & 0x0f; + if (c || pos != buf || !i || i < prec) { + c += '0'; + if (c > '9') + c += 'a' - '9' - 1; + *pos++ = c; + } + } + *pos = 0; + print(buf); +} + +/** + * efi_input_yn() - get answer to yes/no question + * + * Return: + * y or Y + * EFI_SUCCESS + * n or N + * EFI_ACCESS_DENIED + * ESC + * EFI_ABORTED + */ +static efi_status_t efi_input_yn(void) +{ + struct efi_input_key key = {0}; + efi_uintn_t index; + efi_status_t ret; + + /* Drain the console input */ + ret = cin->reset(cin, true); + for (;;) { + ret = bs->wait_for_event(1, &cin->wait_for_key, &index); + if (ret != EFI_SUCCESS) + continue; + ret = cin->read_key_stroke(cin, &key); + if (ret != EFI_SUCCESS) + continue; + switch (key.scan_code) { + case 0x17: /* Escape */ + return EFI_ABORTED; + default: + break; + } + /* Convert to lower case */ + switch (key.unicode_char | 0x20) { + case 'y': + return EFI_SUCCESS; + case 'n': + return EFI_ACCESS_DENIED; + default: + break; + } + } +} + +/** + * efi_input() - read string from console + * + * @buffer: input buffer + * @buffer_size: buffer size + * Return: status code + */ +static efi_status_t efi_input(u16 *buffer, efi_uintn_t buffer_size) +{ + struct efi_input_key key = {0}; + efi_uintn_t index; + efi_uintn_t pos = 0; + u16 outbuf[2] = L" "; + efi_status_t ret; + + /* Drain the console input */ + ret = cin->reset(cin, true); + *buffer = 0; + for (;;) { + ret = bs->wait_for_event(1, &cin->wait_for_key, &index); + if (ret != EFI_SUCCESS) + continue; + ret = cin->read_key_stroke(cin, &key); + if (ret != EFI_SUCCESS) + continue; + switch (key.scan_code) { + case 0x17: /* Escape */ + print(L"\r\nAborted\r\n"); + return EFI_ABORTED; + default: + break; + } + switch (key.unicode_char) { + case 0x08: /* Backspace */ + if (pos) { + buffer[pos--] = 0; + print(L"\b \b"); + } + break; + case 0x0a: /* Linefeed */ + case 0x0d: /* Carriage return */ + print(L"\r\n"); + return EFI_SUCCESS; + default: + break; + } + /* Ignore surrogate codes */ + if (key.unicode_char >= 0xD800 && key.unicode_char <= 0xDBFF) + continue; + if (key.unicode_char >= 0x20 && + pos < buffer_size - 1) { + *outbuf = key.unicode_char; + buffer[pos++] = key.unicode_char; + buffer[pos] = 0; + print(outbuf); + } + } +} + +/** + * skip_whitespace() - skip over leading whitespace + * + * @pos: UTF-16 string + * Return: pointer to first non-whitespace + */ +static u16 *skip_whitespace(u16 *pos) +{ + for (; *pos && *pos <= 0x20; ++pos) + ; + return pos; +} + +/** + * starts_with() - check if @string starts with @keyword + * + * @string: string to search for keyword + * @keyword: keyword to be searched + * Return: true fi @string starts with the keyword + */ +static bool starts_with(u16 *string, u16 *keyword) +{ + for (; *keyword; ++string, ++keyword) { + if (*string != *keyword) + return false; + } + return true; +} + +/** + * do_help() - print help + */ +static void do_help(void) +{ + error(L"load - show length and CRC32 of initial RAM disk\r\n"); + error(L"save <initrd> - save initial RAM disk to file\r\n"); + error(L"exit - exit the shell\r\n"); +} + +/** + * get_initrd() - read initial RAM disk via EFI_LOAD_FILE2_PROTOCOL + * + * @initrd: on return buffer with initial RAM disk + * @initrd_size: size of initial RAM disk + * Return: status code + */ +static efi_status_t get_initrd(void **initrd, efi_uintn_t *initrd_size) +{ + struct efi_device_path *dp = (struct efi_device_path *)&initrd_dp; + struct efi_load_file_protocol *load_file2_prot; + u64 buffer; + efi_handle_t handle; + efi_status_t ret; + + *initrd = NULL; + *initrd_size = 0; + ret = bs->locate_device_path(&load_file2_guid, &dp, &handle); + if (ret != EFI_SUCCESS) { + error(L"Load File2 protocol not found\r\n"); + return ret; + } + ret = bs->handle_protocol(handle, &load_file2_guid, + (void **)&load_file2_prot); + ret = load_file2_prot->load_file(load_file2_prot, dp, false, + initrd_size, NULL); + if (ret != EFI_BUFFER_TOO_SMALL) { + error(L"Load File2 protocol does not provide file length\r\n"); + return EFI_LOAD_ERROR; + } + ret = bs->allocate_pages(EFI_ALLOCATE_ANY_PAGES, EFI_LOADER_DATA, + efi_size_in_pages(*initrd_size), &buffer); + if (ret != EFI_SUCCESS) { + error(L"Out of memory\r\n"); + return ret; + } + *initrd = (void *)buffer; + ret = load_file2_prot->load_file(load_file2_prot, dp, false, + initrd_size, *initrd); + if (ret != EFI_SUCCESS) { + error(L"Load File2 protocol failed to provide file\r\n"); + bs->free_pages(buffer, efi_size_in_pages(*initrd_size)); + return EFI_LOAD_ERROR; + } + return ret; +} + +/** + * do_load() - load initial RAM disk and display CRC32 and length + * + * @filename: file name + * Return: status code + */ +static efi_status_t do_load(void) +{ + void *initrd; + efi_uintn_t initrd_size; + u32 crc32; + efi_uintn_t ret; + + ret = get_initrd(&initrd, &initrd_size); + if (ret != EFI_SUCCESS) + return ret; + print(L"length: 0x"); + printx(initrd_size, 1); + print(L"\r\n"); + + ret = bs->calculate_crc32(initrd, initrd_size, &crc32); + if (ret != EFI_SUCCESS) { + error(L"Calculating CRC32 failed\r\n"); + return EFI_LOAD_ERROR; + } + print(L"crc32: 0x"); + printx(crc32, 8); + print(L"\r\n"); + + return EFI_SUCCESS; +} + +/** + * do_save() - save initial RAM disk + * + * @filename: file name + * Return: status code + */ +static efi_status_t do_save(u16 *filename) +{ + struct efi_loaded_image *loaded_image; + struct efi_simple_file_system_protocol *file_system; + struct efi_file_handle *root, *file; + void *initrd; + efi_uintn_t initrd_size; + efi_uintn_t ret; + + ret = get_initrd(&initrd, &initrd_size); + if (ret != EFI_SUCCESS) + return ret; + + filename = skip_whitespace(filename); + + ret = bs->open_protocol(handle, &loaded_image_guid, + (void **)&loaded_image, NULL, NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (ret != EFI_SUCCESS) { + error(L"Loaded image protocol not found\r\n"); + goto out; + } + + /* Open the simple file system protocol */ + ret = bs->open_protocol(loaded_image->device_handle, + &guid_simple_file_system_protocol, + (void **)&file_system, NULL, NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (ret != EFI_SUCCESS) { + error(L"Failed to open simple file system protocol\r\n"); + goto out; + } + + /* Open volume */ + ret = file_system->open_volume(file_system, &root); + if (ret != EFI_SUCCESS) { + error(L"Failed to open volume\r\n"); + goto out; + } + /* Check if file already exists */ + ret = root->open(root, &file, filename, EFI_FILE_MODE_READ, 0); + if (ret == EFI_SUCCESS) { + file->close(file); + print(L"Overwrite existing file (y/n)? "); + ret = efi_input_yn(); + print(L"\r\n"); + if (ret != EFI_SUCCESS) { + root->close(root); + error(L"Aborted by user\r\n"); + goto out; + } + } + + /* Create file */ + ret = root->open(root, &file, filename, + EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | + EFI_FILE_MODE_CREATE, EFI_FILE_ARCHIVE); + if (ret == EFI_SUCCESS) { + /* Write file */ + ret = file->write(file, &initrd_size, initrd); + if (ret != EFI_SUCCESS) { + error(L"Failed to write file\r\n"); + } else { + print(filename); + print(L" written\r\n"); + } + file->close(file); + } else { + error(L"Failed to open file\r\n"); + } + root->close(root); + +out: + if (initrd) + bs->free_pages((uintptr_t)initrd, + efi_size_in_pages(initrd_size)); + return ret; +} + +/** + * efi_main() - entry point of the EFI application. + * + * @handle: handle of the loaded image + * @systab: system table + * @return: status code + */ +efi_status_t EFIAPI efi_main(efi_handle_t image_handle, + struct efi_system_table *systab) +{ + handle = image_handle; + systable = systab; + cerr = systable->std_err; + cout = systable->con_out; + cin = systable->con_in; + bs = systable->boottime; + + cout->set_attribute(cout, EFI_LIGHTBLUE | EFI_BACKGROUND_BLACK); + cout->clear_screen(cout); + cout->set_attribute(cout, EFI_WHITE | EFI_BACKGROUND_BLACK); + print(L"INITRD Dump\r\n========\r\n\r\n"); + cout->set_attribute(cout, EFI_LIGHTBLUE | EFI_BACKGROUND_BLACK); + + for (;;) { + u16 command[BUFFER_SIZE]; + u16 *pos; + efi_uintn_t ret; + + print(L"=> "); + ret = efi_input(command, sizeof(command)); + if (ret == EFI_ABORTED) + break; + pos = skip_whitespace(command); + if (starts_with(pos, L"exit")) + break; + else if (starts_with(pos, L"load")) + do_load(); + else if (starts_with(pos, L"save ")) + do_save(pos + 5); + else + do_help(); + } + + cout->set_attribute(cout, EFI_LIGHTGRAY | EFI_BACKGROUND_BLACK); + cout->clear_screen(cout); + return EFI_SUCCESS; +} diff --git a/lib/string.c b/lib/string.c index ae7835f600..73b984123d 100644 --- a/lib/string.c +++ b/lib/string.c @@ -567,7 +567,19 @@ void * memmove(void * dest,const void *src,size_t count) { char *tmp, *s; - if (dest <= src) { + if (dest <= src || (src + count) <= dest) { + /* + * Use the fast memcpy implementation (ARCH optimized or lib/string.c) when it is possible: + * - when dest is before src (assuming that memcpy is doing forward-copying) + * - when destination don't overlap the source buffer (src + count <= dest) + * + * WARNING: the first optimisation cause an issue, when __HAVE_ARCH_MEMCPY is defined, + * __HAVE_ARCH_MEMMOVE is not defined and if the memcpy ARCH-specific + * implementation is not doing a forward-copying. + * + * No issue today because memcpy is doing a forward-copying in lib/string.c and for ARM32 + * architecture; no other arches use __HAVE_ARCH_MEMCPY without __HAVE_ARCH_MEMMOVE. + */ memcpy(dest, src, count); } else { tmp = (char *) dest + count; diff --git a/lib/uuid.c b/lib/uuid.c index e62d5ca264..5bc68674d0 100644 --- a/lib/uuid.c +++ b/lib/uuid.c @@ -15,6 +15,8 @@ #include <asm/io.h> #include <part_efi.h> #include <malloc.h> +#include <dm/uclass.h> +#include <rng.h> /* * UUID - Universally Unique IDentifier - 128 bits unique number. @@ -96,7 +98,8 @@ static const struct { {"linux", PARTITION_LINUX_FILE_SYSTEM_DATA_GUID}, {"raid", PARTITION_LINUX_RAID_GUID}, {"swap", PARTITION_LINUX_SWAP_GUID}, - {"lvm", PARTITION_LINUX_LVM_GUID} + {"lvm", PARTITION_LINUX_LVM_GUID}, + {"u-boot-env", PARTITION_U_BOOT_ENVIRONMENT}, }; /* @@ -122,20 +125,19 @@ int uuid_guid_get_bin(const char *guid_str, unsigned char *guid_bin) * uuid_guid_get_str() - this function get string for GUID. * * @param guid_bin - pointer to string with partition type guid [16B] - * @param guid_str - pointer to allocated partition type string [7B] + * + * Returns NULL if the type GUID is not known. */ -int uuid_guid_get_str(const unsigned char *guid_bin, char *guid_str) +const char *uuid_guid_get_str(const unsigned char *guid_bin) { int i; - *guid_str = 0; for (i = 0; i < ARRAY_SIZE(list_guid); i++) { if (!memcmp(list_guid[i].guid.b, guid_bin, 16)) { - strcpy(guid_str, list_guid[i].string); - return 0; + return list_guid[i].string; } } - return -ENODEV; + return NULL; } #endif @@ -249,9 +251,22 @@ void gen_rand_uuid(unsigned char *uuid_bin) { u32 ptr[4]; struct uuid *uuid = (struct uuid *)ptr; - int i; - - srand(get_ticks() + rand()); + int i, ret; + struct udevice *devp; + u32 randv = 0; + + if (IS_ENABLED(CONFIG_DM_RNG)) { + ret = uclass_get_device(UCLASS_RNG, 0, &devp); + if (ret) { + ret = dm_rng_read(devp, &randv, sizeof(randv)); + if (ret < 0) + randv = 0; + } + } + if (randv) + srand(randv); + else + srand(get_ticks() + rand()); /* Set all fields randomly */ for (i = 0; i < 4; i++) diff --git a/lib/zlib/deflate.c b/lib/zlib/deflate.c index 1fe58d5da6..63473359e4 100644 --- a/lib/zlib/deflate.c +++ b/lib/zlib/deflate.c @@ -1284,7 +1284,7 @@ local void check_match(s, start, match, length) } if (z_verbose > 1) { fprintf(stderr,"\\[%d,%d]", start-match, length); - do { putc(s->window[start++], stderr); } while (--length != 0); + do { putc(s->window[start++]); } while (--length != 0); } } #else diff --git a/lib/zlib/trees.c b/lib/zlib/trees.c index 3e09517ed0..700c62f6d7 100644 --- a/lib/zlib/trees.c +++ b/lib/zlib/trees.c @@ -38,7 +38,7 @@ #include "deflate.h" #ifdef DEBUG -# include <ctype.h> +# include <linux/ctype.h> #endif /* =========================================================================== diff --git a/net/eth-uclass.c b/net/eth-uclass.c index 0156324032..7c2454f5ae 100644 --- a/net/eth-uclass.c +++ b/net/eth-uclass.c @@ -26,6 +26,7 @@ DECLARE_GLOBAL_DATA_PTR; */ struct eth_device_priv { enum eth_state_t state; + bool running; }; /** @@ -290,6 +291,7 @@ int eth_init(void) dev_get_uclass_priv(current); priv->state = ETH_STATE_ACTIVE; + priv->running = true; return 0; } } else { @@ -319,13 +321,16 @@ void eth_halt(void) struct eth_device_priv *priv; current = eth_get_dev(); - if (!current || !eth_is_active(current)) + if (!current) return; - eth_get_ops(current)->stop(current); priv = dev_get_uclass_priv(current); - if (priv) - priv->state = ETH_STATE_PASSIVE; + if (!priv || !priv->running) + return; + + eth_get_ops(current)->stop(current); + priv->state = ETH_STATE_PASSIVE; + priv->running = false; } int eth_is_active(struct udevice *dev) @@ -534,6 +539,7 @@ static int eth_post_probe(struct udevice *dev) #endif priv->state = ETH_STATE_INIT; + priv->running = false; /* Check if the device has a valid MAC address in device tree */ if (!eth_dev_get_mac_address(dev, pdata->enetaddr) || diff --git a/net/eth_legacy.c b/net/eth_legacy.c index 6e0c058761..6870afb505 100644 --- a/net/eth_legacy.c +++ b/net/eth_legacy.c @@ -365,7 +365,7 @@ int eth_send(void *packet, int length) ret = eth_current->send(eth_current, packet, length); #if defined(CONFIG_CMD_PCAP) if (ret >= 0) - pcap_post(packet, lengeth, true); + pcap_post(packet, length, true); #endif return ret; } diff --git a/net/net_rand.h b/net/net_rand.h index 4bf9bd817e..6a52cda85e 100644 --- a/net/net_rand.h +++ b/net/net_rand.h @@ -10,6 +10,8 @@ #define __NET_RAND_H__ #include <common.h> +#include <dm/uclass.h> +#include <rng.h> /* * Return a seed for the PRNG derived from the eth0 MAC address. @@ -37,7 +39,22 @@ static inline unsigned int seed_mac(void) */ static inline void srand_mac(void) { - srand(seed_mac()); + int ret; + struct udevice *devp; + u32 randv = 0; + + if (IS_ENABLED(CONFIG_DM_RNG)) { + ret = uclass_get_device(UCLASS_RNG, 0, &devp); + if (ret) { + ret = dm_rng_read(devp, &randv, sizeof(randv)); + if (ret < 0) + randv = 0; + } + } + if (randv) + srand(randv); + else + srand(seed_mac()); } #endif /* __NET_RAND_H__ */ diff --git a/net/ping.c b/net/ping.c index 0e33660f6c..075df3663f 100644 --- a/net/ping.c +++ b/net/ping.c @@ -90,6 +90,9 @@ void ping_receive(struct ethernet_hdr *et, struct ip_udp_hdr *ip, int len) net_set_state(NETLOOP_SUCCESS); return; case ICMP_ECHO_REQUEST: + if (net_ip.s_addr == 0) + return; + eth_hdr_size = net_update_ether(et, et->et_src, PROT_IP); debug_cond(DEBUG_DEV_PKT, diff --git a/net/tftp.c b/net/tftp.c index 6fdb1a821a..03079ded34 100644 --- a/net/tftp.c +++ b/net/tftp.c @@ -329,6 +329,12 @@ static void tftp_complete(void) time_start * 1000, "/s"); } puts("\ndone\n"); + if (IS_ENABLED(CONFIG_CMD_BOOTEFI)) { + if (!tftp_put_active) + efi_set_bootdev("Net", "", tftp_filename, + map_sysmem(tftp_load_addr, 0), + net_boot_file_size); + } net_set_state(NETLOOP_SUCCESS); } @@ -624,8 +630,10 @@ static void tftp_handler(uchar *pkt, unsigned dest, struct in_addr sip, tftp_cur_block++; tftp_cur_block %= TFTP_SEQUENCE_SIZE; - if (tftp_state == STATE_SEND_RRQ) + if (tftp_state == STATE_SEND_RRQ) { debug("Server did not acknowledge any options!\n"); + tftp_next_ack = tftp_windowsize; + } if (tftp_state == STATE_SEND_RRQ || tftp_state == STATE_OACK || tftp_state == STATE_RECV_WRQ) { @@ -841,9 +849,6 @@ void tftp_start(enum proto_t protocol) printf("Load address: 0x%lx\n", tftp_load_addr); puts("Loading: *\b"); tftp_state = STATE_SEND_RRQ; -#ifdef CONFIG_CMD_BOOTEFI - efi_set_bootdev("Net", "", tftp_filename); -#endif } time_start = get_timer(0); diff --git a/post/post.c b/post/post.c index 0f1fe8d905..7d6a647312 100644 --- a/post/post.c +++ b/post/post.c @@ -128,7 +128,7 @@ static void post_log_mark_succ(unsigned long testid) } /* ... and the messages are output once we are relocated */ -void post_output_backlog(void) +int post_output_backlog(void) { int j; @@ -143,6 +143,8 @@ void post_output_backlog(void) } } } + + return 0; } static void post_bootmode_test_on(unsigned int last_test) diff --git a/test/Makefile b/test/Makefile index d4323f9963..3c7bc8b549 100644 --- a/test/Makefile +++ b/test/Makefile @@ -2,7 +2,7 @@ # # (C) Copyright 2012 The Chromium Authors -ifneq ($(CONFIG_SANDBOX),) +ifneq ($(CONFIG_$(SPL_)BLOBLIST),) obj-$(CONFIG_$(SPL_)CMDLINE) += bloblist.o endif obj-$(CONFIG_$(SPL_)CMDLINE) += bootm.o diff --git a/test/bloblist.c b/test/bloblist.c index 0bb9e2d81e..900299dd68 100644 --- a/test/bloblist.c +++ b/test/bloblist.c @@ -7,7 +7,6 @@ #include <bloblist.h> #include <log.h> #include <mapmem.h> -#include <asm/state.h> #include <test/suites.h> #include <test/test.h> #include <test/ut.h> @@ -240,7 +239,6 @@ BLOBLIST_TEST(bloblist_test_checksum, 0); /* Test the 'bloblist info' command */ static int bloblist_test_cmd_info(struct unit_test_state *uts) { - struct sandbox_state *state = state_get_current(); struct bloblist_hdr *hdr; char *data, *data2; @@ -250,8 +248,7 @@ static int bloblist_test_cmd_info(struct unit_test_state *uts) data2 = bloblist_ensure(TEST_TAG2, TEST_SIZE2); console_record_reset_enable(); - if (!state->show_test_output) - gd->flags |= GD_FLG_SILENT; + ut_silence_console(uts); console_record_reset(); run_command("bloblist info", 0); ut_assert_nextline("base: %lx", (ulong)map_to_sysmem(hdr)); @@ -259,7 +256,7 @@ static int bloblist_test_cmd_info(struct unit_test_state *uts) ut_assert_nextline("alloced: 70 112 Bytes"); ut_assert_nextline("free: 390 912 Bytes"); ut_assert_console_end(); - gd->flags &= ~(GD_FLG_SILENT | GD_FLG_RECORD); + ut_unsilence_console(uts); return 0; } @@ -268,7 +265,6 @@ BLOBLIST_TEST(bloblist_test_cmd_info, 0); /* Test the 'bloblist list' command */ static int bloblist_test_cmd_list(struct unit_test_state *uts) { - struct sandbox_state *state = state_get_current(); struct bloblist_hdr *hdr; char *data, *data2; @@ -278,8 +274,7 @@ static int bloblist_test_cmd_list(struct unit_test_state *uts) data2 = bloblist_ensure(TEST_TAG2, TEST_SIZE2); console_record_reset_enable(); - if (!state->show_test_output) - gd->flags |= GD_FLG_SILENT; + ut_silence_console(uts); console_record_reset(); run_command("bloblist list", 0); ut_assert_nextline("Address Size Tag Name"); @@ -288,7 +283,7 @@ static int bloblist_test_cmd_list(struct unit_test_state *uts) ut_assert_nextline("%08lx %8x 2 SPL hand-off", (ulong)map_to_sysmem(data2), TEST_SIZE2); ut_assert_console_end(); - gd->flags &= ~(GD_FLG_SILENT | GD_FLG_RECORD); + ut_unsilence_console(uts); return 0; } diff --git a/test/cmd/Makefile b/test/cmd/Makefile index b2f71af847..758bc14273 100644 --- a/test/cmd/Makefile +++ b/test/cmd/Makefile @@ -4,4 +4,5 @@ obj-y += mem.o obj-$(CONFIG_CMD_MEM_SEARCH) += mem_search.o +obj-$(CONFIG_CMD_PWM) += pwm.o obj-y += setexpr.o diff --git a/test/cmd/mem.c b/test/cmd/mem.c index fa6770e8c0..fbaa8a4b3c 100644 --- a/test/cmd/mem.c +++ b/test/cmd/mem.c @@ -15,6 +15,6 @@ int do_ut_mem(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) struct unit_test *tests = ll_entry_start(struct unit_test, mem_test); const int n_ents = ll_entry_count(struct unit_test, mem_test); - return cmd_ut_category("cmd_mem", "cmd_mem_", tests, n_ents, argc, + return cmd_ut_category("cmd_mem", "mem_test_", tests, n_ents, argc, argv); } diff --git a/test/cmd/pwm.c b/test/cmd/pwm.c new file mode 100644 index 0000000000..5343af83fa --- /dev/null +++ b/test/cmd/pwm.c @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Test for pwm command + * + * Copyright 2020 SiFive, Inc + * + * Authors: + * Pragnesh Patel <pragnesh.patel@sifive.com> + */ + +#include <dm.h> +#include <dm/test.h> +#include <test/test.h> +#include <test/ut.h> + +/* Basic test of 'pwm' command */ +static int dm_test_pwm_cmd(struct unit_test_state *uts) +{ + struct udevice *dev; + + ut_assertok(uclass_get_device(UCLASS_PWM, 0, &dev)); + ut_assertnonnull(dev); + + ut_assertok(console_record_reset_enable()); + + /* pwm <invert> <pwm_dev_num> <channel> <polarity> */ + ut_assertok(run_command("pwm invert 0 0 1", 0)); + ut_assert_console_end(); + + ut_assertok(run_command("pwm invert 0 0 0", 0)); + ut_assert_console_end(); + + /* pwm <config> <pwm_dev_num> <channel> <period_ns> <duty_ns> */ + ut_assertok(run_command("pwm config 0 0 10 50", 0)); + ut_assert_console_end(); + + /* pwm <enable/disable> <pwm_dev_num> <channel> */ + ut_assertok(run_command("pwm enable 0 0", 0)); + ut_assert_console_end(); + + ut_assertok(run_command("pwm disable 0 0", 0)); + ut_assert_console_end(); + + return 0; +} + +DM_TEST(dm_test_pwm_cmd, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT | UT_TESTF_CONSOLE_REC); diff --git a/test/lib/Makefile b/test/lib/Makefile index 98a9abf40e..97c11e35a8 100644 --- a/test/lib/Makefile +++ b/test/lib/Makefile @@ -7,7 +7,7 @@ obj-$(CONFIG_EFI_LOADER) += efi_device_path.o obj-$(CONFIG_EFI_SECURE_BOOT) += efi_image_region.o obj-y += hexdump.o obj-y += lmb.o -obj-y += test_print.o +obj-$(CONFIG_CONSOLE_RECORD) += test_print.o obj-$(CONFIG_SSCANF) += sscanf.o obj-y += string.o obj-$(CONFIG_ERRNO_STR) += test_errno_str.o diff --git a/test/log/Makefile b/test/log/Makefile index 88bc573e9f..afdafa502a 100644 --- a/test/log/Makefile +++ b/test/log/Makefile @@ -8,6 +8,7 @@ obj-$(CONFIG_CMD_LOG) += log_filter.o ifdef CONFIG_UT_LOG obj-y += test-main.o +obj-y += pr_cont_test.o ifdef CONFIG_SANDBOX obj-$(CONFIG_LOG_SYSLOG) += syslog_test.o diff --git a/test/log/log_test.c b/test/log/log_test.c index ea4fc6bc30..82234a6994 100644 --- a/test/log/log_test.c +++ b/test/log/log_test.c @@ -15,29 +15,44 @@ DECLARE_GLOBAL_DATA_PTR; /* emit some sample log records in different ways, for testing */ -static int do_log_run(int cat, const char *file) +static int do_log_run(struct unit_test_state *uts, int cat, const char *file) { int i; + int ret, expected_ret; + + if (gd->flags & GD_FLG_LOG_READY) + expected_ret = 0; + else + expected_ret = -ENOSYS; gd->log_fmt = LOGF_TEST; debug("debug\n"); for (i = LOGL_FIRST; i < LOGL_COUNT; i++) { log(cat, i, "log %d\n", i); - _log(log_uc_cat(cat), i, file, 100 + i, "func", "_log %d\n", - i); + ret = _log(log_uc_cat(cat), i, file, 100 + i, + "func", "_log %d\n", i); + ut_asserteq(ret, expected_ret); + } + /* test with LOGL_COUNT flag */ + for (i = LOGL_FIRST; i < LOGL_COUNT; i++) { + ret = _log(log_uc_cat(cat), i | LOGL_FORCE_DEBUG, file, 100 + i, + "func", "_log force %d\n", i); + ut_asserteq(ret, expected_ret); } gd->log_fmt = log_get_default_format(); return 0; } -#define log_run_cat(cat) do_log_run(cat, "file") -#define log_run_file(file) do_log_run(UCLASS_SPI, file) -#define log_run() do_log_run(UCLASS_SPI, "file") +#define log_run_cat(cat) do_log_run(uts, cat, "file") +#define log_run_file(file) do_log_run(uts, UCLASS_SPI, file) +#define log_run() do_log_run(uts, UCLASS_SPI, "file") #define EXPECT_LOG BIT(0) #define EXPECT_DIRECT BIT(1) #define EXPECT_EXTRA BIT(2) +#define EXPECT_FORCE BIT(3) +#define EXPECT_DEBUG BIT(4) static int do_check_log_entries(struct unit_test_state *uts, int flags, int min, int max) @@ -49,11 +64,22 @@ static int do_check_log_entries(struct unit_test_state *uts, int flags, int min, ut_assert_nextline("do_log_run() log %d", i); if (flags & EXPECT_DIRECT) ut_assert_nextline("func() _log %d", i); + if (flags & EXPECT_DEBUG) { + ut_assert_nextline("log %d", i); + ut_assert_nextline("_log %d", i); + } } if (flags & EXPECT_EXTRA) for (; i <= LOGL_MAX ; i++) ut_assert_nextline("func() _log %d", i); + for (i = LOGL_FIRST; i < LOGL_COUNT; i++) { + if (flags & EXPECT_FORCE) + ut_assert_nextline("func() _log force %d", i); + if (flags & EXPECT_DEBUG) + ut_assert_nextline("_log force %d", i); + } + ut_assert_console_end(); return 0; } @@ -66,10 +92,10 @@ static int do_check_log_entries(struct unit_test_state *uts, int flags, int min, #define check_log_entries_flags(flags) \ check_log_entries_flags_levels(flags, LOGL_FIRST, _LOG_MAX_LEVEL) -#define check_log_entries() check_log_entries_flags(EXPECT_LOG | EXPECT_DIRECT) +#define check_log_entries() check_log_entries_flags(EXPECT_LOG | EXPECT_DIRECT | EXPECT_FORCE) #define check_log_entries_extra() \ - check_log_entries_flags(EXPECT_LOG | EXPECT_DIRECT | EXPECT_EXTRA) -#define check_log_entries_none() check_log_entries_flags(0) + check_log_entries_flags(EXPECT_LOG | EXPECT_DIRECT | EXPECT_EXTRA | EXPECT_FORCE) +#define check_log_entries_none() check_log_entries_flags(EXPECT_FORCE) /* Check a category filter using the first category */ int log_test_cat_allow(struct unit_test_state *uts) @@ -126,7 +152,7 @@ int log_test_file(struct unit_test_state *uts) ut_assertok(console_record_reset_enable()); log_run_file("file"); - check_log_entries_flags(EXPECT_DIRECT | EXPECT_EXTRA); + check_log_entries_flags(EXPECT_DIRECT | EXPECT_EXTRA | EXPECT_FORCE); ut_assertok(console_record_reset_enable()); log_run_file("file2"); @@ -147,7 +173,7 @@ int log_test_file_second(struct unit_test_state *uts) ut_assertok(console_record_reset_enable()); log_run_file("file2"); - check_log_entries_flags(EXPECT_DIRECT | EXPECT_EXTRA); + check_log_entries_flags(EXPECT_DIRECT | EXPECT_EXTRA | EXPECT_FORCE); ut_assertok(log_remove_filter("console", filt)); return 0; @@ -182,8 +208,8 @@ int log_test_level(struct unit_test_state *uts) ut_assertok(console_record_reset_enable()); log_run(); - check_log_entries_flags_levels(EXPECT_LOG | EXPECT_DIRECT, LOGL_FIRST, - LOGL_WARNING); + check_log_entries_flags_levels(EXPECT_LOG | EXPECT_DIRECT | EXPECT_FORCE, + LOGL_FIRST, LOGL_WARNING); ut_assertok(log_remove_filter("console", filt)); return 0; @@ -351,7 +377,7 @@ int log_test_level_deny(struct unit_test_state *uts) ut_assertok(console_record_reset_enable()); log_run(); - check_log_entries_flags_levels(EXPECT_LOG | EXPECT_DIRECT, + check_log_entries_flags_levels(EXPECT_LOG | EXPECT_DIRECT | EXPECT_FORCE, LOGL_WARNING + 1, _LOG_MAX_LEVEL); ut_assertok(log_remove_filter("console", filt1)); @@ -374,7 +400,7 @@ int log_test_min(struct unit_test_state *uts) ut_assertok(console_record_reset_enable()); log_run(); - check_log_entries_flags_levels(EXPECT_LOG | EXPECT_DIRECT, + check_log_entries_flags_levels(EXPECT_LOG | EXPECT_DIRECT | EXPECT_FORCE, LOGL_WARNING, LOGL_INFO - 1); ut_assertok(log_remove_filter("console", filt1)); @@ -382,3 +408,23 @@ int log_test_min(struct unit_test_state *uts) return 0; } LOG_TEST_FLAGS(log_test_min, UT_TESTF_CONSOLE_REC); + +/* Check dropped traces */ +int log_test_dropped(struct unit_test_state *uts) +{ + /* force LOG not ready */ + gd->flags &= ~(GD_FLG_LOG_READY); + gd->log_drop_count = 0; + + ut_assertok(console_record_reset_enable()); + log_run(); + + ut_asserteq(gd->log_drop_count, 3 * (LOGL_COUNT - LOGL_FIRST - 1)); + check_log_entries_flags_levels(EXPECT_DEBUG, LOGL_FIRST, CONFIG_LOG_DEFAULT_LEVEL); + + gd->flags |= GD_FLG_LOG_READY; + gd->log_drop_count = 0; + + return 0; +} +LOG_TEST_FLAGS(log_test_dropped, UT_TESTF_CONSOLE_REC); diff --git a/test/log/pr_cont_test.c b/test/log/pr_cont_test.c new file mode 100644 index 0000000000..236eff4b33 --- /dev/null +++ b/test/log/pr_cont_test.c @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2021, Heinrich Schuchardt <xypron.glpk@gmx.de> + * + * Test continuation of log messages using pr_cont(). + */ + +#include <common.h> +#include <console.h> +#include <test/log.h> +#include <test/test.h> +#include <test/suites.h> +#include <test/ut.h> +#include <linux/printk.h> + +#define BUFFSIZE 64 + +#undef CONFIG_LOGLEVEL +#define CONFIG_LOGLEVEL 4 + +DECLARE_GLOBAL_DATA_PTR; + +static int log_test_pr_cont(struct unit_test_state *uts) +{ + int log_fmt; + int log_level; + + log_fmt = gd->log_fmt; + log_level = gd->default_log_level; + + /* Write two messages, the second continuing the first */ + gd->log_fmt = BIT(LOGF_MSG); + gd->default_log_level = LOGL_INFO; + console_record_reset_enable(); + pr_err("ea%d ", 1); + pr_cont("cc%d\n", 2); + gd->default_log_level = log_level; + gd->log_fmt = log_fmt; + gd->flags &= ~GD_FLG_RECORD; + ut_assertok(ut_check_console_line(uts, "ea1 cc2")); + ut_assertok(ut_check_console_end(uts)); + + return 0; +} +LOG_TEST(log_test_pr_cont); diff --git a/test/py/tests/test_log.py b/test/py/tests/test_log.py index 387b392ce9..f889120f2b 100644 --- a/test/py/tests/test_log.py +++ b/test/py/tests/test_log.py @@ -36,3 +36,14 @@ def test_log_format(u_boot_console): run_with_format('FLfm', 'file.c:123-func() msg') run_with_format('lm', 'NOTICE. msg') run_with_format('m', 'msg') + +@pytest.mark.buildconfigspec('debug_uart') +@pytest.mark.boardspec('sandbox') +def test_log_dropped(u_boot_console): + """Test dropped 'log' message when debug_uart is activated""" + + cons = u_boot_console + cons.restart_uboot() + output = cons.get_spawn_output().replace('\r', '') + assert 'sandbox: starting...' in output + assert (not 'debug: main' in output) diff --git a/test/str_ut.c b/test/str_ut.c index ef1205dbbd..cd5045516d 100644 --- a/test/str_ut.c +++ b/test/str_ut.c @@ -19,7 +19,7 @@ static const char str3[] = "0xbI'm sorry you're alive."; /* Declare a new str test */ #define STR_TEST(_name, _flags) UNIT_TEST(_name, _flags, str_test) -static int str_test_upper(struct unit_test_state *uts) +static int str_upper(struct unit_test_state *uts) { char out[TEST_STR_SIZE]; @@ -55,7 +55,7 @@ static int str_test_upper(struct unit_test_state *uts) return 0; } -STR_TEST(str_test_upper, 0); +STR_TEST(str_upper, 0); static int run_strtoul(struct unit_test_state *uts, const char *str, int base, ulong expect_val, int expect_endp_offset, bool upper) @@ -8,6 +8,9 @@ #include <common.h> #include <console.h> #include <malloc.h> +#ifdef CONFIG_SANDBOX +#include <asm/state.h> +#endif #include <test/test.h> #include <test/ut.h> @@ -114,3 +117,18 @@ int ut_check_console_dump(struct unit_test_state *uts, int total_bytes) return upto == total_bytes ? 0 : 1; } + +void ut_silence_console(struct unit_test_state *uts) +{ +#ifdef CONFIG_SANDBOX + struct sandbox_state *state = state_get_current(); + + if (!state->show_test_output) + gd->flags |= GD_FLG_SILENT; +#endif +} + +void ut_unsilence_console(struct unit_test_state *uts) +{ + gd->flags &= ~(GD_FLG_SILENT | GD_FLG_RECORD); +} diff --git a/tools/efivar.py b/tools/efivar.py index ebfcab2f0a..67729fa850 100755 --- a/tools/efivar.py +++ b/tools/efivar.py @@ -51,21 +51,21 @@ var_guids = { } class EfiStruct: - # struct efi_var_file - var_file_fmt = '<QQLL' - var_file_size = struct.calcsize(var_file_fmt) - # struct efi_var_entry - var_entry_fmt = '<LLQ16s' - var_entry_size = struct.calcsize(var_entry_fmt) - # struct efi_time - var_time_fmt = '<H6BLh2B' - var_time_size = struct.calcsize(var_time_fmt) - # WIN_CERTIFICATE - var_win_cert_fmt = '<L2H' - var_win_cert_size = struct.calcsize(var_win_cert_fmt) - # WIN_CERTIFICATE_UEFI_GUID - var_win_cert_uefi_guid_fmt = var_win_cert_fmt+'16s' - var_win_cert_uefi_guid_size = struct.calcsize(var_win_cert_uefi_guid_fmt) + # struct efi_var_file + var_file_fmt = '<QQLL' + var_file_size = struct.calcsize(var_file_fmt) + # struct efi_var_entry + var_entry_fmt = '<LLQ16s' + var_entry_size = struct.calcsize(var_entry_fmt) + # struct efi_time + var_time_fmt = '<H6BLh2B' + var_time_size = struct.calcsize(var_time_fmt) + # WIN_CERTIFICATE + var_win_cert_fmt = '<L2H' + var_win_cert_size = struct.calcsize(var_win_cert_fmt) + # WIN_CERTIFICATE_UEFI_GUID + var_win_cert_uefi_guid_fmt = var_win_cert_fmt+'16s' + var_win_cert_uefi_guid_size = struct.calcsize(var_win_cert_uefi_guid_fmt) class EfiVariable: def __init__(self, size, attrs, time, guid, name, data): @@ -149,7 +149,7 @@ class EfiVariableStore: offs = 0 while offs < len(self.ents): var, loffs = self._next_var(offs) - if var.name == name and str(var.guid): + if var.name == name and str(var.guid) == guid: if var.attrs != attrs: print("err: attributes don't match") exit(1) @@ -292,7 +292,7 @@ def pkcs7_sign(cert, key, buf): # UEFI 2.8 Errata B "8.2.2 Using the EFI_VARIABLE_AUTHENTICATION_2 descriptor" def cmd_sign(args): - guid, name, attrs, data, size = parse_args(args) + guid, name, attrs, data, _ = parse_args(args) attrs |= EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS efi = EfiStruct() @@ -357,7 +357,10 @@ def main(): signp.set_defaults(func=cmd_sign) args = ap.parse_args() - args.func(args) + if hasattr(args, "func"): + args.func(args) + else: + ap.print_help() def group(a, *ns): for n in ns: diff --git a/tools/mtk_image.c b/tools/mtk_image.c index 2ca519483d..bde1e5da4b 100644 --- a/tools/mtk_image.c +++ b/tools/mtk_image.c @@ -246,6 +246,7 @@ static const struct brom_img_type { /* Image type selected by user */ static enum brlyt_img_type hdr_media; static int use_lk_hdr; +static bool is_arm64_image; /* LK image name */ static char lk_name[32] = "U-Boot"; @@ -276,6 +277,7 @@ static int mtk_brom_parse_imagename(const char *imagename) static const char *media = ""; static const char *nandinfo = ""; static const char *lk = ""; + static const char *arm64_param = ""; key = buf; while (key) { @@ -323,6 +325,9 @@ static int mtk_brom_parse_imagename(const char *imagename) if (!strcmp(key, "lkname")) snprintf(lk_name, sizeof(lk_name), "%s", val); + + if (!strcmp(key, "arm64")) + arm64_param = val; } if (next) @@ -354,6 +359,9 @@ static int mtk_brom_parse_imagename(const char *imagename) } } + if (arm64_param && arm64_param[0] == '1') + is_arm64_image = true; + free(buf); if (hdr_media == BRLYT_TYPE_INVALID) { @@ -458,6 +466,9 @@ static int mtk_image_verify_gen_header(const uint8_t *ptr, int print) le32_to_cpu(gfh->file_info.load_addr) + le32_to_cpu(gfh->file_info.jump_offset)); + if (print) + printf("Architecture: %s\n", is_arm64_image ? "ARM64" : "ARM"); + return 0; } @@ -523,6 +534,9 @@ static int mtk_image_verify_nand_header(const uint8_t *ptr, int print) le32_to_cpu(gfh->file_info.load_addr) + le32_to_cpu(gfh->file_info.jump_offset)); + if (print) + printf("Architecture: %s\n", is_arm64_image ? "ARM64" : "ARM"); + return 0; } @@ -581,6 +595,8 @@ static void put_ghf_common_header(struct gfh_common_header *gfh, int size, static void put_ghf_header(struct gfh_header *gfh, int file_size, int dev_hdr_size, int load_addr, int flash_type) { + uint32_t cfg_bits; + memset(gfh, 0, sizeof(struct gfh_header)); /* GFH_FILE_INFO header */ @@ -608,11 +624,15 @@ static void put_ghf_header(struct gfh_header *gfh, int file_size, /* GFH_BROM_CFG header */ put_ghf_common_header(&gfh->brom_cfg.gfh, sizeof(gfh->brom_cfg), GFH_TYPE_BROM_CFG, 3); - gfh->brom_cfg.cfg_bits = cpu_to_le32( - GFH_BROM_CFG_USBDL_AUTO_DETECT_DIS | - GFH_BROM_CFG_USBDL_BY_KCOL0_TIMEOUT_EN | - GFH_BROM_CFG_USBDL_BY_FLAG_TIMEOUT_EN); + cfg_bits = GFH_BROM_CFG_USBDL_AUTO_DETECT_DIS | + GFH_BROM_CFG_USBDL_BY_KCOL0_TIMEOUT_EN | + GFH_BROM_CFG_USBDL_BY_FLAG_TIMEOUT_EN; gfh->brom_cfg.usbdl_by_kcol0_timeout_ms = cpu_to_le32(5000); + if (is_arm64_image) { + gfh->brom_cfg.jump_bl_arm64 = GFH_BROM_CFG_JUMP_BL_ARM64; + cfg_bits |= GFH_BROM_CFG_JUMP_BL_ARM64_EN; + } + gfh->brom_cfg.cfg_bits = cpu_to_le32(cfg_bits); /* GFH_BL_SEC_KEY header */ put_ghf_common_header(&gfh->bl_sec_key.gfh, sizeof(gfh->bl_sec_key), diff --git a/tools/mtk_image.h b/tools/mtk_image.h index 4e78b3d0ff..7dda71ce88 100644 --- a/tools/mtk_image.h +++ b/tools/mtk_image.h @@ -136,7 +136,9 @@ struct gfh_brom_cfg { struct gfh_common_header gfh; uint32_t cfg_bits; uint32_t usbdl_by_auto_detect_timeout_ms; - uint8_t unused[0x48]; + uint8_t unused[0x45]; + uint8_t jump_bl_arm64; + uint8_t unused2[2]; uint32_t usbdl_by_kcol0_timeout_ms; uint32_t usbdl_by_flag_timeout_ms; uint32_t pad; @@ -146,6 +148,8 @@ struct gfh_brom_cfg { #define GFH_BROM_CFG_USBDL_AUTO_DETECT_DIS 0x10 #define GFH_BROM_CFG_USBDL_BY_KCOL0_TIMEOUT_EN 0x80 #define GFH_BROM_CFG_USBDL_BY_FLAG_TIMEOUT_EN 0x100 +#define GFH_BROM_CFG_JUMP_BL_ARM64_EN 0x1000 +#define GFH_BROM_CFG_JUMP_BL_ARM64 0x64 struct gfh_bl_sec_key { struct gfh_common_header gfh; diff --git a/tools/socfpgaimage.c b/tools/socfpgaimage.c index 3ba3c93af1..eba812fec9 100644 --- a/tools/socfpgaimage.c +++ b/tools/socfpgaimage.c @@ -61,6 +61,7 @@ #define HEADER_OFFSET 0x40 #define VALIDATION_WORD 0x31305341 +#define IMAGE_ALIGN 16 /* Minimum and default entry point offset */ #define ENTRY_POINT_OFFSET 0x14 @@ -97,7 +98,7 @@ static unsigned int sfp_hdr_size(uint8_t ver) return 0; } -static unsigned int sfp_pad_size(uint8_t ver) +static unsigned int sfp_max_size(uint8_t ver) { if (ver == 0) return sizeof(buffer_v0); @@ -106,6 +107,12 @@ static unsigned int sfp_pad_size(uint8_t ver) return 0; } +static unsigned int sfp_aligned_len(uint32_t size) +{ + /* Add 4 bytes for CRC and align to 16 bytes */ + return ALIGN(size + sizeof(uint32_t), IMAGE_ALIGN); +} + /* * The header checksum is just a very simple checksum over * the header area. @@ -208,22 +215,24 @@ static int sfp_sign_buffer(uint8_t *buf, uint8_t ver, uint8_t flags, struct image_tool_params *params) { uint32_t calc_crc; + uint32_t crc_off; /* Align the length up */ - len = ALIGN(len, 4); + len = sfp_aligned_len(len); - /* Build header, adding 4 bytes to length to hold the CRC32. */ - sfp_build_header(buf + HEADER_OFFSET, ver, flags, len + 4, params); + /* Build header */ + sfp_build_header(buf + HEADER_OFFSET, ver, flags, len, params); /* Calculate and apply the CRC */ - calc_crc = ~pbl_crc32(0, (char *)buf, len); + crc_off = len - sizeof(uint32_t); /* at last 4 bytes of image */ + calc_crc = ~pbl_crc32(0, (char *)buf, crc_off); - *((uint32_t *)(buf + len)) = cpu_to_le32(calc_crc); + *((uint32_t *)(buf + crc_off)) = cpu_to_le32(calc_crc); if (!pad_64k) return len + 4; - return sfp_pad_size(ver); + return sfp_max_size(ver); } /* Verify that the buffer looks sane */ @@ -240,7 +249,7 @@ static int sfp_verify_buffer(const uint8_t *buf) return -1; } - if (len < HEADER_OFFSET || len > sfp_pad_size(ver)) { + if (len < HEADER_OFFSET || len > sfp_max_size(ver)) { debug("Invalid header length (%i)\n", len); return -1; } @@ -274,12 +283,51 @@ static int socfpgaimage_verify_header(unsigned char *ptr, int image_size, return sfp_verify_buffer(ptr); } +static void socfpgaimage_print_header_v0(struct socfpga_header_v0 *header) +{ + printf("Image Type\t: Cyclone V / Arria V SoC Image\n"); + printf("Validation word\t: 0x%08x\n", + le32_to_cpu(header->validation)); + printf("Version\t\t: 0x%08x\n", header->version); + printf("Flags\t\t: 0x%08x\n", header->flags); + printf("Program length\t: 0x%08x\n", + le16_to_cpu(header->length_u32)); + printf("Header checksum\t: 0x%08x\n", + le16_to_cpu(header->checksum)); +} + +static void socfpgaimage_print_header_v1(struct socfpga_header_v1 *header) +{ + printf("Image Type\t: Arria 10 SoC Image\n"); + printf("Validation word\t: 0x%08x\n", + le32_to_cpu(header->validation)); + printf("Version\t\t: 0x%08x\n", header->version); + printf("Flags\t\t: 0x%08x\n", header->flags); + printf("Header length\t: 0x%08x\n", + le16_to_cpu(header->header_u8)); + printf("Program length\t: 0x%08x\n", + le32_to_cpu(header->length_u8)); + printf("Program entry\t: 0x%08x\n", + le32_to_cpu(header->entry_offset)); + printf("Header checksum\t: 0x%08x\n", + le16_to_cpu(header->checksum)); +} + static void socfpgaimage_print_header(const void *ptr) { - if (sfp_verify_buffer(ptr) == 0) - printf("Looks like a sane SOCFPGA preloader\n"); - else + const void *header = ptr + HEADER_OFFSET; + struct socfpga_header_v0 *header_v0; + + if (sfp_verify_buffer(ptr) == 0) { + header_v0 = (struct socfpga_header_v0 *)header; + + if (header_v0->version == 0) + socfpgaimage_print_header_v0(header_v0); + else + socfpgaimage_print_header_v1((struct socfpga_header_v1 *)header); + } else { printf("Not a sane SOCFPGA preloader\n"); + } } static int socfpgaimage_check_params_v0(struct image_tool_params *params) @@ -328,19 +376,25 @@ static int socfpgaimage_check_image_types_v1(uint8_t type) * To work in with the mkimage framework, we do some ugly stuff... * * First, socfpgaimage_vrec_header() is called. - * We prepend a fake header big enough to make the file sfp_pad_size(). + * We prepend a fake header big enough to include crc32 and align image to 16 + * bytes. * This gives us enough space to do what we want later. * * Next, socfpgaimage_set_header() is called. * We fix up the buffer by moving the image to the start of the buffer. - * We now have some room to do what we need (add CRC and padding). + * We now have some room to do what we need (add CRC). */ static int data_size; static int sfp_fake_header_size(unsigned int size, uint8_t ver) { - return sfp_pad_size(ver) - size; + unsigned int align_size; + + align_size = sfp_aligned_len(size); + + /* extra bytes needed */ + return align_size - size; } static int sfp_vrec_header(struct image_tool_params *params, @@ -350,7 +404,7 @@ static int sfp_vrec_header(struct image_tool_params *params, if (params->datafile && stat(params->datafile, &sbuf) == 0 && - sbuf.st_size <= (sfp_pad_size(ver) - sizeof(uint32_t))) { + sbuf.st_size <= (sfp_max_size(ver) - sizeof(uint32_t))) { data_size = sbuf.st_size; tparams->header_size = sfp_fake_header_size(data_size, ver); } @@ -378,7 +432,7 @@ static void sfp_set_header(void *ptr, unsigned char ver, /* * This function is called after vrec_header() has been called. * At this stage we have the sfp_fake_header_size() dummy bytes - * followed by data_size image bytes. Total = sfp_pad_size(). + * followed by data_size image bytes. * We need to fix the buffer by moving the image bytes back to * the beginning of the buffer, then actually do the signing stuff... */ |